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 #ifndef _NR_PLUGIN_RESOURCE__H_ 00015 #define _NR_PLUGIN_RESOURCE__H_ 00016 00017 00018 //---------------------------------------------------------------------------------- 00019 // Includes 00020 //---------------------------------------------------------------------------------- 00021 #include "Prerequisities.h" 00022 #include "Resource.h" 00023 #include "PluginLoader.h" 00024 00025 /*! 00026 * \defgroup plugin Plugin managment 00027 * 00028 * Plugins are used to extend the functionality of the underlying system 00029 * without recompiling it. So our engine does support plugins, which allows 00030 * programm new functionality to the engine without recompiling it. 00031 * 00032 * One of the best examples of such a plugin is a possibility to extend the resource 00033 * managment system to new resources. You can program addiditional texture loader 00034 * for example and "plug in" this into the engine. The new loader could load 00035 * textures and prepare them as resources, so your program can get use of them. 00036 * 00037 * Another example could be a plugin that runs as task in the engine's kernel 00038 * and do something. For example an ingame console could be such a task, which can 00039 * be fully programmed as external plugin. 00040 * 00041 * Each plugin is a simple dynamic library (*.dll, *.so) file, which contains the plugin. 00042 * Each plugin will be loaded if it is added to the plugin manager. The plgLoad() function 00043 * of the plugin will be called. If the plugin is unloaded, so call plgUnload(). 00044 * 00045 * Each plugin should export some default functions to be able to be loaded by the manager. 00046 * Plugins could be simple functionality plugins (like any loader) or a new task 00047 * in the engine's kernel (like a console). This capability of each plugin is readed 00048 * through special plugin functions. 00049 * 00050 * Also each plugin should provide a function which can be used to access internal 00051 * functionality of that plugin by using of strings. In our case this subroutine 00052 * should be called plgCall and accept as first the name of the function and then a 00053 * parameter list of parameters and their values. We use this to provide the user 00054 * applications a possibility to call certain functions from plugins which are not 00055 * replace a default behaviour of the engine but add some new functionality. The good 00056 * example where it can be used is a scripting. You load a plugins from the script 00057 * and then call some functions from the plugin whithin scripting. 00058 * 00059 **/ 00060 00061 namespace nrEngine{ 00062 00063 00064 /** 00065 * Each plugin is an dynamic library. So we have to use some handles 00066 * given by the os api to handle with these libraries. On each os 00067 * this handle is of different type. So we have to find out 00068 * which os do we using now and define the right type 00069 * 00070 * \ingroup plugin 00071 **/ 00072 #if NR_PLATFORM == NR_PLATFORM_WIN32 00073 typedef HINSTANCE PluginHandle; 00074 #elif NR_PLATFORM == NR_PLATFORM_LINUX 00075 typedef void* PluginHandle; 00076 #elif NR_PLATFORM == NR_PLATFORM_APPLE 00077 typedef CFBundleRef PluginHandle; 00078 #endif 00079 00080 //! General interface for any plugin in the engine 00081 /** 00082 * Plugins are used to extend the functionality of the engine without rewriting it. 00083 * You can just write new plugin and add this to the engine, so the engine could get 00084 * it loaded. The user will then get the new functionality automaticaly or by using 00085 * the concept of application - plugin - communication. 00086 * 00087 * Plugins are resources that used in the same way like normal resources. 00088 * 00089 * Each plugin library has to export following symbols: 00090 * - int plgInitialize(Engine*) 00091 * - will be called after library is loaded 00092 * - plugin will get the pointer to the root object of the engine 00093 * - return 0 for success otherwise error code 00094 * 00095 * - unsigned int plgEngineVersion() 00096 * - plugin should return a version number according to the engine 00097 * - return the value also if not initialized before 00098 * 00099 * - char* plgVersionString() 00100 * - return a full string containing information about the plugin version/name 00101 * - return the strign also if not initialized before 00102 * 00103 * - char* plgError (int) 00104 * - return a short error string for the given code 00105 * 00106 * - void plgRelease() 00107 * - will be called before plugin is getting unloaded 00108 * 00109 * 00110 * Following symbols are optional: 00111 * 00112 * - void plgGetMethods (std::vector<PlgMethod> &) 00113 * - should fill the given vector whithin informations of plugin methods 00114 * which could be used as extra calls from the user point of view (e.g. scripts) 00115 * 00116 * - void plgCall (const std::string&, std::vector<PlgParam>& ) 00117 * - call a subroutine from the plugin, also send parameters 00118 * 00119 * 00120 * @see IResource 00121 * \ingroup plugin 00122 **/ 00123 class _NRExport Plugin : public IResource{ 00124 public: 00125 00126 Plugin(); 00127 virtual ~Plugin(); 00128 00129 /** 00130 * Retuns the addres of a symbol (function,variable) from the plugin. 00131 * You have to cast this addres for using. 00132 * 00133 * @param name Unique name of the symbol 00134 **/ 00135 virtual void* getSymbol(const std::string& name) const; 00136 00137 //! Each method in the plugin accept parameters of this type 00138 /*typedef struct _plgParam { 00139 00140 //! Parameter name 00141 std::string name; 00142 00143 //! Parameter value as string 00144 std::string value; 00145 00146 } PlgParam; 00147 00148 //! This structure describes a subroutine in a plugin 00149 typedef struct _plgMethod { 00150 00151 //! Name of the subroutine 00152 std::string name; 00153 00154 //! parameter names which can be passed to this method 00155 std::vector<PlgParam> param; 00156 00157 //! Pointer pointing to the provided method 00158 void* symbol_ptr; 00159 00160 } PlgMethod;*/ 00161 00162 protected: 00163 00164 //! Plugin loader is a friend, so it get full accecc to our functions 00165 friend class PluginLoader; 00166 00167 //! Handle of the used dynamic library 00168 PluginHandle mPluginHandle; 00169 00170 //! this is the list of methods from the plugin 00171 //std::vector<PlgMethod> mPlgMethods; 00172 00173 //! This defines the interface of the initialization function of the plugin 00174 typedef int (*plgInitialize) ( Engine*, PropertyList* ); 00175 00176 //! Define the type of the error get function of th eplugin 00177 typedef char* (*plgError) ( int ); 00178 00179 //! This is the interface of the release function of the plugin 00180 typedef void (*plgRelease) ( void ); 00181 00182 //! Interface for the version information 00183 typedef unsigned int (*plgEngineVersion) ( void ); 00184 00185 //! Get full version string of the plugin 00186 typedef char* (*plgVersionString) ( void ); 00187 00188 /*//! Get a list of exported functions 00189 typedef void (*plgGetMethods) ( std::vector<PlgMethod>& ); 00190 00191 //! Call a method whithin given parameters 00192 typedef void (*plgCall) (const std::string&, const std::vector<PlgParam>& ); 00193 */ 00194 00195 plgInitialize m_plgInitialize; 00196 plgError m_plgError; 00197 plgRelease m_plgRelease; 00198 plgEngineVersion m_plgEngineVersion; 00199 plgVersionString m_plgVersionString; 00200 00201 /*plgGetMethods m_plgGetMethods; 00202 plgCall m_plgCall; 00203 */ 00204 /** 00205 * This method is called by the plugin loader after it has loaed the library. 00206 * The plugin object has now to get all symbols and initialize the library. 00207 * @return error code 00208 **/ 00209 Result initialize(PropertyList* params = NULL); 00210 00211 /** 00212 * Derived function from IResource 00213 **/ 00214 virtual Result unloadResource(); 00215 virtual Result reloadResource(PropertyList* params); 00216 00217 //! Get last plugin error message from the system 00218 std::string getLastPluginError(); 00219 00220 }; 00221 00222 00223 //! Simple class for empty plugin. This plugin doesn't have any effect 00224 /** 00225 * This class represents an empty plugin object. This corresponds 00226 * to our empty resource interface, needed to work for resource managment. 00227 * Empty plugin does not do anything. 00228 * 00229 * \ingroup plugin 00230 **/ 00231 class _NRExport EmptyPlugin : public Plugin{ 00232 public: 00233 00234 //! Constructor does not call anything 00235 EmptyPlugin(); 00236 00237 //! Release used memory 00238 ~EmptyPlugin(); 00239 00240 //! Unload the empty resource 00241 Result unloadResource(); 00242 00243 //! Reload the empty resource 00244 Result reloadResource(); 00245 00246 //! Return always NULL 00247 void* getSymbol(const std::string& name) const; 00248 00249 }; 00250 00251 }; 00252 00253 #endif