Closed stefnotch closed 4 years ago
The problem is the MicroThread
being created when you call AddOnEventAction
will listen for the SenderScript.SomeEvent
indefinitely (until the game is closed). Even if you change scenes, the Entity
that HandleSomeEvent
is declared in is removed from the scene or the ScriptComponent
is removed from the Entity
.
So if your game logic requires you to stop handling that event i.e. player is dead or you change to the next level you need a way to stop handling the event. The list was just a convenience so if you started multiple MicroThreads
you could stop them all with one method call. You could also just store them in variables. i.e.
someEventMicroThread = Script.AddOnEventAction(SenderScript.SomeEvent, HandleSomeEvent);
//.......
someEventMicroThread.Cancel();
This is the same as if you used the out of the box Script.AddTask
.
It might be possible to make it so it automatically handles the Scene
, Entity
or ScriptComponent
being removed. (Possibly requiring an extra parameter.) Which is probably the common scenario when you would want to stop handling the event.
As for Rx it's, probably not a massive amount of work to create methods like:
public static IObservable<T> AsObservable<T>(
this ScriptSystem scriptSystem,
EventKey<T> eventKey,
long priority = 0L)
{
//...
}
I personally have never used Rx so wasn't high on my priority. But if there is demand for it we can look into it.
I tried to create a ScriptComponent.AddTask()
, that adds a task which gets cancelled when the script gets cancelled. That sort of approach could also be used for event handlers.
What do you think about it?
public static class ScriptComponentExtensions
{
public static void AddTask(this ScriptComponent script, Func<Task> task, long priority = 0L)
{
MicroThread t = script.Script.AddTask(task, priority);
script.Entity.GetOrCreate<TaskDisposer>().Tasks.Add(t);
}
private class TaskDisposer : ScriptComponent
{
public List<MicroThread> Tasks { get; } = new List<MicroThread>();
public override void Cancel()
{
Tasks.ForEach(task => task.Cancel());
}
}
}
That is an option. I was going to try something a bit fancier/trickier.
Regarding Rx, this seems to be fairly similar to your Script.AddTask(DelayedTask, TimeSpan.FromSeconds(2));
.
Closing this issue for now.
What's the point of the List of MicroThreads? Doesn't
AddOnEventAction
take care of that stuff?I wonder if it's possible to make the syntax more elegant. (And as powerful as Rx?)