#include <QCoreApplication>
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
class Data
{
public:
Data(void) {}
Data(const std::wstring &name, int key) : dataName(name), m_key(key) {}
virtual ~Data() {}
std::string getClassName(void) {
return typeid(*this).name();
}
std::shared_ptr<Data> clone(void) const {
auto data = newData();
QJsonObject json;
write(json);
data->read(json);
return data;
}
std::wstring getName(void) {
return dataName;
}
int getKey()
{
return m_key;
}
virtual void write(QJsonObject &json) const {
json["Name"] = QString::fromStdWString(dataName.c_str());
json["Key"] = m_key;
}
virtual void read(const QJsonObject &json) {
dataName = json["Name"].toString().toStdWString();
m_key = json["Key"].toInt();
}
virtual void print(std::wostream &out) {
out << dataName.c_str() << std::endl;
}
protected:
virtual std::shared_ptr<Data> newData(void) const = 0;
private:
std::wstring dataName;
int m_key;
};
class DataAnalog : public Data
{
public:
DataAnalog(void) {}
DataAnalog(const std::wstring &name, int key, const double value) :Data(name, key), dataValue(value) {}
virtual ~DataAnalog() {}
virtual void write(QJsonObject &json) const override {
Data::write(json);
json["Value"] = dataValue;
json["X"] = X;
json["Y"] = Y;
json["R"] = R;
}
virtual void read(const QJsonObject &json) override {
Data::read(json);
dataValue = json["Value"].toDouble();
X = json["X"].toDouble();
Y = json["Y"].toDouble();
R = json["R"].toDouble();
}
virtual void print(std::wostream &out) {
out << getName().c_str() << L"=" << dataValue << std::endl;
}
void setData(double x, double y, double r)
{
this->X = x;
this->Y = y;
this->R = r;
}
protected:
virtual std::shared_ptr<Data> newData(void) const override {
return std::make_shared<DataAnalog>();
}
private:
double dataValue = 0;
double X;
double Y;
double R;
};
class DataDigital : public Data
{
public:
DataDigital(void) {}
DataDigital(const std::wstring &name, int key, const bool value) :Data(name, key), dataValue(value) {}
virtual ~DataDigital() {}
virtual void write(QJsonObject &json) const override {
Data::write(json);
json["Value"] = dataValue;
}
virtual void read(const QJsonObject &json) override {
Data::read(json);
dataValue = json["Value"].toBool();
}
virtual void print(std::wostream &out) override {
out << getName().c_str() << L"=" << (dataValue ? L"true" : L"false") << std::endl;
}
protected:
virtual std::shared_ptr<Data> newData(void) const override {
return std::make_shared<DataAnalog>();
}
private:
bool dataValue = false;
};
class DataFacotry
{
public:
static DataFacotry& instance(void) {
static DataFacotry ins;
static bool initialized = false;
if (!initialized)
{
ins.registerPrototype(std::make_shared<DataAnalog>());
ins.registerPrototype(std::make_shared<DataDigital>());
initialized = true;
}
return ins;
}
void registerPrototype(std::shared_ptr<Data> protoType) {
prototypeDatas.emplace(protoType->getClassName(), protoType);
}
std::shared_ptr<Data> create(const std::string &className) {
auto it = prototypeDatas.find(className);
if (it != prototypeDatas.end()) {
return it->second->clone();
}
return nullptr;
}
private:
std::map<std::string, std::shared_ptr<Data>> prototypeDatas;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
{
std::vector<std::shared_ptr<Data>> datas;
datas.emplace_back(new DataAnalog(L"Anlog_1", 1, 1.1));
DataAnalog *A = new DataAnalog(L"Anlog_2", 2, 2.2);
A->setData(7, 8, 9);
datas.emplace_back(A);
datas.emplace_back(new DataDigital(L"Digita_1", 3, true));
datas.emplace_back(new DataDigital(L"Digita_2", 4, false));
QFile file(QCoreApplication::applicationDirPath() + "\\data.json");
if (file.open(QFile::WriteOnly))
{
QJsonArray dataArray;
for (auto data : datas)
{
QJsonObject obj;
obj["Class"] = data->getClassName().c_str();
QJsonObject dataObj;
data->write(dataObj);
obj["Data"] = dataObj;
dataArray.append(obj);
}
QJsonObject json;
json["Datas"] = dataArray;
QJsonDocument doc(json);
file.write(doc.toJson());
}
}
{
QFile file(QCoreApplication::applicationDirPath() + "\\data.json");
if (file.open(QFile::ReadOnly))
{
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
if (!doc.isNull())
{
QJsonObject json = doc.object();
std::vector<std::shared_ptr<Data>> datas;
QJsonArray dataArray = json["Datas"].toArray();
for (auto i : dataArray)
{
QJsonObject obj = i.toObject();
QString className = obj["Class"].toString();
auto data = DataFacotry::instance().create(className.toStdString());
if (data)
{
datas.emplace_back(data);
datas.back()->read(obj["Data"].toObject());
}
}
std::for_each(datas.begin(), datas.end()
, [](std::shared_ptr<Data> data) {data->print(std::wcout); });
}
}
}
return a.exec();
}