home *** CD-ROM | disk | FTP | other *** search
- { Event.eng Version 1.2 86/08/25
-
- Author: Mike Babulic Compuserve ID: 72307,314 FIDO: 134/1
- 3827 Charleswood Dr. N.W.
- Calgary, Alberta,
- CANADA
- T2L 2C7
-
- This utility uses the procedure pointers routines in "ProcParm.p" to create an
- "engine" for writing event-driven programs.
-
- See EVENT.PAS for an example program.
- }
-
- {---------------------- Event Engine ----------------------------}
-
- type ActionArray = Array [0..1] of ProcPtr; {Procedures by Event No.}
- ActionPtr = ^ActionArray;
-
- var theAction: ActionPtr; {Current Action Array used by the Engine}
- EventEngineFinished: boolean; {see Quit & DoEvents}
-
-
- procedure GetNextEvent(var e:integer; p:ProcPtr); EXTERNAL ProcParm[NEAR];
-
- procedure DoProcedure(p:ProcPtr); EXTERNAL ProcParm[NEAR];
-
- procedure PassEvent(e:integer; p:ProcPtr); EXTERNAL ProcParm[NEAR];
-
- procedure DoNothing; begin end;
-
- procedure Quit;
- begin
- EventEngineFinished := TRUE;
- end;
-
- procedure MissingEvent(event:integer);
- begin
- writeln;
- writeln('*** Programmer error! Event number ',event,' has no Action.');
- writeln(' Check your ActionArray definition.');
- writeln;
- Quit;
- end;
-
- procedure DoEvents(Events:ProcPtr; Action:ActionPtr; NoSuchEvent:ProcPtr);
- {
- Events -- this is your GetNextEvent(var e:integer) procedure. It returns
- the number of the Action to execute;
- Action -- the n'th item in this array points to the procedure that will
- execute when event number n occurs;
- NoSuchEvent -- this is what will be done if the programmer was in idiot
- mode when he/she/it wrote "Events". The Action number "e" that
- was returned does not exist!
- }
- var
- a: ActionPtr;
- Finished: boolean;
- e: integer;
- begin
- {Save current state in case of recursion}
- a := theAction;
- Finished := EventEngineFinished;
- theAction := Action;
- EventEngineFinished := FALSE;
- repeat
- repeat
- GetNextEvent(e,Events);
- until (e>0) or EventEngineFinished;
- if (e>0) and (e<=Action^[0]) then
- DoProcedure(Action^[e])
- else
- PassEvent(e,NoSuchEvent); {Only a programmer error will get you here!}
- until EventEngineFinished;
- {Restore state to what it was before recursion}
- EventEngineFinished := Finished;
- theAction := a;
- end;
-
- {---------------------------- ACTIONS routines ------------------------------}
-
- procedure ACTIONS; EXTERNAL 'Actions.bin';
- { POP AX ; Offset of Actions
- MOV DX,CS ; Seg of Actions (TURBO function returns pointer = DX:AX)
- MOV SP,BP ; Standard TURBO return sequence
- POP BP
- RET 4 ; Pop function variable
- }
- {
- 'ACTIONS' is usually used called in a function of the form:
-
- function ActionsArrayInside: ActionPtr;
- begin
- ACTIONS;
- include( >3 (* 3 events *)
- /proc1 (* do this on event #1 *)
- /proc2 (* do this on event #2 *)
- /proc3 (* do this on event #3 *)
- );
- end;
-
- Causes the function to return a pointer to the ActionArray that follows
- the call to 'ACTIONS'.
- }
-
- function ActionLen(a:ActionPtr):integer;
- begin
- ActionLen := a^[0];
- end;
-
- procedure NewActions(var a:ActionPtr; count:integer);
- var i: integer;
- begin
- GetMem(a,count+count+2);
- a^[0] := count;
- for i := 1 to count do a^[i] := ofs(DoNothing);
- end;
-
- procedure DisposeActions(var a:ActionPtr);
- begin
- FreeMem(a,ActionLen(a) shl 1 + 2);
- end;
-
- procedure CopyActions(aFrom,aTo:ActionPtr);
- var i,max: integer;
- begin
- if ActionLen(aFrom) > ActionLen(aTo) then
- max:=ActionLen(aTo)
- else
- max:=ActionLen(aFrom);
- for i := 1 to max do aTo^[i] := aFrom^[i];
- for i := max+1 to aFrom^[0] do aTo^[i] := ofs(DoNothing);
- end;