mirror of
https://github.com/moparisthebest/Simba
synced 2024-11-25 10:42:20 -05:00
230 lines
5.8 KiB
ObjectPascal
230 lines
5.8 KiB
ObjectPascal
|
unit psextension;
|
||
|
|
||
|
{$mode objfpc}
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses
|
||
|
Classes, SysUtils,mufasabase, virtualextension,
|
||
|
uPSComponent,uPSCompiler, uPSRuntime, uPSPreProcessor,forms;
|
||
|
|
||
|
|
||
|
|
||
|
type
|
||
|
|
||
|
{ TSimbaPSExtension }
|
||
|
|
||
|
TSimbaPSExtension = class(TVirtualSimbaExtension)
|
||
|
public
|
||
|
constructor Create(FileStr: String; StartDisabled : boolean = false);
|
||
|
destructor Destroy; override;
|
||
|
private
|
||
|
PSInstance: TPSScript;
|
||
|
FWorking: Boolean;
|
||
|
Script: TStringList;
|
||
|
procedure StartExtension;
|
||
|
private
|
||
|
function FreeScript: boolean;
|
||
|
function InitScript: Boolean;
|
||
|
procedure OutputMessages;
|
||
|
|
||
|
public
|
||
|
function HookExists(HookName: String): Boolean;override;
|
||
|
function ExecuteHook(HookName: String; fArgs: Array of Variant; out OutVariant : Variant): Integer;override;
|
||
|
property Working : boolean read FWorking;
|
||
|
protected
|
||
|
procedure RegisterPSCComponents(Sender: TObject; x: TPSPascalCompiler);
|
||
|
procedure RegisterPSRComponents(Sender: TObject; se: TPSExec; x: TPSRuntimeClassImporter);
|
||
|
procedure RegisterMyMethods(Sender: TPSScript);
|
||
|
procedure OnPSExecute(Sender: TPSScript);
|
||
|
procedure SetEnabled(bool : boolean);override;
|
||
|
end;
|
||
|
|
||
|
|
||
|
implementation
|
||
|
uses
|
||
|
uPSC_std, uPSC_controls,uPSC_classes,uPSC_graphics,uPSC_stdctrls,uPSC_forms,
|
||
|
uPSC_extctrls,uPSC_menus, //Compile libs
|
||
|
uPSR_std, uPSR_controls,uPSR_classes,uPSR_graphics,uPSR_stdctrls,uPSR_forms,
|
||
|
uPSR_extctrls,uPSR_menus, //Runtime-libs
|
||
|
testunit//Writeln
|
||
|
;
|
||
|
|
||
|
function TSimbaPSExtension.HookExists(HookName: String): Boolean;
|
||
|
begin
|
||
|
Result := False;
|
||
|
if FWorking then
|
||
|
if PSInstance.Exec.GetProc(HookName) <> InvalidVal then
|
||
|
result := True;
|
||
|
end;
|
||
|
|
||
|
function TSimbaPSExtension.ExecuteHook(HookName: String; fArgs: Array of Variant; out OutVariant : Variant): Integer;
|
||
|
begin
|
||
|
result := SExt_error;
|
||
|
if not FWorking then
|
||
|
exit;
|
||
|
try
|
||
|
outvariant := PSInstance.ExecuteFunction(fArgs, HookName);
|
||
|
result := SExt_ok;
|
||
|
except
|
||
|
on e : exception do
|
||
|
formWritelnEx(format('Error in Simba extension (%s): %s',[Self.GetName,e.message]));
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
constructor TSimbaPSExtension.Create(FileStr: String; StartDisabled: boolean = false);
|
||
|
begin
|
||
|
inherited create;
|
||
|
FWorking := False;
|
||
|
FileName := FileStr;
|
||
|
try
|
||
|
Script := TStringList.Create;
|
||
|
Script.LoadFromFile(FileName);
|
||
|
except
|
||
|
raise Exception.CreateFmt('File %s could not be read', [FileName]);
|
||
|
end;
|
||
|
FEnabled := false;
|
||
|
PSInstance := nil;
|
||
|
if not StartDisabled then
|
||
|
StartExtension;
|
||
|
end;
|
||
|
|
||
|
function TSimbaPSExtension.InitScript: Boolean;
|
||
|
begin
|
||
|
if not HookExists('init') then
|
||
|
exit(false);
|
||
|
result := true;
|
||
|
try
|
||
|
PSInstance.ExecuteFunction([], 'init');
|
||
|
except
|
||
|
result := false;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TSimbaPSExtension.FreeScript: boolean;
|
||
|
var
|
||
|
bla : variant;
|
||
|
begin
|
||
|
if not HookExists('Free') then
|
||
|
exit(false);
|
||
|
result := ExecuteHook('Free',[],bla) = SExt_ok;
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TSimbaPSExtension.RegisterMyMethods(Sender: TPSScript);
|
||
|
begin
|
||
|
Sender.AddFunction(@formWritelnEx,'procedure Writeln(s : string)');
|
||
|
Sender.AddRegisteredVariable('Simba','TForm');
|
||
|
Sender.AddRegisteredVariable('Simba_MainMenu','TMainMenu');
|
||
|
end;
|
||
|
|
||
|
procedure TSimbaPSExtension.OnPSExecute(Sender: TPSScript);
|
||
|
begin
|
||
|
Sender.SetVarToInstance('simba',Form1);
|
||
|
Sender.SetVarToInstance('Simba_MainMenu',Form1.MainMenu);
|
||
|
end;
|
||
|
|
||
|
procedure TSimbaPSExtension.SetEnabled(bool: boolean);
|
||
|
var
|
||
|
temp : variant;
|
||
|
begin
|
||
|
if bool <> FEnabled then
|
||
|
begin
|
||
|
if bool then
|
||
|
begin;
|
||
|
if not assigned(PSInstance) then //We enable it for the first time, calls SetEnabled.
|
||
|
StartExtension
|
||
|
else
|
||
|
begin
|
||
|
if not FWorking then
|
||
|
Exit;
|
||
|
if hookexists('attach') then
|
||
|
ExecuteHook('attach',[],temp);
|
||
|
end;
|
||
|
end else
|
||
|
if HookExists('detach') then
|
||
|
ExecuteHook('detach',[],temp);
|
||
|
end;
|
||
|
inherited SetEnabled(bool);
|
||
|
end;
|
||
|
|
||
|
procedure TSimbaPSExtension.RegisterPSCComponents(Sender: TObject; x: TPSPascalCompiler);
|
||
|
begin
|
||
|
SIRegister_Std(x);
|
||
|
SIRegister_Classes(x, True);
|
||
|
SIRegister_Controls(x);
|
||
|
SIRegister_Graphics(x, True);
|
||
|
SIRegister_stdctrls(x);
|
||
|
SIRegister_Forms(x);
|
||
|
SIRegister_ExtCtrls(x);
|
||
|
SIRegister_Menus(x);
|
||
|
end;
|
||
|
|
||
|
procedure TSimbaPSExtension.RegisterPSRComponents(Sender: TObject; se: TPSExec; x: TPSRuntimeClassImporter);
|
||
|
begin
|
||
|
RIRegister_Std(x);
|
||
|
RIRegister_Classes(x, True);
|
||
|
RIRegister_Controls(x);
|
||
|
RIRegister_Graphics(x, True);
|
||
|
RIRegister_stdctrls(x);
|
||
|
RIRegister_Forms(x);
|
||
|
RIRegister_ExtCtrls(x);
|
||
|
RIRegister_Menus(x);
|
||
|
end;
|
||
|
|
||
|
destructor TSimbaPSExtension.Destroy;
|
||
|
begin
|
||
|
FreeScript;
|
||
|
if Assigned(PSInstance) then
|
||
|
FreeAndNil(PSInstance);
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
procedure TSimbaPSExtension.StartExtension;
|
||
|
begin
|
||
|
if assigned(PSInstance) then
|
||
|
exit;//Already started..
|
||
|
{ Create script, and see if the extension is valid. (If it compiles) }
|
||
|
PSInstance := TPSScript.Create(nil);
|
||
|
|
||
|
PSInstance.Script := Self.Script;
|
||
|
PSInstance.OnCompImport:=@RegisterPSCComponents;
|
||
|
PSInstance.OnExecImport:=@RegisterPSRComponents;
|
||
|
PSInstance.OnCompile:=@RegisterMyMethods;
|
||
|
PSInstance.OnExecute:=@OnPSExecute;
|
||
|
|
||
|
formWritelnEx(Format('Loading extension %s', [FileName]));
|
||
|
try
|
||
|
FWorking := PSInstance.Compile;
|
||
|
except
|
||
|
on e : exception do
|
||
|
FormWritelnEx(format('Error in Simba extension (%s) : %s',[FileName,e.message]));
|
||
|
end;
|
||
|
if FWorking then
|
||
|
formWritelnEx('Extension Enabled')
|
||
|
else
|
||
|
begin
|
||
|
formWritelnEx('Extension Disabled - Did not compile');
|
||
|
OutputMessages;
|
||
|
end;
|
||
|
|
||
|
if InitScript then
|
||
|
mDebugLn('Init procedure succesfully called')
|
||
|
else
|
||
|
mDebugLn('Init procedure didn''t execute right, or couldn''t be found');
|
||
|
Enabled:= FWorking;
|
||
|
end;
|
||
|
|
||
|
procedure TSimbaPSExtension.OutputMessages;
|
||
|
var
|
||
|
l: Longint;
|
||
|
begin
|
||
|
for l := 0 to PSInstance.CompilerMessageCount - 1 do
|
||
|
formWritelnEx(PSInstance.CompilerErrorToStr(l) + ' at line ' + inttostr(PSInstance.CompilerMessages[l].Row));
|
||
|
end;
|
||
|
|
||
|
|
||
|
|
||
|
end.
|
||
|
|