diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/common/Rtti.hpp | 182 | ||||
-rw-r--r-- | src/core/model/Document.cpp | 28 | ||||
-rw-r--r-- | src/core/model/Domain.cpp | 20 | ||||
-rw-r--r-- | src/core/model/Typesystem.cpp | 39 |
4 files changed, 226 insertions, 43 deletions
diff --git a/src/core/common/Rtti.hpp b/src/core/common/Rtti.hpp index 237c60f..9d0cdab 100644 --- a/src/core/common/Rtti.hpp +++ b/src/core/common/Rtti.hpp @@ -105,6 +105,152 @@ public: }; /** + * The RttiBuilder class is used to conveniently build new instances of the Rtti + * or the RttiBase class. It follows the "Builder" pattern and allows to create + * the properties of the RttiBase class by chaining method calls. The RttiBase + * and Rtti class can be constructed from the RttiBuilder instance. + */ +class RttiBuilder { +public: + /** + * Type describing a set of RttiBase pointers. + */ + using RttiBaseSet = std::unordered_set<const RttiBase *>; + + /** + * Contains the human readable name of the type for which the type + * information is being built. + */ + std::string currentName; + + /** + * Set containing references to all parent types. + */ + RttiBaseSet parentTypes; + + /** + * Set containing references to all composite types. + */ + RttiBaseSet compositeTypes; + + /** + * Default constructor, initializes the name of the type described by the + * RttiBaseSet with "unknown". + */ + RttiBuilder() : currentName("unknown"){}; + + /** + * Default constructor, initializes the name of the type described by the + * RttiBaseSet with the given name. + * + * @param name is the initial name of the type described by the type + * builder. + */ + RttiBuilder(std::string name) : currentName(std::move(name)){}; + + /** + * Sets the human readable name of the type information being built to the + * given string. + * + * @param s is the name to which the name should be set. + * @return a reference to the current RttiBuilder reference to allow method + * chaining. + */ + RttiBuilder &name(const std::string &s) + { + currentName = s; + return *this; + } + + /** + * Adds the given type descriptor as "parent" of the type information that + * is being built by this RttiBuilder instance. + * + * @param p is the pointer to the type descriptor that should be added. + * @return a reference to the current RttiBuilder reference to allow method + * chaining. + */ + RttiBuilder &parent(const RttiBase *p) + { + parentTypes.insert(p); + return *this; + } + + /** + * Adds the given type descriptor as "parent" of the type information that + * is being built by this RttiBuilder instance. + * + * @param p is the pointer to the type descriptor that should be added. + * @return a reference to the current RttiBuilder reference to allow method + * chaining. + */ + RttiBuilder &parent(const RttiBase &p) + { + parentTypes.insert(&p); + return *this; + } + + /** + * Adds the given type descriptors as "parent" of the type information that + * is being built by this RttiBuilder instance. + * + * @param p is a + * @return a reference to the current RttiBuilder reference to allow method + * chaining. + */ + RttiBuilder &parent(const RttiBaseSet &p) + { + parentTypes.insert(p.begin(), p.end()); + return *this; + } + + /** + * Marks the current type being built by this RttiBuilder instance as being + * a composition of the given other type. + * + * @param p is the pointer to the type descriptor that should be added as + * composition type. + * @return a reference to the current RttiBuilder reference to allow method + * chaining. + */ + RttiBuilder &composedOf(const RttiBase *p) + { + compositeTypes.insert(p); + return *this; + } + + /** + * Marks the current type being built by this RttiBuilder instance as being + * a composition of the given other type. + * + * @param p is the pointer to the type descriptor that should be added as + * composition type. + * @return a reference to the current RttiBuilder reference to allow method + * chaining. + */ + RttiBuilder &composedOf(const RttiBase &p) + { + compositeTypes.insert(&p); + return *this; + } + + /** + * Marks the current type being built by this RttiBuilder instance as being + * a composition of the given other types. + * + * @param p is the pointer to the type descriptor that should be added as + * composition type. + * @return a reference to the current RttiBuilder reference to allow method + * chaining. + */ + RttiBuilder &composedOf(const RttiBaseSet &p) + { + compositeTypes.insert(p.begin(), p.end()); + return *this; + } +}; + +/** * 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 @@ -151,13 +297,15 @@ public: /** * Creates a new RttiBase instance and registers it in the global type - * table. Use the Rtti class for more convinient registration of type - * information. + * table. Use the Rtti and the RttiBuilder class for more convenient + * 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. + * @param compositeTypes is a list of types of which instances of this type + * are composited (consist of). */ RttiBase(std::string name, const std::type_info &native, std::unordered_set<const RttiBase *> parents = @@ -173,6 +321,22 @@ public: } /** + * Creates a new RttiBase instance and registers it in the global type + * table. Use the Rtti class for more convenient registration of type + * information. + * + * @param builder is the builder instance containing the Rtti data. + */ + RttiBase(const std::type_info &native, const RttiBuilder &builder) + : initialized(false), + parents(builder.parentTypes), + compositeTypes(builder.compositeTypes), + name(builder.currentName) + { + RttiStore::store(native, this); + } + + /** * Returns true if this Rtti instance is the given type or has the * given type as one of its parents. * @@ -204,11 +368,12 @@ template <class T> class Rtti : public RttiBase { public: /** - * Creates a new RttiBase instance and registers it in the global type - * table. + * Creates a new Rtti 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. + * @param compositeTypes is a list of types of which instances of this type + * are composited (consist of). */ Rtti(std::string name, const std::unordered_set<const RttiBase *> &parents = std::unordered_set<const RttiBase *>{}, @@ -218,6 +383,15 @@ public: std::move(compositeTypes)) { } + + /** + * Creates a new Rtti instance from the data stored in the given builder + * instance and registers it in the global type table. + * + * @param builder is the RttiBuilder instance containing the data from which + * the Rtti information should be copied. + */ + Rtti(const RttiBuilder &builder) : RttiBase(typeid(T), builder){}; }; /** diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index b700ba4..f40e452 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -191,19 +191,21 @@ Rooted<DocumentPrimitive> DocumentPrimitive::buildEntity( } namespace RttiTypes { -const Rtti<model::Document> Document{ - "Document", {&Node}, {&AnnotationEntity, &StructuredEntity}}; -const Rtti<model::DocumentEntity> DocumentEntity{"DocumentEntity", {&Node}}; -const Rtti<model::AnnotationEntity> AnnotationEntity{ - "AnnotationEntity", {&DocumentEntity}, {&StructuredEntity}}; -const Rtti<model::StructuredEntity> StructuredEntity{ - "StructuredEntity", - {&DocumentEntity}, - {&StructuredEntity, &Anchor, &DocumentPrimitive}}; -const Rtti<model::DocumentPrimitive> DocumentPrimitive{"DocumentPrimitive", - {&StructuredEntity}}; -const Rtti<model::AnnotationEntity::Anchor> Anchor{"Anchor", - {&StructuredEntity}}; +const Rtti<model::DocumentEntity> DocumentEntity = + RttiBuilder("DocumentEntity").parent(&Node); +const Rtti<model::Document> Document = + RttiBuilder("Document").parent(&Node).composedOf( + {&AnnotationEntity, &StructuredEntity}); +const Rtti<model::AnnotationEntity> AnnotationEntity = + RttiBuilder("AnnotationEntity").parent(&DocumentEntity).composedOf( + &StructuredEntity); +const Rtti<model::StructuredEntity> StructuredEntity = + RttiBuilder("StructuredEntity").parent(&DocumentEntity).composedOf( + {&StructuredEntity, &Anchor, &DocumentPrimitive}); +const Rtti<model::DocumentPrimitive> DocumentPrimitive = + RttiBuilder("DocumentPrimitive").parent(&StructuredEntity); +const Rtti<model::AnnotationEntity::Anchor> Anchor = + RttiBuilder("Anchor").parent(&StructuredEntity); } } diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index f9e2a55..e2aaba4 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -82,14 +82,18 @@ void Domain::doResolve(std::vector<Rooted<Managed>> &res, /* Type registrations */ namespace RttiTypes { -const Rtti<model::FieldDescriptor> FieldDescriptor{"FieldDescriptor", {&Node}}; -const Rtti<model::Descriptor> Descriptor{"Descriptor", {&Node}}; -const Rtti<model::StructuredClass> StructuredClass{ - "StructuredClass", {&Descriptor}, {&FieldDescriptor}}; -const Rtti<model::AnnotationClass> AnnotationClass{"AnnotationClass", - {&Descriptor}}; -const Rtti<model::Domain> Domain{ - "Domain", {&Node}, {&StructuredClass, &AnnotationClass}}; +const Rtti<model::FieldDescriptor> FieldDescriptor = + RttiBuilder("FieldDescriptor").parent(&Node); +const Rtti<model::Descriptor> Descriptor = + RttiBuilder("Descriptor").parent(&Node); +const Rtti<model::StructuredClass> StructuredClass = + RttiBuilder("StructuredClass").parent(&Descriptor).composedOf( + &FieldDescriptor); +const Rtti<model::AnnotationClass> AnnotationClass = + RttiBuilder("AnnotationClass").parent(&Descriptor); +const Rtti<model::Domain> Domain = + RttiBuilder("Domain").parent(&Node).composedOf( + {&StructuredClass, &AnnotationClass}); } } diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp index 2945635..a852294 100644 --- a/src/core/model/Typesystem.cpp +++ b/src/core/model/Typesystem.cpp @@ -438,24 +438,27 @@ SystemTypesystem::SystemTypesystem(Manager &mgr) /* RTTI type registrations */ namespace RttiTypes { -const Rtti<model::Type> Type{"Type", {&Node}}; -const Rtti<model::StringType> StringType{"StringType", {&Type}}; -const Rtti<model::IntType> IntType{"IntType", {&Type}}; -const Rtti<model::DoubleType> DoubleType{"DoubleType", {&Type}}; -const Rtti<model::BoolType> BoolType{"BoolType", {&Type}}; -const Rtti<model::EnumType> EnumType{"EnumType", {&Type}}; -const Rtti<model::StructType> StructType{"StructType", {&Type}, {&Attribute}}; -const Rtti<model::ArrayType> ArrayType{"ArrayType", {&Type}}; -const Rtti<model::UnknownType> UnknownType{"UnknownType", {&Type}}; -const Rtti<model::Constant> Constant{"Constant", {&Node}}; -const Rtti<model::Attribute> Attribute{"Attribute", {&Node}}; -const Rtti<model::Typesystem> Typesystem{ - "Typesystem", - {&Node}, - {&StringType, &IntType, &DoubleType, &BoolType, &EnumType, &StructType, - &Constant}}; -const Rtti<model::SystemTypesystem> SystemTypesystem{"SystemTypesystem", - {&Typesystem}}; +const Rtti<model::Type> Type = RttiBuilder("Type").parent(&Node); +const Rtti<model::StringType> StringType = + RttiBuilder("StringType").parent(&Type); +const Rtti<model::IntType> IntType = RttiBuilder("IntType").parent(&Type); +const Rtti<model::DoubleType> DoubleType = + RttiBuilder("DoubleType").parent(&Type); +const Rtti<model::BoolType> BoolType = RttiBuilder("BoolType").parent(&Type); +const Rtti<model::EnumType> EnumType = RttiBuilder("EnumType").parent(&Type); +const Rtti<model::StructType> StructType = + RttiBuilder("StructType").parent(&Type).composedOf(&Attribute); +const Rtti<model::ArrayType> ArrayType = RttiBuilder("ArrayType").parent(&Type); +const Rtti<model::UnknownType> UnknownType = + RttiBuilder("UnknownType").parent(&Type); +const Rtti<model::Constant> Constant = RttiBuilder("Constant").parent(&Node); +const Rtti<model::Attribute> Attribute = RttiBuilder("Attribute").parent(&Node); +const Rtti<model::Typesystem> Typesystem = + RttiBuilder("Typesystem").parent(&Node).composedOf( + {&StringType, &IntType, &DoubleType, &BoolType, &EnumType, &StructType, + &Constant}); +const Rtti<model::SystemTypesystem> SystemTypesystem = + RttiBuilder("SystemTypesystem").parent(&Typesystem); } } |