I want to know this too, I tried a pile of things as well but nothing worked. I think I saw on discord somewhere that it isn’t implemented yet? Not sure though.
Hello,
you can’t initialize a listenable interface inside a class.
For now, I recommend exposing an event like the CountdownEndedEvent (for example OnTimerIteration/OnTick) that lets users of the class Await it. You’d then Signal the event when needed.
I haven’t played around with it much, but maybe something like this could also be helpful to you:
# In this case the functions we accept should take one string parameter and return void.
my_fun := type{_(:string):void}
my_subscribable := class:
var Funs<private>:[]my_fun = array{}
Subscribe<public>(Fun:my_fun):void =
set Funs += array{Fun}
Dispatch<private>():void =
for (Fun:Funs):
Fun("Hello")
o/ Is there a way to implement custom subcribable events with generics?
Ideally You’d want my_subscribable use subscribable and signalable, be parametric type passing t:type to Funs as you do.
But seems we are hitting dead end of “sane” here with mutables not implemented in parametric types, so how would one go about using those interfaces in custom events?
By “sane” dead end I mean relatively not way-arounds approach, for example user Ep8Script#8819 posted this:
custom_cancelable<public> := class:
var Canceled : logic = false
CancelEvent : event() = event(){}
Cancel():void=
set Canceled = true
CancelEvent.Signal()
custom_subscribable<public>(t:type)<computes> := class<public>(awaitable(t)):
InnerEvent : event(t) = event(t){}
Subscribe(Callback:type {__(:t):void}):custom_cancelable=
Cancelable := custom_cancelable{}
spawn{_WaitForEvent(Callback, Cancelable)}
Cancelable
_WaitForEvent(Callback:type {__(:t):void}, Cancelable: custom_cancelable)<suspends>:void=
race:
# Wait for payload to be sent
loop:
Payload := InnerEvent.Await()
# Just in case
if(not Cancelable.Canceled?):
Callback(Payload)
else:
break # Just in case
# Cancelable got canceled
Cancelable.CancelEvent.Await()
Signal<public>(Payload:t):void =
InnerEvent.Signal(Payload)
Await<override>()<suspends>:t=
InnerEvent.Await()
These might not be stored along in an array of cancelable, but it seem to work good (forgetting that it uses spawns)
I’m not sure that it works flawlessly for now, so if someone wants to try it out
EDIT: For anyone wanting to use this, just need to warn you, the garbage collector will not clean up the suspending calls (which is obvious but I didn’t realise at the time)
So each .Subscribe() call will stay alive untill you manually call .Cancel() or .CancelAll()
So to say, try to not dynamically generate .Subscribe() calls and you should be fine
Here I’ve writen a custom timer divice, which we can call any where in our code, with events call in every secound and on the end of the timer that we can subscribe.
Check it here: