But before we go there, there's some plumbing in our way. As I hinted in a few previous entries, the fact that the reaction handlers worked at all was much more good luck than good management. All the task scheduler was doing was running any activated task until it completed. So while most of the event handlers (like the turn-when-you-bump-into-something Moove task) seemed to be working, what was actually happening was that the Agent was being told to both move forward (the default behaviour) and turn (the event handler) at the same time, and the turn won because it was last in the list. And while we got away with this for really simple behaviours, things start to break once we start adding more complicated behaviours (as all the tasks running on top of each other start to clobber and fight with each other, dead-locking the tasks and making the agent start trashing around on the screen).
So, my first job this week was to implement the default task scheduler. This little puppy works out which tasks should be running at any point based on the relative priorities assigned to tasks and the order they get run in. The default scheduler fell out a little easier than I'd been expecting - it's basically just a prioritised queue of tasks waiting to run, giving some special handling to sensors and parallel tasks.
Anyway, with this in place, the Agents now diligently stop whatever they were doing when an event interrupts them, go off and execute the tasks attached to that event, and then go back to what it was doing.
In the Agent program below, the little elephant now stops his bump'n'turn path when he notices the cow and runs after him using the new GoTo task:
You can see that I've cranked up the speed on the GoTo block so he really takes off after you. Here's a quick movie of the program in action (noting that only one of the elephants has the chase behaviour on him):
The task scheduler ensures that any bump events don't interrupt the GoTo block (as they're at the same priority and the GoTo started first) - but you could easily change this by messing about with the Task priorities.
There are still a lot of big-ticket items to add to the task framework - like explicit multi-threading which will allow the designer to have a lot more control over how tasks are scheduled. But the default behaviour above should let me do quite a bit.