0

I have a Task-Scheduler Object that basically takes

TTriggerProc=procedure(Triggername:String)of object;
TSchedulerTask=Record
    ID:Cardinal;
    Name:String;
    TriggerTime:TDateTime;
    TriggerProc:TTriggerProc;
  End;

for each task. I want to keep those tasks through a restart of the application.

Currently I save the names of the task and the Triggertime to the registry and on load use a (huge) if...then..else...if...else..if...else..if...else to assign the TriggerProc according to the name.

Can i store the TriggerProc so that it works after the load again? Or can I build some CONST-array to map names to procs? I tried to build a record array but didnt work with the ProcTask:

TaskLoader=Record
    Taskname:String;
    TaskProc:TTriggerProc;
  end;
  TTaskLoaderArr=Array of TTaskLoader;

Const
  Task1:TTaskLoader=(Taskname:'Firsttask';TaskProc:EndBathTime);

throws error E2026 "Expected a constant" (translated)

The use of this looks like this (as a code sample was requested):

procedure TMain.TaskProc1(Taskname:String);

Begin
 ...
end;

procedure TMain.AssignTask;

Begin
 Scheduler.AddTask('Task1',IncHour(Now,1),TaskProc1);
end

procedure TMain.ReloadTask(TaskName:String;TriggerTime:TDateTime);

Begin
 If TaskName='Task1' then
   Scheduler.AddTask(TaskName,TriggerTime,TaskProc1)
 else
  .
  .
  .
end;

I would like to turn the ReloadTask into something like

procedure TMain.ReloadTask(TaskName:String;TriggerTime:TDateTime);
Const
 TaskConst:TTaskLoaderArr=[(Taskname:'Task1';ProcTrigger:TaskProc1)]
Begin
 for task in TaskConst do Begin
  If Task.taskname=Taskname then
   Scheduler.AddTask(Taskname,TriggerTime,Task.ProcTrigger)
 end;
End;
Wolfgang Bures
  • 509
  • 4
  • 12
  • 1
    In a word, no, because you declared `TTriggerProc` as `of object`, which requires you to create object instances before you can assign them to `TSchedulerTask.TriggerProc`. If you [edit] your question to include your actual code, maybe so,done can provide a better alternative. – Remy Lebeau Dec 21 '20 at 07:55
  • 1
    Look at https://stackoverflow.com/questions/4186458/delphi-call-a-function-whose-name-is-stored-in-a-string. When you load the procedure names from registry, you can look up the pointers and initialize your records. This will replace your huge if then elseif.... – fpiette Dec 21 '20 at 08:40
  • If you publish complete and simple code (pas and dfm files), I'll try to fix it (I have no time to write everything for you). – fpiette Dec 21 '20 at 11:01
  • I think I would create a singleton dictionary TDictionare, and register the procedures in there from eg the initialization section. After arestart, the procs can easliy found by name. OR otherwise your objectprocedures to be public/published, then you can find them using RTTI. – H.Hasenack Dec 23 '20 at 22:51

0 Answers0