エディタの JavaScript 環境と統合されたカスタム プラグインを開発することは困難な場合があります。このページでは、開始するのに役立つヒントや背景情報について説明します。
Stingray エディタのフロントエンド HTML5 環境は、Chromium Embedded Framework (CEF)で実行されます。つまり、多くの重要な開発リソースが用意されている Chrome Developer Tools パネルにアクセスする必要があります。DevTools を使用してブレークポイントの設定、JavaScript コードのデバッグ、パネルの HTML の調査、およびコンソール内での JavaScript コマンドの実行を行うことができます。
DevTool を起動するには、[Ctrl]+[F12]を押します。
各 Stingray エディタ ウィンドウが DevTool の独自のインスタンスを取得します。特定のパネルに焦点を絞る場合は、このパネルをドッキング解除して独自のフローティング ウィンドウにし、このウィンドウにフォーカスがある状態で[Ctrl]+[F12]を押します。
DevTool の全機能の詳細については、Google 開発者向けサイトのホーム ページを参照してください。
エディタの JavaScript アーキテクチャの大部分は、非同期相互作用の原則を中心に構築されています。
エディタ サービスで関数を呼び出す場合は、JavaScript コードの次の行が実行されるときにこの呼び出しが終了するとは限りません。サービスは通常、呼び出された後のある時点で解決する Promise オブジェクトを返します。一般に、JavaScript サービスが C# バックエンドと連携する必要がある場合は、バックエンドとの連携が完了した時点で Promise の解決と、実際の値の生成のみを行います。
Promise とは、要求された作業が、将来の指定されていないある時点で最終的に実行されることを保証することです。これらの命令で生成される実際の値を利用する必要がある場合は、Promise の then() 関数を呼び出して、元の命令が完了したときに実行する追加作業をいくつか指定します。たとえば、次のようになります。
// This won't print the expected value, since the promise returned by getCurrentProjectPath() // has not resolved yet when the value is logged: var project_path = projectService.getCurrentProjectPath(); console.info(project_path); // Instead, we use then() to hook up new functions that will be called when the promise is finished: projectService.getCurrentProjectPath().then( function( project_path ) { console.info(project_path) }, function( error_message ) { console.error(error_message) } );
関数が Promise を返したとき(上記の例の getCurrentProjectPath() など)はいつでも、返された Promise に関する then() を呼び出して、この Promise で表される作業が終了するまでコード ブロックの実行を遅らせます。then() 関数は、それぞれコールバック関数を表す、次の 2 つのパラメータを取ります。
最初のコールバック関数は、元の Promise が正常に解決された場合に実行を取得します。この関数は通常、Promise を解決するときに、元の関数から渡されたパラメータ(上記の例の project_path など)を取得します。
2 番目のコールバック関数は、元の Promise が「拒否」された場合、つまりエラーが発生して正常に解決できない場合に、実行を取得します。この関数には通常、エラーを示す文字列が渡されます。
これらのコールバックから値を返すと、この値が then() 呼び出しの返り値になります。つまり、複数の then() 呼び出しを連結して、長いシーケンスを作成することができます。これは値を何度もトランスフォームする場合や、複数の非同期呼び出しを確定された順序で実行する場合に利用することができます。また、他の then() 呼び出しの解決内で then() 呼び出しをネストすることもできます。
JavaScript の Promise の詳細については、Mozilla Developer Network のこのページを参照してください。
Stingray エディタのフロントエンドは極めて複雑なシステムであり、多数の JavaScript モジュールを 1 つのわかりやすい機能に統合する必要があります。オートデスクでは、これらのすべてのモジュールを整理して、自社のモジュールとコード ブロックにこれらが依存している他のモジュールを「含める」構造的な方法を提供するために、require.js を使用しています。
このファイルは、プラグインに重要な影響をいくつか及ぼします。たとえば、Stingray エディタが提供するサービスまたはその他のモジュールのいずれかにアクセスできるようにするには、require.js が提供する require() 関数または define() 関数を使用する必要があります。
この仕組みを示すコード例については、「組み込みのエディタ サービスを使用する」方法に関するページを参照してください。
詳細情報については、http://requirejs.org/ も参照してください。
require() または define() の呼び出しなどでスクリプト モジュールを参照する場合は、このモジュールのパスをいくつかの方法で構築することができます。
Stingray エディタの組み込みサービスやコンポーネントを参照する必要がある場合は、editor/core フォルダの相対パスを使用します。たとえば、次の例の services および components フォルダは、editor/core/services および editor/core/components に自動的に解決されます。
require(['services/engine-service', 'components/list-view'], function(engineService, listView) { ... })
プラグインに付属している別のスクリプト ファイルを参照する必要がある場合は、呼び出しているモジュールに対する require() または define() 呼び出しを含むファイルからの単純な相対パスを使用することをお勧めします。たとえば、次のようになります。
require(['my-module-file', '../subfolder/my-other-module'], function(myModule, anotherModule) { ... })
異なるプラグイン内のスクリプト ファイルを参照する必要がある場合は、パスの先頭に @ を配置し、その後にプラグインの名前、このプラグインのフォルダ内のモジュールのパスを続けることができます。これらのプラグインのパスは require.js によって自動的に解決されます。たとえば、次のようになります。
require(['@my-other-plugin/some-module', '@asset-browser/asset-browser-actions'], function(otherPluginModule, assetBrowserActions) { ... })