From 989cc6d8064a95426962588f806bb987a6896e7f Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Sun, 21 Dec 2014 00:40:52 +0100 Subject: moved Rtti from managed to common folder, added Function header --- src/core/common/Function.cpp | 24 ++++ src/core/common/Function.hpp | 149 +++++++++++++++++++++++++ src/core/common/Rtti.cpp | 72 ++++++++++++ src/core/common/Rtti.hpp | 253 +++++++++++++++++++++++++++++++++++++++++++ src/core/managed/Managed.hpp | 3 +- src/core/managed/Rtti.cpp | 66 ----------- src/core/managed/Rtti.hpp | 220 ------------------------------------- 7 files changed, 500 insertions(+), 287 deletions(-) create mode 100644 src/core/common/Function.cpp create mode 100644 src/core/common/Function.hpp create mode 100644 src/core/common/Rtti.cpp create mode 100644 src/core/common/Rtti.hpp delete mode 100644 src/core/managed/Rtti.cpp delete mode 100644 src/core/managed/Rtti.hpp (limited to 'src/core') diff --git a/src/core/common/Function.cpp b/src/core/common/Function.cpp new file mode 100644 index 0000000..d4b8ccc --- /dev/null +++ b/src/core/common/Function.cpp @@ -0,0 +1,24 @@ +/* + 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 . +*/ + +#include "Function.hpp" + +namespace ousia { + +} + diff --git a/src/core/common/Function.hpp b/src/core/common/Function.hpp new file mode 100644 index 0000000..3a0ed9f --- /dev/null +++ b/src/core/common/Function.hpp @@ -0,0 +1,149 @@ +/* + 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 . +*/ + +/** + * @file Function.hpp + * + * Contains the definition of a Function class used to describe both methods and + * functions in the host code and functions in the script code. + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_FUNCTION_HPP_ +#define _OUSIA_FUNCTION_HPP_ + +#include +#include + +#include "Variant.hpp" + +namespace ousia { + +/** + * The AbstractFunction interface defines all the methods needed to represent + * a reference at a generic function object. Function objects can be called + * using the call function in which an array of Variant is supplied to the + * function and a Variant is returned to the caller. + */ +class AbstractFunction { +private: + /** + * Private, non-callable constructor. + */ + AbstractFunction(){}; + + /* No copy constructor */ + AbstractFunction(const AbstractFunction &) = delete; + + /* No move constructor */ + AbstractFunction(AbstractFunction &&) = delete; + +public: + /** + * Pure virtual method used to create a copy of the AbstractFunction + * object. + * + * @return a unique pointer pointing at a copy of the AbstractFunction + * object. + */ + virtual std::unique_ptr clone() const = 0; + + /** + * Virtual destructor. + */ + virtual ~AbstractFunction() {} + + /** + * Abstract function which is meant to call the underlying function (be it + * a host or a script function) with the given arguments. + * + * @param args is a vector containing all arguments that shall be passed to + * the function. + * @return a Variant containing the return value. + */ + virtual Variant call(const Variant::arrayType &args = Variant::arrayType{}, + void *thisRef = nullptr) const = 0; +}; + +/** + * The Method class refers to a method in the C++ code, belonging to an object + * of a certain type T. + * + * @tparam T is the type of the method that should be called. + */ +template +class Method : public AbstractFunction { +public: + /** + * Type of the Callback function that is being called by the "call" + * function. + * + * @param args contains the input arguments that were passed to the + * function. + * @param thisRef is a pointer pointing at an instance of type T. + * @return the return value of the function as Variant instance. + */ + using Callback = Variant (*)(const Variant::arrayType &args, T *thisRef); + +private: + /** + * Pointer at the actual C++ method being called. + */ + const Callback method; + +public: + /** + * Constructor of the Method class. + * + * @param method is a pointer at the C++ function that should be called. + */ + Method(Callback method) : method(method){}; + + /** + * Creates a copy of this Method object. + */ + std::unique_ptr clone() const override + { + return std::unique_ptr{new Method(method)}; + } + + /** + * Calls the underlying method. + * + * @param args is a vector containing all arguments that shouild be passed + * to the method. + * @return a Variant containing the return value. + */ + Variant call(const Variant::arrayType &args = Variant::arrayType{}, + void *thisRef = nullptr) const override + { + // Dynamically cast thisRef to the given type + T *tRef = dynamic_cast(thisRef); + + // Make sure the cast is successfull + assert(tRef != nullptr); + + // Call the method + return method(args, tRef); + } +}; +} + +#endif /* _OUSIA_FUNCTION_HPP_ */ + diff --git a/src/core/common/Rtti.cpp b/src/core/common/Rtti.cpp new file mode 100644 index 0000000..eeae41f --- /dev/null +++ b/src/core/common/Rtti.cpp @@ -0,0 +1,72 @@ +/* + 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 . +*/ + +#include "Rtti.hpp" + +namespace ousia { + +/* Class RttiStore */ + +std::unordered_map &RttiStore::table() +{ + static std::unordered_map table; + return table; +} + +void RttiStore::store(const std::type_info &native, const RttiBase *rtti) +{ + table().emplace(std::type_index{native}, rtti); +} + +const RttiBase &RttiStore::lookup(const std::type_info &native) +{ + const auto &tbl = table(); + auto it = tbl.find(std::type_index{native}); + if (it == tbl.end()) { + return RttiTypes::None; + } else { + return *(it->second); + } +} + +/* Class RttiBase */ + +bool RttiBase::isa(const RttiBase &other) const +{ + if (&other == this) { + return true; + } + for (auto t : parents) { + if (t->isa(other)) { + return true; + } + } + return false; +} + +/* Constant initialization */ + +const RttiBase RttiTypes::None; +const RttiBase RttiTypes::Int; +const RttiBase RttiTypes::Double; +const RttiBase RttiTypes::String; +const RttiBase RttiTypes::Array; +const RttiBase RttiTypes::Map; + +} + diff --git a/src/core/common/Rtti.hpp b/src/core/common/Rtti.hpp new file mode 100644 index 0000000..b91bd35 --- /dev/null +++ b/src/core/common/Rtti.hpp @@ -0,0 +1,253 @@ +/* + 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 . +*/ + +/** + * @file Rtti.hpp + * + * Classes used for storing runtime type information (RTTI). RTTI is used to + * resolve objects of a certain type in the object graph and to attach + * information that should be accessible to the script engine. + * + * Why is this needed? C++ provides the typeid operator to + * retrieve a reference at an internal table associated with type information + * for the given class. However, there is no native way for attaching additonal + * information to this type information table. Additional information we need to + * store is the inheritance graph (which cannot easily be extracted from C++) + * and information relevant for script engines (such as a list of methods and + * properties). One could of course store information about the type within each + * instance of this type, however when managing thousands of objects + * this would create a significant overhead. + * + * How to use: The Rtti class allows to attach information to a certain + * C++ class. To do so, create a global constant of the type Rtti in the + * source file associated with the type declaration, where T is the type you + * want to register. As the type must only be registered once, you must not + * declare the variable as "static" in the header file (this would register it + * whever the header is included). If you want to access the global constant + * from other Rtti definitions (as parent), create a forward declaration + * in the header file. If you want to access the RTTI of a certain object or + * type, use the global typeOf() function (however, don't use it + * within global variable initializations). + * + * Example: + * In the header file: + * \code{.hpp} + * // Only needed if the type needs to be accessed + * // from other compilation units! + * extern const Rtti MyType_Rtti; + * \endcode + * In the source file: + * \code{.cpp} + * const Rtti MyType_Rtti{"MyType", {&MyOtherType_Rtti}, [...]}; + * \endcode + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_RTTI_HPP_ +#define _OUSIA_RTTI_HPP_ + +#include +#include +#include +#include + +namespace ousia { + +class RttiBase; + +/** + * Helper class used to globally store and access the runtime type information. + */ +class RttiStore { +private: + /** + * Function used internally to access the static map storing all registered + * native types and their corresponding type information. + */ + static std::unordered_map &table(); + +public: + /** + * Registers the given pointer to the RttiBase class in the RTTI table. Does + * not override information for already registered types. + * + * @param native is a reference at the native type information provided + * by the compiler. + * @param rtti is a pointer pointing at the type information that should be + * stored for this type. + */ + static void store(const std::type_info &native, const RttiBase *rtti); + + /** + * Looks up the type information stored for the given native type + * information. + */ + static const RttiBase &lookup(const std::type_info &native); +}; + +/** + * The Rtti class allows for attaching data to native types that can be accessed + * at runtime. This type information can e.g. be retrieved using the "type" + * method of the Managed class. This system is used for attaching human readable + * names, parent types and script engine functionality. Use the Rtti class for + * convenient registration of type information. + */ +class RttiBase { +private: + /** + * Set containing references to the parent types. + */ + const std::vector parents; + +public: + /** + * Human readable name associated with the type. + */ + const std::string name; + + /** + * Default constructor. Creates a Rtti instance with name "unknown" + * and no parents. + */ + RttiBase() : name("unknown") {} + + /** + * Creates a new RttiBase instance and registers it in the global type + * table. Use the Rtti class for more convinient registration of type + * information. + * + * @param name is the name of the type. + * @param native is a reference at the native type information provided by + * the compiler. + * @param parents is a list of parent types. + */ + RttiBase( + std::string name, const std::type_info &native, + std::vector parents = std::vector{}) + : parents(std::move(parents)), name(std::move(name)) + { + RttiStore::store(native, this); + } + + /** + * Returns true if this Rtti instance is the given type or has the + * given type as one of its parents. + * + * @param other is the other type for which the relation to this type + * should be checked. + */ + bool isa(const RttiBase &other) const; +}; + +/** + * The Rtti class allows for attaching data to native types that can be accessed + * at runtime. This type information can e.g. be retrieved using the "type" + * method of the Managed class. This system is used for attaching human + * readable names, parent types and script engine functionality. + * + * @tparam T is the class for which the type information should be registered. + */ +template +class Rtti : public RttiBase { +public: + /** + * Creates a new RttiBase instance and registers it in the global type + * table. + * + * @param name is the name of the type. + * @param parents is a list of parent types. + */ + Rtti(std::string name, const std::vector &parents = + std::vector{}) + : RttiBase(name, typeid(T), parents) + { + } +}; + +/** + * Function that can be used to retrieve the RTTI information of a Managed + * object. Do not use this function in the initialization of global Rtti + * variables, use pointers at the other global variable instead (as the + * initialization order is not well defined). + * + * @tparam T is the C++ type for which the type information should be returned. + */ +template +inline const RttiBase &typeOf() +{ + return RttiStore::lookup(typeid(T)); +} + +/** + * Function that can be used to retrieve the RTTI information of a Managed + * object. Do not use this function in the initialization of global Rtti + * variables, use pointers at the other global variable instead (as the + * initialization order is not well defined). + * + * @tparam T is the C++ type for which the type information should be returned. + * @param obj is a dummy object for which the type information should be + * returned. + */ +template +inline const RttiBase &typeOf(const T &obj) +{ + return RttiStore::lookup(typeid(obj)); +} + +/** + * Struct defining static constants describing certain Variant types. These + * constants are used to e.g. define the type of function arguments while + * allowing for both primitive variant types and more complex variant types. + */ +struct RttiTypes { + /** + * Type of no particular color. + */ + static const RttiBase None; + + /** + * Constant representing a variant int type. + */ + static const RttiBase Int; + + /** + * Constant representing a variant double type. + */ + static const RttiBase Double; + + /** + * Constant representing a variant string type. + */ + static const RttiBase String; + + /** + * Constant representing a variant array type. + */ + static const RttiBase Array; + + /** + * Constant representing a variant map type. + */ + static const RttiBase Map; +}; + +} + +#endif /* _OUSIA_RTTI_HPP_ */ + diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp index 8582702..70136d3 100644 --- a/src/core/managed/Managed.hpp +++ b/src/core/managed/Managed.hpp @@ -19,7 +19,8 @@ #ifndef _OUSIA_MANAGED_HPP_ #define _OUSIA_MANAGED_HPP_ -#include "Rtti.hpp" +#include + #include "Manager.hpp" namespace ousia { diff --git a/src/core/managed/Rtti.cpp b/src/core/managed/Rtti.cpp deleted file mode 100644 index eade524..0000000 --- a/src/core/managed/Rtti.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - 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 . -*/ - -#include "Rtti.hpp" - -namespace ousia { - -/* Class RttiStore */ - -std::unordered_map &RttiStore::table() -{ - static std::unordered_map table; - return table; -} - -void RttiStore::store(const std::type_info &native, const RttiBase *rtti) -{ - table().emplace(std::type_index{native}, rtti); -} - -const RttiBase &RttiStore::lookup(const std::type_info &native) -{ - const auto &tbl = table(); - auto it = tbl.find(std::type_index{native}); - if (it == tbl.end()) { - return RttiBase::None; - } else { - return *(it->second); - } -} - -/* Class RttiBase */ - -const RttiBase RttiBase::None; - -bool RttiBase::isa(const RttiBase &other) const -{ - if (&other == this) { - return true; - } - for (auto t : parents) { - if (t->isa(other)) { - return true; - } - } - return false; -} - - -} - diff --git a/src/core/managed/Rtti.hpp b/src/core/managed/Rtti.hpp deleted file mode 100644 index 4a754a7..0000000 --- a/src/core/managed/Rtti.hpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - 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 . -*/ - -/** - * @file Rtti.hpp - * - * Classes used for storing runtime type information (RTTI). RTTI is used to - * resolve objects of a certain type in the object graph and to attach - * information that should be accessible to the script engine. - * - * Why is this needed? C++ provides the typeid operator to - * retrieve a reference at an internal table associated with type information - * for the given class. However, there is no native way for attaching additonal - * information to this type information table. Additional information we need to - * store is the inheritance graph (which cannot easily be extracted from C++) - * and information relevant for script engines (such as a list of methods and - * properties). One could of course store information about the type within each - * instance of this type, however when managing thousands of objects - * this would create a significant overhead. - * - * How to use: The Rtti class allows to attach information to a certain - * C++ class. To do so, create a global constant of the type Rtti in the - * source file associated with the type declaration, where T is the type you - * want to register. As the type must only be registered once, you must not - * declare the variable as "static" in the header file (this would register it - * whever the header is included). If you want to access the global constant - * from other Rtti definitions (as parent), create a forward declaration - * in the header file. If you want to access the RTTI of a certain object or - * type, use the global typeOf() function (however, don't use it - * within global variable initializations). - * - * Example: - * In the header file: - * \code{.hpp} - * // Only needed if the type needs to be accessed - * // from other compilation units! - * const Rtti MyType_Rtti; - * \endcode - * In the source file: - * \code{.cpp} - * const Rtti MyType_Rtti{"MyType", {&MyOtherType_Rtti}, [...]}; - * \endcode - * - * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) - */ - -#ifndef _OUSIA_MANAGED_RTTI_HPP_ -#define _OUSIA_MANAGED_RTTI_HPP_ - -#include -#include -#include -#include - -namespace ousia { - -class RttiBase; - -/** - * Helper class used to globally store and access the runtime type information. - */ -class RttiStore { -private: - /** - * Function used internally to access the static map storing all registered - * native types and their corresponding type information. - */ - static std::unordered_map &table(); - -public: - /** - * Registers the given pointer to the RttiBase class in the RTTI table. Does - * not override information for already registered types. - * - * @param native is a reference at the native type information provided - * by the compiler. - * @param rtti is a pointer pointing at the type information that should be - * stored for this type. - */ - static void store(const std::type_info &native, const RttiBase *rtti); - - /** - * Looks up the type information stored for the given native type - * information. - */ - static const RttiBase &lookup(const std::type_info &native); -}; - -/** - * The Rtti class allows for attaching data to native types that can be accessed - * at runtime. This type information can e.g. be retrieved using the "type" - * method of the Managed class. This system is used for attaching human readable - * names, parent types and script engine functionality. Use the Rtti class for - * convenient registration of type information. - */ -class RttiBase { -private: - /** - * Set containing references to the parent types. - */ - const std::vector parents; - -public: - /** - * Rtti of no particular type. - */ - static const RttiBase None; - - /** - * Human readable name associated with the type. - */ - const std::string name; - - /** - * Default constructor. Creates a Rtti instance with name "unknown" - * and no parents. - */ - RttiBase() : name("unknown") {} - - /** - * Creates a new RttiBase instance and registers it in the global type - * table. Use the Rtti class for more convinient registration of type - * information. - * - * @param name is the name of the type. - * @param native is a reference at the native type information provided by - * the compiler. - * @param parents is a list of parent types. - */ - RttiBase( - std::string name, const std::type_info &native, - std::vector parents = std::vector{}) - : parents(std::move(parents)), name(std::move(name)) - { - RttiStore::store(native, this); - } - - /** - * Returns true if this Rtti instance is the given type or has the - * given type as one of its parents. - * - * @param other is the other type for which the relation to this type - * should be checked. - */ - bool isa(const RttiBase &other) const; -}; - -/** - * The Rtti class allows for attaching data to native types that can be accessed - * at runtime. This type information can e.g. be retrieved using the "type" - * method of the Managed class. This system is used for attaching human - * readable names, parent types and script engine functionality. - * - * @tparam T is the class for which the type information should be registered. - */ -template -class Rtti : public RttiBase { -public: - /** - * Creates a new RttiBase instance and registers it in the global type - * table. - * - * @param name is the name of the type. - * @param parents is a list of parent types. - */ - Rtti(std::string name, const std::vector &parents = - std::vector{}) - : RttiBase(name, typeid(T), parents) - { - } -}; - -/** - * Function that can be used to retrieve the RTTI information of a Managed - * object. Do not use this function in the initialization of global Rtti - * variables, use pointers at the other global variable instead (as the - * initialization order is not well defined). - * - * @tparam T is the C++ type for which the type information should be returned. - */ -template -inline const RttiBase &typeOf() -{ - return RttiStore::lookup(typeid(T)); -} - -/** - * Function that can be used to retrieve the RTTI information of a Managed - * object. Do not use this function in the initialization of global Rtti - * variables, use pointers at the other global variable instead (as the - * initialization order is not well defined). - * - * @tparam T is the C++ type for which the type information should be returned. - * @param obj is a dummy object for which the type information should be - * returned. - */ -template -inline const RttiBase &typeOf(const T &obj) -{ - return RttiStore::lookup(typeid(obj)); -} -} - -#endif /* _OUSIA_MANAGED_RTTI_HPP_ */ - -- cgit v1.2.3