The following is an attempt at a TaskManager that lets you run services "asynchronously" in BlitzMax.
Tasks may be serviced whenever, not just when you call WaitEvent, but when calling any BlitzMax function that causes a PollSystem including KeyDown, WaitEvent and many others.
There is protection built into the TaskManager that will stop services being reentrant so your callback will never be called while its running it's current refresh cycle (see _busy field).
Basically the following creates a multitasking environment where any services (functions) you need to call on a regular basis can be easily added to a tasklist.
Note how the tasks keep printing even when you are dragging the Max2D window, the trick is to never call any Max2D drawing from such tasks as I think this will create a deadlock in Windows. MaxGUI offers more flexibility for graphics rendering where the GADGETPAINT event can be used to synchronize Max2D drawing with the operating systems own expectations / requirements.
Similar to a multithreading environment you need to be careful to cooperate with the main program and any other tasks.
Also, as timers are a limited resource on some systems (16 per Windows app etc.), a single 100hz timer is used by the TaskManager to service all threads.
Possibly all uses of the word Task should be replaced with Service as it is currently required that each task return from it's callback for the system to continue.
Will add more details after answering initial questions....
yes, you sir at the back -
Tasks may be serviced whenever, not just when you call WaitEvent, but when calling any BlitzMax function that causes a PollSystem including KeyDown, WaitEvent and many others.
There is protection built into the TaskManager that will stop services being reentrant so your callback will never be called while its running it's current refresh cycle (see _busy field).
Basically the following creates a multitasking environment where any services (functions) you need to call on a regular basis can be easily added to a tasklist.
Note how the tasks keep printing even when you are dragging the Max2D window, the trick is to never call any Max2D drawing from such tasks as I think this will create a deadlock in Windows. MaxGUI offers more flexibility for graphics rendering where the GADGETPAINT event can be used to synchronize Max2D drawing with the operating systems own expectations / requirements.
Similar to a multithreading environment you need to be careful to cooperate with the main program and any other tasks.
Also, as timers are a limited resource on some systems (16 per Windows app etc.), a single 100hz timer is used by the TaskManager to service all threads.
' blitzmax multitasking example Strict Global TaskManager:TTaskManager=New TTaskManager Function task1() Print "task1" End Function Function task2() Print "task2" End Function TaskManager.StartTask 10,task1 TaskManager.StartTask 20,task2 Graphics 640,480 While WaitEvent() DebugLog CurrentEvent.toString() Wend End Type TTask Field _hertz# Field _count Field _millis Field _ticks Field _callback() Field _busy Method Start(hz#,callback()) _count=0 _hertz=hz _millis=MilliSecs() _callback=callback TaskManager._tasklist.AddFirst Self End Method Method Stop() _hertz=0 TaskManager._tasklist.Remove Self End Method Method Update(ms) Local count If _busy Or _hertz=0 Return 'ignore if stopped or already in callback _busy=True count=((ms-_millis)*_hertz)/1000 If count>_count _ticks:+1 _count=count _callback() EndIf _busy=False End Method End Type Type TTaskManager Global _tasklist:TList Global _timer:TTimer Global _event:TEvent Method New() _tasklist=New TList _event=CreateEvent( EVENT_TIMERTICK,Null,0 ) AddHook EmitEventHook,hook _timer=CreateTimer(100,_event) End Method Function hook:Object( id,data:Object,context:Object ) Local ms Local t:TTask If data<>_event Return data ms=MilliSecs() For t=EachIn _tasklist t.Update(ms) Next End Function Method StartTask:TTask( hertz#,callback() ) Local t:TTask t=New TTask t.Start hertz,callback Return t End Method End Type
Possibly all uses of the word Task should be replaced with Service as it is currently required that each task return from it's callback for the system to continue.
Will add more details after answering initial questions....
yes, you sir at the back -