From 5d4ee2baa1505be9b38bc587e35f50558d75870b Mon Sep 17 00:00:00 2001 From: BenLand100 Date: Thu, 21 Jan 2010 15:53:54 +0000 Subject: [PATCH] Still working in the branch. Made some oop changes to plugin loading to allow any class to extend a generic loader and provide specific loading capabilities. Also implemented the EIOS loader. I'll be working on making SMART implement EIOS (and change the specification as needed) next. git-svn-id: http://www.villavu.com/repositories/merlijn/mufasa@440 3f818213-9676-44b0-a9b4-5e4c4e03d09d --- .../Projects/SAMufasaGUI/project1.lpi | 202 +++++++++++------- branches/iomanager/Units/MMLAddon/plugins.pas | 143 +++++++------ .../iomanager/Units/MMLCore/iomanager.pas | 169 +++++++++++---- 3 files changed, 333 insertions(+), 181 deletions(-) diff --git a/branches/iomanager/Projects/SAMufasaGUI/project1.lpi b/branches/iomanager/Projects/SAMufasaGUI/project1.lpi index 7150c9d..12a6d28 100644 --- a/branches/iomanager/Projects/SAMufasaGUI/project1.lpi +++ b/branches/iomanager/Projects/SAMufasaGUI/project1.lpi @@ -10,7 +10,7 @@ <UseXPManifest Value="True"/> - <ActiveEditorIndexAtStart Value="1"/> + <ActiveEditorIndexAtStart Value="0"/> </General> <VersionInfo> <ProjectVersion Value=""/> @@ -43,7 +43,7 @@ <UnitName Value="project1"/> <CursorPos X="12" Y="25"/> <TopLine Value="15"/> - <EditorIndex Value="6"/> + <EditorIndex Value="7"/> <UsageCount Value="205"/> <Loaded Value="True"/> </Unit0> @@ -139,9 +139,10 @@ <HasResources Value="True"/> <ResourceBaseClass Value="Form"/> <UnitName Value="TestUnit"/> - <CursorPos X="99" Y="1797"/> - <TopLine Value="1789"/> - <EditorIndex Value="10"/> + <ComponentState Value="1"/> + <CursorPos X="14" Y="1305"/> + <TopLine Value="1288"/> + <EditorIndex Value="11"/> <UsageCount Value="202"/> <Loaded Value="True"/> </Unit13> @@ -189,8 +190,8 @@ <Filename Value="../../Units/MMLCore/client.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="Client"/> - <CursorPos X="47" Y="33"/> - <TopLine Value="23"/> + <CursorPos X="1" Y="64"/> + <TopLine Value="47"/> <EditorIndex Value="0"/> <UsageCount Value="201"/> <Loaded Value="True"/> @@ -201,7 +202,7 @@ <UnitName Value="MufasaTypes"/> <CursorPos X="21" Y="33"/> <TopLine Value="15"/> - <EditorIndex Value="2"/> + <EditorIndex Value="3"/> <UsageCount Value="201"/> <Loaded Value="True"/> </Unit21> @@ -268,9 +269,11 @@ <Filename Value="../../Units/MMLAddon/mmlpsthread.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="mmlpsthread"/> - <CursorPos X="17" Y="131"/> - <TopLine Value="2"/> + <CursorPos X="27" Y="328"/> + <TopLine Value="228"/> + <EditorIndex Value="1"/> <UsageCount Value="202"/> + <Loaded Value="True"/> </Unit30> <Unit31> <Filename Value="../../Units/PascalScript/uPSComponent.pas"/> @@ -489,8 +492,8 @@ <Filename Value="../../Units/MMLAddon/PSInc/Wrappers/mouse.inc"/> <CursorPos X="11" Y="26"/> <TopLine Value="12"/> - <EditorIndex Value="5"/> - <UsageCount Value="16"/> + <EditorIndex Value="6"/> + <UsageCount Value="18"/> <Loaded Value="True"/> </Unit63> <Unit64> @@ -535,9 +538,9 @@ <Filename Value="../../Units/MMLAddon/plugins.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="plugins"/> - <CursorPos X="12" Y="68"/> - <TopLine Value="1"/> - <EditorIndex Value="3"/> + <CursorPos X="40" Y="132"/> + <TopLine Value="132"/> + <EditorIndex Value="4"/> <UsageCount Value="200"/> <Loaded Value="True"/> </Unit70> @@ -626,7 +629,7 @@ <UnitName Value="windowselector"/> <CursorPos X="37" Y="34"/> <TopLine Value="12"/> - <EditorIndex Value="8"/> + <EditorIndex Value="9"/> <UsageCount Value="201"/> <Loaded Value="True"/> </Unit82> @@ -1196,10 +1199,9 @@ <ComponentName Value="ColourHistoryForm"/> <ResourceBaseClass Value="Form"/> <UnitName Value="colourhistory"/> - <ComponentState Value="1"/> <CursorPos X="7" Y="73"/> <TopLine Value="55"/> - <EditorIndex Value="7"/> + <EditorIndex Value="8"/> <UsageCount Value="200"/> <Loaded Value="True"/> </Unit166> @@ -1370,8 +1372,8 @@ <Filename Value="../../Units/MMLAddon/PSInc/Wrappers/keyboard.inc"/> <CursorPos X="26" Y="43"/> <TopLine Value="13"/> - <EditorIndex Value="4"/> - <UsageCount Value="16"/> + <EditorIndex Value="5"/> + <UsageCount Value="18"/> <Loaded Value="True"/> </Unit191> <Unit192> @@ -1486,7 +1488,7 @@ <UnitName Value="debugimage"/> <CursorPos X="1" Y="1"/> <TopLine Value="1"/> - <EditorIndex Value="9"/> + <EditorIndex Value="10"/> <UsageCount Value="202"/> <Loaded Value="True"/> </Unit207> @@ -1596,7 +1598,7 @@ <UnitName Value="framefunctionlist"/> <CursorPos X="26" Y="295"/> <TopLine Value="7"/> - <UsageCount Value="162"/> + <UsageCount Value="165"/> </Unit223> <Unit224> <Filename Value="../../../usr/local/share/lazarus/lcl/comctrls.pp"/> @@ -1651,7 +1653,7 @@ <UnitName Value="simpleanalyzer"/> <CursorPos X="52" Y="104"/> <TopLine Value="193"/> - <UsageCount Value="149"/> + <UsageCount Value="152"/> </Unit231> <Unit232> <Filename Value="../../Units/Misc/mPasLex.pas"/> @@ -1726,7 +1728,7 @@ <UnitName Value="updater"/> <CursorPos X="38" Y="211"/> <TopLine Value="65"/> - <UsageCount Value="122"/> + <UsageCount Value="125"/> </Unit242> <Unit243> <Filename Value="updateform.pas"/> @@ -1737,7 +1739,7 @@ <ComponentState Value="1"/> <CursorPos X="111" Y="102"/> <TopLine Value="207"/> - <UsageCount Value="117"/> + <UsageCount Value="120"/> </Unit243> <Unit244> <Filename Value="../../../Documents/lazarus/lcl/fileutil.pas"/> @@ -1858,7 +1860,7 @@ <UnitName Value="simbasettings"/> <CursorPos X="26" Y="9"/> <TopLine Value="11"/> - <UsageCount Value="80"/> + <UsageCount Value="83"/> </Unit261> <Unit262> <Filename Value="../../Units/MMLAddon/settings.pas"/> @@ -1903,7 +1905,7 @@ <UnitName Value="reportbug"/> <CursorPos X="53" Y="23"/> <TopLine Value="21"/> - <UsageCount Value="63"/> + <UsageCount Value="66"/> </Unit267> <Unit268> <Filename Value="../../Units/Synapse/synsock.pas"/> @@ -1960,7 +1962,7 @@ <UnitName Value="newinternets"/> <CursorPos X="80" Y="2"/> <TopLine Value="1"/> - <UsageCount Value="59"/> + <UsageCount Value="62"/> </Unit275> <Unit276> <Filename Value="reportbug.lrs"/> @@ -2006,10 +2008,10 @@ <Unit282> <Filename Value="../../Units/MMLCore/iomanager.pas"/> <UnitName Value="IOManager"/> - <CursorPos X="11" Y="21"/> - <TopLine Value="1"/> - <EditorIndex Value="1"/> - <UsageCount Value="20"/> + <CursorPos X="43" Y="529"/> + <TopLine Value="516"/> + <EditorIndex Value="2"/> + <UsageCount Value="22"/> <Loaded Value="True"/> </Unit282> <Unit283> @@ -2017,8 +2019,8 @@ <UnitName Value="os_linux"/> <CursorPos X="5" Y="21"/> <TopLine Value="1"/> - <EditorIndex Value="12"/> - <UsageCount Value="20"/> + <EditorIndex Value="13"/> + <UsageCount Value="22"/> <Loaded Value="True"/> </Unit283> <Unit284> @@ -2033,8 +2035,8 @@ <UnitName Value="os_windows"/> <CursorPos X="4" Y="21"/> <TopLine Value="1"/> - <EditorIndex Value="11"/> - <UsageCount Value="16"/> + <EditorIndex Value="12"/> + <UsageCount Value="18"/> <Loaded Value="True"/> </Unit285> <Unit286> @@ -2052,99 +2054,127 @@ <UsageCount Value="10"/> </Unit287> </Units> - <JumpHistory Count="23" HistoryIndex="22"> + <JumpHistory Count="30" HistoryIndex="29"> <Position1> - <Filename Value="colourhistory.pas"/> - <Caret Line="16" Column="43" TopLine="1"/> + <Filename Value="../../Units/MMLAddon/plugins.pas"/> + <Caret Line="106" Column="29" TopLine="82"/> </Position1> <Position2> - <Filename Value="project1.lpr"/> - <Caret Line="49" Column="1" TopLine="16"/> + <Filename Value="../../Units/MMLAddon/plugins.pas"/> + <Caret Line="102" Column="35" TopLine="85"/> </Position2> <Position3> - <Filename Value="testunit.pas"/> - <Caret Line="1543" Column="61" TopLine="1530"/> + <Filename Value="../../Units/MMLAddon/plugins.pas"/> + <Caret Line="106" Column="19" TopLine="89"/> </Position3> <Position4> - <Filename Value="testunit.pas"/> - <Caret Line="1673" Column="101" TopLine="1656"/> + <Filename Value="../../Units/MMLAddon/plugins.pas"/> + <Caret Line="229" Column="26" TopLine="199"/> </Position4> <Position5> - <Filename Value="testunit.pas"/> - <Caret Line="1733" Column="57" TopLine="1716"/> + <Filename Value="../../Units/MMLAddon/plugins.pas"/> + <Caret Line="174" Column="24" TopLine="155"/> </Position5> <Position6> - <Filename Value="testunit.pas"/> - <Caret Line="1735" Column="36" TopLine="1716"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="486" Column="36" TopLine="461"/> </Position6> <Position7> - <Filename Value="testunit.pas"/> - <Caret Line="1741" Column="36" TopLine="1716"/> + <Filename Value="../../Units/MMLAddon/plugins.pas"/> + <Caret Line="181" Column="48" TopLine="156"/> </Position7> <Position8> - <Filename Value="testunit.pas"/> - <Caret Line="1743" Column="21" TopLine="1716"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="179" Column="68" TopLine="166"/> </Position8> <Position9> - <Filename Value="testunit.pas"/> - <Caret Line="1747" Column="40" TopLine="1716"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="157" Column="30" TopLine="141"/> </Position9> <Position10> - <Filename Value="testunit.pas"/> - <Caret Line="1748" Column="38" TopLine="1716"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="178" Column="47" TopLine="7"/> </Position10> <Position11> - <Filename Value="testunit.pas"/> - <Caret Line="1750" Column="44" TopLine="1733"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="29" Column="90" TopLine="1"/> </Position11> <Position12> <Filename Value="testunit.pas"/> - <Caret Line="1752" Column="24" TopLine="1733"/> + <Caret Line="1792" Column="84" TopLine="1789"/> </Position12> <Position13> - <Filename Value="testunit.pas"/> - <Caret Line="1764" Column="26" TopLine="1733"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="480" Column="16" TopLine="465"/> </Position13> <Position14> - <Filename Value="testunit.pas"/> - <Caret Line="1768" Column="42" TopLine="1751"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="481" Column="19" TopLine="464"/> </Position14> <Position15> - <Filename Value="testunit.pas"/> - <Caret Line="1786" Column="65" TopLine="1769"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="475" Column="15" TopLine="458"/> </Position15> <Position16> - <Filename Value="testunit.pas"/> - <Caret Line="1789" Column="31" TopLine="1769"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="497" Column="48" TopLine="486"/> </Position16> <Position17> - <Filename Value="testunit.pas"/> - <Caret Line="1791" Column="29" TopLine="1769"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="441" Column="22" TopLine="424"/> </Position17> <Position18> - <Filename Value="testunit.pas"/> - <Caret Line="1793" Column="29" TopLine="1769"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="564" Column="7" TopLine="550"/> </Position18> <Position19> - <Filename Value="testunit.pas"/> - <Caret Line="1794" Column="44" TopLine="1769"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="574" Column="76" TopLine="551"/> </Position19> <Position20> - <Filename Value="testunit.pas"/> - <Caret Line="1795" Column="52" TopLine="1769"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="546" Column="17" TopLine="529"/> </Position20> <Position21> - <Filename Value="testunit.pas"/> - <Caret Line="1796" Column="37" TopLine="1769"/> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="549" Column="16" TopLine="532"/> </Position21> <Position22> - <Filename Value="../../Units/MMLAddon/windowselector.pas"/> - <Caret Line="199" Column="20" TopLine="173"/> + <Filename Value="testunit.pas"/> + <Caret Line="566" Column="18" TopLine="551"/> </Position22> <Position23> - <Filename Value="debugimage.pas"/> - <Caret Line="17" Column="66" TopLine="1"/> + <Filename Value="testunit.pas"/> + <Caret Line="560" Column="69" TopLine="551"/> </Position23> + <Position24> + <Filename Value="testunit.pas"/> + <Caret Line="564" Column="41" TopLine="551"/> + </Position24> + <Position25> + <Filename Value="testunit.pas"/> + <Caret Line="566" Column="18" TopLine="551"/> + </Position25> + <Position26> + <Filename Value="testunit.pas"/> + <Caret Line="567" Column="18" TopLine="551"/> + </Position26> + <Position27> + <Filename Value="../../Units/MMLAddon/mmlpsthread.pas"/> + <Caret Line="216" Column="18" TopLine="206"/> + </Position27> + <Position28> + <Filename Value="../../Units/MMLAddon/plugins.pas"/> + <Caret Line="69" Column="31" TopLine="56"/> + </Position28> + <Position29> + <Filename Value="../../Units/MMLCore/iomanager.pas"/> + <Caret Line="247" Column="52" TopLine="234"/> + </Position29> + <Position30> + <Filename Value="../../Units/MMLCore/client.pas"/> + <Caret Line="33" Column="47" TopLine="45"/> + </Position30> </JumpHistory> </ProjectOptions> <CompilerOptions> @@ -2155,7 +2185,7 @@ <SearchPaths> <IncludeFiles Value="$(ProjOutDir)/;$(ProjPath)../../Units/MMLAddon/PSInc/"/> <OtherUnitFiles Value="$(ProjPath)../../Units/MMLCore/;$(ProjPath)../../Units/MMLAddon/;$(ProjPath)../../Units/PascalScript/;$(ProjPath)../../Units/Misc/;$(ProjPath)../../Units/MMLAddon/PSInc/;$(ProjPath)../../Units/Linux/;$(ProjPath)../../Units/Synapse/;$(LazarusDir)/components/mouseandkeyinput/"/> - <UnitOutputDirectory Value="$(ProjPath)../../build/$(TargetOS)/"/> + <UnitOutputDirectory Value="$(ProjPath)../../build/$(TargetOS)"/> </SearchPaths> <CodeGeneration> <TargetOS Value="Linux"/> @@ -2180,6 +2210,12 @@ </Other> </CompilerOptions> <Debugging> + <BreakPoints Count="1"> + <Item1> + <Source Value="../../Units/MMLCore/client.pas"/> + <Line Value="64"/> + </Item1> + </BreakPoints> <Exceptions Count="3"> <Item1> <Name Value="EAbort"/> diff --git a/branches/iomanager/Units/MMLAddon/plugins.pas b/branches/iomanager/Units/MMLAddon/plugins.pas index 0d48c52..35bdaf7 100644 --- a/branches/iomanager/Units/MMLAddon/plugins.pas +++ b/branches/iomanager/Units/MMLAddon/plugins.pas @@ -34,7 +34,7 @@ unit plugins; interface uses - Classes, SysUtils,dynlibs; + Classes, SysUtils, dynlibs; type TMPluginMethod = record @@ -44,31 +44,45 @@ type TMPlugin = record Methods : Array of TMPluginMethod; - dllHandle : TLibHandle; - filename : string; MethodLen : integer; end; TMPluginArray = array of TMPlugin; - { TMPlugins } + TGenericLib = record + filename: string; + handle: TLibHandle; + end; + TGenericLibArray = array of TGenericLib; - TMPlugins = class (TObject) - private - Plugins : TMPluginArray; - PluginLen : integer; - procedure FreePlugins; - public - PluginDirs : TStringList; - procedure ValidateDirs; - procedure LoadPluginsDir( DirIndex : integer); - function LoadPlugin(PluginName : string) : integer; - property Count : integer read PluginLen; - property MPlugins : TMPluginArray read Plugins; - constructor Create; - destructor Destroy;override; + TGenericLoader = class(TObject) + private + PluginLen : integer; + Loaded: TGenericLibArray; + procedure FreePlugins; + protected + function InitPlugin(plugin: TLibHandle): boolean; virtual; abstract; + public + PluginDirs : TStringList; + constructor Create; + destructor Destroy; override; + procedure ValidateDirs; + procedure LoadPluginsDir(DirIndex : integer); + function LoadPlugin(PluginName : string) : integer; end; + { TMPlugins } + + TMPlugins = class (TGenericLoader) + private + Plugins : TMPluginArray; + NumPlugins : integer; + protected + function InitPlugin(plugin: TLibHandle): boolean; override; + public + property MPlugins : TMPluginArray read Plugins; + property Count : integer read NumPlugins; + end; implementation @@ -77,24 +91,24 @@ uses { TMPlugins } -procedure TMPlugins.FreePlugins; +procedure TGenericLoader.FreePlugins; var I : integer; begin for i := 0 to PluginLen - 1 do begin; - if (Plugins[i].dllHandle > 0) then + if (Loaded[i].handle > 0) then try Writeln(inttostr(I)); - FreeLibrary(Plugins[i].dllHandle); + FreeLibrary(Loaded[i].handle); except end; end; - SetLength(Plugins,0); + SetLength(Loaded,0); PluginLen:= 0; end; -procedure TMPlugins.ValidateDirs; +procedure TGenericLoader.ValidateDirs; var i : integer; TempStr : string; @@ -115,7 +129,7 @@ begin end; end; -procedure TMPlugins.LoadPluginsDir(DirIndex: integer); +procedure TGenericLoader.LoadPluginsDir(DirIndex: integer); var PlugExt: String = {$IFDEF LINUX}'*.so';{$ELSE}'*.dll';{$ENDIF} FileSearcher : TSearchRec; @@ -133,16 +147,10 @@ begin FindClose(FileSearcher); end; -function TMPlugins.LoadPlugin(PluginName: string): Integer; + +function TGenericLoader.LoadPlugin(PluginName: string): Integer; var i, ii : integer; - pntrArrc : function : integer; stdcall; - GetFuncInfo : function (x: Integer; var ProcAddr: Pointer; var ProcDef: PChar) : Integer; stdcall; - GetTypeCount : function : Integer; stdcall; - GetTypeInfo : function (x: Integer; var sType, sTypeDef: string): Integer; stdcall; - PD : PChar; - pntr : Pointer; - arrc : integer; Status : LongInt; PlugExt: String = {$IFDEF LINUX}'.so';{$ELSE}'.dll';{$ENDIF} begin @@ -162,51 +170,66 @@ begin if ii = -1 then raise Exception.CreateFMT('Plugins(%s) has not been found',[PluginName]); for i := 0 to PluginLen - 1 do - if Plugins[i].filename = (PluginDirs.Strings[ii] + PluginName + PlugExt) then + if Loaded[i].filename = (PluginDirs.Strings[ii] + PluginName + PlugExt) then Exit(i); - pd := StrAlloc(255); - SetLength(Plugins,PluginLen + 1); + SetLength(Loaded,PluginLen + 1); Writeln(Format('Loading plugin %s at %s',[PluginName,PluginDirs.Strings[ii]])); - Plugins[PluginLen].filename:= PluginDirs.Strings[ii] + Pluginname + PlugExt; - Plugins[PluginLen].dllHandle:= LoadLibrary(PChar(Plugins[PluginLen].filename)); - if Plugins[PluginLen].dllHandle = 0 then - Raise Exception.CreateFMT('Error loading plugin %s',[Plugins[PluginLen].filename]); - Pointer(pntrArrc) := GetProcAddress(Plugins[PluginLen].dllHandle, PChar('GetFunctionCount')); - if @pntrArrc = nil then - Raise Exception.CreateFMT('Error loading plugin %s',[Plugins[PluginLen].filename]); - arrc := pntrArrc(); - SetLength(Plugins[PluginLen].Methods, ArrC); - Pointer(GetFuncInfo) := GetProcAddress(Plugins[PluginLen].dllHandle, PChar('GetFunctionInfo')); - if @GetFuncInfo = nil then - Raise Exception.CreateFMT('Error loading plugin %s',[Plugins[PluginLen].filename]); - Plugins[PluginLen].MethodLen := Arrc; - for ii := 0 to ArrC-1 do - begin; - if (GetFuncInfo(ii, pntr, pd) < 0) then - Continue; - Plugins[Pluginlen].Methods[ii].FuncPtr := pntr; - Plugins[Pluginlen].Methods[ii].FuncStr := pd; - end; + Loaded[PluginLen].filename:= PluginDirs.Strings[ii] + Pluginname + PlugExt; + Loaded[PluginLen].handle:= LoadLibrary(PChar(Loaded[PluginLen].filename)); + if Loaded[PluginLen].handle = 0 then + Raise Exception.CreateFMT('Error loading plugin %s',[Loaded[PluginLen].filename]); + if InitPlugin(Loaded[PluginLen].handle) then + inc(PluginLen) + else + FreeLibrary(Loaded[PluginLen].handle); Result := PluginLen; - inc(PluginLen); - StrDispose(pd); - end; -constructor TMPlugins.Create; +constructor TGenericLoader.Create; begin inherited Create; PluginLen := 0; PluginDirs := TStringList.Create; end; -destructor TMPlugins.Destroy; +destructor TGenericLoader.Destroy; begin FreePlugins; PluginDirs.Free; inherited Destroy; end; +function TMPlugins.InitPlugin(plugin: TLibHandle): boolean; +var + pntrArrc : function : integer; stdcall; + GetFuncInfo : function (x: Integer; var ProcAddr: Pointer; var ProcDef: PChar) : Integer; stdcall; + GetTypeCount : function : Integer; stdcall; + GetTypeInfo : function (x: Integer; var sType, sTypeDef: string): Integer; stdcall; + PD : PChar; + pntr : Pointer; + arrc, ii : integer; +begin + Pointer(pntrArrc) := GetProcAddress(plugin, PChar('GetFunctionCount')); + if @pntrArrc = nil then begin result:= false; exit; end; + Pointer(GetFuncInfo) := GetProcAddress(plugin, PChar('GetFunctionInfo')); + if @GetFuncInfo = nil then begin result:= false; exit; end; + arrc := pntrArrc(); + SetLength(Plugins,NumPlugins+1); + Plugins[NumPlugins].MethodLen := Arrc; + SetLength(Plugins[NumPlugins].Methods, ArrC); + pd := StrAlloc(255); + for ii := 0 to ArrC-1 do + begin; + if (GetFuncInfo(ii, pntr, pd) < 0) then + Continue; + Plugins[NumPlugins].Methods[ii].FuncPtr := pntr; + Plugins[NumPlugins].Methods[ii].FuncStr := pd; + end; + StrDispose(pd); + inc(NumPlugins); + result:= true; +end; + end. diff --git a/branches/iomanager/Units/MMLCore/iomanager.pas b/branches/iomanager/Units/MMLCore/iomanager.pas index 45ab2cd..e0debbe 100644 --- a/branches/iomanager/Units/MMLCore/iomanager.pas +++ b/branches/iomanager/Units/MMLCore/iomanager.pas @@ -26,7 +26,7 @@ unit IOManager; interface uses - Classes, SysUtils, mufasatypes, graphics, LCLType, bitmaps, LCLIntf; + Classes, SysUtils, mufasatypes, graphics, LCLType, bitmaps, LCLIntf, plugins, dynlibs; type @@ -115,9 +115,6 @@ interface HoldKey: procedure(target: pointer; key: integer); stdcall; ReleaseKey: procedure(target: pointer; key: integer); stdcall; IsKeyHeld: function(target: pointer; key: integer): boolean; stdcall; - - Initialize: procedure; stdcall; - Finalize: procedure; stdcall; end; { Implements a EIOS target. This is, for all intensive purposes, a TRawTarget with added @@ -155,7 +152,6 @@ interface | a TEIOS_Client with the method pointers set. } type TEIOS_LoadedPlugin = record name: string; - plugin: pointer; client: TEIOS_Client; end; @@ -167,14 +163,16 @@ interface | would be the single call.... | SetTarget('SMART',SmartSetupRecord); | Sexy, right? ;} - TEIOS_Controller = class(TObject) + TEIOS_Controller = class(TGenericLoader) public constructor Create(plugin_dir: string); destructor Destroy; override; function ClientExists(name: string): boolean; function GetClient(name: string): TEIOS_Client; - + + protected + function InitPlugin(plugin: TLibHandle): boolean; override; private plugs: array of TEIOS_LoadedPlugin; function FindClient(name:string): integer; @@ -237,7 +235,7 @@ interface implementation - uses + uses FileUtil, {$IFDEF MSWINDOWS} os_windows {$ENDIF} {$IFDEF LINUX} os_linux {$ENDIF}; @@ -246,7 +244,7 @@ implementation constructor TIOManager_Abstract.Create(plugin_dir: string); begin inherited Create; - controller:= nil; + controller:= TEIOS_Controller.Create(plugin_dir); keymouse:= nil; image:= nil; frozen:= nil; @@ -392,9 +390,13 @@ implementation constructor TEIOS_Target.Create(client: TEIOS_Client; initval: pointer); begin inherited Create; self.client:= client; - self.target:= client.RequestTarget(initval); - self.buffer:= client.GetImageBuffer(target); - client.GetTargetDimensions(target,self.width,self.height); + if Pointer(client.RequestTarget) <> nil then + self.target:= client.RequestTarget(initval); + if Pointer(client.GetImageBuffer) <> nil then + self.buffer:= client.GetImageBuffer(target) + else + self.buffer:= nil; + GetTargetDimensions(self.width,self.height); end; destructor TEIOS_Target.Destroy; begin @@ -402,39 +404,95 @@ implementation inherited Destroy; end; - procedure TEIOS_Target.GetTargetDimensions(var w, h: integer); begin client.GetTargetDimensions(target,w,h); end; + procedure TEIOS_Target.GetTargetDimensions(var w, h: integer); + begin + if Pointer(client.GetTargetDimensions) <> nil then + client.GetTargetDimensions(target,w,h) + else + inherited GetTargetDimensions(w,h); + end; function TEIOS_Target.ReturnData(xs, ys, width, height: Integer): TRetData; begin - client.UpdateImageBufferBounds(target,xs,ys,xs+width,ys+height); + if Pointer(client.UpdateImageBufferBounds) <> nil then + client.UpdateImageBufferBounds(target,xs,ys,xs+width,ys+height) + else if Pointer(client.UpdateImageBuffer) <> nil then + client.UpdateImageBuffer(target) + else begin + {no update command exported} + end; result.Ptr := buffer; result.RowLen:= self.width; result.IncPtrWith:= result.RowLen - width; Inc(result.Ptr, ys * result.RowLen + xs); end; - procedure TEIOS_Target.GetMousePosition(var x,y: integer); begin client.GetMousePosition(target,x,y); end; - procedure TEIOS_Target.MoveMouse(x,y: integer); begin client.MoveMouse(target,x,y); end; + procedure TEIOS_Target.GetMousePosition(var x,y: integer); + begin + if Pointer(client.GetMousePosition) <> nil then + client.GetMousePosition(target,x,y) + else + inherited GetMousePosition(x,y); + end; + procedure TEIOS_Target.MoveMouse(x,y: integer); + begin + if Pointer(client.MoveMouse) <> nil then + client.MoveMouse(target,x,y) + else + inherited MoveMouse(x,y); + end; procedure TEIOS_Target.HoldMouse(x,y: integer; button: TClickType); begin - case button of - mouse_Left: client.HoldMouse(target,x,y,true); - mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.'); - mouse_Right: client.HoldMouse(target,x,y,false); - end; + if Pointer(client.HoldMouse) <> nil then + begin + case button of + mouse_Left: client.HoldMouse(target,x,y,true); + mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.'); + mouse_Right: client.HoldMouse(target,x,y,false); + end; + end else + inherited HoldMouse(x,y,button); end; procedure TEIOS_Target.ReleaseMouse(x,y: integer; button: TClickType); begin - case button of - mouse_Left: client.ReleaseMouse(target,x,y,true); - mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.'); - mouse_Right: client.ReleaseMouse(target,x,y,false); - end; + if Pointer(client.ReleaseMouse) <> nil then + begin + case button of + mouse_Left: client.ReleaseMouse(target,x,y,true); + mouse_Middle: raise Exception.Create('EIOS does not implement the middle mouse button.'); + mouse_Right: client.ReleaseMouse(target,x,y,false); + end; + end else + inherited ReleaseMouse(x,y,button); end; - procedure TEIOS_Target.SendString(str: string); begin client.SendString(target,PChar(@str[1])); end; - procedure TEIOS_Target.HoldKey(key: integer); begin client.HoldKey(target,key); end; - procedure TEIOS_Target.ReleaseKey(key: integer); begin client.ReleaseKey(target,key); end; - function TEIOS_Target.IsKeyHeld(key: integer): boolean; begin result:= client.IsKeyHeld(target,key); end; + procedure TEIOS_Target.SendString(str: string); + begin + if Pointer(client.SendString) <> nil then + client.SendString(target,PChar(@str[1])) + else + inherited SendString(str); + end; + procedure TEIOS_Target.HoldKey(key: integer); + begin + if Pointer(client.HoldKey) <> nil then + client.HoldKey(target,key) + else + inherited HoldKey(key); + end; + procedure TEIOS_Target.ReleaseKey(key: integer); + begin + if Pointer(client.ReleaseKey) <> nil then + client.ReleaseKey(target,key) + else + inherited ReleaseKey(key); + end; + function TEIOS_Target.IsKeyHeld(key: integer): boolean; + begin + if Pointer(client.IsKeyHeld) <> nil then + result:= client.IsKeyHeld(target,key) + else + result:= inherited IsKeyHeld(key); + end; //***implementation*** TRawTarget @@ -471,22 +529,57 @@ implementation constructor TEIOS_Controller.Create(plugin_dir: string); begin inherited Create; - SetLength(Plugs, 0); - //Load plugins from plugins folder + PluginDirs.Add(plugin_dir); + LoadPluginsDir(0); end; destructor TEIOS_Controller.Destroy; var i: integer; begin - for i:= 0 to length(plugs) - 1 do - if plugs[i].plugin <> nil then - begin - //Unload plugin that was loaded - end; + SetLength(plugs,0); inherited Destroy; end; - + + function TEIOS_Controller.InitPlugin(plugin: TLibHandle): boolean; + var + GetName: procedure(name: pchar); stdcall; + buffer: pchar; + idx: integer; + begin + Pointer(GetName) := GetProcAddress(plugin, PChar('EIOS_GetName')); + if Pointer(GetName) = nil then begin result:= false; exit; end; + idx:= Length(plugs); + SetLength(plugs,idx+1); + buffer:= stralloc(255); + GetName(buffer); + plugs[idx].name:= buffer; + strdispose(buffer); + {link in all eios methods that *might* exist} + with plugs[idx].client do + begin + Pointer(RequestTarget):= GetProcAddress(plugin, PChar('EIOS_RequestTarget')); + Pointer(ReleaseTarget):= GetProcAddress(plugin, PChar('EIOS_ReleaseTarget')); + + Pointer(GetTargetDimensions):= GetProcAddress(plugin, PChar('EIOS_GetTargetDimensions')); + Pointer(GetImageBuffer):= GetProcAddress(plugin, PChar('EIOS_GetImageBuffer')); + Pointer(UpdateImageBuffer):= GetProcAddress(plugin, PChar('EIOS_UpdateImageBuffer')); + Pointer(UpdateImageBufferBounds):= GetProcAddress(plugin, PChar('EIOS_UpdateImageBufferBounds')); + + Pointer(GetMousePosition):= GetProcAddress(plugin, PChar('EIOS_GetMousePosition')); + Pointer(MoveMouse):= GetProcAddress(plugin, PChar('EIOS_MoveMouse')); + Pointer(HoldMouse):= GetProcAddress(plugin, PChar('EIOS_HoldMouse')); + Pointer(ReleaseMouse):= GetProcAddress(plugin, PChar('EIOS_ReleaseMouse')); + + Pointer(SendString):= GetProcAddress(plugin, PChar('EIOS_SendString')); + Pointer(HoldKey):= GetProcAddress(plugin, PChar('EIOS_HoldKey')); + Pointer(ReleaseKey):= GetProcAddress(plugin, PChar('EIOS_ReleaseKey')); + Pointer(IsKeyHeld):= GetProcAddress(plugin, PChar('EIOS_IsKeyHeld')); + end; + {done linking in methods} + result:= true; + end; + function TEIOS_Controller.FindClient(name: string): integer; var i: integer;