🔧
[Verse]Subscribeのコールバックにパラメータを追加してみた!
やりたいこと
listenableなイベントのSubscribeメソッドに渡されるコールバックはペイロードの型のパラメータしか受け取れないため、コールバックに任意の型のパラメータを追加できるような実装を考えてみました。
やってることとしてはこちらの記事とあまり変わらないのですが、相互依存の解消とパラメトリック型を使用することで抽象度を上げています。抽象度を上げることで、追加したい型とペイロードの型のさまざまな組み合わせでも使いやすくなるように実装しています。
動画
全体のコード
button_management_device.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/UI }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Colors }
using { /Verse.org/Simulation }
using { CustomCallback }
ToMessage<localizes>(Text : string)<computes> : message = "{Text}"
button_management_device := class(creative_device):
@editable
Buttons : []button_device = array{}
OnBegin<override>()<suspends>:void=
for:
Index -> Button : Buttons
CstmCallback := custom_callback(string, agent):
Value := "Button{Index} Clicked!"
Callback := OnInteracted
do:
Button.InteractedWithEvent.Subscribe(CstmCallback.Invoke)
OnInteracted<private>(Str : string, Agent : agent) : void =
if (PlayerUI := GetPlayerUI[player[Agent]]):
Widget := CreateWidget(Str)
PlayerUI.AddWidget(Widget)
spawn{ DelayedRemoveWidget(PlayerUI, Widget) }
DelayedRemoveWidget<private>(PlayerUI : player_ui, Widget : widget)<suspends> : void =
Sleep(3.0)
PlayerUI.RemoveWidget(Widget)
CreateWidget<private>(Str : string) : widget =
return canvas:
Slots := array:
canvas_slot:
Anchors := anchors:
Minimum := vector2{X := 0.5, Y := 0.6}
Maximum := vector2{X := 0.5, Y := 0.6}
Offsets := margin{Top := 0.0, Left := 0.0, Right := 0.0, Bottom := 0.0}
Alignment := vector2{X := 0.5, Y := 0.5}
SizeToContent := true
Widget := text_block{ DefaultText := ToMessage(Str) }
custom_callback.verse
CustomCallback<public> := module:
custom_callback<public>(t1:type, t2:type) := class:
Value<public> : t1
Callback<public> : tuple(t1, t2) -> void
Invoke<public>(Payload : t2) : void = Callback(Value, Payload)
解説
custom_callbackクラスのt1の型には追加したいパラメータの型をt2にはイベントのペイロードの型を入れます。
button_management_device.verse
OnBegin<override>()<suspends>:void=
for:
Index -> Button : Buttons
#t1にstring型、t2にagent型を指定
CstmCallback := custom_callback(string, agent):
Value := "Button{Index} Clicked!" #追加のパラメータ
Callback := OnInteracted
do:
#button_deviceクラスのInteractedWithEventのペイロードはagent型
Button.InteractedWithEvent.Subscribe(CstmCallback.Invoke)
今回の場合はstring型のパラメータを追加したいので、t1にstring型、t2にbutton_deviceクラスのInteractedWithEventのペイロードであるagent型を指定しています。
Discussion