DeerEngine/Deer/Include/DeerCore/DataManagment.h

83 lines
2.5 KiB
C++

#pragma once
#include "DeerCore/Tools/Memory.h"
#include "DeerCore/Tools/TypeDefs.h"
#include <string>
#include <unordered_map>
#include <vector>
namespace Deer {
/*
class DataSource {
public:
using DataImporter = [ClassOfTheDataImporter]
};
*/
using StorageMetadata = std::unordered_map<std::string, std::string>;
template <typename T>
concept HasMetadata = requires(const std::string& location) {
{ T::loadMetadata(location) } -> std::same_as<StorageMetadata>;
{ T::saveMetadata(StorageMetadata{}, location) };
};
class StorageData {
public:
StorageData() = default;
StorageData(uint32_t dataSize) : size(dataSize), data(MakeScope<uint8_t[]>(dataSize)) {}
inline uint8_t* getData() { return data.get(); }
inline const uint8_t* getData() const { return data.get(); }
inline uint32_t getSize() const { return size; }
inline StorageMetadata& getMetadata() { return metadata; }
template <typename DataImporter, typename T>
Scope<T> deserialize();
template <typename DataImporter, typename T>
static StorageData serialize(const T&);
inline explicit operator bool() const { return size != 0; }
private:
StorageMetadata metadata;
Scope<uint8_t[]> data = nullptr;
uint32_t size = 0;
};
template <typename DataSource>
class StorageBackend {
public:
static StorageData loadData(const std::string& location);
static void saveData(const std::string& location, const StorageData& data);
static StorageMetadata loadMetadata(const std::string& location);
static void saveMetadata(const StorageMetadata& metadata, const std::string& location);
static std::vector<std::string> indexResources(const std::string& location);
};
template <typename DataSource>
class DataManager {
public:
template <typename T>
static Scope<T> load(const std::string& dataId) {
StorageData data = StorageBackend<DataSource>::loadData(dataId);
if constexpr (HasMetadata<StorageBackend<DataSource>>) {
data.getMetadata() = StorageBackend<DataSource>::loadMetadata(dataId);
data.getMetadata()["dataId"] = dataId;
}
return data.deserialize<typename DataSource::DataImporter, T>();
}
template <typename T>
static void store(const std::string& dataId, T& value) {
StorageData data = StorageData::serialize<typename DataSource::DataImporter, T>(value);
StorageBackend<DataSource>::saveData(dataId, data);
if constexpr (HasMetadata<StorageBackend<DataSource>>) {
StorageBackend<DataSource>::saveMetadata(data.getMetadata(), dataId);
}
}
};
} // namespace Deer