Banner left   Banner center   Banner right

Germanenglish Home · News · Diary · Screenshots · Documentation (Wiki) · Downloads · Guestbook · Forum

Home · Benutzer registrieren · Suchen · Statistik · FAQ · Benutzerliste

Zur Zeit online: keiner ausser dir

 X-Force - Fight For Destiny - Forum —› X-Skript / Developer-Pack —› eval() ?

Autor Mitteilung
verfasst am: 25.01.2010, 10:42 · Edited by: sujin
Spielsatz Alliances

Registrierdatum: 14.07.2004, 14:47

 Beiträge: 1185
Keine Ahnung, ob eval() jemandem was sagt. Ist Bestandteil vieler interpretierten Sprachen (Java, PHP, Python, Ruby) und führt den String, der übergeben wird, als Befehl(e) der jeweiligen Sprache aus. Das ist v.A. nützlich für selbstmodifizierenden Code, aber man kann damit auch eine interaktive "Shell", die Befehle der jeweiligen Sprache akzeptiert, sehr leicht umsetzen, was jedem mit Skriptfähigkeiten das debuggen/testen sehr erleichtern könnte. Wenn PascalScript also soetwas hergibt, baut es bitte ein *zu Natter schiel, der das nach dem Mergen der Skriptsprache wissen könnte*
verfasst am: 25.01.2010, 21:36
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Was genau willst du damit machen? Ich glaube, einen entsprechenden Befehl gibt es in PascalScript nicht. Eventuell ließe sich eine Funktion basteln, die einen String als Grundlage für ein neues Skript verwendet, und dieses startet. Wäre aber schon etwas arbeit - und man müsste auch überlegen wie so ein Befehl arbeiten sollte, bzw. was man damit alles erreichen will.
verfasst am: 26.01.2010, 13:57 · Edited by: sujin
Spielsatz Alliances

Registrierdatum: 14.07.2004, 14:47

 Beiträge: 1185
Naja, PascalScript wird doch max. zu Bytecode kompiliert (wenn überhaupt) und von einem in Delphi geschriebenen Interpreter ausgeführt, oder? Prinzipiell macht eval nichts anderes, als diesen Interpreter mit einem String zu füttern, der nicht im Sourcecode stand, sondern aus irgendwelchen Quellen zur runtime entsteht.
Stark vereinfacht: Nehmen wir eine Schleife an, die das Script ausliest, und die einzelnen Zeilen an den eigentlichen Interpreter überreicht. Stößt diese Schleife auf eval(str), reicht es nicht "eval(str)" weiter, sondern nur "str".

Ich habe keine Ahnung von der Engine... aber wenn ich das hier richtig lese, ist es wohl durchaus möglich. Ich meine diesen Teil:
function TPSCE.Compile(const FileName: string): Boolean;
var
  S: TStringList;
  i: Integer;
begin
  Result:=False;
  if FileExists(FileName) then begin
    S:=TStringList.Create;
    S.LoadFromFile(FileName);
    FScr.Script:=S;
    Result:=FScr.Compile; // hier wird zur runtime kompiliert
    S.Free;
    if not Result then
      if FScr.CompilerMessageCount > 0 then
        for i:=0 to FScr.CompilerMessageCount-1 do
          Writeln(FScr.CompilerErrorToStr(i));
  end else Writeln('File not found: ', FileName);
end;

function TPSCE.Execute: Boolean;
begin
  Result:=FScr.Execute; // und hier wird das kompilierte ausgeführt
  if not Result then
    Writeln('Run-time error:' + FScr.ExecErrorToString);
end;


Das ist wohl, was du mit "String als Grundlage für ein neues Skript" meinst?
verfasst am: 27.01.2010, 01:14 · Edited by: Natter
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Zitat: sujin

Das ist wohl, was du mit "String als Grundlage für ein neues Skript" meinst?

Ja, so ungefähr. Allerdings wird man trotzdem ein ordentliches Skript benötigen - also es reicht nicht, game_api_MessageBox() zu schreiben, man bräuchte auch program Name etc. Außerdem wird für normale Skripte ja zu Beginn StartMission aufgerufen. Man müsste sich halt überlegen, wie man das am besten umsetzen will. Also user komplettes Skript eingeben lassen, oder Gerüst automatisch erzeugen (String in StartMission einfügen), oder eine Alternative programmieren, die direkt den String an den Compiler gibt. Dann müsste man aber je nach Zweck eine völlig ungewohnte Syntax verwenden, was auch nicht immer praktisch wäre. Daher die Frage, wofür du das verwenden willst. Oder soll der Befehl im laufenden Skript ausgeführt werden (also dass Skript, das den String abfragt)? Das wäre wohl die schwierigste Variante. Man müsste auch beachten, dass bei der Variante wohl jeder Eingabefehler das Skript beenden würde - und somit weitere Eingaben nicht möglich wären.
verfasst am: 27.01.2010, 02:26
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Man könnte alternativ auch überlegen, z.B. bei gesetztem DEBUG-Wert (globale Variable) ein Shortcut zu aktivieren, das im Geoscape die Stringeingabe ermöglicht.
verfasst am: 27.01.2010, 13:49
Spielsatz Alliances

