aboutsummaryrefslogblamecommitdiffstats
path: root/ServiceBasedPlugins/src/pluginsupport/UPluginLoader_DLL.pas
blob: b143cd2a0c63087ddcf9baa6c647b70cccbed288 (plain) (tree)




















































































































































































                                                                                                                              
{* UltraStar Deluxe - Karaoke Game
 *
 * UltraStar Deluxe is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * 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; see the file COPYING. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * $URL: https://ultrastardx.svn.sourceforge.net/svnroot/ultrastardx/trunk/src/base/UMain.pas $
 * $Id: UMain.pas 1629 2009-03-07 22:30:04Z k-m_schindler $
 *}

unit UPluginLoader_DLL;

interface

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

{$I switches.inc}

uses UPluginDefines, UPlugin;

type
  TPluginLoader_DLL = class
    protected
      PluginDir: WideString;
    public
      constructor Create(PluginDir: WideString);
      procedure Browse(Dir: WideString);
  end;
  
  TPlugin_DLL = class (TPlugin)
    protected
      hLib: THandle; //< handle of loaded library
      Lib_Proc_Init: TUS_Plugin_Proc_Init;
      Lib_OnChangeStatus: TUS_Plugin_OnChangeStatus;
      
      procedure OnChangeStatus(Status: TUS_PluginStatus); override;
    public
      constructor Create(Handle: TUS_Handle; Filename: WideString); override;
      destructor Destroy; override;
  end;

const
  {$IF Defined(MSWINDOWS)}
    DLLExt  = '.dll';
  {$ELSEIF Defined(DARWIN)}
    DLLExt  = '.dylib';
  {$ELSEIF Defined(UNIX)}
    DLLExt  = '.so';
  {$IFEND}

implementation
uses
  {$IFDEF MSWINDOWS}
  windows,
  {$ELSE}
  dynlibs,
  {$ENDIF}
  SysUtils, Dialogs,
  UPluginManager,
  UPlatform;

{ implementation of TPluginLoader_DLL }
constructor TPluginLoader_DLL.Create(PluginDir: WideString);
begin
  Self.PluginDir := PluginDir;
  Browse(PluginDir);
end;

procedure TPluginLoader_DLL.Browse(Dir: WideString);
  var
    Files: TDirectoryEntryArray;
    I: Integer;
begin
  Showmessage(Dir + ' - ' + DLLExt);
  Files := Platform.DirectoryFindFiles(Dir, DLLExt, True);

  for I := 0 to High(Files) do
  begin
    ShowMessage(Dir + Files[I].Name);
    if (Files[I].IsDirectory) then
      Browse(Dir + Files[I].Name + PathDelim)
    else if (Files[I].IsFile) then
      PluginManager.AddPlugin(TPlugin_DLL.Create(PluginManager.GetHandle, Dir + Files[I].Name));
  end;
end;

{ implementation of TPlugin_DLL }
constructor TPlugin_DLL.Create(Handle: TUS_Handle; Filename: WideString);
begin
  inherited;
  
  hLib := 0;
  Lib_Proc_Init := nil;
  Lib_OnChangeStatus := nil;

  //try to load the library
  SetStatus(psWaitingInit);
end;

destructor TPlugin_DLL.Destroy;
begin

  inherited;
end;

procedure TPlugin_DLL.OnChangeStatus(Status: TUS_PluginStatus);
begin
  Case Status of
    psWaitingInit: begin
      //we have to try to load the plugin here
      hLib := LoadLibrary(PChar(AnsiString(Filename)));
      if (hlib <> 0) then
      begin
        @Lib_Proc_Init := GetProcAddress(hLib, PChar('Proc_Init'));

        If (not Assigned(Lib_Proc_Init)) then
        begin
          FreeLibrary(hLib);

          {$IFDEF MSWINDOWS}
          SetError('Can''t export Proc_Init procedure from library. Windows reports: ' + SysErrorMessage(GetLastError));
          {$ELSE}
          SetError('Can''t export Proc_Init procedure from library.');
          {$ENDIF}
          Exit;
        end;

        @Lib_OnChangeStatus := GetProcAddress(hLib, PChar('OnChangeStatus'));

        If (not Assigned(Lib_OnChangeStatus)) then
        begin
          FreeLibrary(hLib);

          {$IFDEF MSWINDOWS}
          SetError('Can''t export OnChangeStatus procedure from library. Windows reports: ' + SysErrorMessage(GetLastError));
          {$ELSE}
          SetError('Can''t export OnChangeStatus procedure from library.');
          {$ENDIF}
          Exit;
        end;  

      end
      else
      begin
        {$IFDEF MSWINDOWS}
        SetError('Error loading library. Windows reports: ' + SysErrorMessage(GetLastError));
        {$ELSE}
        SetError('Error loading library.');
        {$ENDIF}
        Exit;
      end;

    end;

  end;

  //call plugins OnChangeStatus procedure
  If assigned(Lib_OnChangeStatus) then
    Lib_OnChangeStatus(Self.Handle, Status);

  Self.Status := Status;
end;

end.