ScriptEngine.h

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_SCRIPT_ENGINE_H_
00015 #define _NR_SCRIPT_ENGINE_H_
00016 
00017 
00018 //----------------------------------------------------------------------------------
00019 // Includes
00020 //----------------------------------------------------------------------------------
00021 #include "Prerequisities.h"
00022 
00023 //! Declare a scripting function as static memeber of class (c++ only)  \ingroup script
00024 #define ScriptFunctionDef(name)\
00025         public: static nrEngine::ScriptResult name (const std::vector<std::string>&, const std::vector<nrEngine::ScriptParam>&)
00026 
00027 //! Declare a scripting function out of the class class (c++ only)  \ingroup script
00028 #define ScriptFunctionDec(name, class)\
00029         nrEngine::ScriptResult class::name (const std::vector<std::string>& args, const std::vector<nrEngine::ScriptParam>& param)
00030 
00031 namespace nrEngine{
00032 
00033 
00034         //! Each script function can return variable argument as a result \ingroup script
00035         typedef VarArg ScriptResult;
00036 
00037         //! The real functions accept this default parameter \ingroup script
00038         typedef boost::any ScriptParam;
00039 
00040         //! We define each function that can be called from the scripts as this type \ingroup script
00041         typedef boost::function<ScriptResult (const std::vector<std::string>&, const std::vector<ScriptParam>&)> ScriptFunctor;
00042 
00043         //! Script engine is a glue code between the scripts and the engine
00044         /**
00045          * The script engine is a main class representing the glue code between
00046          * the scripting languages (from plugins or whatever) and the game engine.
00047          * The game engine will register functions by the script engine, so
00048          * you get an access to this functions in your scripts. So the script
00049          * engine class is something like an engine's API for the scripts.
00050          *
00051          * In the future we want to improve the functionality of the scripting
00052          * engine, by adding the possibility to use meta classes. So the scripts
00053          * could create new classes based on engine's.
00054          *
00055          * \ingroup script
00056         **/
00057         class _NRExport ScriptEngine{
00058                 public:
00059 
00060                         /**
00061                          * Cast a script parameter, which is of type "any", to any other type.
00062                          * Note: we use here any_cast, so you have to worry about catching the
00063                          * error throws
00064                          **/
00065                         template<class T>
00066                         static T parameter_cast(const ScriptParam& p){
00067                                 return boost::any_cast<T>(p);
00068                         }
00069 
00070                         /**
00071                         * Register new functions, that can be called from scripts.
00072                         * The functions registered here are called through call() method.
00073                         *
00074                         * You can also specify one default parameter, that will be passed
00075                         * to the called function (e.g. pointer to your object). The parameter is
00076                         * of the boost type "any". So it does not have certain type.
00077                         *
00078                         * @param name Name of the function, must be unique
00079                         * @param func Function itself (i.e. boost::function)
00080                         * @param param Parameters you want to be stored to pass later to the function
00081                         *
00082                         * @return either OK or an error code if there is some problems
00083                         **/
00084                         Result add(const std::string& name, ScriptFunctor func, const std::vector<ScriptParam>& param = std::vector<ScriptParam>());
00085 
00086                         /**
00087                          * Using variable parameter arguments.
00088                          * @see add()
00089                          **/
00090                         Result add(const std::string& name, ScriptFunctor func, const VarArg& v);
00091 
00092                         /**
00093                         * Delete already registered function from the api database.
00094                         *
00095                         * @param name name of the function to be deregistered
00096                         *
00097                         * @return either OK or an error code
00098                         **/
00099                         Result del(const std::string& name);
00100 
00101                         /**
00102                         * Call a certain function from the database whithin the given parameters.
00103                         * First script engine database will look if there is a function
00104                         * whithin the given name. Then if such could be found the functor
00105                         * according to the function will be called. As first parameter it sends
00106                         * the user predefined parameters, stored in the database. As second
00107                         * it will pass the string parameters coming from the script or from
00108                         * the subroutine called this method.
00109                         *
00110                         * @param name Unique name of hte function to be called
00111                         * @param args Argument list of arguments given to the function (like in
00112                         *                               the console, first must always be the function name)
00113                         **/
00114                         ScriptResult call(const std::string& name, const std::vector<std::string>& args = std::vector<std::string>());
00115 
00116                         /**
00117                          * Load a new script from the given file. The script will be loaded
00118                          * by the resource manager, which will try to find the appropriate
00119                          * loader for this type of scripts. If there is no such loader could
00120                          * be found, so null will be returned. Otherwise you get a resource
00121                          * pointer to the script. The resource pointer garanty that the according
00122                          * script will be used in the way like all other resources. This means if
00123                          * a script is unloaded,so EmptyScript will be used. You do not have
00124                          * to care about given pointers, because resource pointers have similar
00125                          * behaviours as smart pointers.
00126                          *
00127                          * The function does load the scripts in the memory, so you do not have
00128                          * to carry about the returned pointer, if you do not want to. Loaded scripts
00129                          * are still accessable by their names.
00130                          * 
00131                          * @param name Name for the script.
00132                          * @param fileName Name of the file containign the script.
00133                          *
00134                          * @return ResourcePtr<IScript> to the script. 
00135                          **/
00136                         ResourcePtr<IScript> load(const std::string& name, const std::string& fileName);
00137 
00138                         /**
00139                          * This method will execute script of a certain name loaded before
00140                          * with loadScript() method.
00141                          *
00142                          * @param name Unique name for the script
00143                          * @param runOnce If true the script will be executed only one time
00144                          * @param immediate If true the script will be run immediately. If false
00145                          * the script will be added as a task into the kernel, and will be started
00146                          * in the next execution cycle.
00147                          *
00148                          * @return Returning code of IScript::execute() method.
00149                          **/
00150                         Result execute(const std::string& name, bool runOnce = true, bool immediate = false);
00151 
00152                         /**
00153                          * Combined method of load() and execute(). See documentation for them
00154                          * instead
00155                          **/
00156                         Result execute(const std::string& name, const std::string& fileName, bool runOnce = true, bool immediate = false);
00157 
00158                         /**
00159                          * Get count of functions registered in the database
00160                          **/
00161                         NR_FORCEINLINE uint32 getFunctionCount() const { return mDatabase.size(); }
00162 
00163                         /**
00164                          * Return an functor element of a certain index from the database.
00165                          * Any functor element is a pair of the functor and script parameters
00166                          * defined by the user.
00167                          **/
00168                         const std::string& getFunction(uint32 index, ScriptFunctor& functor);
00169                                         
00170                 private:
00171 
00172                         //! Run not by name, but by pointer
00173                         Result _execute(const ResourcePtr<IScript>& ptr, bool runOnce = true, bool immediate = false);
00174 
00175                         //! Only engine is allowed to create the instances
00176                         friend class Engine;
00177 
00178                         //! Allocate memory and define all default values
00179                         ScriptEngine();
00180 
00181                         //! Release used memory and close the scripting engine
00182                         ~ScriptEngine();
00183 
00184                         //! This is our database holding the registered functions
00185                         typedef std::map<std::string, std::pair<ScriptFunctor, std::vector<ScriptParam> > > FunctionDatabase;
00186 
00187                         //! Here we store our registered functions
00188                         FunctionDatabase mDatabase;
00189 
00190                         //! Check whenever a function with the given name is already in the database
00191                         bool isRegistered(const std::string& name);
00192 
00193                         //! Get  the function according to the given name
00194                         FunctionDatabase::iterator get(const std::string& name);
00195 
00196 
00197                         ScriptFunctionDef(scriptLoad);
00198                         ScriptFunctionDef(scriptRun);
00199                         ScriptFunctionDef(scriptLoadAndRun);
00200                         ScriptFunctionDef(scriptCall);
00201                         
00202         };
00203 
00204 
00205 };
00206 
00207 #endif

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