executeAsModalって何?
executeAsModalはPhotoshopCC2022より導入されました。これは何かというと Photoshopの実行スコープをexecuteAsModal内に限定するもので。 そう聞くとそれも前バージョンに比べて不便じゃないか、なんでややこしくするの?と思うかもしれません。 実際CC2022に移行時に混乱した開発者も少なくありませんでした。
PhotoshopCore module
PhotoshopCC2022より新しく追加されたモジュールです。 Photoshopのアプリケーションにアクセスするためのモジュールでしょうか。 PhotoshopCoreモジュールのexecuteAsModalメソッド内に書いていく事になります。 本題のexecuteAsModalですが具体的には以下の通りです。
上記のようにexecuteAsModalスコープ内にPhotoshopのコードを書かないと行けないわけですがtry catch分で囲まないとエラーすらコンソール上に出ないので 誰もがハマる原因になっているのでしょう。スコープ内に書く必要が出てきたためCC2021に比べてCEPにやや戻ったような印象もあります。 では面倒になっただけなのかというと実は進化した部分もあります。
executeAsModal導入によってもたらされるメリット
スコープが限定的になった事によってやや面倒になりましたがPhotoshop実行時のアプリケーションの管理をすることが可能になりました。 具体的にはキャンセルの状態の取得、プログレスバーの状態もしくは更新、ダイアログのタイトル、ヒストリーの状態等です。まずアプリケーションの状態にアクセスするためにはexecuteAsModal内の 関数の引数のexecutionContextからアクセスできます。具体的には以下のようになります。
ダイアログのタイトルはcallback関数実行前に渡すことも可能で。 上のコード上ではcommandNameプロパティーの”My Script Command”をexecuteAsModalメソッドの第二引数に渡しています。 Photoshop側の処理が実行されている途中に状態を変更する場合はexecutionControlオブジェクトのreportProgressメソッドを呼び出します。
commandNameがダイアログのタイトル、valueがプログレスバーの値、0~1の間の数値を渡します。簡単にダイアログの実装が可能ですね。 またユーザーによりキャンセルが押された時の状態も確認できます。

executionControl.isCancelledよりキャンセル状態かどうかbooleanが取得できます。 trueだったらキャンセル済、falseだったらボタンが押されていない状態。 上のコードではloop処理の中でキャンセルボタンが押されるとErrorオブジェクトを返してloopを抜けるようになっています。 その他hisotryの状態も管理できます。 例えば一連のscriptによる処理を一つのhisotryにまとめたい場合などです。 executionControlのhostControlオブジェクトのメソッドより操作します。
hisotryの進行を止める前にdocumentのidを取得しています。 そしてsuspendHistoryメソッドが実行されて以降hisotryの更新が止まります。 メソッド実行時にdocumentのidをhistoryに登録する名前をオブジェクトとして引数に渡すのも忘れないでください。 最後にhistoryの更新を再開する時にresumeHistoryメソッドを呼び出します。 引数には事前にsuspendHistorメソッドより返ってきたsuspend idを渡しています。

これまで非同期の処理のキャンセルからプログレスバーまで自力で実装する必要がありました。CEPに至っては 上記の実装はパネルとアプリケーション側のシステムが分離していたため難しかったのですがexecuteAsModalの登場で このような非同期絡みのアプリケーションの実装がやりやすくなっています。