1
0
mirror of https://github.com/moparisthebest/Simba synced 2024-11-13 12:55:05 -05:00
Simba/Projects/Simba/psextension.pas

401 lines
11 KiB
ObjectPascal

unit psextension;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, virtualextension, forms, client, uPSComponent,uPSCompiler,
uPSRuntime, stdCtrls, uPSPreProcessor,MufasaTypes,MufasaBase, web,
bitmaps, plugins, libloader, dynlibs,internets,scriptproperties, settingssandbox;
type
{ TSimbaPSExtension }
TSimbaPSExtension = class(TVirtualSimbaExtension)
private
PSInstance: TPSScript;
FWorking: Boolean;
Script: TStringList;
FClient : TClient;
procedure StartExtension;
function FreeScript: boolean;
function InitScript: Boolean;
procedure OutputMessages;
protected
procedure RegisterPSCComponents(Sender: TObject; x: TPSPascalCompiler);
procedure RegisterPSRComponents(Sender: TObject; se: TPSExec; x: TPSRuntimeClassImporter);
procedure RegisterMyMethods(x: TPSScript);
procedure OnPSExecute(Sender: TPSScript);
function OnNeedFile(Sender: TObject;const OrginFileName: string; var FilePath, Output: string): Boolean;
procedure SetEnabled(bool : boolean);override;
public
constructor Create(FileStr: String; StartDisabled : boolean = false);
destructor Destroy; override;
function HookExists(const HookName: String): Boolean;override;
function ExecuteHook(const HookName: String;var Args:TVariantArray; out OutVariant : Variant): Integer;override;
property Working : boolean read FWorking;
end;
implementation
uses
colour_conv,dtmutil,
{$ifdef mswindows}windows, MMSystem,{$endif}//MMSystem -> Sounds
uPSC_std, uPSC_controls,uPSC_classes,uPSC_graphics,uPSC_stdctrls,uPSC_forms, uPSC_menus,
uPSC_extctrls, uPSC_mml, uPSC_dll, //Compile-libs
uPSUtils,
fontloader,
IOmanager,//TTarget_Exported
IniFiles,//Silly INI files
stringutil, //String st00f
uPSR_std, uPSR_controls,uPSR_classes,uPSR_graphics,uPSR_stdctrls,uPSR_forms, uPSR_mml,
uPSR_menus, uPSI_ComCtrls, uPSI_Dialogs, uPSR_dll,
files,
dialogs,
dtm, //Dtms!
uPSR_extctrls, //Runtime-libs
Graphics, //For Graphics types
math, //Maths!
mmath, //Real maths!
strutils,
fileutil,
tpa, //Tpa stuff
SynRegExpr,
lclintf,
SimbaUnit,updateform, mmisc, mmlpsthread; // for GetTickCount and others.//Writeln
{$ifdef Linux}
{$define PS_SafeCall}
{$else}
//{$define PS_SafeCall}
{$endif}
{$MACRO ON}
{$ifdef PS_SafeCall}
{$define extdecl := safecall}
{$else}
{$define extdecl := register}
{$endif}
procedure psWriteLn(s: string);
begin
formWritelnEx(s);
end;
function TSimbaPSExtension.HookExists(const HookName: String): Boolean;
begin
Result := False;
if FWorking then
if PSInstance.Exec.GetProc(HookName) <> InvalidVal then
result := True;
end;
function TSimbaPSExtension.ExecuteHook(const HookName: String;var Args: TVariantArray; out OutVariant : Variant): Integer;
begin
result := SExt_error;
if not FWorking then
exit;
try
outvariant := PSInstance.ExecuteFunction(Args, HookName);
result := SExt_ok;
except
on e : exception do
psWriteLn(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;
FClient := TClient.Create('',SimbaForm.Manager);
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;
Args : TVariantArray;
begin
if not HookExists('Free') then
exit(false);
result := ExecuteHook('Free',Args,bla) = SExt_ok;
end;
{$DEFINE MML_EXPORT_THREADSAFE}
{$I ../../Units/MMLAddon/PSInc/Wrappers/other.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/settings.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/bitmap.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/window.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/tpa.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/strings.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/colour.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/colourconv.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/math.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/mouse.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/file.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/keyboard.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/dtm.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/ocr.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/internets.inc}
{$I ../../Units/MMLAddon/PSInc/Wrappers/extensions.inc}
procedure TSimbaPSExtension.RegisterMyMethods(x: TPSScript);
procedure SetCurrSection(s: string);
begin
end;
begin
with SimbaForm, x do
begin
{$i ../../Units/MMLAddon/PSInc/psexportedmethods.inc}
AddFunction(@ext_SDTMToMDTM,'function SDTMToMDTM(Const DTM: TSDTM): TMDTM;');
AddFunction(@ext_GetPage,'function GetPage(const url : string) : string');
AddFunction(@ext_DecompressBZip2,'function DecompressBZip2(const input: string;out output : string; const BlockSize: Cardinal): boolean;');
AddFunction(@ext_UnTar,'function UnTar(const Input : string; out Content : TStringArray) : boolean;');
AddFunction(@ext_UnTarEx,'function UnTarEx(const Input : string;const outputdir : string; overwrite : boolean): boolean;');
AddFunction(@ext_MessageDlg,'function MessageDlg(const aCaption, aMsg: string; DlgType: TMsgDlgType;Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer;');
AddFunction(@ext_InputQuery,'function InputQuery(const ACaption, APrompt : String; var Value : String) : Boolean;');
AddRegisteredPTRVariable('Settings','TMMLSettingsSandbox');
AddRegisteredVariable('Simba','TForm');
AddRegisteredVariable('Simba_MainMenu','TMainMenu');
AddRegisteredVariable('Client','TClient');
end;
end;
procedure TSimbaPSExtension.OnPSExecute(Sender: TPSScript);
begin
Sender.SetVarToInstance('Simba',SimbaForm);
Sender.SetVarToInstance('Simba_MainMenu',SimbaForm.MainMenu);
Sender.SetVarToInstance('Client',FClient);
Sender.SetPointerToData('Settings',@Self.Settings,Sender.FindNamedType('TMMLSettingsSandbox'));
end;
procedure TSimbaPSExtension.SetEnabled(bool: boolean);
var
temp : variant;
Args : TVariantArray;
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',Args,temp);
end;
end else
if HookExists('detach') then
ExecuteHook('detach',Args,temp);
end;
inherited SetEnabled(bool);
end;
procedure TMufasaBitmapCopyClientToBitmap(self : TMufasaBitmap; Resize : boolean;x,y : integer; xs, ys, xe, ye: Integer);
begin
self.CopyClientToBitmap(SimbaForm.Manager,resize,x,y,xs,ys,xe,ye);
end;
procedure TSimbaPSExtension.RegisterPSCComponents(Sender: TObject; x: TPSPascalCompiler);
var
AppPath, ScriptPath: string;
i: Integer;
begin
SIRegister_Std(x);
SIRegister_Controls(x);
SIRegister_Classes(x, true);
SIRegister_Graphics(x, true);
SIRegister_stdctrls(x);
SIRegister_Forms(x);
SIRegister_ExtCtrls(x);
SIRegister_Menus(x);
SIRegister_ComCtrls(x);
SIRegister_Dialogs(x);
AppPath := MainDir + DirectorySeparator;
ScriptPath := ExtractFileDir(Filename);
with SimbaForm,x do
begin
{$I ../../Units/MMLAddon/PSInc/pscompile.inc}
AddTypes('TStringArray','Array of String');
AddConstantN('ExtPath','string').SetString(ExtPath);
for i := 0 to high(VirtualKeys) do
AddConstantN(Format('VK_%S',[VirtualKeys[i].Str]),'Byte').SetInt(VirtualKeys[i].Key);
end;
SIRegister_MML(x);
RegisterDll_Compiletime(x);
with x.AddFunction('procedure writeln;').decl do
with AddParam do
begin
OrgName:= 'x';
Mode:= pmIn;
end;
with x.AddFunction('function ToStr:string').decl do
with addparam do
begin
OrgName:= 'x';
Mode:= pmIn;
end;
with x.AddFunction('procedure swap;').decl do
begin
with addparam do
begin
OrgName:= 'x';
Mode:= pmInOut;
end;
with addparam do
begin
OrgName:= 'y';
Mode:= pmInOut;
end;
end;
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);
RIRegister_ComCtrls(x);
RIRegister_Dialogs(x);
RegisterDLLRuntime(se);
RIRegister_MML(x);
{ with x.FindClass('TMufasaBitmap') do
begin
RegisterMethod(@TMufasaBitmapCopyClientToBitmap,'CopyClientToBitmap');
end;}
se.RegisterFunctionName('WRITELN',@Writeln_,nil,nil);
se.RegisterFunctionName('TOSTR',@ToStr_,nil,nil);
se.RegisterFunctionName('SWAP',@swap_,nil,nil);
end;
destructor TSimbaPSExtension.Destroy;
begin
FClient.free;
FreeScript;
if Assigned(PSInstance) then
FreeAndNil(PSInstance);
inherited;
end;
function TSimbaPSExtension.OnNeedFile(Sender: TObject;
const OrginFileName: string; var FilePath, Output: string): Boolean;
var
path: string;
f: TFileStream;
begin
with SimbaForm do
path := FindFile(FilePath,[includepath, ExtractFileDir(Filename),ExtractFileDir(OrginFileName)]);
if path = '' then
begin
psWriteln(Path + ' doesn''t exist');
Result := false;
Exit;
end;
FilePath := path;//Yeah!
try
f:= TFileStream.Create(UTF8ToSys(Path), fmOpenRead);
SetLength(Output, f.Size);
f.Read(Output[1], Length(Output));
result:= true;
f.free;
except
Result := false;
psWriteln('TSimbaPSExtension.OnNeedFile');
end;
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);
with PSInstance do
begin
{$I ../../Units/MMLAddon/PSInc/psdefines.inc}
Defines.Add('PS_EXTENSION');
Defines.Add('EXTENSION');
end;
PSInstance.Script := Self.Script;
PSInstance.OnCompImport:=@RegisterPSCComponents;
PSInstance.OnExecImport:=@RegisterPSRComponents;
PSInstance.OnCompile:=@RegisterMyMethods;
PSInstance.OnExecute:=@OnPSExecute;
PSInstance.OnNeedFile:=@OnNeedFile;
PSInstance.UsePreProcessor:= True;
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.