ティックイベントハンドラー
ティックイベントは、時間が経過すると発生します。handleTickイベントハンドラーを使用して、ティックイベントを取得し、時間に基づいて定期的にコマンドを実行できます。
例えば、以下のTouchWrapper
は、コンポーネントがpressed
状態にある限り、リピートカウンターを約100ミリ秒ごとにインクリメントします。ユーザーがコンポーネントを解放し、pressed
状態が終了すると、onPress
ハンドラーはカウンターをゼロにリセットします。
{
"type": "TouchWrapper",
"bind": [
{
"name": "RepeatCounter",
"value": 0
}
],
"handleTick": {
"when": "${event.source.pressed}",
"minimumDelay": 100,
"commands": {
"type": "SetValue",
"property": "RepeatCounter",
"value": "${RepeatCounter + 1}"
}
},
"onPress": {
"type": "SetValue",
"property": "RepeatCounter",
"value": 0
},
"items": {
"type": "Text",
"text": "${RepeatCounter}カウントこのボタンをホールドしました"
}
}
ティックイベントハンドラー
ティックハンドラーは、コンポーネントレベルまたはドキュメントレベルで定義できます。
すべてのコンポーネントにhandleTick
プロパティがあります。APLドキュメントには、最上位のhandleTick
プロパティもあります。
プロパティ | 型 | デフォルト | スタイル設定 | 動的 | 説明 |
---|---|---|---|---|---|
handleTick | ティックハンドラーの配列 | [] | ✕ | ✕ | ティックイベントが発生したときに実行するハンドラーです。 |
単一のティックハンドラーは、以下のプロパティを持つオブジェクトです。
プロパティ | 型 | デフォルト | 説明 |
---|---|---|---|
commands | コマンド配列 | 必須 | このハンドラーが呼び出された場合に実行するコマンドです。 |
description | 文字列 | "" | このティックハンドラーの説明です。(任意) |
minimumDelay | 数値 | 1000 | このハンドラーが再度呼び出される前に経過する必要がある最小期間(ミリ秒)。 |
when | ブール値 | true | trueの場合、このハンドラーが呼び出されます。 |
ティックハンドラーの配列は並列に実行されます。各ティックハンドラーには、when
句があります。ティックハンドラーは、次の条件の両方が満たされたときに実行されます。
- ハンドラーの
when
句がtrueと評価されたとき。 - このティックハンドラーが最後に実行されてから、
minimumDelay
ミリ秒以上経過したとき。
個々のAPL実行環境は、不定期にティックハンドラーをチェックして実行できます。APL実行環境は1秒間に60回以上ティックハンドラーをチェックする必要がありますが、リソースに制約のある環境ではチェック頻度を少なくすることもできます。
たとえば、ティックハンドラーのminimumDelay
を30に設定すると、APLは最多で30ミリ秒ごとにティックハンドラーを呼び出します。頻度はこれより低くなる場合があります。ティックカウンターを経過時間の測定に使わないでください。代わりに、elapsedTime
プロパティ、utcTime
プロパティのいずれかを使用します。
commands
このティックハンドラーが呼び出されたときに実行するコマンドの配列です。
生成されるイベントの形式は次のようになります。
"event": {
"source": {
"type": "COMPONENT_TYPE", // コンポーネントの種類または"ドキュメント"
"handler": "Tick",
"id": ID, // コンポーネントIDまたはnull(ドキュメントの場合)
"uid": UID, // ランタイムで生成されたコンポーネントの一意IDまたはnull(ドキュメントの場合)
"value": NUMBER // コンポーネントの値またはnull(ドキュメントの場合)
}
}
ティックコマンドは常に高速モードで実行されます。
minimumDelay
このティックハンドラーを次に呼び出すまでに経過する必要のある最小時間です。
when
trueの場合、システムがティックイベントを検出すると、このハンドラーが実行されます。
ティックハンドラーの例
アニメーションの例
ティックハンドラーを使用して、コマンドを定期的に実行するステートマシンを作成できます。以下は、ランダムな間隔(ただし、およそ4秒に1回)で信号機のライトを切り替えます。
{
"type": "Container",
"bind": [
{
"name": "CurrentIndex",
"value": 0
}
],
"handleTick": [
{
"minimumDelay": 1000,
"description": "信号機のライトをランダムな間隔で切り替えます。 切り替える順序は青、黄色、赤、緑色...です",
"commands": [
{
"when": "${Math.random() < 0.25}",
"type": "SetValue",
"property": "CurrentIndex",
"value": "${(CurrentIndex + 2) % 3}"
}
]
},
{
"minimumDelay": 15000,
"description": "15秒ごとに赤に戻って人々を苛立たせます",
"commands": [
{
"type": "SetValue",
"property": "CurrentIndex",
"value": 0
}
]
}
],
"items": {
"type": "Frame",
"width": 100,
"height": 100,
"borderRadius": 100,
"backgroundColor": "${index == CurrentIndex ? data : 'grey'}"
},
"data": [
"red",
"yellow",
"green"
]
}
レート制限
ティックハンドラーを使用してレート制限を追加できます。たとえば、ユーザーが画面をスクロールする情報を定期的にスキルに渡す必要があるとします。
ティックハンドラーがない場合、SendEvent
コマンドをScrollView
のonScroll
ハンドラーに割り当てることができます。このアプローチでは、コマンドがスクロールして表示内容が変わるたびにシステムに大量のSendEvent
メッセージを送信するため、問題が生じます。
{
"type": "ScrollView",
"onScroll": {
"type": "SendEvent",
"sequencer": "SendEventSequencer",
"arguments": [
"今の位置:${event.source.position}"
]
}
}
これを改善するには、handleTick
ハンドラーを使ってメッセージを抑制します。この例では、ティックハンドラーが更新情報を送信する頻度を1秒あたり1回に制限し、最後に報告した位置が変更された場合に更新したスクロール位置を送信します。
{
"type": "ScrollView",
"bind": [
{
"name": "ScrollPosition",
"value": 0
},
{
"name": "LastScrollPosition",
"value": 0
}
],
"handleTick": {
"minimumDelay": 1000,
"when": "${ScrollPosition != LastScrollPosition}",
"commands": [
{
"type": "SetValue",
"property": "LastScrollPosition",
"value": "${ScrollPosition}"
},
{
"type": "SendEvent",
"sequencer": "SendEventSequencer",
"arguments": [
"今の位置:${ScrollPosition}"
]
}
],
"onScroll": {
"type": "SetValue",
"property": "ScrollPosition",
"value": "{event.source.position}"
}
}
}