提供: Japanese Scratch-Wiki

このきじは ひらがなのページがありません。ごめんなさい。編集者向け:作成する

Dispatchは、拡張機能とScratchの仮想マシン間で利用される双方向リモート・プロシージャ・コールの名前である。Dispatchは主にサンドボックス化された拡張機能への通信のために実装されているが、実際はサンドボックス化されていない、組み込みの拡張機能への通信もDispatchを経由している。サンドボックス化された拡張機能への通信には、postMessage関数が利用されている。

Dispatchを実装するクラスは、2種類存在する:

  • CentralDispatch - 仮想マシン側。シングルトンである。
  • WorkerDispatch - 拡張機能側。拡張機能あたり1つ読み込まれる。

サービス

Dispatchのメッセージを送受信するものは、「サービス」と呼ばれている。Scratch 3.0の実装では、ランタイム(サービス名runtime)、拡張機能マネージャー(サービス名extensions)、そして各拡張機能のWorker(サンドボックス化されていない場合、拡張機能のクラスインスタンス)がサービスとして登録されている。サービスは、Dispatchを実装するクラスのインスタンスを通じ別のサービスにメッセージを送信することにより、相手側に定義されたメソッドを実行する。メッセージを受信したサービスは、メッセージに含まれるメソッド名と引数を利用してメソッドを実行し、返り値を相手に送り返す。

Workerへのメソッド実行と、Workerからのメソッド実行は、非同期的に行わなければならないが、仮想マシン側同士が利便性のためDispatchを利用してメソッドを実行している場合は、同期的に実行することも可能である。

メソッドの一覧

以下に、実際に呼び出されるメソッドの一覧を示す。もちろん、これ以外のメソッドも、サービスに属する限り呼び出すことができる。

呼び出し元サービス 呼び出し元メソッド 宛先サービス 宛先メソッド 目的
ExtensionManager registerExtensionServiceSync 拡張機能のインスタンス getInfo サンドボックス化されていない拡張機能の登録時に、拡張機能に関する情報を取得する。このため、「Sync」(同期)とある。
ExtensionManager registerExtensionService ExtensionWorker getInfo サンドボックス化されている拡張機能の登録時に、拡張機能に関する情報を取得する。
ExtensionManager refreshBlocks ExtensionWorker getInfo 表示更新時に、拡張機能に関する情報を取得する。
ExtensionManager refreshBlocks Runtime _refreshExtensionPrimitives ランタイムに、拡張機能が登録するブロック(Primitive)の情報を更新するよう伝える。
ExtensionManager _registerInternalExtension ExtensionManager registerExtensionServiceSync サンドボックス化されていない拡張機能を登録する。
ExtensionManager _registerExtensionInfo Runtime _registerExtensionPrimitives ランタイムに、拡張機能のブロック(Primitive)を登録するよう伝える。
ExtensionWorker constructor ExtensionManager allocateWorker 起動したばかりのExtensionWorkerから拡張機能マネージャーに、どのURLを読み込むかの情報を要求する。
ExtensionWorker constructor ExtensionManager onWorkerInit Workerの準備が完了したことを伝える。
ExtensionWorker register ExtensionManager registerExtensionService 拡張機能を登録する。

メッセージ

Dispatchメッセージは、以下の5種類である。以下のメッセージが、postMessage関数経由で送信される。

呼び出し

基本のメッセージで、サービスのメソッドを実行する。

{
  "service": "extension_0_scratch3_pen",
  "method": "getInfo",
  "args": []
}
メッセージ
キー
service サービス名
method メソッド名
args 引数を含む配列

返り値

メソッドの返り値を送信する。

{
  "responseId": 0,
  "error": null,
  "result": 42
}
メッセージ
キー
responseId レスポンスID (数値)
error エラーを示す文字列。成功の場合null
result 返り値

サービスの登録

Workerからサービスを登録する。

{
  "service": "dispatch",
  "method": "setService",
  "args": ["extension.0.hogehoge"]
}
メッセージ
キー
service dispatch
method setService
args サービス名を含む配列

ハンドシェイク

Workerへ接続できたことを確認するために、CentralDispatchが送信する。

{
  "service": "dispatch",
  "method": "handshake",
  "args": []
}
メッセージ
キー
service dispatch
method handshake
args 空の配列

切断

Workerが切断される前に、CentralDispatchが送信する。実際は、利用されていない。

{
  "service": "dispatch",
  "method": "terminate",
  "args": []
}
メッセージ
キー
service dispatch
method terminate
args 空の配列

使用方法

仮想マシン側では/src/dispatch/central-dispatch.jsから読み込めるCentralDispatchを利用し、Worker側ではworker-dispatch.js(または互換のコード)を利用する。Dispatchにより非同期的にメソッドを実行するには、次のように書く:

// サービス名 extension.0.hoge の returnAnswerToLifeUniverseEverything メソッドを実行し、返り値を出力する
dispatch.call('extension.0.hoge', 'returnAnswerToLifeUniverseEverything').then(result => console.log(result)); // 42

サービス側:

class HogeService {
  constructor () {
    // サービスを登録する
    dispatch.setService('extension.0.hoge', this);
  }

  returnAnswerToLifeUniverseEverything () {
    return 42;
  }
}

引数がある場合は:

// サービス名 extension.0.hoge の addTwo メソッドを実行し、返り値を出力する
dispatch.call('extension.0.hoge', 'addTwo', 40).then(result => console.log(result)); // 42

サービス側:

class HogeService {
  constructor () {
    // サービスを登録する
    dispatch.setService('extension.0.hoge', this);
  }

  addTwo (i) {
    return i + 2;
  }
}

関連項目

Cookieは私達のサービスを提供するのに役立ちます。このサービスを使用することにより、お客様はCookieの使用に同意するものとします。