source: nrEngine/src/PluginLoader.cpp @ 32

Revision 32, 6.4 KB checked in by art, 12 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14//----------------------------------------------------------------------------------
15// Includes
16//----------------------------------------------------------------------------------
17#include "PluginLoader.h"
18#include "Log.h"
19
20namespace nrEngine{
21       
22        //----------------------------------------------------------------------------------
23        ScriptFunctionDec(loadPlugin, PluginLoader)
24        {
25                // check if the parameter count is valid
26                if (args.size() <= 2){
27                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "PluginLoader: loadPlugin(name, file) : wrong parameter count");
28                        return ScriptResult(std::string("More parameters required! loadPlugin(name, file)"));
29                }
30               
31                // try to load all the plugins given
32                Engine::instance()->loadPlugin("", args[2], args[1]);
33
34                // ok
35                return ScriptResult();
36        }
37       
38        //----------------------------------------------------------------------------------
39        PluginLoader::PluginLoader() : IResourceLoader("PluginLoader")
40        {
41                initializeResourceLoader();
42               
43                // register some new functions by the scripting engine
44                Engine::sScriptEngine()->add("loadPlugin", loadPlugin);
45               
46        }
47
48       
49        //----------------------------------------------------------------------------------
50        PluginLoader::~PluginLoader()
51        {
52                // remove the functions provided to the scripting engine
53                Engine::sScriptEngine()->del("loadPlugin");
54        }
55       
56        //----------------------------------------------------------------------------------
57        Result PluginLoader::initializeResourceLoader(){
58
59                // fill out supported resource types;
60                declareSupportedResourceType("Plugin");
61                declareSupportedResourceType("nrPlugin");
62               
63                // we do only support dll files in windows version of our engine
64#if NR_PLATFORM == NR_PLATFORM_WIN32
65                declareSupportedFileType("dll");
66                declareTypeMap("dll", "Plugin");
67#elif NR_PLATFORM == NR_PLATFORM_LINUX
68                declareSupportedFileType("so");
69                declareTypeMap("so", "Plugin");
70#endif
71                return OK;
72        }
73
74        //----------------------------------------------------------------------------------
75        std::string PluginLoader::getSuffix(const std::string& resType)
76        {
77#if NR_PLATFORM == NR_PLATFORM_WIN32
78                return std::string("dll");
79#elif NR_PLATFORM == NR_PLATFORM_LINUX
80                return std::string("so");
81#endif
82        }
83
84        //----------------------------------------------------------------------------------
85        Result PluginLoader::loadResourceImpl(IResource* res, const std::string& fileName, PropertyList* param)
86        {
87
88                // check whenever we have a valid file name of the plugin
89                if (fileName.length() <= 3){
90                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "File name of the plugin is not valid %s. It must contain at least 3 characters.", fileName.c_str());
91                        return RES_BAD_FILETYPE;
92                }
93
94                std::string name = fileName;
95               
96#if NR_PLATFORM == NR_PLATFORM_LINUX
97                if (name.substr(name.length() - 3, 3) != ".so")
98                {
99                        // dlopen() does not add .so to the filename, like windows does for .dll
100                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "\".so\" added to the plugin file name %s", name.c_str());
101                        name += ".so";
102                }
103#elif NR_PLATFORM == NR_PLATFORM_WIN32
104                if (name.substr(name.length() - 4, 4) == ".dll")
105                {
106                        // windows does automaticly add .dll to the file name, so we have to cut the name
107                        name = name.substr(0, name.length() - 4);
108                }               
109#endif
110
111                // cast to plugin type
112                Plugin* plugin = dynamic_cast<Plugin*>(res);
113                NR_ASSERT(plugin != NULL);
114
115                // now load the library
116                plugin->mPluginHandle = (PluginHandle)NR_PLUGIN_LOAD(name.c_str());
117
118                // check whenever the library could be loaded
119                if (plugin->mPluginHandle == NULL)
120                {
121                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR,
122                                "Plugin %s could not be loaded! System Msg: %s",
123                                plugin->getResName().c_str(), getLastPluginError().c_str());
124                        return PLG_COULD_NOT_LOAD;
125                }
126
127                // force the plugin resource object to initialize itself after loading
128                return  plugin->initialize(param);
129        }
130       
131       
132        //----------------------------------------------------------------------------------
133        Result PluginLoader::unloadResourceImpl(IResource* resource)
134        {
135
136                // now unload the library from the memory
137                Plugin* plugin = dynamic_cast<Plugin*>(resource);
138                if (plugin)
139                {
140                        plugin->unloadRes();
141                                       
142                        if (NR_PLUGIN_UNLOAD(plugin->mPluginHandle))
143                        {
144                                NR_Log(Log::LOG_ENGINE, Log::LL_ERROR,
145                                        "Could not unload plugin %s. System Msg: %s",
146                                        plugin->getResName().c_str(), getLastPluginError().c_str());
147                                return PLG_UNLOAD_ERROR;
148                        }
149       
150                        // set the handle to 0
151                        plugin->mPluginHandle = NULL;
152                }
153               
154                // OK
155                return OK;             
156        }
157       
158       
159        //----------------------------------------------------------------------------------
160        IResource* PluginLoader::createResourceImpl(const std::string& resourceType, PropertyList* params)
161        {       
162                // create an plugin instance
163                return new Plugin();
164        }
165       
166       
167        //----------------------------------------------------------------------------------
168        IResource* PluginLoader::createEmptyResource(const std::string& resourceType)
169        {
170                // create an instance of empty plugin
171                return new EmptyPlugin();       
172        }
173       
174       
175        //-----------------------------------------------------------------------
176        std::string PluginLoader::getLastPluginError() 
177        {
178#if NR_PLATFORM == NR_PLATFORM_WIN32
179                LPVOID lpMsgBuf; 
180                FormatMessage( 
181                        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
182                        FORMAT_MESSAGE_FROM_SYSTEM | 
183                        FORMAT_MESSAGE_IGNORE_INSERTS, 
184                        NULL, 
185                        GetLastError(), 
186                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
187                        (LPTSTR) &lpMsgBuf, 
188                        0, 
189                        NULL 
190                        ); 
191                std::string ret = (char*)lpMsgBuf;
192               
193                // Free the buffer.
194                LocalFree( lpMsgBuf );
195                return ret;
196#elif NR_PLATFORM == NR_PLATFORM_LINUX
197                return std::string(dlerror());
198#elif NR_PLATFORM == NR_PLATFORM_APPLE
199                return std::string(mac_errorBundle());
200#else
201                return std::string("");
202#endif
203        }
204
205};
206
Note: See TracBrowser for help on using the repository browser.