From 0534ed2bd02da9eb9676c8b0002706e1b4d75beb Mon Sep 17 00:00:00 2001 From: Olly Date: Sun, 26 Nov 2023 20:52:33 +0000 Subject: [PATCH] Support sending script though communication --- Source/Simba.lpr | 37 +++++++++------ Source/script/simba.script.pas | 30 +++++++------ Source/script/simba.script_communication.pas | 16 +++++++ Source/script/simba.scriptthread.pas | 45 ++++++++++--------- Source/simba.env.pas | 37 +++++---------- Source/simba.mufasatypes.pas | 2 +- Source/simba.scriptinstance_communication.pas | 8 ++++ Source/simba.scripttab.pas | 19 +++++--- 8 files changed, 113 insertions(+), 81 deletions(-) diff --git a/Source/Simba.lpr b/Source/Simba.lpr index 5258424a8..90e6ee80b 100644 --- a/Source/Simba.lpr +++ b/Source/Simba.lpr @@ -78,24 +78,35 @@ if (not Application.HasOption('open')) and (Application.HasOption('run') or Application.HasOption('compile')) then begin - if not FileExists(Application.Params[Application.ParamCount]) then - begin - DebugLn('Script "' + Application.Params[Application.ParamCount] + '" does not exist.'); - - Halt(); - end; - if Application.HasOption('simbacommunication') then SimbaProcessType := ESimbaProcessType.SCRIPT_WITH_COMMUNICATION else SimbaProcessType := ESimbaProcessType.SCRIPT; - TSimbaScriptRunner.Create( - Application.Params[Application.ParamCount], - Application.GetOptionValue('simbacommunication'), - Application.GetOptionValue('target'), - Application.HasOption('compile') - ); + // Script will be sent though communication + if (Application.Params[Application.ParamCount] = '--run') or (Application.Params[Application.ParamCount] = '--compile') then + begin + TSimbaScriptRunner.Create( + Application.GetOptionValue('simbacommunication'), + Application.GetOptionValue('target'), + Application.HasOption('compile') + ); + end else + // Script will be loaded from file + begin + if not FileExists(Application.Params[Application.ParamCount]) then + begin + DebugLn('Script "' + Application.Params[Application.ParamCount] + '" does not exist.'); + Halt(); + end; + + TSimbaScriptRunner.Create( + Application.Params[Application.ParamCount], + Application.GetOptionValue('simbacommunication'), + Application.GetOptionValue('target'), + Application.HasOption('compile') + ); + end; end else begin SimbaProcessType := ESimbaProcessType.IDE; diff --git a/Source/script/simba.script.pas b/Source/script/simba.script.pas index 816ee26a5..718550672 100644 --- a/Source/script/simba.script.pas +++ b/Source/script/simba.script.pas @@ -40,7 +40,6 @@ TSimbaScript = class(TObject) function GetState: ESimbaScriptState; - procedure SetSimbaCommunicationServer(Value: String); procedure SetTargetWindow(Value: String); procedure SetState(Value: ESimbaScriptState); public @@ -50,7 +49,6 @@ TSimbaScript = class(TObject) property Compiler: TSimbaScript_Compiler read FCompiler; property SimbaCommunication: TSimbaScriptCommunication read FSimbaCommunication; - property SimbaCommunicationServer: String write SetSimbaCommunicationServer; property TargetWindow: String write SetTargetWindow; @@ -61,14 +59,15 @@ TSimbaScript = class(TObject) property Script: String read FScript write FScript; property ScriptFileName: String read FScriptFileName write FScriptFileName; - constructor Create; + constructor Create(Communication: TSimbaScriptCommunication); reintroduce; overload; + constructor Create(FileName: String; Communication: TSimbaScriptCommunication = nil); reintroduce; overload; destructor Destroy; override; end; implementation uses - simba.env, simba.datetime, simba.httpclient, simba.target, + simba.env, simba.files, simba.datetime, simba.httpclient, simba.target, simba.script_pluginloader; procedure TSimbaScript.DoCompilerHint(Sender: TLapeCompilerBase; Hint: lpString); @@ -217,14 +216,6 @@ function TSimbaScript.GetState: ESimbaScriptState; end; end; -procedure TSimbaScript.SetSimbaCommunicationServer(Value: String); -begin - if (Value = '') then - Exit; - - FSimbaCommunication := TSimbaScriptCommunication.Create(Value); -end; - procedure TSimbaScript.SetTargetWindow(Value: String); begin if (Value = '') then @@ -278,11 +269,24 @@ function TSimbaScript.Run: Boolean; Result := True; end; -constructor TSimbaScript.Create; +constructor TSimbaScript.Create(Communication: TSimbaScriptCommunication); +begin + inherited Create(); + + FState := bTrue; + + FSimbaCommunication := Communication; + FScript := FSimbaCommunication.GetScript(FScriptFileName); +end; + +constructor TSimbaScript.Create(FileName: String; Communication: TSimbaScriptCommunication); begin inherited Create(); FState := bTrue; + + FScriptFileName := FileName; + FScript := TSimbaFile.FileRead(FileName); end; destructor TSimbaScript.Destroy; diff --git a/Source/script/simba.script_communication.pas b/Source/script/simba.script_communication.pas index 09dbabfdf..0bbf76899 100644 --- a/Source/script/simba.script_communication.pas +++ b/Source/script/simba.script_communication.pas @@ -16,6 +16,8 @@ interface type TSimbaScriptCommunication = class(TSimbaIPCClient) public + function GetScript(out Name: String): String; + function GetSimbaTargetWindow: TWindowHandle; function GetSimbaTargetPID: TProcessID; function GetSimbaPID: TProcessID; @@ -37,6 +39,20 @@ TSimbaScriptCommunication = class(TSimbaIPCClient) implementation +function TSimbaScriptCommunication.GetScript(out Name: String): String; +begin + BeginInvoke(Integer(ESimbaCommunicationMessage.SCRIPT)); + + try + Invoke(); + + Name := FResult.ReadAnsiString(); + Result := FResult.ReadAnsiString(); + finally + EndInvoke(); + end; +end; + function TSimbaScriptCommunication.GetSimbaTargetWindow: TWindowHandle; begin BeginInvoke(Integer(ESimbaCommunicationMessage.SIMBA_TARGET_WINDOW)); diff --git a/Source/script/simba.scriptthread.pas b/Source/script/simba.scriptthread.pas index 9c6c407c5..f7030421a 100644 --- a/Source/script/simba.scriptthread.pas +++ b/Source/script/simba.scriptthread.pas @@ -23,18 +23,15 @@ TSimbaScriptRunner = class(TThread) procedure DoDebugLn(Flags: EDebugLnFlags; Text: String); procedure DoCompilerHint(Sender: TLapeCompilerBase; Hint: lpString); - procedure DoTerm(Sender: TObject); + procedure DoApplicationTerminate(Sender: TObject); procedure DoInputThread; procedure DoError(E: Exception); procedure Execute; override; public - property Script: TSimbaScript read FScript; - - constructor Create(FileName: String; - SimbaCommunication, TargetWindow: String; - CompileOnly: Boolean - ); reintroduce; + constructor Create; + constructor Create(FileName: String; SimbaCommunication, TargetWindow: String; CompileOnly: Boolean); reintroduce; overload; + constructor Create(SimbaCommunication, TargetWindow: String; CompileOnly: Boolean); reintroduce; overload; end; implementation @@ -61,7 +58,7 @@ procedure TSimbaScriptRunner.DoCompilerHint(Sender: TLapeCompilerBase; Hint: lpS DoDebugLn([EDebugLn.YELLOW], Hint); end; -procedure TSimbaScriptRunner.DoTerm(Sender: TObject); +procedure TSimbaScriptRunner.DoApplicationTerminate(Sender: TObject); begin Application.Terminate(); while (not Application.Terminated) do @@ -132,30 +129,38 @@ procedure TSimbaScriptRunner.Execute; end; end; -constructor TSimbaScriptRunner.Create(FileName: String; SimbaCommunication, TargetWindow: String; CompileOnly: Boolean); +constructor TSimbaScriptRunner.Create; begin inherited Create(False); FreeOnTerminate := True; - OnTerminate := @DoTerm; + OnTerminate := @DoApplicationTerminate; +end; + +constructor TSimbaScriptRunner.Create(FileName: String; SimbaCommunication, TargetWindow: String; CompileOnly: Boolean); +begin + Create(); FCompileOnly := CompileOnly; - FScript := TSimbaScript.Create(); + if (SimbaCommunication <> '') then + FScript := TSimbaScript.Create(FileName, TSimbaScriptCommunication.Create(SimbaCommunication)) + else + FScript := TSimbaScript.Create(FileName); + FScript.Script := TSimbaFile.FileRead(FileName); FScript.ScriptFileName := FileName; - FScript.SimbaCommunicationServer := SimbaCommunication; FScript.TargetWindow := TargetWindow; +end; - // Simba created a temp file. Most likely default script. - if FileIsInDirectory(FileName, SimbaEnv.TempPath) then - begin - FScript.ScriptFileName := ChangeFileExt(ExtractFileName(FileName), ''); +constructor TSimbaScriptRunner.Create(SimbaCommunication, TargetWindow: String; CompileOnly: Boolean); +begin + Create(); - // temp file, so delete. - if FileExists(FileName) then - DeleteFile(FileName); - end; + FCompileOnly := CompileOnly; + + FScript := TSimbaScript.Create(TSimbaScriptCommunication.Create(SimbaCommunication)); + FScript.TargetWindow := TargetWindow; end; end. diff --git a/Source/simba.env.pas b/Source/simba.env.pas index bb9949ede..bd497f270 100644 --- a/Source/simba.env.pas +++ b/Source/simba.env.pas @@ -32,8 +32,6 @@ SimbaEnv = class public class constructor Create; - class function WriteTempFile(const Contents, Prefix: String): String; - class property SimbaPath: String read FSimbaPath; class property IncludesPath: String read FIncludesPath; class property PluginsPath: String read FPluginsPath; @@ -79,24 +77,9 @@ function FindInclude(var FileName: String; ExtraSearchDirs: TStringArray): Boole Result := FindFile(FileName, '', ExtraSearchDirs + [SimbaEnv.IncludesPath, SimbaEnv.SimbaPath]); end; -class function SimbaEnv.WriteTempFile(const Contents, Prefix: String): String; -var - Number: Integer = 0; -begin - Result := Format('%s%s.%d', [SimbaEnv.TempPath, Prefix, Number]); - while FileExists(Result) do - begin - Inc(Number); - - Result := Format('%s%s.%d', [SimbaEnv.TempPath, Prefix, Number]); - end; - - TSimbaFile.FileWrite(Result, Contents); -end; - class constructor SimbaEnv.Create; - function Setup(Dir: String): String; + function Init(Dir: String): String; begin if (not DirectoryExists(Dir)) then ForceDirectories(Dir); @@ -107,16 +90,16 @@ class function SimbaEnv.WriteTempFile(const Contents, Prefix: String): String; begin FSimbaPath := IncludeTrailingPathDelimiter(Application.Location); - FIncludesPath := Setup(FSimbaPath + 'Includes'); - FPluginsPath := Setup(FSimbaPath + 'Plugins'); - FScriptsPath := Setup(FSimbaPath + 'Scripts'); - FScreenshotsPath := Setup(FSimbaPath + 'Screenshots'); - FDataPath := Setup(FSimbaPath + 'Data'); + FIncludesPath := Init(FSimbaPath + 'Includes'); + FPluginsPath := Init(FSimbaPath + 'Plugins'); + FScriptsPath := Init(FSimbaPath + 'Scripts'); + FScreenshotsPath := Init(FSimbaPath + 'Screenshots'); + FDataPath := Init(FSimbaPath + 'Data'); - FDumpsPath := Setup(FDataPath + 'Dumps'); - FTempPath := Setup(FDataPath + 'Temp'); - FPackagesPath := Setup(FDataPath + 'Packages'); - FBackupsPath := Setup(FDataPath + 'Backups'); + FDumpsPath := Init(FDataPath + 'Dumps'); + FTempPath := Init(FDataPath + 'Temp'); + FPackagesPath := Init(FDataPath + 'Packages'); + FBackupsPath := Init(FDataPath + 'Backups'); end; end. diff --git a/Source/simba.mufasatypes.pas b/Source/simba.mufasatypes.pas index 4741d9d4d..07706c57d 100644 --- a/Source/simba.mufasatypes.pas +++ b/Source/simba.mufasatypes.pas @@ -198,7 +198,7 @@ interface ESimbaCommunicationMessage = ( SIMBA_TITLE, SIMBA_PID, SIMBA_TARGET_PID, SIMBA_TARGET_WINDOW, - SCRIPT_ERROR, SCRIPT_STATE_CHANGE, + SCRIPT, SCRIPT_ERROR, SCRIPT_STATE_CHANGE, TRAY_NOTIFICATION, DEBUGIMAGE_UPDATE, DEBUGIMAGE_MOVETO, DEBUGIMAGE_MAXSIZE, DEBUGIMAGE_SHOW, DEBUGIMAGE_HIDE, diff --git a/Source/simba.scriptinstance_communication.pas b/Source/simba.scriptinstance_communication.pas index d1fba94c0..653972714 100644 --- a/Source/simba.scriptinstance_communication.pas +++ b/Source/simba.scriptinstance_communication.pas @@ -23,6 +23,7 @@ TSimbaScriptInstanceCommunication = class(TSimbaIPCServer) procedure OnMessage(MessageID: Integer; Params, Result: TMemoryStream); override; + procedure GetScript; procedure SetSimbaTitle; procedure ShowTrayNotification; @@ -61,6 +62,12 @@ procedure TSimbaScriptInstanceCommunication.OnMessage(MessageID: Integer; Params FMethods[Message](); end; +procedure TSimbaScriptInstanceCommunication.GetScript; +begin + FResult.WriteAnsiString(FRunner.ScriptTitle); + FResult.WriteAnsiString(FRunner.Script); +end; + procedure TSimbaScriptInstanceCommunication.SetSimbaTitle; procedure Execute; @@ -366,6 +373,7 @@ constructor TSimbaScriptInstanceCommunication.Create(Runner: TSimbaScriptTabRunn FRunner := Runner; + FMethods[ESimbaCommunicationMessage.SCRIPT] := @GetScript; FMethods[ESimbaCommunicationMessage.SIMBA_TITLE] := @SetSimbaTitle; FMethods[ESimbaCommunicationMessage.SIMBA_PID] := @GetSimbaPID; FMethods[ESimbaCommunicationMessage.SIMBA_TARGET_PID] := @GetSimbaTargetPID; diff --git a/Source/simba.scripttab.pas b/Source/simba.scripttab.pas index 00d7a3188..89a54275f 100644 --- a/Source/simba.scripttab.pas +++ b/Source/simba.scripttab.pas @@ -37,6 +37,10 @@ TSimbaScriptTabRunner = class(TComponent) FState: ESimbaScriptState; + FScriptFile: String; + FScript: String; + FScriptTitle: String; + procedure Start(Args: TStringArray); procedure ShowError; @@ -49,6 +53,9 @@ TSimbaScriptTabRunner = class(TComponent) procedure SetState(Value: ESimbaScriptState); public + property Script: String read FScript; + property ScriptTitle: String read FScriptTitle; + property Tab: TSimbaScriptTab read FTab; property Process: TProcess read FProcess; @@ -214,19 +221,17 @@ procedure TSimbaScriptTabRunner.SetState(Value: ESimbaScriptState); end; procedure TSimbaScriptTabRunner.Start(Args: TStringArray); -var - FileName: String; begin - if (FTab.FScriptFileName = '') then - FileName := SimbaEnv.WriteTempFile(FTab.Script, FTab.ScriptTitle) - else - FileName := FTab.ScriptFileName; + FScriptFile := FTab.ScriptFileName; + FScriptTitle := FTab.ScriptTitle; + FScript := FTab.Script; FStartTime := GetTickCount64(); FProcess.Parameters.Add('--simbacommunication=%s', [TSimbaScriptInstanceCommunication.Create(Self).ClientID]); FProcess.Parameters.AddStrings(Args); - FProcess.Parameters.Add(FileName); + if (FScriptFile <> '') then + FProcess.Parameters.Add(FScriptFile); FProcess.Execute(); FOutputThread := RunInThread(@DoOutputThread);