Scripting custom drawing in Delphi application with IF/THEN/ELSE statements?

Posted by Jerry Dodge on Programmers See other posts from Programmers or by Jerry Dodge
Published on 2012-10-31T03:49:48Z Indexed on 2012/10/31 5:20 UTC
Read the original article Hit count: 301

Filed under:
|
|
|

I'm building a Delphi application which displays a blueprint of a building, including doors, windows, wiring, lighting, outlets, switches, etc. I have implemented a very lightweight script of my own to call drawing commands to the canvas, which is loaded from a database. For example, one command is ELP 1110,1110,1290,1290,3,8388608 which draws an ellipse, parameters are 1110x1110 to 1290x1290 with pen width of 3 and the color 8388608 converted from an integer to a TColor.

What I'm now doing is implementing objects with common drawing routines, and I'd like to use my scripting engine, but this calls for IF/THEN/ELSE statements and such. For example, when I'm drawing a light, if the light is turned on, I'd like to draw it yellow, but if it's off, I'd like to draw it gray. My current scripting engine has no recognition of such statements. It just accepts simple drawing commands which correspond with TCanvas methods.

Here's the procedure I've developed (incomplete) for executing a drawing command on a canvas:

function DrawCommand(const Cmd: String; var Canvas: TCanvas): Boolean;
type
  TSingleArray = array of Single;
var
  Br: TBrush;
  Pn: TPen;
  X: Integer;
  P: Integer;
  L: String;
  Inst: String;
  T: String;
  Nums: TSingleArray;
begin
  Result:= False;
  Br:= Canvas.Brush;
  Pn:= Canvas.Pen;
  if Assigned(Canvas) then begin
    if Length(Cmd) > 5 then begin
      L:= UpperCase(Cmd);
      if Pos(' ', L)> 0 then begin
        Inst:= Copy(L, 1, Pos(' ', L) - 1);
        Delete(L, 1, Pos(' ', L));
        L:= L + ',';
        SetLength(Nums, 0);
        X:= 0;
        while Pos(',', L) > 0 do begin
          P:= Pos(',', L);
          T:= Copy(L, 1, P - 1);
          Delete(L, 1, P);
          SetLength(Nums, X + 1);
          Nums[X]:= StrToFloatDef(T, 0);
          Inc(X);
        end;
        Br.Style:= bsClear;
        Pn.Style:= psSolid;
        Pn.Color:= clBlack;
        if Inst = 'LIN' then begin
          Pn.Width:= Trunc(Nums[4]);
          if Length(Nums) > 5 then begin
            Br.Style:= bsSolid;
            Br.Color:= Trunc(Nums[5]);
          end;
          Canvas.MoveTo(Trunc(Nums[0]), Trunc(Nums[1]));
          Canvas.LineTo(Trunc(Nums[2]), Trunc(Nums[3]));
          Result:= True;
        end else
        if Inst = 'ELP' then begin
          Pn.Width:= Trunc(Nums[4]);
          if Length(Nums) > 5 then begin
            Br.Style:= bsSolid;
            Br.Color:= Trunc(Nums[5]);
          end;
          Canvas.Ellipse(Trunc(Nums[0]),Trunc(Nums[1]),Trunc(Nums[2]),Trunc(Nums[3]));
          Result:= True;
        end else
        if Inst = 'ARC' then begin
          Pn.Width:= Trunc(Nums[8]);
          Canvas.Arc(Trunc(Nums[0]),Trunc(Nums[1]),Trunc(Nums[2]),Trunc(Nums[3]),
            Trunc(Nums[4]),Trunc(Nums[5]),Trunc(Nums[6]),Trunc(Nums[7]));
          Result:= True;
        end else
        if Inst = 'TXT' then begin
          Canvas.Font.Size:= Trunc(Nums[2]);
          Br.Style:= bsClear;
          Pn.Style:= psSolid;
          T:= Cmd;
          Delete(T, 1, Pos(' ', T));
          Delete(T, 1, Pos(',', T));
          Delete(T, 1, Pos(',', T));
          Delete(T, 1, Pos(',', T));
          Canvas.TextOut(Trunc(Nums[0]), Trunc(Nums[1]), T);
          Result:= True;
        end;
      end else begin
        //No space found, not a valid command
      end;
    end;
  end;
end;

What I'd like to know is what's a good lightweight third-party scripting engine I could use to accomplish this? I would hate to implement parsing of IF, THEN, ELSE, END, IFELSE, IFEND, and all those necessary commands. I need simply the ability to tell the scripting engine if certain properties meet certain conditions, it needs to draw the object a certain way.

The light example above is only one scenario, but the same solution needs to also be applicable to other scenarios, such as a door being open or closed, locked or unlocked, and draw it a different way accordingly. This needs to be implemented in the object script drawing level. I can't hard-code any of these scripting/drawing rules, the drawing needs to be controlled based on the current state of the object, and I may also wish to draw a light a certain shade or darkness depending on how dimmed the light is.

© Programmers or respective owner

Related posts about scripting

Related posts about delphi