apophysis/2.10/Source/varGenericPlugin.pas

564 lines
17 KiB
ObjectPascal

{
Apophysis Copyright (C) 2001-2004 Mark Townsend
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
Apophysis Copyright (C) 2007 Piotr Borys, Peter Sdobnov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
{
Variation Plugin DLL support for Apophysis:
Generic Plugin Support Unit
Started by Jed Kelsey, June 2007
}
{TODO : Make it creating new classes at runtime for itself...}
unit varGenericPlugin;
interface
uses
BaseVariation, XFormMan,
Classes, //TStrings/TStringList
SysUtils, //FindFirst/FindNext/FindClose
Dialogs; //ShowMessage
type
TPluginVarGetName = function : PChar; cdecl;
TPluginVarGetNrVariables = function : Integer; cdecl;
TPluginVarGetVariableNameAt = function(const Index: integer): PChar; cdecl;
TPluginVarCreate = function : Pointer; cdecl;
TPluginVarDestroy = function(var MyVariation : Pointer) : LongBool; cdecl;
TPluginVarInit = function(MyVariation, FPx, FPy, FTx, FTy: Pointer; vvar: double) : LongBool; cdecl;
TPluginVarPrepare = function(MyVariation : Pointer) : LongBool; cdecl;
TPluginVarCalc = function(MyVariation : Pointer) : LongBool; cdecl;
TPluginVarGetVariable = function(MyVariation:Pointer; const Name: PChar; var value: double) : LongBool; cdecl;
TPluginVarSetVariable = function(MyVariation:Pointer; const Name: PChar; var value: double) : LongBool; cdecl;
TPluginVariationClass = class of TPluginVariation;
TPluginData = record
Instance : Integer;
PluginHandle : THandle;
PluginClass : TPluginVariationClass;
PluginVarGetName : TPluginVarGetName;
PluginVarGetNrVariables : TPluginVarGetNrVariables;
PluginVarGetVariableNameAt: TPluginVarGetVariableNameAt;
PluginVarCreate : TPluginVarCreate;
PluginVarDestroy : TPluginVarDestroy;
PluginVarInit : TPluginVarInit;
PluginVarPrepare : TPluginVarPrepare;
PluginVarCalc : TPluginVarCalc;
PluginVarGetVariable : TPluginVarGetVariable;
PluginVarSetVariable : TPluginVarSetVariable;
end;
PPluginData = ^TPluginData;
// This class serves as a proxy for the plugin variations.
TPluginVariation = class(TBaseVariation)
private
MyVariation : Pointer;
public
constructor Create;
destructor Destroy; override;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
class function GetNrVariables: integer; override;
class function GetVariableNameAt(const Index: integer): string; override;
function SetVariable(const Name: string; var value: double): boolean; override;
function GetVariable(const Name: string; var value: double): boolean; override;
procedure Prepare; override;
procedure CalcFunction; override;
class function GetPluginData : PPluginData; virtual;
end;
//////////////////////////////////////////////////////////////////////
{
Either this, either interfaces...
Anyone has some other suggestion?... :) please?
}
TPluginVariation0 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation1 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation2 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation3 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation4 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation5 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation6 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation7 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation8 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation9 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation10 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation11 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation12 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation13 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation14 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation15 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation16 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation17 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation18 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation19 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation20 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation21 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation22 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation23 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation24 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation25 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation26 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation27 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation28 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
TPluginVariation29 = class(TPluginVariation)
class function GetPluginData : PPluginData; override;
end;
//////////////////////////////////////////////////////////////////////
var
//PluginVariationClasses : array of TPluginVariationClass;
PluginData : array of TPluginData;
NumPlugins : Integer;
implementation
uses
Windows, //LoadLibrary
Math;
{ TPluginVariation }
///////////////////////////////////////////////////////////////////////////////
{ These overridden functions are explicitly defined here to ensure that they
return the appropriate data record for the class (need to have one per
derived class so that class methods for multiple plugins get executed
correctly. Again, I'm sure there's a much better way around this, but being
new to Delphi, I don't know what it is. }
class function TPluginVariation.GetPluginData : PPluginData;
begin
Result := @(PluginData[0]); // As the base class, this shouldn't get called...
end;
class function TPluginVariation0.GetPluginData : PPluginData;
begin
Result := @(PluginData[0]);
end;
class function TPluginVariation1.GetPluginData : PPluginData;
begin
Result := @(PluginData[1]);
end;
class function TPluginVariation2.GetPluginData : PPluginData;
begin
Result := @(PluginData[2]);
end;
class function TPluginVariation3.GetPluginData : PPluginData;
begin
Result := @(PluginData[3]);
end;
class function TPluginVariation4.GetPluginData : PPluginData;
begin
Result := @(PluginData[4]);
end;
class function TPluginVariation5.GetPluginData : PPluginData;
begin
Result := @(PluginData[5]);
end;
class function TPluginVariation6.GetPluginData : PPluginData;
begin
Result := @(PluginData[6]);
end;
class function TPluginVariation7.GetPluginData : PPluginData;
begin
Result := @(PluginData[7]);
end;
class function TPluginVariation8.GetPluginData : PPluginData;
begin
Result := @(PluginData[8]);
end;
class function TPluginVariation9.GetPluginData : PPluginData;
begin
Result := @(PluginData[9]);
end;
class function TPluginVariation10.GetPluginData : PPluginData;
begin
Result := @(PluginData[10]);
end;
class function TPluginVariation11.GetPluginData : PPluginData;
begin
Result := @(PluginData[11]);
end;
class function TPluginVariation12.GetPluginData : PPluginData;
begin
Result := @(PluginData[12]);
end;
class function TPluginVariation13.GetPluginData : PPluginData;
begin
Result := @(PluginData[13]);
end;
class function TPluginVariation14.GetPluginData : PPluginData;
begin
Result := @(PluginData[14]);
end;
class function TPluginVariation15.GetPluginData : PPluginData;
begin
Result := @(PluginData[15]);
end;
class function TPluginVariation16.GetPluginData : PPluginData;
begin
Result := @(PluginData[16]);
end;
class function TPluginVariation17.GetPluginData : PPluginData;
begin
Result := @(PluginData[17]);
end;
class function TPluginVariation18.GetPluginData : PPluginData;
begin
Result := @(PluginData[18]);
end;
class function TPluginVariation19.GetPluginData : PPluginData;
begin
Result := @(PluginData[19]);
end;
class function TPluginVariation20.GetPluginData : PPluginData;
begin
Result := @(PluginData[20]);
end;
class function TPluginVariation21.GetPluginData : PPluginData;
begin
Result := @(PluginData[21]);
end;
class function TPluginVariation22.GetPluginData : PPluginData;
begin
Result := @(PluginData[22]);
end;
class function TPluginVariation23.GetPluginData : PPluginData;
begin
Result := @(PluginData[23]);
end;
class function TPluginVariation24.GetPluginData : PPluginData;
begin
Result := @(PluginData[24]);
end;
class function TPluginVariation25.GetPluginData : PPluginData;
begin
Result := @(PluginData[25]);
end;
class function TPluginVariation26.GetPluginData : PPluginData;
begin
Result := @(PluginData[26]);
end;
class function TPluginVariation27.GetPluginData : PPluginData;
begin
Result := @(PluginData[27]);
end;
class function TPluginVariation28.GetPluginData : PPluginData;
begin
Result := @(PluginData[28]);
end;
class function TPluginVariation29.GetPluginData : PPluginData;
begin
Result := @(PluginData[29]);
end;
//////////// ////////// ////////////
procedure TPluginVariation.Prepare;
begin
GetPluginData.PluginVarInit(MyVariation, Pointer(FPX), Pointer(FPy), Pointer(FTx), Pointer(FTy), vvar);
GetPluginData.PluginVarPrepare(MyVariation);
end;
///////////////////////////////////////////////////////////////////////////////
procedure TPluginVariation.CalcFunction;
begin
GetPluginData.PluginVarInit(MyVariation, Pointer(FPX), Pointer(FPy), Pointer(FTx), Pointer(FTy), vvar);
GetPluginData.PluginVarCalc(MyVariation);
end;
///////////////////////////////////////////////////////////////////////////////
constructor TPluginVariation.Create;
begin
MyVariation := GetPluginData.PluginVarCreate;
end;
///////////////////////////////////////////////////////////////////////////////
destructor TPluginVariation.Destroy;
begin
GetPluginData.PluginVarDestroy(MyVariation);
inherited;
end;
///////////////////////////////////////////////////////////////////////////////
class function TPluginVariation.GetInstance: TBaseVariation;
begin
Result := Self.Create;
end;
///////////////////////////////////////////////////////////////////////////////
class function TPluginVariation.GetName: string;
begin
Result := String(GetPluginData.PluginVarGetName());
end;
///////////////////////////////////////////////////////////////////////////////
class function TPluginVariation.GetNrVariables: integer;
begin
Result := GetPluginData.PluginVarGetNrVariables();
end;
///////////////////////////////////////////////////////////////////////////////
class function TPluginVariation.GetVariableNameAt(const Index: integer): string;
begin
Result := String(GetPluginData.PluginVarGetVariableNameAt(Index));
end;
///////////////////////////////////////////////////////////////////////////////
function TPluginVariation.SetVariable(const Name: string; var value: double): boolean;
begin
Result := GetPluginData.PluginVarSetVariable(MyVariation,PChar(Name),value);
end;
///////////////////////////////////////////////////////////////////////////////
function TPluginVariation.GetVariable(const Name: string; var value: double): boolean;
begin
Result := GetPluginData.PluginVarGetVariable(MyVariation,PChar(Name),value);
end;
///////////////////////////////////////////////////////////////////////////////
procedure InitializePlugins;
var
searchResult : TSearchRec;
begin
NumPlugins := 0;
// Try to find regular files matching *.dll in the plugins dir
if FindFirst('.\Plugins\*.dll', faAnyFile, searchResult) = 0 then
begin
repeat
with PluginData[NumPlugins] do begin
//Load DLL and initialize plugins!
PluginHandle := LoadLibrary(PChar('.\Plugins\'+searchResult.Name));
if PluginHandle<>0 then begin
@PluginVarGetName := GetProcAddress(PluginHandle,'PluginVarGetName');
if @PluginVarGetName = nil then begin // Must not be a valid plugin!
FreeLibrary(PluginHandle);
ShowMessage('Invalid Plugin: Could not find PluginVarGetName in '+searchResult.Name);
end else begin
@PluginVarGetNrVariables := GetProcAddress(PluginHandle,'PluginVarGetNrVariables');
@PluginVarGetVariableNameAt := GetProcAddress(PluginHandle,'PluginVarGetVariableNameAt');
@PluginVarCreate := GetProcAddress(PluginHandle,'PluginVarCreate');
@PluginVarDestroy := GetProcAddress(PluginHandle,'PluginVarDestroy');
@PluginVarInit := GetProcAddress(PluginHandle,'PluginVarInit');
@PluginVarPrepare := GetProcAddress(PluginHandle,'PluginVarPrepare');
@PluginVarCalc := GetProcAddress(PluginHandle,'PluginVarCalc');
@PluginVarGetVariable := GetProcAddress(PluginHandle,'PluginVarGetVariable');
@PluginVarSetVariable := GetProcAddress(PluginHandle,'PluginVarSetVariable');
Instance := NumPlugins+1;
RegisterVariation(PluginClass);
Inc(NumPlugins);
if NumPlugins >= Length(PluginData) then
break;
end;
end else
ShowMessage('Could not load a plugin: '+searchResult.Name);
end;
until (FindNext(searchResult) <> 0);
SysUtils.FindClose(searchResult); //Since we use Windows unit (LoadLibrary)
end;
end;
///////////////////////////////////////////////////////////////////////////////
procedure FinalizePlugins;
var
I : Integer;
begin
for I := 0 to NumPlugins - 1 do begin
if PluginData[NumPlugins].PluginHandle<>0 then begin
FreeLibrary(PluginData[NumPlugins].PluginHandle);
end;
end;
end;
///////////////////////////////////////////////////////////////////////////////
initialization
SetLength(PluginData,30);
PluginData[0].PluginClass := TPluginVariation0;
PluginData[1].PluginClass := TPluginVariation1;
PluginData[2].PluginClass := TPluginVariation2;
PluginData[3].PluginClass := TPluginVariation3;
PluginData[4].PluginClass := TPluginVariation4;
PluginData[5].PluginClass := TPluginVariation5;
PluginData[6].PluginClass := TPluginVariation6;
PluginData[7].PluginClass := TPluginVariation7;
PluginData[8].PluginClass := TPluginVariation8;
PluginData[9].PluginClass := TPluginVariation9;
PluginData[10].PluginClass := TPluginVariation10;
PluginData[11].PluginClass := TPluginVariation11;
PluginData[12].PluginClass := TPluginVariation12;
PluginData[13].PluginClass := TPluginVariation13;
PluginData[14].PluginClass := TPluginVariation14;
PluginData[15].PluginClass := TPluginVariation15;
PluginData[16].PluginClass := TPluginVariation16;
PluginData[17].PluginClass := TPluginVariation17;
PluginData[18].PluginClass := TPluginVariation18;
PluginData[19].PluginClass := TPluginVariation19;
PluginData[20].PluginClass := TPluginVariation20;
PluginData[21].PluginClass := TPluginVariation21;
PluginData[22].PluginClass := TPluginVariation22;
PluginData[23].PluginClass := TPluginVariation23;
PluginData[24].PluginClass := TPluginVariation24;
PluginData[25].PluginClass := TPluginVariation25;
PluginData[26].PluginClass := TPluginVariation26;
PluginData[27].PluginClass := TPluginVariation27;
PluginData[28].PluginClass := TPluginVariation28;
PluginData[29].PluginClass := TPluginVariation29;
InitializePlugins;
finalization
//Release all loaded plugin(s)
FinalizePlugins;
end.