source: nrEngine/src/PluginLoader.cpp @ 15

Revision 15, 6.1 KB checked in by art, 13 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        Result PluginLoader::loadResourceImpl(IResource* res, const std::string& fileName, PropertyList* param)
76        {
77
78                // check whenever we have a valid file name of the plugin
79                if (fileName.length() <= 3){
80                        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());
81                        return RES_BAD_FILETYPE;
82                }
83
84                std::string name = fileName;
85               
86#if NR_PLATFORM == NR_PLATFORM_LINUX
87                if (name.substr(name.length() - 3, 3) != ".so")
88                {
89                        // dlopen() does not add .so to the filename, like windows does for .dll
90                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "\".so\" added to the plugin file name %s", name.c_str());
91                        name += ".so";
92                }
93#elif NR_PLATFORM == NR_PLATFORM_WIN32
94                if (name.substr(name.length() - 4, 4) == ".dll")
95                {
96                        // windows does automaticly add .dll to the file name, so we have to cut the name
97                        name = name.substr(0, name.length() - 4);
98                }               
99#endif
100
101                // cast to plugin type
102                Plugin* plugin = dynamic_cast<Plugin*>(res);
103                NR_ASSERT(plugin != NULL);
104
105                // now load the library
106                plugin->mPluginHandle = (PluginHandle)NR_PLUGIN_LOAD(name.c_str());
107
108                // check whenever the library could be loaded
109                if (plugin->mPluginHandle == NULL)
110                {
111                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR,
112                                "Plugin %s could not be loaded! System Msg: %s",
113                                plugin->getResName().c_str(), getLastPluginError().c_str());
114                        return PLG_COULD_NOT_LOAD;
115                }
116
117                // force the plugin resource object to initialize itself after loading
118                return  plugin->initialize(param);
119        }
120       
121       
122        //----------------------------------------------------------------------------------
123        Result PluginLoader::unloadResourceImpl(IResource* resource)
124        {
125
126                // now unload the library from the memory
127                Plugin* plugin = dynamic_cast<Plugin*>(resource);
128                if (plugin)
129                {
130                        plugin->unloadRes();
131                                       
132                        if (NR_PLUGIN_UNLOAD(plugin->mPluginHandle))
133                        {
134                                NR_Log(Log::LOG_ENGINE, Log::LL_ERROR,
135                                        "Could not unload plugin %s. System Msg: %s",
136                                        plugin->getResName().c_str(), getLastPluginError().c_str());
137                                return PLG_UNLOAD_ERROR;
138                        }
139       
140                        // set the handle to 0
141                        plugin->mPluginHandle = NULL;
142                }
143               
144                // OK
145                return OK;             
146        }
147       
148       
149        //----------------------------------------------------------------------------------
150        IResource* PluginLoader::createResourceImpl(const std::string& resourceType, PropertyList* params)
151        {       
152                // create an plugin instance
153                return new Plugin();
154        }
155       
156       
157        //----------------------------------------------------------------------------------
158        IResource* PluginLoader::createEmptyResource(const std::string& resourceType)
159        {
160                // create an instance of empty plugin
161                return new EmptyPlugin();       
162        }
163       
164       
165        //-----------------------------------------------------------------------
166        std::string PluginLoader::getLastPluginError() 
167        {
168#if NR_PLATFORM == NR_PLATFORM_WIN32
169                LPVOID lpMsgBuf; 
170                FormatMessage( 
171                        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
172                        FORMAT_MESSAGE_FROM_SYSTEM | 
173                        FORMAT_MESSAGE_IGNORE_INSERTS, 
174                        NULL, 
175                        GetLastError(), 
176                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
177                        (LPTSTR) &lpMsgBuf, 
178                        0, 
179                        NULL 
180                        ); 
181                std::string ret = (char*)lpMsgBuf;
182               
183                // Free the buffer.
184                LocalFree( lpMsgBuf );
185                return ret;
186#elif NR_PLATFORM == NR_PLATFORM_LINUX
187                return std::string(dlerror());
188#elif NR_PLATFORM == NR_PLATFORM_APPLE
189                return std::string(mac_errorBundle());
190#else
191                return std::string("");
192#endif
193        }
194
195};
196
Note: See TracBrowser for help on using the repository browser.