#pragma once #include #include #include #include #include #include "geometry/snake.h" #include "AreaData.h" namespace routing { class GeneratorBase : public QObject { Q_OBJECT public: using Data = AreaData *; using Generator = std::function; explicit GeneratorBase(QObject *parent = nullptr); explicit GeneratorBase(Data d, QObject *parent = nullptr); ~GeneratorBase(); Q_PROPERTY(QString editorQml READ editorQml CONSTANT) Q_PROPERTY(QString mapVisualQml READ mapVisualQml CONSTANT) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) virtual QString editorQml() const = 0; virtual QString mapVisualQml() const = 0; virtual bool save(QJsonObject &obj) const; // must be called if overridden virtual bool load(const QJsonObject &obj, QString &errorString); // must be called if overridden QString name() const; void setName(const QString &name); virtual QString abbreviation() const = 0; virtual QString type() const = 0; virtual bool get(Generator &generator) = 0; Data data() const; void setData(Data d); static const char *typeKey; static const char *nameKey; signals: void generatorChanged(); void dataChanged(); void nameChanged(); protected: Data _d; QString _name; private: }; class GeneratorFactory { GeneratorFactory(); GeneratorFactory(GeneratorFactory &other) = delete; static GeneratorFactory *createInstance(); public: typedef std::function Creator; ~GeneratorFactory(); static GeneratorFactory *instance(); bool registerGenerator(const QString &type, Creator creator); // use REGISTER_GENERATOR to register // a generator befor main() bool registered(const QString &type); void unregisterGenerator(const QString &type); GeneratorBase *create(const QString &type, QObject *parent = nullptr); GeneratorBase *create(const QJsonObject &jsonGenerator, QString &errorMessage, QObject *parent = nullptr); private: std::map _creatorMap; }; #define REGISTER_GENERATOR(type, creator) \ namespace { \ auto registered = \ GeneratorFactory::instance() -> registerGenerator(type, creator); \ } } // namespace routing