機能フラグをオンにする
TurboWarpを動かしているページ(ブラウザーのコンソールや独自のホストページなど)で、拡張を読み込む前に globalThis.STRUCTURED_DATA_MVP = true
を実行します。
TurboWarp カスタム機能拡張
JSONやYAMLを一度読み込んで名前を付ければ、あとはそのまま扱えます。項目を1つ読む、値を1つ書き換える、リストを順に処理する、そして結果をテキストに戻す。文字列の分割や、複数のリストの同期に悩む必要はありません。
speed: 4 as cfg
cfg at path $.speed to JSON 6
cfg
{"speed":6}
01 · はじめに
Structured Dataは明示的に有効にして使うプレビュー機能です。拡張を読み込む前に起動時フラグを設定したときだけブロックが表示されるので、既存のプロジェクトに意図せず影響することはありません。
TurboWarpを動かしているページ(ブラウザーのコンソールや独自のホストページなど)で、拡張を読み込む前に globalThis.STRUCTURED_DATA_MVP = true
を実行します。
下のURLをカスタム拡張機能として追加し、 サンドボックスなしで実行するを選びます。
parse JSON [ ] as [data] または
parse YAML [ ] as [data] をスクリプトに置いてクリックします。これで名前 data に値が入ります。
https://cdn.jsdelivr.net/npm/@kubohiroya/turbowarp-structured-data@0.6.2/dist/structured-data.js
サンドボックスなしの実行が必要です。スプライトとステージがそれぞれ自分の名前付きの値を持ち、繰り返しが実行中のスクリプトを追跡するため、TurboWarp VMへの直接アクセスが必要です。この拡張はネットワーク通信をせず、実行中のプロジェクト以外には何も保存しません。拡張ファイルは信頼できる配布元からのみ読み込んでください。
02 · しくみ
テキストを読み込むと、名前付きの値がスプライトの中に保持され、求めたときだけテキストに戻ります。その間、すべてのブロックはオブジェクト、配列、数値、文字列、真偽値、
null という実際の構造をそのまま扱います。
$.path で読む・確かめる・書く・消す・繰り返す
スプライト1の config とステージの config は別の値です。同じ名前でもう一度読み込むと、値が置き換わります。
名前付きの値はプロジェクトの実行中だけ存在します。停止ボタンで消え、プロジェクトファイルにも保存されません。後で使う場合は元のテキストを変数に残してください。
parse JSON [{"level":{"speed":4}}] as [cfg]
get JSON from [cfg] at path [$.level.speed]
→ 4
数値やテキストを入れる場所なら、どこでもこのレポーターを使えます。
set [save] at path [$.score] to JSON [120]
set [save] at path [$.name] to JSON ["Mio"]
[saved text] を (to JSON [save]) にする
値はJSONなので、文字列には引用符が必要です。Mio ではなく "Mio"。
もし <structured data [save] has path [$.items]?> なら(length of array in [save] at path [$.items]) と言う
先に確かめれば、データやパスがないことによるエラーを避けられます。
03 · パス
パスは値全体を表す $ から始まり、キーまたは添字を1つずつたどります。どのパスも必ず1か所だけを指すように、あえて単純にしてあります。意図した以上の場所をブロックが変更することはありません。
| パス | 指す場所 |
|---|---|
$ |
値全体。 |
$.player.name |
キー player の中のキー name。ドットで書けるキーは英字・数字・_ からなり、数字で始まらないものです。 |
$.items[0] |
配列 items の最初の項目。添字は0から数えます。 |
$["キー.ドット 入り"] |
空白・ドット・日本語を含む任意のキー。引用符と角かっこで囲みます。 |
set と delete path でできることset は値全体の置き換え、既存の配列項目の置き換え、既存オブジェクトのキーの追加・置き換えができます。$ の削除(代わりに delete structured data を使います)。04 · 繰り返し
for each in [ ] at path [ ] max [ ] は、配列の項目またはオブジェクトのキーごとに中のブロックを1回ずつ実行します。ループの中では3つのレポーターで現在位置がわかります。
parse JSON [{"items":["apple","pear"]}] as [shop]
for each in [shop] at path [$.items] max [100]
((current index) と (current value JSON)) と言う
→ 0"apple" 1"pear"
| レポーター | ループの中で返す値 |
|---|---|
current key |
オブジェクトのキー、または配列の添字(文字列)。 |
current index |
0から始まる回数。 |
current value JSON |
現在の項目(JSON)。 |
配列は添字順、オブジェクトはUnicodeのコードポイント順にソートしたキーの順です。元のテキストの書き方に結果が左右されません。
max は安全のための上限1〜1000の整数を指定します(既定は100)。項目数がこれを超えると、黙って一部を飛ばすのではなくエラーになります。
ループの中に別のループを置けます。レポーターは常に、実行中のいちばん内側のループを表します。
05 · ブロックの選び方
どのブロックも NAME で値を指定します。各引数と既定値は
Complete block reference(英語)にあります。
| やりたいこと | 使うブロック |
|---|---|
| テキストを名前付きの値として読み込む | parse JSON [ ] as [ ]、parse YAML [ ] as [ ] |
| 値全体をテキストに戻す | to JSON [ ]、to YAML [ ] |
| 名前付きの値の有無を調べる・消す | structured data [ ] exists?、delete structured data [ ] |
| 1か所を読む・確かめる | get JSON from [ ] at path [ ]、structured data [ ] has path [ ]? |
| 1か所を変更する | set [ ] at path [ ] to JSON [ ]、delete path [ ] from [ ] |
| コレクションを調べる | keys in [ ] at path [ ](ソート済み、JSON配列)、length of array in [ ] at path [ ] |
| 項目ごとに繰り返す | for each in [ ] at path [ ] max [ ] と current key、current index、current value JSON |
06 · 制限と安全性
Structured Dataは純粋なデータだけを受け付け、推測せずにはっきりと失敗します。大きな入力や特殊な入力でプロジェクトが固まったり、意味が変わったりするのを防ぎます。
1回の読み込みで、テキストは256 KiBまで、入れ子は64段まで、値の総数は50,000個までです。
エイリアス、未知のタグ、重複キー、文字列以外のキー、未対応のスカラー型、パーサーの警告は拒否します。
to JSON と to YAML は常にキーをソートします。同じデータからは同じテキストが得られるので、比較・保存・送信が簡単です。
07 · オプションの連携機能
以下の機能は既定でオフで、通常の利用には必要ありません。対応したTurboWarpビルドやホストでのみ有効にしてください。
GUIの起動オプション blockEditorDialogs=1 と
blockEditorSourceForms=1 を指定すると、parse JSON、
parse YAML、set … to JSON のJSON/YAML入力を、ソーステキストとフォームを切り替えられるエディターで編集できます。変更していないテキストは書いたとおりに保たれ、ブロックが拒否する入力は保存できません。
max の固定入力エディター
blockEditorDialogs と blockEditorFixedInputs の両方をオンにして再読み込みすると、for each の max を1〜1000の整数で編集するフォームが使えます。入力途中・空白・有限でない新しい値は保存できず、NAMEとPATHは変更しません。既存の値は編集しない限り書き換えず、接続したレポーターは評価しません。
globalThis.NAMED_DATA_REGISTRY_MVP = true を設定すると、名前付きの値が共有の Named Data
レジストリを通じて structured データとして他の拡張にも提供されます。
__TW_NAMED_DATA_FEATURE_FLAGS__ = {NAMED_DATA_SCHEMA_REF: true}
を加えると、Schemaの識別情報も受け渡します。
08 · 困ったとき
多くの問題は、起動時フラグ、JSONの引用符、停止による値の消去が原因です。ブロックが失敗すると下の安定したエラーコードのいずれかを報告し、名前付きの値は元のまま残ります。
先に globalThis.STRUCTURED_DATA_MVP = true を設定してから、拡張を読み込み直してください。フラグは起動時に1回だけ読み取られます。
get JSON はJSONを返すため、文字列 Mio は
"Mio" として返ります。保存するときも引用符を付けます:
set … to JSON ["Mio"]。
停止するとすべての名前付きの値が消えます。緑の旗が押されたときのスクリプトでもう一度読み込んでください。
名前は読み込みを実行したスプライトまたはステージに属します。必要なスプライトごとに読み込むか、JSONテキストを全体用の変数で受け渡してください。
set は存在しない親を作りません。先に親を作ってから(例:
$.player を {} に)、$.player.name を設定します。
コレクションが max より大きいためです。max を(1000まで)増やすか、データのより小さな部分を対象にしてください。
| エラーコード | 意味 |
|---|---|
INVALID_JSON / INVALID_YAML | テキストを解析できないか、許可されていないYAMLの機能を使っています。 |
PARSE_LIMIT_EXCEEDED | テキストのサイズ、深さ、値の数が上限を超えています。 |
INVALID_NAME | 名前が空か、空白だけです。 |
DATA_NOT_FOUND | このスプライトにその名前の値がありません。 |
INVALID_PATH | パスが対応している書き方になっていません。 |
PATH_NOT_FOUND | パス、またはその親が存在しません。 |
TYPE_MISMATCH | 配列を期待した場所に数値があるなど、型が異なります。 |
INDEX_OUT_OF_RANGE | 配列の添字が末尾を超えています。 |
ITERATION_LIMIT_EXCEEDED | コレクションの項目数が max を超えています。 |
ITERATION_CONTEXT_REQUIRED | current … レポーターを for each ループの外で使いました。 |