Mega Code Archive

 
Categories / Delphi / Examples
 

Triggered Callback Stack

Title: Triggered Callback Stack Question: Store callaback functions on a stack and link to a string based list to look for in a buffer. To be used as a parser engine. Answer: Here is the source code for a component that holds a stringlist. In the StringList's objects array are stored a stack of pointers. The pointers are callback functions that the developer can use to create string based triggers. The trigger happens when the buffer property is set. The pointers are in a stack to allow the developer to change the callback temporarily and be able to easily return to the normal everyday callback. --- TriggerCB --- unit TriggerCB; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, contnrs; type PFunc = function (msg:String) : Integer; TTriggerType = ( ttPrefix, ttSubStr ); TTriggerList = class(TStringList) private list:TStringList; public procedure AddFunc(s: String; p: PFunc); procedure AddTrigger(s: String; p: PFunc); function GetFunc(s: String): PFunc; function GetTriggeredFunc(s: String; t: TTriggerType): PFunc; procedure RemoveFunc(s: String); procedure RemoveTrigger(s: String); constructor Create; destructor Destroy; override; end; TTriggerCB = class(TComponent) private FTriggerType: TTriggerType; FTriggerList: TTriggerList; Fbuffer: String; procedure SetTriggerType(const Value: TTriggerType); procedure SetTriggerList(const Value: TTriggerList); procedure Setbuffer(const Value: String); { Private declarations } protected { Protected declarations } public constructor Create(AOwner:TComponent); override; destructor Destroy; override; published property TriggerType:TTriggerType read FTriggerType write SetTriggerType default ttPrefix; property TriggerList:TTriggerList read FTriggerList write SetTriggerList; property buffer:String read Fbuffer write Setbuffer; { Published declarations } end; procedure Register; implementation procedure Register; begin RegisterComponents('Samples', [TTriggerCB]); end; { TTriggerCB } constructor TTriggerCB.Create(AOwner:TComponent); begin inherited; FTriggerList := TTriggerList.Create; FTriggerType := ttPrefix; end; destructor TTriggerCB.Destroy; begin inherited; FTriggerList.free; end; procedure TTriggerCB.Setbuffer(const Value: String); var p:PFunc; begin Fbuffer := Value; p:=FTriggerList.GetTriggeredFunc(Fbuffer, FTriggerType); if (@pNil) then p(Fbuffer); end; procedure TTriggerCB.SetTriggerList(const Value: TTriggerList); begin FTriggerList := Value; end; procedure TTriggerCB.SetTriggerType(const Value: TTriggerType); begin FTriggerType := Value; end; { TTriggerList } procedure TTriggerList.AddFunc(s: String; p: PFunc); var i:Integer; stack:TStack; begin i := list.IndexOf(s); if (i-1) then begin stack := TStack(list.Objects[i]); if (stackNil) then begin stack.Push(@p); end; end; end; procedure TTriggerList.AddTrigger(s: String; p: PFunc); var stack:TStack; begin stack := TStack.Create; list.AddObject(s, stack); stack.Push(@p); end; constructor TTriggerList.Create; begin list:=TStringList.Create; end; destructor TTriggerList.Destroy; begin inherited; while list.Count 0 do begin list.Objects[0].free; list.Delete(0); end; list.Free; end; function TTriggerList.GetFunc(s: String): PFunc; var i:Integer; stack:TStack; begin Result:=Nil; i := list.IndexOf(s); if (i-1) then begin stack := TStack(list.Objects[i]); if (stackNil) then begin if (stack.Count0) then Result := Pointer(stack.Peek); end; end; end; function TTriggerList.GetTriggeredFunc(s: String; t: TTriggerType): PFunc; var i:Integer; p:Integer; begin Result:=Nil; for i:=0 to list.Count-1 do begin p := Pos(list.Strings[i], s); if (t = ttSubStr) and (p 0) then break; if (t = ttPrefix) and (p = 1) then break; end; if (i Result := GetFunc(list.Strings[i]); end; end; procedure TTriggerList.RemoveFunc(s: String); var i:Integer; stack:TStack; begin i := list.IndexOf(s); if (i-1) then begin stack := TStack(list.Objects[i]); if (stackNil) then begin if stack.Count0 then stack.Pop; end; end; end; procedure TTriggerList.RemoveTrigger(s: String); var i:Integer; begin i := list.IndexOf(s); if (i-1) then begin list.Objects[i].free; list.Delete(i); end; end; end. --- Unit1 -- unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, TriggerCB, StdCtrls, shellapi; type TForm1 = class(TForm) TriggerCB1: TTriggerCB; Button1: TButton; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} function MyFunc(s:String):Integer; begin ShowMessage(s); result:=0; end; function MyFunc2(s:String):Integer; begin ShowMessage('2'); result:=0; end; procedure TForm1.FormCreate(Sender: TObject); begin TriggerCB1.TriggerType := ttSubStr; TriggerCB1.TriggerList.AddTrigger('wow', @MyFunc); TriggerCB1.TriggerList.AddFunc('wow', @MyFunc2); TriggerCB1.buffer := 'it is wownderful'; TriggerCB1.TriggerList.RemoveFunc('wow'); TriggerCB1.buffer := 'it is wownderful'; TriggerCB1.TriggerList.RemoveFunc('wow'); TriggerCB1.buffer := 'it is wownderful'; end; end.