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
#include "datadecorator.h"
+#include "data/entity.h"
namespace cm::data {
#include <QScopedPointer>
#include "cm-lib_global.h"
-#include "entity.h"
namespace cm::data {
+ class Entity;
class CMLIBSHARED_EXPORT DataDecorator : public QObject
{
QScopedPointer<Implementation> implementation;
};
}
+
#endif // DATADECORATOR_H
--- /dev/null
+#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
#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;
+ }
}
#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