Call procedures in changeable order

Could anyone please help me in the following problem?

There are four (or more) procedures which look like that:

procedure TForm1.Zero;
begin
  DoThis;
end;

procedure TForm1.One;
begin
  DoThat;
end;

procedure TForm1.Two;
begin
  DoSomething;
end;

procedure TForm1.Three;
begin
  DoAnother;
end;

How could the user execute some of them in a user-desired order during run-time?
That means the user selects to execute following procedures.

Two;
Zero;
Three; //in that order,

or in another running

One;
Two;

Variables involving in these procs are declared globally in the implementation section, so their scope covers all procs.

My idea is to save addresses of each proc in an array of pointers (how?), then follow array-items in the wished order, for example [2] [0] [3] or [1] [2], then call procedure that each pointer points to.

If this idea could work efficiently, please advice me (or any other idea could implement this question). I use D6.

Best regards

Nikif
nikifAsked:
Who is Participating?
 
mlmccCommented:
Why do you need addresses/pointers?

A simple loop like

For I := 1 to 4 do
    If ProcedureName[I] = "ONE" then
        ProcedureOne
    Else If  ProcedureName[I] = "TWO" then
        ProcedureTwo
    Else If  ProcedureName[I] = "THREE" then
        ProcedureThree
    Else If  ProcedureName[I] = "FOUR" then
        ProcedureFour;

Open in new window

mlmcc
0
 
mlmccCommented:
Would they ever run a procedure more than once?

You could have the application first prompt the user for the order of execution saving the values in an array.  Then Loop through the array testing the values and calling the appropriate procedure

mlmcc
0
 
nikifAuthor Commented:
Every selected procedure will run just once.
The user decides which procedures will run in which order.
How could I get adresses?
How can I run a procedure by his pointer?

nikif
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
MerijnBSr. Software EngineerCommented:
mlmcc's solution is fine, keep in mind it's case sensitive though. If you don't want that either use uppercase() or lowercase() on both sides, or use SameText() :)
0
 
Duy PhamFreelance IT ConsultantCommented:
You don't really need to hold pointers of your procedures. Simply use procedure names and let's users to define the order of procedure calls with those names, and then using If statement to call appropriate procedures.

Sample pseudo code
procedure CallProcedure(procName: String);
begin
    if procName = 'Zero' then Zero;
    if procName = 'One' then One;
    if procName = 'Two' then Two;
    ...
end;

procedure ExecuteProceduresUsingOrderDefinedByUsers(arrOrder : Array[1..10] of String);
var i : Integer;
begin
    for i := 1 to 10 do
    begin
        CallProcedure(arrOrder[i]);
    end;
end;

Open in new window

0
 
Bruno BuesserCommented:
Use a TListBox and drag and drop for ordering the procedures. The user can simply move the procedures by mouse.
Store the procedure pointers into the list box by using a holder object since the procedures are object methods and need two pointers. It's not possible to just use the @ Operator and simply make a TObject(@proc) type cast.

Below the whole code in XE7 which you can also use in D6 with minor changes.
Set the DragMode of the ListBox1 to dmAutomatic.

unit MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure Button1Click(Sender: TObject);
    procedure ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
  private
    procedure Zero;
    procedure One;
    procedure Two;
    procedure Three;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


type
  TProc = procedure of object;

  TProcHolder = class
    Proc: TProc;
    constructor Create(AProc: TProc);
  end;

  constructor TProcHolder.Create(AProc: TProc);
  begin
    Proc:= AProc;
  end;

procedure TForm1.Zero;
begin
  ShowMessage('Zero');
end;

procedure TForm1.One;
begin
  ShowMessage('One');
end;

procedure TForm1.Two;
begin
  ShowMessage('Two');
end;

procedure TForm1.Three;
begin
  ShowMessage('Three');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to ListBox1.Items.Count - 1 do
    TProcHolder(ListBox1.Items.Objects[i]).Proc;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListBox1.Items.AddObject('Zero', TProcHolder.Create(Zero));
  ListBox1.Items.AddObject('One', TProcHolder.Create(One));
  ListBox1.Items.AddObject('Two', TProcHolder.Create(Two));
  ListBox1.Items.AddObject('Three', TProcHolder.Create(Three));
end;

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  SourceIndex: Integer;
begin
  SourceIndex:= ListBox1.ItemAtPos(Point(X,Y),True);
  ListBox1.Items.Exchange(ListBox1.ItemIndex,SourceIndex);
end;

procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept:= True;
end;

end.

Open in new window

0
 
nikifAuthor Commented:
Thank you all you looked into this question.
I should award 220 points to mlmcc for the simplicity of the solution and prompt reply. It was much simplier than I thought.
I give 180 points to Duy Pham who also described a similarly simple solution.
I kept 100 points for Bruno Buesser for the very strict reply and completeness of his solution, although I cannot still test it in XE7. I am in the prehistoric era of D6.
Kind regards
Nikif
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.