74 lines
No EOL
2.6 KiB
C++
74 lines
No EOL
2.6 KiB
C++
#pragma once
|
|
|
|
#include "error/instance.h"
|
|
#include "error/result.h"
|
|
#include "logger.h"
|
|
#include "objects/base/instance.h"
|
|
#include "objects/base/refstate.h"
|
|
#include "objects/meta.h"
|
|
#include "panic.h"
|
|
#include <memory>
|
|
#include <variant>
|
|
|
|
class Workspace;
|
|
|
|
class DataModel;
|
|
class Service;
|
|
|
|
// The root instance to all objects in the hierarchy
|
|
class DataModel : public Instance {
|
|
private:
|
|
void DeserializeService(pugi::xml_node node);
|
|
static void cloneService(std::shared_ptr<DataModel> target, std::shared_ptr<Service>, RefState<_RefStatePropertyCell>);
|
|
public:
|
|
const static InstanceType TYPE;
|
|
|
|
std::map<std::string, std::shared_ptr<Service>> services;
|
|
|
|
std::optional<std::string> currentFile;
|
|
|
|
DataModel();
|
|
void Init();
|
|
|
|
static inline std::shared_ptr<DataModel> New() { return std::make_shared<DataModel>(); };
|
|
virtual const InstanceType* GetClass() override;
|
|
|
|
// Inserts a service if it doesn't already exist
|
|
fallible<ServiceAlreadyExists, NoSuchService> InsertService(std::string name) {
|
|
if (services.count(name) != 0)
|
|
return fallible<ServiceAlreadyExists, NoSuchService>(ServiceAlreadyExists(name));
|
|
|
|
if (!INSTANCE_MAP[name] || (INSTANCE_MAP[name]->flags ^ (INSTANCE_NOTCREATABLE | INSTANCE_SERVICE)) != 0) {
|
|
Logger::fatalErrorf("Attempt to create instance of unknown type %s", name);
|
|
panic();
|
|
}
|
|
|
|
services[name] = std::dynamic_pointer_cast<Service>(INSTANCE_MAP[name]->constructor());
|
|
AddChild(std::dynamic_pointer_cast<Instance>(services[name]));
|
|
|
|
return {};
|
|
}
|
|
|
|
result<std::shared_ptr<Service>, NoSuchService> GetService(std::string className);
|
|
result<std::optional<std::shared_ptr<Service>>, NoSuchService> FindService(std::string className);
|
|
|
|
template <typename T>
|
|
result<std::shared_ptr<T>, NoSuchService> GetService() {
|
|
auto result = GetService(T::TYPE.className);
|
|
if (result.isError()) return result.error().value();
|
|
return std::dynamic_pointer_cast<T>(result.success().value());
|
|
}
|
|
|
|
template <typename T>
|
|
std::optional<std::shared_ptr<T>> FindService() {
|
|
auto result = FindService(T::TYPE.className);
|
|
if (result.isError()) return result.error().value();
|
|
return std::dynamic_pointer_cast<T>(result.success().value());
|
|
}
|
|
|
|
// Saving/loading
|
|
inline bool HasFile() { return this->currentFile.has_value(); }
|
|
void SaveToFile(std::optional<std::string> path = std::nullopt);
|
|
static std::shared_ptr<DataModel> LoadFromFile(std::string path);
|
|
std::shared_ptr<DataModel> CloneModel();
|
|
}; |