Plugin.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
00004  *       mailto: <tevs@mpi-sb.mpg.de>                                      *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  ***************************************************************************/
00012 
00013 
00014 //----------------------------------------------------------------------------------
00015 // Includes
00016 //----------------------------------------------------------------------------------
00017 #include "Plugin.h"
00018 #include "Engine.h"
00019 
00020 namespace nrEngine {
00021 
00022         //----------------------------------------------------------------------------------
00023         Plugin::Plugin() : IResource("Plugin"), mPluginHandle(0)
00024         {
00025                 m_plgInitialize = NULL;
00026                 m_plgError = NULL;
00027                 m_plgRelease = NULL;
00028         }
00029 
00030         //----------------------------------------------------------------------------------
00031         Plugin::~Plugin()
00032         {
00033                 unloadResource();
00034         }
00035 
00036         //----------------------------------------------------------------------------------
00037         void* Plugin::getSymbol(const std::string& name) const
00038         {
00039                 PluginHandle hdl =  (PluginHandle)NR_PLUGIN_GETSYM(mPluginHandle, name.c_str());
00040                 return hdl;
00041         }
00042 
00043         //----------------------------------------------------------------------------------
00044         Result Plugin::initialize(PropertyList* params)
00045         {
00046                 NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "Check if the loaded library is valid plugin");
00047 
00048                 // get version information
00049                 m_plgEngineVersion = (plgEngineVersion)getSymbol("plgEngineVersion");
00050                 m_plgVersionString = (plgVersionString)getSymbol("plgVersionString");
00051 
00052                 if (!m_plgEngineVersion || !m_plgVersionString)
00053                 {
00054                         NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin seems not to be written for the nrEngine");
00055                         NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "plgVersionString/plgEngineVersion symbols were not found!!!");
00056                         return PLG_SYMBOL_NOT_FOUND;
00057                 }
00058 
00059                 // Log this
00060                 NR_Log(Log::LOG_ENGINE, "Plugin found: %s written for nrEngine v%s", m_plgVersionString(), convertVersionToString(m_plgEngineVersion()).c_str());
00061 
00062                 // check if plugin is working with the current engine version
00063                 if (m_plgEngineVersion() > nrEngineVersion){
00064                         NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin has got greater version as the engine, so plugin not loaded");
00065                         return PLG_WRONG_VERSION;
00066                 }
00067 
00068                 // log something
00069                 NR_Log(Log::LOG_PLUGIN, "Initialize plugin %s", getResourceName().c_str());
00070 
00071 #define GET_SYMBOL(var, type)\
00072                 {\
00073                         NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "Get plugin symbol %s", #type);\
00074                         var = (type)getSymbol(#type);\
00075                         if (!var){\
00076                                 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin symbol %s was not found", #type);\
00077                                 return PLG_SYMBOL_NOT_FOUND;\
00078                         }\
00079                 }
00080 
00081                 // Get plugin symbols
00082                 GET_SYMBOL(m_plgInitialize, plgInitialize);
00083                 GET_SYMBOL(m_plgError, plgError);
00084                 GET_SYMBOL(m_plgRelease, plgRelease);
00085 #undef GET_SYMBOL
00086 
00087                 // call the function and check for return code
00088                 int result = m_plgInitialize(Engine::instance(), params);
00089 
00090                 // check for error
00091                 if (result != 0){
00092                         NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin returns error %d (%s). See plugin log for more detail information", result, m_plgError(result));
00093                         return PLG_EXTERNAL_ERROR;
00094                 }
00095 
00096                 // now get some extra symbols
00097                 /*m_plgGetMethods = (plgGetMethods)getSymbol("plgGetMethods");
00098                 m_plgCall = (plgCall)getSymbol("plgCall");
00099 
00100                 if (m_plgGetMethods){
00101 
00102                         // get the list of methods provided by this plugin
00103                         m_plgGetMethods(mPlgMethods);
00104 
00105                         NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "Plugin provides following symbols: ");
00106 
00107                         // now go through each of this method and print some log info about it
00108                         for (uint32 i=0; i < mPlgMethods.size(); i++){
00109                                 std::string params;                             
00110                                 for (uint32 j=0; j < mPlgMethods[i].param.size(); j++){
00111                                         params += mPlgMethods[i].param[j].name;
00112                                         if (j < mPlgMethods[i].param.size() - 1) params += ", ";
00113                                 }
00114                                 NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "  found  -  %s (%s)", mPlgMethods[i].name.c_str(), params.c_str());
00115                         }               
00116                 }*/
00117                 
00118                 // all right!
00119                 return OK;
00120         }
00121 
00122         //----------------------------------------------------------------------------------
00123         Result Plugin::unloadResource()
00124         {
00125                 // only unload, if we are loaded
00126                 if (isResourceLoaded())
00127                 {
00128                         // call the release function of the plugin
00129                         m_plgRelease();
00130 
00131                         // set all symbols to NULL
00132                         m_plgInitialize = NULL;
00133                         m_plgEngineVersion = NULL;
00134                         m_plgVersionString = NULL;
00135                         m_plgError = NULL;
00136                         m_plgRelease = NULL;
00137 
00138                         // now unload the plugin handle from memory
00139                         if (NR_PLUGIN_UNLOAD(mPluginHandle))
00140                         {
00141                                 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR,
00142                                         "Could not unload plugin %s. System Msg: %s",
00143                                         getResourceName().c_str(), getLastPluginError().c_str());
00144                                 return PLG_UNLOAD_ERROR;
00145                         }
00146         
00147                         // set the handle to 0
00148                         mPluginHandle = NULL;
00149                         markResourceUnloaded();
00150                 }
00151 
00152                 // OK
00153                 return OK;
00154         }
00155 
00156         //----------------------------------------------------------------------------------
00157         Result Plugin::reloadResource(PropertyList* params)
00158         {
00159                 if (!isResourceLoaded())
00160                 {
00161                         // get filename
00162                         const std::string& name = getResourceFilenameList().front();
00163                         
00164                         // now load the library
00165                         mPluginHandle = (PluginHandle)NR_PLUGIN_LOAD(name.c_str());
00166 
00167                         // check whenever the library could be loaded
00168                         if (mPluginHandle == NULL)
00169                         {
00170                                 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR,
00171                                         "Plugin %s could not be loaded! System Msg: %s",
00172                                         getResourceName().c_str(), getLastPluginError().c_str());
00173                                 return PLG_COULD_NOT_LOAD;
00174                         }
00175 
00176                         // force the plugin resource object to initialize itself after loading
00177                         return initialize(params);
00178                 }
00179                 return OK;
00180         }
00181 
00182         //-----------------------------------------------------------------------
00183         std::string Plugin::getLastPluginError()
00184         {
00185 #if NR_PLATFORM == NR_PLATFORM_WIN32
00186                 LPVOID lpMsgBuf; 
00187                 FormatMessage( 
00188                         FORMAT_MESSAGE_ALLOCATE_BUFFER | 
00189                         FORMAT_MESSAGE_FROM_SYSTEM | 
00190                         FORMAT_MESSAGE_IGNORE_INSERTS, 
00191                         NULL, 
00192                         GetLastError(), 
00193                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
00194                         (LPTSTR) &lpMsgBuf, 
00195                         0, 
00196                         NULL 
00197                         ); 
00198                 std::string ret = (char*)lpMsgBuf;
00199                 
00200                 // Free the buffer.
00201                 LocalFree( lpMsgBuf );
00202                 return ret;
00203 #elif NR_PLATFORM == NR_PLATFORM_LINUX
00204                 return std::string(dlerror());
00205 #elif NR_PLATFORM == NR_PLATFORM_APPLE
00206                 return std::string(mac_errorBundle());
00207 #else
00208                 return std::string("");
00209 #endif
00210         }
00211 
00212         //----------------------------------------------------------------------------------
00213         EmptyPlugin::EmptyPlugin() : Plugin()
00214         {
00215 
00216         }
00217 
00218         //----------------------------------------------------------------------------------
00219         EmptyPlugin::~EmptyPlugin()
00220         {
00221 
00222         }
00223 
00224         //----------------------------------------------------------------------------------
00225         Result EmptyPlugin::unloadResource()
00226         {
00227                 return OK;
00228         }
00229         //----------------------------------------------------------------------------------
00230         Result EmptyPlugin::reloadResource()
00231         {
00232                 return OK;
00233         }
00234 
00235         //----------------------------------------------------------------------------------
00236         void* EmptyPlugin::getSymbol(const std::string& name) const
00237         {
00238                 return NULL;
00239         }
00240 
00241 };
00242 

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1