Simba/Projects/Simba/extensionmanager.pas

171 lines
4.2 KiB
Plaintext

unit extensionmanager;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,virtualextension,psextension,mufasabase,mufasatypes;
type
TExtension = TVirtualSimbaExtension;
(**
TExtensionManager holds a list of TExtension, and
has functions to easily handle hooks.
*)
{ TExtensionManager }
TExtensionManager = class(TObject)
private
FOnChange: TNotifyEvent;
procedure SetOnchange(const AValue: TNotifyEvent);
public
constructor Create;
destructor Destroy; override;
public
Extensions: TList;
StartDisabled : boolean;
property OnChange : TNotifyEvent read FOnChange write SetOnchange;
function GetExtensionIndex(Filename : string) : integer;
function LoadPSExtension(Filename : string; enabled : boolean=false) : boolean;
function LoadPSExtensionsDir(Directory,ext : string) : boolean;
function HandleHook(const HookName: String; var Args: TVariantArray): Variant;
end;
var
ExtManager : TExtensionManager;
implementation
uses
SimbaUnit, settingssandbox,Simbasettings;
procedure TExtensionManager.SetOnchange(const AValue: TNotifyEvent);
var
i : integer;
begin
for i := 0 to Extensions.Count - 1 do
TExtension(Extensions[i]).OnChange := AValue;;
FOnChange:=AValue;
end;
constructor TExtensionManager.Create;
begin
inherited Create;
Extensions := TList.Create;
StartDisabled := True;
end;
destructor TExtensionManager.Destroy;
var
I, C: Integer;
begin
C := Extensions.Count - 1;
for I := 0 to C do
begin
TExtension(Extensions.Items[I]).Settings.Free;
TExtension(Extensions.Items[I]).Free;
end;
Extensions.Free;
inherited Destroy;
end;
function TExtensionManager.GetExtensionIndex(Filename: string): integer;
var
i : integer;
begin
for i := 0 to Extensions.Count - 1 do
if CompareText(TExtension(Extensions[i]).Filename,filename) = 0 then
exit(i);
result := -1;
end;
function TExtensionManager.LoadPSExtension(Filename: string; enabled: boolean): boolean;
var
Ext : TExtension;
begin
if GetExtensionIndex(filename) <> -1 then
exit(true);
Result := False;
try
Ext := TSimbaPSExtension.Create(filename,True);
// result := TSimbaPSExtension(ext).Working;
Extensions.Add(ext);
ext.Settings := TMMLSettingsSandbox.Create(SettingsForm.Settings);
ext.Settings.Prefix := format('Extensions/Extension%d/Settings/',[Extensions.Count - 1]);
if enabled then
ext.Enabled := true;
ext.OnChange:= FOnChange;
if assigned(FOnChange) then
FOnChange(Self);
Result := True;
except
on e : exception do
formWritelnex(format('Error in LoadPSExtension(%s): %s',[FileName, e.message]));
end;
end;
function GetFiles(Path, Ext: string): TstringArray;
var
SearchRec : TSearchRec;
c : integer;
begin
c := 0;
if FindFirst(Path + '*.' + ext, faAnyFile, SearchRec) = 0 then
begin
repeat
inc(c);
SetLength(Result,c);
Result[c-1] := SearchRec.Name;
until FindNext(SearchRec) <> 0;
SysUtils.FindClose(SearchRec);
end;
end;
function TExtensionManager.LoadPSExtensionsDir(Directory, ext: string): boolean;
var
Files : TstringArray;
i : integer;
tempevent : TNotifyEvent;
begin
result := false;
if not DirectoryExists(directory) then
exit;
tempevent := FOnChange;
FOnChange := nil;
Directory := IncludeTrailingPathDelimiter(directory);
Files := GetFiles(Directory,ext);
for i := 0 to high(Files) do
result := LoadPSExtension(Directory + files[i],not StartDisabled) or result;
FOnChange := Tempevent;
if Assigned(FOnChange) then
FOnChange(self);
end;
// How do we return more than one result?
function TExtensionManager.HandleHook(const HookName: String;var Args: TVariantArray): Variant;
var
i: Integer;
begin
for i := 0 to Extensions.Count -1 do
with TExtension(Extensions[i]) do
if Enabled then
if HookExists(HookName) then
if ExecuteHook(HookName, Args, Result) <> 0 then
begin
mDebugLn('Execute hook failed: Hookname: %s',[hookname]);
// Not succesfull.
end;
end;
initialization
ExtManager := TExtensionManager.Create;
ExtManager.StartDisabled := True;
finalization
if ExtManager <> nil then
FreeAndNil(ExtManager);
end.