エクステンション間でコミュニケーションを取ってみる見本
先日娘が学校から持って帰ってきたものをみていました。将来どんな仕事につきたいかって質問に彼女は「さんすうだいすきだから、パパみたいなぷろぐらまーになる!」ってかいてました。そうかそうか、算数好きか?面白いよな、数学なんかもっと面白いぞ…で、プログラマー?ぱぱみたいな???何かがおかしい気もしますが…まあ、いいかwww
そして話は全く関連しないのはいつもの事ですが、CEP関連に関しては移行当初より結構まじめに解説しています。しかしながら全く手をつけていない部分というのもあったりします。それがこのVulcanインターフェースクラスです。なぜやらないかというと、テストするのにエクステンション2つ用意しないといけないから「めんどくさい」というのが大きいというのは内緒にしておきましょう。とりあえず解説すると「ばるかんいんたーふぇいす」はエクステンション間の通信を行う為のクラスです。おおよその場合において、これを利用するということはかなり大きな規模のプロジェクトだと言えるでしょう。
今回は以前作ってなるほどなるほどねってなってそのまま放置してたやつをサンプルに見ていきましょう。
まずホスト側のエクステンションです。こちらはPhotoshop専用となります。何故かと言うとinvisibleなエクステンションだからです。AIやIDはこの見えないエクステンションをサポートしません。ですからPSで起動時に表示されないエクステンションをアクティブにしてサーバー的な動作をさせます。
さて、この「PSGlobalStorage」というinvisibleエクステンションはエクステンション間通信を待ち受けデータを受け取ると自身のローカルストレージへkeyとvalueを紐付けした状態で書き込みます。また、リクエストを受け取ると指定されたkeyのvalueを読み出しリクエストしたエクステンションに返します。
プロジェクトを見たい方はgitを覗いてきて下さい。
https://github.com/ten-A/CreativeSuiteSDK_Experimentals/tree/master/PSGlobalStorage
先ずはマニフェストから。AdobeCEPサンプルのLeaが作ったものとほとんど変わりません。invisibleエクステンションのマニフェストの見本みたいな構成です。
Manifest.xml
<?xml version="1.0" encoding="UTF-8"?> <ExtensionManifest Version="6.0" ExtensionBundleId="net.sytes.chuwa.psGrovalStorage" ExtensionBundleVersion="1.0.0" ExtensionBundleName="testVulcan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Author><![CDATA[Ten]]></Author> <Abstract><![CDATA[]]></Abstract> <ExtensionList> <Extension Id="net.sytes.chuwa.psGrovalStorage" Version="1.0.0" /> </ExtensionList> <ExecutionEnvironment> <HostList> <Host Name="PHXS" Version="16.0"/> <Host Name="PHSP" Version="16.0"/> </HostList> <LocaleList> <Locale Code="All" /> </LocaleList> <RequiredRuntimeList> <RequiredRuntime Name="CSXS" Version="6.0" /> </RequiredRuntimeList> </ExecutionEnvironment> <DispatchInfoList> <Extension Id="net.sytes.chuwa.psGrovalStorage"> <DispatchInfo > <Resources> <MainPath>./index.html</MainPath> </Resources> <Lifecycle> <AutoVisible>false</AutoVisible> <StartOn> <Event>applicationActivate</Event> </StartOn> </Lifecycle> <UI> <Type>Custom</Type> <Geometry> <Size> <Height>1</Height> <Width>1</Width> </Size> </Geometry> <Icons> </Icons> </UI> </DispatchInfo> </Extension> </DispatchInfoList> </ExtensionManifest>
続いてindex.htmlです。ここでvulcan.jsを読み込んでいます。
index.html
<!doctype html> <head> <meta charset="utf-8"> <title>Invisible</title> </head> <body> http://js/libs/Vulcan.js http://js/main.js </body> </html>
Javascriptの構成は以下のような物
main.js
(function(){ VulcanInterface.addMessageListener("vulcan.SuiteMessage.getMessage", getMessage); VulcanInterface.addMessageListener("vulcan.SuiteMessage.setMessage", setMessage); function getMessage(message) { var st = ""; var str = VulcanInterface.getPayload(message).split(","); if (window.localStorage) { if (localStorage.getItem(str[0])!==undefined) st = localStorage.getItem(str[0]); var customMessage = new VulcanMessage("vulcan.SuiteMessage.recieve." + str[1]); customMessage.setPayload(st); VulcanInterface.dispatchMessage(customMessage); } } function setMessage(message) { if (window.localStorage) { var str = VulcanInterface.getPayload(message).split(","); if (window.localStorage) localStorage.setItem(str[0],str[1]); } } }())
githubのプロジェクトでは使い方見本がコメントにかいてあります。まず注意しておきたいところがVulcanInterfaceはシングルインスタンスである点です。csInterfaceクラスみたいにインスタンスを作らないように注意しましょう。
addMessageListenerメソッドを利用して待ち受けるイベントを設定します。引数は1つ目がID、2つめがコールバックになります。
この例ではsetMessageを受け取るとメッセージに添付されてきたペイロードを展開してkey、valueのペアを得ます。それをそのままローカルストレージに書き込んでおしまい。
getMessageは受け取ったkeyに対応するvalueをローカルストレージから読み出し。ペイロードにセットして要求を出したエクステンションにコールバックします。
さてクライアントですが、こちらは普通のエクステンションですからAIとかIDでも大丈夫。
こちらもプロジェクトの全体像はgitで見て下さい。
https://github.com/ten-A/CreativeSuiteSDK_Experimentals/tree/master/testVulcan
とりあえずダイジェスト的に
HTMLではinputTextとボタン2つのシンプル設計。
index.html
<!doctype html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/styles.css"/> <link id="hostStyle" rel="stylesheet" href="css/theme.css"/> <title>Property Explorer</title> </head> <body class="ps-cs6">
http://js/libs/jquery-2.0.2.min.js http://js/themeManager.js http://js/libs/Vulcan.js http://js/main.js </body> </html>
で、こちらがJavascriptです。セットする場合はvulcanMessageオブジェクトを組み立てて、それをペイロードとしてホストエクステンションをコールします。
main.js
function setStr(){ var str = $("input#textString").val(); var customMessage = new VulcanMessage("vulcan.SuiteMessage.setMessage"); customMessage.setPayload("GlobalStorageTest" + "," + str); VulcanInterface.dispatchMessage(customMessage); } function getStr(){ VulcanInterface.addMessageListener("vulcan.SuiteMessage.recieve."+"GlobalStorage", recieve); function recieve(rt){ alert(VulcanInterface.getPayload(rt)); } var customMessage = new VulcanMessage("vulcan.SuiteMessage.getMessage"); customMessage.setPayload("GlobalStorageTest" + "," + "GlobalStorage"); VulcanInterface.dispatchMessage(customMessage); }
読み出しも同様で、vulcanMessageオブジェクトを組み立てdispatchすることになります。
こちらは読み出しの状況。この様にエクステンションをまたいでだけでなく、アプリケーション間もまたぐことができます。うまく使えばAIからPSを呼び出して処理したものをAIで配置して書き出し、IDにページを指示して自動貼り付けとか良くわからないこともできます。