Einzelnen Beitrag anzeigen

I love Delphi

Registriert seit: 6. Nov 2007
68 Beiträge
 
#11

AW: Skript-Engine integrieren

  Alt 24. Aug 2010, 16:11
So,
habe mich jetzt in das PDF zu SE2 eingelesen, das "einbauen" ist mir allerdings nicht geglückt. Zwar bekomme ich keinerlei Fehlermeldungen, dafür aber auch nicht das was ich will. Wenn ich die Dokumentation richtig verstanden habe, brauche ich doch eine Unit die die Prozeduren registriert und den Quelltext der, welche die external-Aufrufe beinhaltet, in einer Konstanten enthält. Auf die sollte ich dann während der Ausführung zugreifen können, richtig?

Mein Code:
Delphi-Quellcode:
unit Skripting;

interface

uses AdSprites, Dialogs, murmel, SysUtils, uSE2Compiler, uSE2UnitCacheMngr, uSE2Errors, uSE2Reader, uSE2PEData, uSE2RunTime, uSE2RunAccess, uSE2UnitManager, uSE2Consts, Murmelspiel_Form1_CODE;

  procedure Prepare();
  procedure ParseSkript(ASkript: String; AMurmel: TMurmel);
  procedure ZeigeNachricht(ANachricht: String);
  procedure Murmel_SetXSpeed(AXSpeed: double; AMurmel: TMurmel);
  procedure Murmel_SetYSpeed(AYSpeed: double; AMurmel: TMurmel);

const
// diese Variable mit dem Namen der Unit füllen
C_UnitName = 'SkriptCommands';
// in diese Variable kommt der komplette Script-Quelltext
C_UnitSource =
  'unit SkriptCommands;'+#13#10+ #13#10+
  'interface'+#13#10+#13#10+
  'uses Murmel, Skripting;'+#13#10+#13#10+
  'procedure ZeigeNachricht(ANachricht: String); external;'+#13#10+
  'procedure Murmel_SetXSpeed(AXSpeed: double; AMurmel: TMurmel); external;'+#13#10+
  'procedure Murmel_SetYSpeed(AYSpeed: double; AMurmel: TMurmel); external;'+#13#10+#13#10+
  'implementation'+#13#10+#13#10+
  'end.';

var
  Compiler : TSE2Compiler;
  RunTime : TSE2RunTime;
  PEData : TSE2PE;

implementation

procedure Unit_GetSource(var Target: string);
begin
  Target := C_UnitSource;
end;

procedure Unit_RegisterMethods(const Target: TSE2RunAccess);
begin
  if Target.HasUnit(C_UnitName) then
  begin
    // hier die Funktions-Pointer setzen
    Target.Method['ZeigeNachricht[0]', C_UnitName] := @ZeigeNachricht;
  end;
end;

procedure RegisterUnit;
var p : TSE2MethodUnit;
begin
  p := TSE2MethodUnit.Create;
  p.DoRegisterMethods := Unit_RegisterMethods;
  p.DoGetUnitSource := Unit_GetSource;
  p.UnitName := C_UnitName;
  TSE2UnitManager.RegisterUnit(p);
end;

procedure ParseSkript(ASkript: String; AMurmel: TMurmel);
begin
  //ShowMessage('Hallo');
  //Das Parsen übernimmt nun die S(cript) E(ngine) 2 (http://www.delphipraxis.net/140590-scriptengine-ii-v-0-5-3-2-a-4.html)
  Compiler := TSE2Compiler.Create;
  try
    PEData := Compiler.Compile(ASkript);
    if PEData <> nil then
    begin
      RunTime := TSE2RunTime.Create;
      try
        RunTime.AppCode := PEData;
        RunTime.Initialize;
        Pause:=true; //Spiel während Skript-Ausführung anhalten
        RunTime.Run;
        Pause:=false;
        RunTime.Finalize;
        RunTime.AppCode := nil;
      finally
        RunTime.Free;
      end;
    end;
  except
    ShowMessage('Beim Ausführen des Skripts ist ein Fehler aufgetreten!');
  end;
  PEData.Free;
end;

procedure Murmel_SetXSpeed(AXSpeed: Double; AMurmel: TMurmel);
begin
  AMurmel.XSpeed := AXSpeed;
end;

procedure Murmel_SetYSpeed(AYSpeed: Double; AMurmel: TMurmel);
begin
  AMurmel.YSpeed := AYSpeed;
end;

procedure ZeigeNachricht(ANachricht: string);
begin
  ShowMessage(ANachricht);
end;

initialization
RegisterUnit;

end.
Das hier wäre der Aufruf, der funktioniert jedoch: Skripting.ParseSkript(Sprite.Skript, self); Vielleicht habe ich auch einfach das Konzept dahinter noch nicht ganz verstanden...


Ich hoffe, jemand versteht mich.

Vielen Dank!

Viele Grüße,
I love Delphi!

EDIT: Als Skript habe ich folgendes verwendet:
Delphi-Quellcode:
program MyScriptProject;
uses
SkriptCommands;
begin
ZeigeNachricht('Hallo');
end.

Geändert von I love Delphi (24. Aug 2010 um 16:15 Uhr)
  Mit Zitat antworten Zitat