83 lines
2.5 KiB
C++
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
|