summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-16 02:10:53 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-16 02:10:53 +0100
commitabbfae912b8d54106dbcbb7260c10e3a204c9f93 (patch)
tree8081a182e815484543e43e1133dc0596edc5228f /src
parent84cbdcaba520f89eb3ddbdaf1fe2ab3db412501a (diff)
added possibility to register a ManagedType for a class derived from Managed, improved Managed readData function
Diffstat (limited to 'src')
-rw-r--r--src/core/managed/Managed.cpp28
-rw-r--r--src/core/managed/Managed.hpp65
-rw-r--r--src/core/managed/ManagedContainer.hpp55
-rw-r--r--src/core/managed/ManagedType.cpp52
-rw-r--r--src/core/managed/ManagedType.hpp119
5 files changed, 259 insertions, 60 deletions
diff --git a/src/core/managed/Managed.cpp b/src/core/managed/Managed.cpp
index 991f941..f55cca5 100644
--- a/src/core/managed/Managed.cpp
+++ b/src/core/managed/Managed.cpp
@@ -20,8 +20,36 @@
#include <queue>
#include "Managed.hpp"
+#include "ManagedContainer.hpp"
namespace ousia {
+/* Class Managed */
+
+void Managed::storeData(const std::string &key, Handle<Managed> h) {
+ mgr.storeData(this, key, h.get());
+}
+
+bool Managed::hasDataKey(const std::string &key)
+{
+ return mgr.readData(this, key) != nullptr;
+}
+
+Rooted<Managed> Managed::readData(const std::string &key) {
+ return mgr.readData(this, key);
+}
+
+std::map<std::string, Rooted<Managed>> Managed::readData() {
+ auto map = mgr.readData(this);
+ std::map<std::string, Rooted<Managed>> res;
+ for (auto e : map) {
+ res.emplace(e.first, e.second);
+ }
+ return res;
+}
+
+bool Managed::deleteData(const std::string &key) {
+ return mgr.deleteData(this, key);
+}
}
diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp
index 8b0bb17..4818c3d 100644
--- a/src/core/managed/Managed.hpp
+++ b/src/core/managed/Managed.hpp
@@ -19,6 +19,7 @@
#ifndef _OUSIA_MANAGED_HPP_
#define _OUSIA_MANAGED_HPP_
+#include "ManagedType.hpp"
#include "Manager.hpp"
namespace ousia {
@@ -32,6 +33,9 @@ class Rooted;
template <class T>
class Owned;
+template <class T>
+class DefaultListener;
+
// TODO: Implement clone, getReferenced and getReferencing
/**
@@ -93,33 +97,36 @@ public:
return Owned<T>{t, this};
}
- template <class T>
- std::vector<Owned<T>> acquire(const std::vector<Handle<T>> &vec)
- {
- std::vector<Owned<T>> res;
- for (auto &e : vec) {
- res.push_back(acquire(e));
- }
- return res;
- }
-
- template <class T>
- std::vector<Owned<T>> acquire(const std::vector<T *> &vec)
- {
- std::vector<Owned<T>> res;
- for (auto &e : vec) {
- res.push_back(acquire(e));
- }
- return res;
- }
-
void storeData(const std::string &key, Handle<Managed> h);
bool hasDataKey(const std::string &key);
Rooted<Managed> readData(const std::string &key);
+ std::map<std::string, Rooted<Managed>> readData();
+
bool deleteData(const std::string &key);
+
+ /**
+ * Returns the ManagedType instance registered for instances of the type
+ * of this Managed instance.
+ *
+ * @return a reference to the registered ManagedType for this particular
+ * Managed class.
+ */
+ const ManagedType& type() const {
+ return ManagedType::typeOf(typeid(*this));
+ }
+
+ /**
+ * Returns true if this Managed instance is of the given ManagedType.
+ *
+ * @param true if the ManagedType registered for this particular Managed
+ * class is
+ */
+ bool isa(const ManagedType &t) const {
+ return type().isa(t);
+ }
};
/**
@@ -506,24 +513,6 @@ public:
Managed *getOwner() const { return owner; }
};
-
-inline void Managed::storeData(const std::string &key, Handle<Managed> h) {
- mgr.storeData(this, key, h.get());
-}
-
-inline bool Managed::hasDataKey(const std::string &key)
-{
- return mgr.readData(this, key) != nullptr;
-}
-
-inline Rooted<Managed> Managed::readData(const std::string &key) {
- return mgr.readData(this, key);
-}
-
-inline bool Managed::deleteData(const std::string &key) {
- return mgr.deleteData(this, key);
-}
-
}
#endif /* _OUSIA_MANAGED_HPP_ */
diff --git a/src/core/managed/ManagedContainer.hpp b/src/core/managed/ManagedContainer.hpp
index 1454608..071db2c 100644
--- a/src/core/managed/ManagedContainer.hpp
+++ b/src/core/managed/ManagedContainer.hpp
@@ -30,14 +30,17 @@
#include <unordered_map>
#include <unordered_set>
#include <vector>
-#include <iostream>
#include <map>
#include <type_traits>
+#include "Manager.hpp"
#include "Managed.hpp"
namespace ousia {
+template <class T>
+class Handle;
+
/**
* Default accessor class for accessing the managed element within a list value
* type.
@@ -57,7 +60,10 @@ struct ListAccessor {
*/
template <class ValueType>
struct MapAccessor {
- Managed *getManaged(const ValueType &val) const { return val.second.get(); }
+ Managed *getManaged(const ValueType &val) const
+ {
+ return val.second.get();
+ }
};
/**
@@ -118,8 +124,9 @@ private:
*/
void initialize()
{
+ Manager &manager = this->getManager();
for (const auto &elem : *this) {
- addElement(elem);
+ addElement(manager, elem);
}
}
@@ -130,8 +137,9 @@ private:
void finalize()
{
if (owner) {
+ Manager &manager = this->getManager();
for (const auto &elem : *this) {
- deleteElement(elem);
+ deleteElement(manager, elem);
}
}
}
@@ -152,9 +160,9 @@ protected:
* @param elem is a reference to the actual element that is being added to
* the underlying container.
*/
- void addElement(const value_type &elem)
+ void addElement(Manager &manager, const value_type &elem)
{
- getManager().addRef(accessor.getManaged(elem), owner);
+ manager.addRef(accessor.getManaged(elem), owner);
listener.addElement(elem, owner);
}
@@ -168,20 +176,21 @@ protected:
* @param elem is a reference to the actual element that is being removed
* from the underlying container.
*/
- void deleteElement(const value_type &elem)
+ void deleteElement(Manager &manager, const value_type &elem)
{
- getManager().deleteRef(accessor.getManaged(elem), owner);
+ manager.deleteRef(accessor.getManaged(elem), owner);
listener.deleteElement(elem, owner);
}
public:
+
/**
* Constructor of the ManagedContainer class.
*
* @param owner is the managed object which owns the collection and all
* handles to other managed objects stored within.
*/
- ManagedContainer(Handle<Managed> owner) : owner(owner.get()){};
+ ManagedContainer(Handle<Managed> owner) : owner(owner.get()) {};
/**
* Copy constructor. Creates a copy of the given container with the same
@@ -211,7 +220,7 @@ public:
* ownership.
*/
ManagedContainer(Handle<Managed> owner, const Collection &collection)
- : owner(owner), c(collection)
+ : owner(owner.get()), c(collection)
{
initialize();
}
@@ -302,26 +311,28 @@ public:
/**
* Equality operator.
*/
- bool operator==(const own_type &other) {
+ bool operator==(const own_type &other)
+ {
return (owner == other.owner) && (c == other.c);
}
/**
* Inequality operator.
*/
- bool operator!=(const own_type &other) {
+ bool operator!=(const own_type &other)
+ {
return (owner != other.owner) || (c != other.c);
}
/**
* Returns the owner of the ManagedContainer instance.
*/
- Managed *getOwner() { return owner; }
+ Managed *getOwner() const { return owner; }
/**
* Returns the manager instance associated with the owner.
*/
- Manager &getManager() { return owner->getManager(); }
+ Manager &getManager() const { return owner->getManager(); }
/* State functions */
@@ -364,7 +375,7 @@ public:
void clear() noexcept
{
for (const_iterator it = cbegin(); it != cend(); it++) {
- deleteElement(*it);
+ deleteElement(this->getManager(), *it);
}
c.clear();
}
@@ -374,7 +385,7 @@ public:
*/
iterator insert(const_iterator position, value_type val)
{
- addElement(val);
+ addElement(this->getManager(), val);
return c.insert(position, val);
}
@@ -386,7 +397,7 @@ public:
*/
iterator erase(iterator position)
{
- deleteElement(*position);
+ deleteElement(this->getManager(), *position);
return c.erase(position);
}
@@ -399,7 +410,7 @@ public:
iterator erase(iterator first, iterator last)
{
for (const_iterator it = first; it != last; it++) {
- this->deleteElement(*it);
+ this->deleteElement(this->getManager(), *it);
}
return c.erase(first, last);
}
@@ -478,14 +489,14 @@ public:
void push_back(Handle<T> h)
{
- this->addElement(h.get());
+ this->addElement(this->getManager(), h.get());
Base::c.push_back(h.get());
}
void pop_back()
{
if (!Base::empty()) {
- this->deleteElement(back());
+ this->deleteElement(this->getManager(), back());
}
Base::c.pop_back();
}
@@ -515,13 +526,13 @@ public:
std::pair<iterator, bool> insert(value_type val)
{
- this->addElement(val);
+ this->addElement(this->getManager(), val);
return Base::c.insert(val);
}
iterator insert(const_iterator position, value_type val)
{
- this->addElement(val);
+ this->addElement(this->getManager(), val);
return Base::c.insert(position, val);
}
diff --git a/src/core/managed/ManagedType.cpp b/src/core/managed/ManagedType.cpp
new file mode 100644
index 0000000..ed4c7da
--- /dev/null
+++ b/src/core/managed/ManagedType.cpp
@@ -0,0 +1,52 @@
+/*
+ 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/>.
+*/
+
+#include "ManagedType.hpp"
+
+namespace ousia {
+
+/* Instantiation of static variables */
+
+const ManagedType ManagedType::None;
+
+/* Class ManagedType */
+
+const ManagedType &ManagedType::typeOf(const std::type_info &nativeType)
+{
+ auto it = table().find(std::type_index{nativeType});
+ if (it == table().end()) {
+ return None;
+ } else {
+ return *(it->second);
+ }
+}
+
+bool ManagedType::isa(const ManagedType &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/ManagedType.hpp b/src/core/managed/ManagedType.hpp
new file mode 100644
index 0000000..f3ed5fd
--- /dev/null
+++ b/src/core/managed/ManagedType.hpp
@@ -0,0 +1,119 @@
+/*
+ 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_MANAGED_TYPE_HPP_
+#define _OUSIA_MANAGED_TYPE_HPP_
+
+#include <typeinfo>
+#include <typeindex>
+#include <unordered_map>
+#include <unordered_set>
+
+namespace ousia {
+
+/**
+ * The ManagedType is used to register type information that can be retrieved
+ * using the "type" method of the Managed class.
+ */
+class ManagedType {
+private:
+ /**
+ * Used internally to store all registered native types and their
+ * corresponding type information.
+ */
+ static std::unordered_map<std::type_index, ManagedType *>& table() {
+ static std::unordered_map<std::type_index, ManagedType *> table;
+ return table;
+ }
+
+ /**
+ * Name of the type -- for messages and debug output.
+ */
+ const std::string name;
+
+ /**
+ * Set containing references to the parent types.
+ */
+ const std::unordered_set<ManagedType *> parents;
+
+public:
+ /**
+ * ManagedType of no particular type.
+ */
+ static const ManagedType None;
+
+ /**
+ * Returns the ManagedType for the given type_info structure.
+ */
+ static const ManagedType &typeOf(const std::type_info &nativeType);
+
+ /**
+ * Default constructor. Creates a ManagedType instance with name "unknown"
+ * and no parents.
+ */
+ ManagedType() : name("unknown") {}
+
+ /**
+ * Creates a new ManagedType instance and registers it in the global type
+ * table.
+ *
+ * @param name is the name of the type.
+ * @param nativeType is the underlying C++ class the type should be attached
+ * to.
+ */
+ ManagedType(std::string name, const std::type_info &nativeType)
+ : name(std::move(name))
+ {
+ table().emplace(std::make_pair(std::type_index{nativeType}, this));
+ }
+
+ /**
+ * Creates a new ManagedType instance and registers it in the global type
+ * table.
+ *
+ * @param name is the name of the type.
+ * @param nativeType is the underlying C++ class the type should be attached
+ * to.
+ * @param parents is a list of parent types.
+ */
+ ManagedType(std::string name, const std::type_info &nativeType,
+ std::unordered_set<ManagedType *> parents)
+ : name(std::move(name)), parents(parents)
+ {
+ table().emplace(std::make_pair(std::type_index{nativeType}, this));
+ }
+
+ /**
+ * Returns the name of this type.
+ */
+ std::string getName() const { return name; }
+
+ /**
+ * Returns true if this ManagedType 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 ManagedType &other) const;
+};
+}
+
+#endif /* _OUSIA_MANAGED_TYPE_HPP_ */
+