00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
00060 NR_Log(Log::LOG_ENGINE, "Plugin found: %s written for nrEngine v%s", m_plgVersionString(), convertVersionToString(m_plgEngineVersion()).c_str());
00061
00062
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
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
00082 GET_SYMBOL(m_plgInitialize, plgInitialize);
00083 GET_SYMBOL(m_plgError, plgError);
00084 GET_SYMBOL(m_plgRelease, plgRelease);
00085 #undef GET_SYMBOL
00086
00087
00088 int result = m_plgInitialize(Engine::instance(), params);
00089
00090
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
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 return OK;
00120 }
00121
00122
00123 Result Plugin::unloadResource()
00124 {
00125
00126 if (isResourceLoaded())
00127 {
00128
00129 m_plgRelease();
00130
00131
00132 m_plgInitialize = NULL;
00133 m_plgEngineVersion = NULL;
00134 m_plgVersionString = NULL;
00135 m_plgError = NULL;
00136 m_plgRelease = NULL;
00137
00138
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
00148 mPluginHandle = NULL;
00149 markResourceUnloaded();
00150 }
00151
00152
00153 return OK;
00154 }
00155
00156
00157 Result Plugin::reloadResource(PropertyList* params)
00158 {
00159 if (!isResourceLoaded())
00160 {
00161
00162 const std::string& name = getResourceFilenameList().front();
00163
00164
00165 mPluginHandle = (PluginHandle)NR_PLUGIN_LOAD(name.c_str());
00166
00167
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
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
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