Registrierdatum: 14.07.2004, 14:47

 Beiträge: 1185
Zitat: Natter
Daher die Frage, wofür du das verwenden willst.

Wie gesagt z.B. eine "Pascal-Shell" - gib "myUFO := TUFO.Create" ein, und es entsteht ein neues UFO, gib dann "myUFO.huntObject(myUFO.nearestEnemy)" ein, und das neue UFO geht aufs nächste Flugzeug los.
Zitat: Natter
Oder soll der Befehl im laufenden Skript ausgeführt werden (also dass Skript, das den String abfragt)?

Ja, das ist eigentlich Sinn der Sache. In einem seperaten Namespace ist die ganze Sache schon deutlich witzloser...
Zitat: Natter
Man müsste auch beachten, dass bei der Variante wohl jeder Eingabefehler das Skript beenden würde - und somit weitere Eingaben nicht möglich wären.

Selbstverständlich. Kennt PascalScript Exceptions? Wenn nicht, dann muss es so gehen...
verfasst am: 27.01.2010, 22:41 · Edited by: Natter
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Zitat: sujin

Ja, das ist eigentlich Sinn der Sache. In einem seperaten Namespace ist die ganze Sache schon deutlich witzloser...

Naja - wenn man mehr als eine Zeile Eingeben kann, könnte man ja auch
myUFO:=ufo_api_create_UFO;
myUFO.huntObject(myUFO.nearestEnemy)

verwenden. Imho ist die Variante eines neuen Skriptes deutlich flexibler, da man z.B. auch neue Variablen anlegen könnte (dein Beispiel würde nämlich nur klappen, wenn man vorher in weiser vorraussicht eine entsprechende Variable angelegt hätte), Events registrieren etc. Natürlich ist dafür die Eingabe etwas komplizierter. Aber man kann ja eine einfache Eingabe ermöglichen, wenn man im Skript das gewünschte Grundgerüst (z.B. als Konstante) automatisch erzeugt.

Zitat: sujin

Selbstverständlich. Kennt PascalScript Exceptions? Wenn nicht, dann muss es so gehen...

Nein. Momentan wird ein Skript bei einer Exception automatisch beeendet, und erst danach der Fehler abgefangen.
verfasst am: 28.01.2010, 15:53 · Edited by: sujin
Spielsatz Alliances

Registrierdatum: 14.07.2004, 14:47

 Beiträge: 1185
Man muss nicht unbedingt neue Variablen anlegen. Ein Dataholder (vom Skript, das zur Eingabe auffordert, verwaltet) würde schon reichen.
Natürlich kann man auch mit dem Erstellen neuer Skripte viel erreichen. Wenn ein ausführen im gleichen Namespace zu aufwändig ist, dann wird die erste Variante auch ausreichen. Wäre nur etwas eleganter für einfachere Zwecke gewesen.
verfasst am: 28.01.2010, 18:52
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
Zitat: sujin
Wäre nur etwas eleganter für einfachere Zwecke gewesen.

Naja, wenn ich davon überzeugt wäre, dass dies die bessere Variante ist, würde ich schon probieren, ob sich das lösen lässt. Da könnte man ja auch in der PascalScript-Newsgroup nachfragen. Momentan sehe ich aber noch nicht den wirklichen Vorteil, weil man auch mit neuen Skripten eine ähnlich einfache Eingabe realisieren könnte, die Variante bei Bedarf aber deutlich flexibler einsetzbar wäre. Aber vielleicht übersehe ich ja auch noch was ^^
verfasst am: 28.01.2010, 20:10
Spielsatz Alliances

Registrierdatum: 14.07.2004, 14:47

 Beiträge: 1185
Wie gesagt: Hat nur bei simplen Zwecken einen Vorteil, nämlich den geringeren Aufwand. Zugriff auf die Variablen des aufrufenden Skripts kann man mit ein minimalem Mehraufwand auch regeln. Ist also eine reine Bequemlichkeitsfrage ;-)
verfasst am: 10.09.2011, 15:35 · Edited by: Natter
Programmierer, allgemeines

Registrierdatum: 06.06.2004, 17:19

 Beiträge: 3186
2503
program YourName;

const
  Nachricht = 'Test';
  Skriptstring =
'program YourName;'+#13#10
+'procedure StartMission;'+#13#10
+'begin'+#13#10
+'game_api_MessageBox('+#39+Nachricht+#39+');'
+'end;'+#13#10
+'begin'+#13#10
+'end.';
procedure StartMission;
begin
  mission_api_StartScriptFromString(Skriptstring,nil);
end;

begin
  MissionName := 'YourName';
  MissionType := mzObjects;
end.


So, hab da mal was umgesetzt. Vielleicht kann jemand mal ein eigenständiges Skript erstellen, welches einen Button + zusätzliche Seite erstellt, in der Skripte zunächst geschrieben (und gespeichert) werden können, und dann nach belieben gestartet.



Du musst dich registrieren um auf dieses Thema zu antworten.
Login :: » Name » Passwort

Ladezeit (sec.): 0.015 · Powered by miniBB 1.6 with parts of 1.7 © 2001-2003