]> Johnzone git - learnqt-cm.git/commitdiff
finish entity definition
authorJohn Janus <mail@johnzone.org>
Tue, 11 Sep 2018 20:51:31 +0000 (22:51 +0200)
committerJohn Janus <mail@johnzone.org>
Tue, 11 Sep 2018 20:51:31 +0000 (22:51 +0200)
cm-lib/cm-lib.pro
cm-lib/src/data/datadecorator.cpp
cm-lib/src/data/datadecorator.h
cm-lib/src/data/entity-collection.h [new file with mode: 0644]
cm-lib/src/data/entity.cpp
cm-lib/src/data/entity.h

index b554948e4d03a7424e824cf0127aeb98b5cb902a..0aaaec77be8d5dca18b36b4201e790a015c56b8e 100644 (file)
@@ -53,7 +53,8 @@ HEADERS += \
     src/data/intdecorator.h \
     src/data/datetimedecorator.h \
     src/data/enumeratordecorator.h \
-    src/data/entity.h
+    src/data/entity.h \
+    src/data/entity-collection.h
 
 unix {
     target.path = /usr/lib
index 64f9e8e69cfcdc453ba49eaa022b3eeae5cd46b7..69c7345171e76e8bb15e32f0cedcf3593be3e12d 100644 (file)
@@ -1,4 +1,5 @@
 #include "datadecorator.h"
+#include "data/entity.h"
 
 namespace cm::data {
 
index 0d6e7ba6f47cc66d45a5167d474b4f73aa10ac32..792cb9d21779b552b99eaac383daaa9c8f089e68 100644 (file)
@@ -7,9 +7,9 @@
 #include <QScopedPointer>
 
 #include "cm-lib_global.h"
-#include "entity.h"
 
 namespace cm::data {
+  class Entity;
 
   class CMLIBSHARED_EXPORT DataDecorator : public QObject
   {
@@ -33,4 +33,5 @@ namespace cm::data {
     QScopedPointer<Implementation> implementation;
   };
 }
+
 #endif // DATADECORATOR_H
diff --git a/cm-lib/src/data/entity-collection.h b/cm-lib/src/data/entity-collection.h
new file mode 100644 (file)
index 0000000..5b8901e
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef ENTITYCOLLECTION_H
+#define ENTITYCOLLECTION_H
+
+#include <QObject>
+#include <QJsonArray>
+#include <QJsonValue>
+#include <QJsonObject>
+
+#include "cm-lib_global.h"
+
+namespace cm::data {
+  class Entity;
+
+  class CMLIBSHARED_EXPORT EntityCollectionObject : public QObject
+  {
+    Q_OBJECT
+
+  public:
+    EntityCollectionObject(QObject* parent = nullptr) : QObject(parent)
+    {}
+
+    virtual ~EntityCollectionObject() {}
+
+  signals:
+    void collectionChanged();
+  };
+
+  class EntityCollectionBase : public EntityCollectionObject
+  {
+  public:
+    EntityCollectionBase(QObject* parent = nullptr, const QString& key = "SomeCollectionKey")
+      : EntityCollectionObject(parent)
+      , key(key)
+    {}
+
+    virtual ~EntityCollectionBase() {}
+
+    QString getKey() const
+    {
+      return key;
+    }
+
+    virtual void clear() = 0;
+    virtual void update(const QJsonArray& json) = 0;
+    virtual std::vector<Entity*> baseEntities() = 0;
+
+    template <class T>
+    QList<T*>& derivedEntites();
+
+    template <class T>
+    T* addEntity(T* entity);
+
+  private:
+    QString key;
+  };
+
+  template <typename T>
+  class EntityCollection : public EntityCollectionBase
+  {
+  public:
+    EntityCollection(QObject* parent = nullptr, const QString& key = "SomeCollectionKey")
+      : EntityCollectionBase(parent, key)
+    {}
+
+    ~EntityCollection() {}
+
+    void clear() override
+    {
+      for (auto entity : collection) {
+        entity->deletaLater();
+      }
+      collection.clear();
+    }
+
+    void update(const QJsonArray& jsonArray) override
+    {
+      clear();
+      for (const QJsonValue& jsonValue : jsonArray) {
+        addEntity(new T(this, jsonValue.toObject()));
+      }
+    }
+
+    std::vector<Entity*> baseEntities() override
+    {
+      std::vector<Entity*> returnValue;
+      for (T* entity : collection) {
+        returnValue.push_back(entity);
+      }
+      return returnValue;
+    }
+
+    QList<T*>& derivedEntities()
+    {
+      return collection;
+    }
+
+    T* addEntity(T* entity)
+    {
+      if (!collection.contains(entity)) {
+        collection.append(entity);
+        EntityCollectionObject::collectionChanged();
+      }
+      return entity;
+    }
+
+  private:
+    QList<T*> collection;
+  };
+
+  template <class T>
+  QList<T*>& EntityCollectionBase::derivedEntites()
+  {
+    return dynamic_cast<const EntityCollection<T>&>(*this).derivedEntites();
+  }
+
+  template <class T>
+  T* EntityCollectionBase::addEntity(T* entity)
+  {
+    return dynamic_cast<const EntityCollection<T>&>(*this).addEntity(entity);
+  }
+}
+
+#endif // ENTITYCOLLECTION_H
index e74d95677a599e5ce2b5e670b7b6866432a92bc1..a41cee5a0e015afe6839e26064a83043464e0199 100644 (file)
@@ -1,6 +1,104 @@
 #include "entity.h"
 
-Entity::Entity(QObject *parent) : QObject(parent)
-{
+#include <QJsonArray>
 
+namespace cm::data {
+
+  class Entity::Implementation {
+  public:
+    Implementation(Entity* _entity, const QString& _key)
+      : entity(_entity)
+      , key(_key)
+    {}
+
+    Entity* entity{nullptr};
+    QString key;
+    std::map<QString, Entity*> childEntities;
+    std::map<QString, DataDecorator*> dataDecorators;
+    std::map<QString, EntityCollectionBase*> childCollections;
+  };
+
+  Entity::Entity(QObject *parent, const QString& key) : QObject(parent)
+  {
+    implementation.reset(new Implementation(this, key));
+  }
+
+  Entity::Entity(QObject* parent, const QString& key, const QJsonObject& jsonObject)
+    : Entity(parent, key)
+  {
+    update(jsonObject);
+  }
+
+  Entity::~Entity()
+  {}
+
+  const QString& Entity::key() const
+  {
+    return implementation->key;
+  }
+
+  Entity* Entity::addChild(Entity* entity, const QString& key)
+  {
+    if (implementation->childEntities.find(key) == std::end(implementation->childEntities)) {
+      implementation->childEntities[key] = entity;
+      emit childEntitiesChanged();
+    }
+    return entity;
+  }
+
+  EntityCollectionBase* Entity::addChildCollection(EntityCollectionBase* entityCollection)
+  {
+    if (implementation->childCollections.find(entityCollection->getKey()) == std::end(implementation->childCollections)) {
+      implementation->childCollections[entityCollection->getKey()] = entityCollection;
+      emit childCollectionsChanged(entityCollection->getKey());
+    }
+    return entityCollection;
+  }
+
+  DataDecorator* Entity::addDataItem(DataDecorator* dataDecorator)
+  {
+    if (implementation->dataDecorators.find(dataDecorator->key()) == std::end(implementation->dataDecorators)) {
+      implementation->dataDecorators[dataDecorator->key()] = dataDecorator;
+      emit dataDecoratorsChanged();
+    }
+    return dataDecorator;
+  }
+
+  void Entity::update(const QJsonObject& jsonObject)
+  {
+    for (std::pair<QString, DataDecorator*> dataDecoratorPair : implementation->dataDecorators) {
+      dataDecoratorPair.second->update(jsonObject);
+    }
+
+    for (std::pair<QString, Entity*> childEntityPair : implementation->childEntities) {
+      childEntityPair.second->update(jsonObject.value(childEntityPair.first).toObject());
+    }
+
+    for (std::pair<QString, EntityCollectionBase*> childCollectionPair : implementation->childCollections) {
+      childCollectionPair.second->update(jsonObject.value(childCollectionPair.first).toArray());
+    }
+  }
+
+  QJsonObject Entity::toJson() const
+  {
+    QJsonObject returnValue;
+
+    for (std::pair<QString, DataDecorator*> dataDecoratorPair : implementation->dataDecorators) {
+      returnValue.insert(dataDecoratorPair.first, dataDecoratorPair.second->jsonValue());
+    }
+
+    for (std::pair<QString, Entity*> childEntityPair : implementation->childEntities) {
+      returnValue.insert(childEntityPair.first, childEntityPair.second->toJson());
+    }
+
+    for (std::pair<QString, EntityCollectionBase*> childCollectionPair : implementation->childCollections) {
+      QJsonArray entityArray;
+      for (Entity* entity : childCollectionPair.second->baseEntities()) {
+        entityArray.append(entity->toJson());
+      }
+      returnValue.insert(childCollectionPair.first, entityArray);
+    }
+
+    return returnValue;
+  }
 }
index f0d628d481002dbcf3a3fc8dc7e49f9cefb544a1..70fb254f409b8711909588d3ca834f8925197b64 100644 (file)
@@ -1,17 +1,48 @@
 #ifndef ENTITY_H
 #define ENTITY_H
 
+#include <map>
+
 #include <QObject>
+#include <QScopedPointer>
+#include <QJsonObject>
+
+#include "cm-lib_global.h"
+#include "data/datadecorator.h"
+#include "data/entity-collection.h"
+
+namespace cm::data {
+
+  class CMLIBSHARED_EXPORT Entity : public QObject
+  {
+    Q_OBJECT
+
+  public:
+    Entity(QObject *parent = nullptr, const QString& key = "SomeEntityKey");
+
+    Entity(QObject* parent, const QString& key, const QJsonObject& jsonObject);
+
+    virtual ~Entity();
+
+    const QString& key() const;
+    void update(const QJsonObject& jsonObject);
+    QJsonObject toJson() const;
+
+  signals:
+    void childEntitiesChanged();
+    void dataDecoratorsChanged();
+    void childCollectionsChanged(const QString& collectionKey);
+
+  protected:
+    Entity* addChild(Entity* entity, const QString& key);
+    DataDecorator* addDataItem(DataDecorator* dataDecorator);
 
-class Entity : public QObject
-{
-  Q_OBJECT
-public:
-  explicit Entity(QObject *parent = nullptr);
+    EntityCollectionBase* addChildCollection(EntityCollectionBase* entityCollection);
 
-signals:
+    class Implementation;
+    QScopedPointer<Implementation> implementation;
 
-public slots:
-};
+  };
+}
 
-#endif // ENTITY_H
\ No newline at end of file
+#endif // ENTITY_H