Files
lazarus-ccr/applications/cactusjukebox/source/plugin/impl/cj_pluginslist.pas
sekelsenmat 6f8c048343 Adds the cactus jukebox to the lazarus ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1748 8e941d3f-bd1b-0410-a28a-d453659cc2b4
2011-07-21 09:39:48 +00:00

248 lines
7.2 KiB
ObjectPascal

//******************************************************************************
//*** Cactus Jukebox ***
//*** ***
//*** (c) 2006-2009 ***
//*** ***
//*** Massimo Magnano, maxm.dev@gmail.com ***
//*** ***
//******************************************************************************
// File : cj_pluginslist.pas
//
// Description : List of Plugins and other plugins functions.
//
//******************************************************************************
unit cj_pluginslist;
{$mode delphi}{$H+}
interface
uses dynlibs, global_vars, MGList, cj_plugin, cj_interfaces, cj_interfaces_impl;
type
TCJ_PluginDescr = record
DllHandle :TLibHandle;
DllPath :String;
Enabled :Boolean;
pClass :TCJ_Plugin;
Info :TCJ_PluginInfo;
end;
PCJ_PluginDescr = ^TCJ_PluginDescr;
TCJ_PluginsList = class (TMGList)
protected
function allocData :Pointer; override;
procedure deallocData(pData :Pointer); override;
public
destructor Destroy; override;
procedure LoadFromINI;
function CanClose :Boolean;
function ExtFind(PluginName :String): PCJ_PluginDescr; overload;
function Find(PluginName :String) :Boolean; overload;
procedure SettingsChanged;
end;
Var
PluginsList :TCJ_PluginsList=Nil;
implementation
uses Classes, Controls, SysUtils, Forms, Dialogs, inifiles;
const
ERR_LOAD_PLUGIN ='Error Loading %s'#13#10'%s'#13#10'Try to Load at next time?';
ERR_LOAD_INVALID ='Invalid Plugin...';
ERR_LOAD_CAPT ='Plugins loading..';
destructor TCJ_PluginsList.Destroy;
var
curPlugin :PCJ_PluginDescr;
begin
try
curPlugin :=Self.FindFirst;
while (curPlugin<>Nil) do
begin
if (curPlugin^.pClass<>Nil)
then try
if curPlugin^.Enabled
then curPlugin^.pClass.SetEnabled(False);
curPlugin^.pClass.OnDestroy;
curPlugin^.pClass.Free;
except
On E:Exception do begin end;
end;
FreeLibrary(curPlugin^.DllHandle);
curPlugin :=Self.FindNext;
end;
Self.FindClose;
except
On E:Exception do begin end;
end;
inherited Destroy;
end;
function TCJ_PluginsList.allocData :Pointer;
begin
GetMem(Result, SizeOf(TCJ_PluginDescr));
FillChar(Result^, SizeOf(TCJ_PluginDescr), 0);
PCJ_PluginDescr(Result)^.DllPath :=''; //Avoid strange String problems
end;
procedure TCJ_PluginsList.deallocData(pData :Pointer);
begin
PCJ_PluginDescr(pData)^.DllPath :='';
FreeMem(pData, SizeOf(TCJ_PluginDescr));
end;
procedure TCJ_PluginsList.LoadFromINI;
var
curPlugin :PCJ_PluginDescr;
theINI :TIniFile;
INIpackList :TStringList;
curSect :String;
i :Integer;
xDllHandle :HModule;
xDllPath :String;
xEnabled :Boolean;
xGetPluginInfo :Tfunction_GetPluginInfo;
xGetPlugin :Tfunction_GetPlugin;
procedure DoInClass;
Var
tmpInfo :TCJ_PluginInfo;
begin
if (curPlugin^.pClass<>Nil) then
begin
try
curPlugin^.pClass.OnCreate(cj_interfaces_impl.CJ_Interface);
except
end;
try
tmpInfo :=curPlugin^.pClass.GetInfo;
curPlugin^.Info :=tmpInfo;
except
end;
try
if xEnabled
then curPlugin^.pClass.SetEnabled(True);
except
end;
end;
end;
begin
theINI :=TIniFile.Create(PATH_Config+INI_PLUGINS);
INIpackList :=TStringList.Create;
try
theINI.ReadSections(INIpackList);
for i :=0 to INIpackList.Count-1 do
begin
curPlugin :=Nil;
try
CurSect :=Uppercase(INIpackList.Strings[i]);
curPlugin := Self.ExtFind(CurSect);
if (curPlugin=Nil) then
begin
curPlugin :=self.Add;
//xDllPath :=ProcessVarValue(theINI.ReadString(CurSect, 'DLL', ''));
xDllPath :=PATH_Plugins+theINI.ReadString(CurSect, 'DLL', '');
xEnabled :=theINI.ReadBool(CurSect, 'ENABLED', True);
xDllHandle := LoadLibrary(PChar(xDllPath));
if (xDllHandle=0)
then raise Exception.Create(ERR_LOAD_INVALID);
curPlugin^.DllHandle :=xDllHandle;
curPlugin^.DllPath :=xDllPath;
curPlugin^.Enabled :=xEnabled;
xGetPluginInfo :=GetProcAddress(xDllHandle, 'GetPluginInfo');
if not(Assigned(xGetPluginInfo))
then raise Exception.Create(ERR_LOAD_INVALID);
//Move(xGetPluginInfo, curPlugin^.Info, SizeOf(TCJ_PluginInfo));
curPlugin^.Info :=xGetPluginInfo;
Case curPlugin^.Info.pType of
PLUGIN_TYPE_NONE : begin end;
PLUGIN_TYPE_STD : begin
xGetPlugin :=GetProcAddress(xDllHandle, 'GetPlugin');
if Assigned(xGetPlugin)
then curPlugin^.pClass := xGetPlugin;
end;
else raise Exception.Create(ERR_LOAD_INVALID);
end;
DoInClass;
end;
except
On E:Exception do
begin
if (MessageDlg(ERR_LOAD_CAPT, Format(ERR_LOAD_PLUGIN, [xDllPath, E.Message]),
mtError, [mbYes, mbNo], 0)=mrNo)
then theINI.EraseSection(CurSect);
if (curPlugin<>Nil)
then self.Delete(curPlugin, 0);
end;
end;
end;
finally
theINI.Free;
INIpackList.Free;
end;
end;
function TCJ_PluginsList.CanClose :Boolean;
var
curPlugin :PCJ_PluginDescr;
begin
Result :=True;
try
curPlugin :=Self.FindFirst;
while (curPlugin<>Nil) and (Result=True) do
begin
if (curPlugin^.pClass<>Nil)
then try
Result :=curPlugin^.pClass.CanClose;
except
Result :=True;
end
else Result :=True;
curPlugin :=Self.FindNext;
end;
Self.FindClose;
except
Result :=True;
end;
end;
function TCJ_PluginsList.ExtFind(PluginName :String): PCJ_PluginDescr;
function FindByName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
begin
Result := (String(PChar(ptData1)) = PCJ_PluginDescr(ptData2)^.Info.pPackName);
end;
begin
Result :=Self.ExtFind(PChar(Uppercase(PluginName)), 0, @FindByName);
end;
function TCJ_PluginsList.Find(PluginName :String) :Boolean;
begin
Result := (ExtFind(PluginName)<>Nil);
end;
procedure TCJ_PluginsList.SettingsChanged;
begin
end;
end.