Photoshop Extension 開発におけるデバッグ効率化対策
はじめに
以前、このブログで Live2D のことを書いてました。今はテクニカルアーティスト室所属の dockurage です。 テクニカルアーティスト室では、Maya、Unity、Photoshop といったソフトウェアにおける業務効率化のためにツールを作成しています。 本記事では私が担当していた Photoshop のツール制作についてのデバッグの対策のお話をしたいと思います。
Adobe の拡張機能について
Photoshop でツールを作成する場合、いくつか選択肢があります。 その中でベーシックな、アプリケーションに統合されたパネルを開発することができる CEP(Common Extensibility Platform)という拡張方法があります。弊社のプロジェクトでは主にこの CEP を使用して業務改善ツールの開発を行なっています。
CEPについて
CEP では2つの VM が動作しておりそれぞれに実装を行う必要があります。 パネルデザイン (UI部分) には HTML5/CSS/JavaScript を使用する Panel VM と Photoshop の動作制御には ExtendScript を使用する Host VM にわかれています。
具合例を挙げて動作の流れを説明すると、「ボタンを押すと新規レイヤーがひとつ追加される機能」の場合、 ユーザーが操作するボタンは Panel VM で動作し、そのクリック操作をフックにして Host VM で新規レイヤーを作成するという流れになります。
CEP の今後について
補足ですが、実は M1 Mac が登場したことにより、以降の機種について、 CEP は Rosetta 2 でしか動作しなくなりました。そのかわりに UXP に移行していく流れがあります。 弊社では Windows / Mac 両方対応しているため、今後 UXP への移行を検討する時期にきています。
CEPのデバッグについて
CEP の UI パネルは Chromium Embedded Framework 上で表示されています。 そのため Chrome の機能が用意されており、デバッグについても同じで Chrome Developer Tool を使用することができます。 ただしこれは Panel VM に限ってであり Host VM のデバッグを効率化できるものではありません。
[補足] デバッグ環境の設定方法について
.debug について
エクステンションフォルダのルートに .debug ファイルを作成し、そこにアプリケーション (Photoshop, Illustrator など) ごとにデバッグ画面をどの Port で表示するかを設定します。
.debug
<?xml version="1.0" encoding="UTF-8"?>
<ExtensionList>
<Extension Id="extension_name">
<HostList>
<!-- Photoshop -->
<Host Name="PHXS" Port="8188"/>
</HostList>
</Extension>
</ExtensionList>
Developer Tool の起動について
Chrome ブラウザを起動し URL フォームに下記を入力します。
chrome://inspect/#devices
「Devices」>「Remote Target」>「[CEP Extension]」を選択すると CEP Extension を対象とした Developer Tool が起動します。
Panel VM と Host VM の連携について
前項で書いたここについて深堀していきます。
ただしこれは Panel VM に限ってであり Host VM のデバッグを効率化できるものではあり ません。
基礎的な連携パターン
CEP でアプリケーションを作るにあたり、Panel VM と Host VM はセットで作成する必要が出てきます。 もっとも基礎的な Panel VM から Host VM に処理を投げる場合は下記の関数を使用します。
csInterface.evalScript("<任意のスクリプト文字列>");
例えば下記のように記述すると文字列で ExntendScript を実行します。
let csInterface = new CSInterface();
csInterface.evalScript(`var a = 1+1; a += 1; a;`, result => {
console.log(`Host VM 側で実行した結果 a = ${result} です`);
});
[実行結果]
Host VM 側で実行した結果 a = 3 です
JavaScript と ExtendScript でファイルを分割するパターン
もしくは ExtendScript 用のファイルを別に作成して関数を定義し、JavaScript 用のファイルにはその関数の呼び出しだけを書くことでも動作します。
[hostvm.jsx] (ExtendScript)
function test(a, b) {
return a + b;
}
[panelvm.js] (JavaScript)
let csInterface = new CSInterface()
csInterface.evalScript(`test(1, 1)`, result => {
console.log(`Host VM 側で実行した結果 a = ${result} です`);
})
[実行結果]
Host VM 側で実行した結果 a = 2 です
JavaScript と ExtendScript の連携中にエラーを起こした場合
例えば Host Vm 内でシンタックスエラーを起こさせるためにあえて「,」を入れます。
let csInterface = new CSInterface();
csInterface.evalScript(`var a = 1+1; ,; a += 1; a;`, result => {
console.log(`Host VM 側で実行した結果 a = ${result} です`);
});
[実行結果]
Host VM 側で実行した結果 a = EvalScript error. です
するとコールバック関数の引数である「result」には「 EvalScript error.」という文字列が返却されます。Host VM で、なんのエラーによるものなのか、動作はどこで止まっているかなどの判断はできません。 これが CEP 開発時に問題が発生した時に、問題箇所を洗い出すのに時間がかかる原因となります。
ここまでが前談となります。以降はこの問題をどう解消するかの本題になります。