diff options
Diffstat (limited to 'src/core/script/ScriptEngine.hpp')
-rw-r--r-- | src/core/script/ScriptEngine.hpp | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/core/script/ScriptEngine.hpp b/src/core/script/ScriptEngine.hpp new file mode 100644 index 0000000..3a53791 --- /dev/null +++ b/src/core/script/ScriptEngine.hpp @@ -0,0 +1,233 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _OUSIA_SCRIPT_ENGINE_HPP_ +#define _OUSIA_SCRIPT_ENGINE_HPP_ + +#include <map> +#include <string> +#include <exception> + +#include <core/utils/Utils.hpp> + +#include "Variant.hpp" + +namespace ousia { +namespace script { + +/** + * Class used for signaling errors while executing code or registering variables + * in the script engine. + */ +class ScriptEngineException : public std::exception { + +public: + /** + * Line and column at which the exception occured. Set to -1 if the error + * does not correspond to a line or column. + */ + const int line, col; + + /** + * Error message. + */ + const std::string msg; + + /** + * ScriptEngineException constructor. + * + * @param line in the script code at which the exception occured. + * @param col in the script code at which the exception occured. + * @param msg is the message containing the reason for the exception. + */ + ScriptEngineException(int line, int col, const std::string &msg); + + /** + * ScriptEngineException constructor. + * + * @param msg is the message containing the reason for the exception. + */ + ScriptEngineException(const std::string &msg); + + /** + * Returns the error message. + */ + virtual const char* what() const noexcept; + +}; + +/** + * The ScriptEngineScope class represents an execution scope -- an execution + * scope is the base class + */ +class ScriptEngineScope { + +private: + + /** + * Helper used to check the given identifiers for their validity. + * + * @param name is the name of the identifier that should be checked. + * @throws ScriptEngineException if the given identifier is invalid. + */ + static void checkIdentifier(const std::string &name) + { + if (!Utils::isIdentifier(name)) { + throw ScriptEngineException{"Invalid identifier \"" + name + "\""}; + } + } + +protected: + + /** + * Implementation of the @see run function. + */ + virtual Variant doRun(const std::string &code) = 0; + + /** + * Implementation of the @see setVariable function. + */ + virtual void doSetVariable(const std::string &name, const Variant &val, + bool constant) = 0; + + /** + * Implementation of the @see getVariable function. + */ + virtual Variant doGetVariable(const std::string &name) = 0; + +public: + + /** + * Virtual destructor. Must be overwritten by implementing classes. + */ + virtual ~ScriptEngineScope() {}; + + /** + * Runs the given code in the excution context. + * + * @param code is a string containing the code the script engine should run. + * @return a variant containg the result of the executed code. + * @throws ScriptEngineException if an error occured during code execution. + */ + Variant run(const std::string &code) + { + return doRun(code); + } + + /** + * Sets the value of a variable in the scope with the given name. + * + * @param name is the name of the variable in the scope. Must be a + * well-formed identifier. + * @param val is the value of the variable. + * @param constant if true, the value of the variable cannot be changed by + * the script code. + * @throws ScriptEngineException if name is not a well-formed identifier. + */ + void setVariable(const std::string &name, const Variant &val, + bool constant = false) + { + checkIdentifier(name); + doSetVariable(name, val, constant); + } + + /** + * Reads the value of the variable with the given name. + * + * @param name is the name of the variable. The name must be well-formed. + * @return the value of the variable, or a NULL variant if the variable does + * not exist. + * @throws ScriptEngineException if name is not a well-formed identifier. + */ + Variant getVariable(const std::string &name) + { + checkIdentifier(name); + return doGetVariable(name); + } + +}; + +/** + * The abstract ScriptEngine class is used to provide an interface for script + * engine implementations. A script engine implementation has to provide a + * function which creates an execution scope. + */ +class ScriptEngine { + +public: + /** + * Requests an execution scope from the script engine implementation. The + * calling code is responsible for disposing the returned pointer. + */ + virtual ScriptEngineScope* createScope() const = 0; + +}; + +/** + * The ScriptEngineFactory class is a central registry for ScriptEngine + * instances and factory of ScriptEngineScope instances for a certain scripting + * language. + */ +class ScriptEngineFactory { + +private: + /** + * Internal map between the script language name and the actual script + * engine instance. + */ + std::map<std::string, ScriptEngine*> registry; + +public: + + /** + * Registers a ScriptEngine instance for a new scripting language. + * + * @param name is the name of the scripting language as MIME, e.g. + * "text/javascript" + * @param engine is the backend that should be registered. + */ + void registerScriptEngine(const std::string &name, ScriptEngine *engine); + + /** + * Removes a script engine from the registry. + * + * @param name is the name of the script engine that + */ + bool unregisterScriptEngine(const std::string &name); + + /** + * Creates an execution scope for the scripting language with the given + * name. + * + * @param name is the name of the scripting language for which the scope + * is being created. + * @return a pointer to the new execution scope or null if a script engine + * with the given name does not exist. The caller of this function is + * responsible + */ + ScriptEngineScope* createScope(const std::string &name) const; + +}; + +} +} + + +#endif /* _OUSIA_SCRIPT_ENGINE_HPP_ */ + + |