Dê uma olhada no DWS . É essencialmente o script Delphi no Delphi. (Ou bastante próximo. É o seu próprio dialeto de Object Pascal, mas o autor fez um trabalho impressionante.)
Estou construindo uma aplicação Delphi que exibe um projeto de um prédio, incluindo portas, janelas, fiação, iluminação, tomadas, interruptores, etc. Eu implementei um script muito leve para chamar comandos de desenho para a tela. , que é carregado de um banco de dados. Por exemplo, um comando é ELP 1110,1110,1290,1290,3,8388608
que desenha uma elipse, os parâmetros são 1110x1110 a 1290x1290 com largura de caneta de 3 e a cor 8388608
convertida de um inteiro para um TColor
.
O que estou fazendo agora é implementar objetos com rotinas de desenho comuns e gostaria de usar meu mecanismo de script, mas isso exige instruções IF/THEN/ELSE
e tal. Por exemplo, quando estou desenhando uma luz, se a luz estiver acesa, gostaria de desenhar amarelo, mas, se estiver apagada, gostaria de desenhar em cinza. Meu mecanismo de script atual não reconhece essas declarações. Apenas aceita comandos de desenho simples que correspondem aos métodos TCanvas
.
Aqui está o procedimento que desenvolvi (incompleto) para executar um comando de desenho em uma tela:
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;
O que eu gostaria de saber é o que é um bom mecanismo de script leve de terceiros que eu poderia usar para realizar isso? Eu odiaria implementar a análise de IF
, THEN
, ELSE
, END
, IFELSE
, IFEND
e todos esses comandos necessários. Eu preciso simplesmente da capacidade de dizer ao mecanismo de script se determinadas propriedades atendem a certas condições, ele precisa desenhar o objeto de uma certa maneira.
O exemplo da luz acima é apenas um cenário, mas a mesma solução também precisa ser aplicável a outros cenários, como abrir ou fechar uma porta, travar ou destravar e desenhar de maneira diferente. Isso precisa ser implementado no nível de desenho de script do objeto. Eu não posso codificar qualquer dessas regras de script / desenho, o desenho precisa ser controlado com base no estado atual do objeto, e eu também posso querer desenhar uma luz com um certo tom ou escuridão dependendo de como a luz é.
Integração Lua?
Lua é uma linguagem projetada para incorporação (também pode ser executada de maneira independente)
Alta velocidade como na classe de intérprete, bom uso controlado de RAM. Muito boa integração com C / C ++ Borland também (não tenho Delphi legal para verificar), existem poucas integrações Delphi.