From 8a7223da7ee84e453170fe3c5a79b6f91f7b5fbd Mon Sep 17 00:00:00 2001 From: John Janus Date: Tue, 11 Sep 2018 22:51:31 +0200 Subject: [PATCH] finish entity definition --- cm-lib/cm-lib.pro | 3 +- cm-lib/src/data/datadecorator.cpp | 1 + cm-lib/src/data/datadecorator.h | 3 +- cm-lib/src/data/entity-collection.h | 123 ++++++++++++++++++++++++++++ cm-lib/src/data/entity.cpp | 102 ++++++++++++++++++++++- cm-lib/src/data/entity.h | 49 +++++++++-- 6 files changed, 268 insertions(+), 13 deletions(-) create mode 100644 cm-lib/src/data/entity-collection.h diff --git a/cm-lib/cm-lib.pro b/cm-lib/cm-lib.pro index b554948..0aaaec7 100644 --- a/cm-lib/cm-lib.pro +++ b/cm-lib/cm-lib.pro @@ -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 diff --git a/cm-lib/src/data/datadecorator.cpp b/cm-lib/src/data/datadecorator.cpp index 64f9e8e..69c7345 100644 --- a/cm-lib/src/data/datadecorator.cpp +++ b/cm-lib/src/data/datadecorator.cpp @@ -1,4 +1,5 @@ #include "datadecorator.h" +#include "data/entity.h" namespace cm::data { diff --git a/cm-lib/src/data/datadecorator.h b/cm-lib/src/data/datadecorator.h index 0d6e7ba..792cb9d 100644 --- a/cm-lib/src/data/datadecorator.h +++ b/cm-lib/src/data/datadecorator.h @@ -7,9 +7,9 @@ #include #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; }; } + #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 index 0000000..5b8901e --- /dev/null +++ b/cm-lib/src/data/entity-collection.h @@ -0,0 +1,123 @@ +#ifndef ENTITYCOLLECTION_H +#define ENTITYCOLLECTION_H + +#include +#include +#include +#include + +#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 baseEntities() = 0; + + template + QList& derivedEntites(); + + template + T* addEntity(T* entity); + + private: + QString key; + }; + + template + 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 baseEntities() override + { + std::vector returnValue; + for (T* entity : collection) { + returnValue.push_back(entity); + } + return returnValue; + } + + QList& derivedEntities() + { + return collection; + } + + T* addEntity(T* entity) + { + if (!collection.contains(entity)) { + collection.append(entity); + EntityCollectionObject::collectionChanged(); + } + return entity; + } + + private: + QList collection; + }; + + template + QList& EntityCollectionBase::derivedEntites() + { + return dynamic_cast&>(*this).derivedEntites(); + } + + template + T* EntityCollectionBase::addEntity(T* entity) + { + return dynamic_cast&>(*this).addEntity(entity); + } +} + +#endif // ENTITYCOLLECTION_H diff --git a/cm-lib/src/data/entity.cpp b/cm-lib/src/data/entity.cpp index e74d956..a41cee5 100644 --- a/cm-lib/src/data/entity.cpp +++ b/cm-lib/src/data/entity.cpp @@ -1,6 +1,104 @@ #include "entity.h" -Entity::Entity(QObject *parent) : QObject(parent) -{ +#include +namespace cm::data { + + class Entity::Implementation { + public: + Implementation(Entity* _entity, const QString& _key) + : entity(_entity) + , key(_key) + {} + + Entity* entity{nullptr}; + QString key; + std::map childEntities; + std::map dataDecorators; + std::map 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 dataDecoratorPair : implementation->dataDecorators) { + dataDecoratorPair.second->update(jsonObject); + } + + for (std::pair childEntityPair : implementation->childEntities) { + childEntityPair.second->update(jsonObject.value(childEntityPair.first).toObject()); + } + + for (std::pair childCollectionPair : implementation->childCollections) { + childCollectionPair.second->update(jsonObject.value(childCollectionPair.first).toArray()); + } + } + + QJsonObject Entity::toJson() const + { + QJsonObject returnValue; + + for (std::pair dataDecoratorPair : implementation->dataDecorators) { + returnValue.insert(dataDecoratorPair.first, dataDecoratorPair.second->jsonValue()); + } + + for (std::pair childEntityPair : implementation->childEntities) { + returnValue.insert(childEntityPair.first, childEntityPair.second->toJson()); + } + + for (std::pair childCollectionPair : implementation->childCollections) { + QJsonArray entityArray; + for (Entity* entity : childCollectionPair.second->baseEntities()) { + entityArray.append(entity->toJson()); + } + returnValue.insert(childCollectionPair.first, entityArray); + } + + return returnValue; + } } diff --git a/cm-lib/src/data/entity.h b/cm-lib/src/data/entity.h index f0d628d..70fb254 100644 --- a/cm-lib/src/data/entity.h +++ b/cm-lib/src/data/entity.h @@ -1,17 +1,48 @@ #ifndef ENTITY_H #define ENTITY_H +#include + #include +#include +#include + +#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; -public slots: -}; + }; +} -#endif // ENTITY_H \ No newline at end of file +#endif // ENTITY_H -- 2.49.0