Compare commits
No commits in common. "946c9e0027547d574c3a5fcf45dbf6d42175b856" and "398b655f3d14ae1a92918ac9a63c81b68d5118f8" have entirely different histories.
946c9e0027
...
398b655f3d
83
Deer/Include/DeerCore/DataManagment.h
Normal file
83
Deer/Include/DeerCore/DataManagment.h
Normal file
@ -0,0 +1,83 @@
|
||||
#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
|
||||
62
Deer/Include/DeerCore/DataStore.h
Executable file
62
Deer/Include/DeerCore/DataStore.h
Executable file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "DeerCore/Tools/Path.h"
|
||||
|
||||
#define DEER_RESOURCE_PATH "Assets"
|
||||
|
||||
#define DEER_VOXEL_PATH "Voxels"
|
||||
#define DEER_VOXEL_DATA_PATH "Voxels/Data"
|
||||
#define DEER_VOXEL_ASPECT_PATH "Voxels/Visuals"
|
||||
#define DEER_VOXEL_TEXTURE_PATH "Voxels/Textures"
|
||||
#define DEER_VOXEL_SHADER_PATH "Voxels/Shaders"
|
||||
|
||||
#define DEER_EDITOR_PATH "Editor"
|
||||
#define DEER_EDITOR_PANEL_PATH "Editor/Panels"
|
||||
#define DEER_EDITOR_SERVICE_PATH "Editor/Services"
|
||||
|
||||
#define DEER_MESH_EXTENSION ".dmesh"
|
||||
#define DEER_SHADER_EXTENSION ".glsl"
|
||||
#define DEER_SCRIPT_EXTENSION ".as"
|
||||
|
||||
#define DEER_BIN_PATH "bin"
|
||||
#define DEER_TEMP_PATH "tmp"
|
||||
#define DEER_NULL_PATH "null"
|
||||
|
||||
namespace Deer {
|
||||
|
||||
struct DirectoryData {
|
||||
std::vector<Path> dirs;
|
||||
std::vector<Path> elements;
|
||||
};
|
||||
|
||||
// Namespace to manage memory interactions
|
||||
namespace DataStore {
|
||||
// Clears the cache of dir data
|
||||
void clearCache();
|
||||
|
||||
// Rerturns a directory data with the elements relative to the id
|
||||
const DirectoryData& getDirData(const Path& id, const Path& dir, const char* extension);
|
||||
|
||||
// TODO: Add safety
|
||||
// Returns the data of the specified file path
|
||||
bool loadFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size);
|
||||
// Returns the data of the specified file path avoiding extension
|
||||
bool loadGlobalFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size);
|
||||
void freeFileData(uint8_t*);
|
||||
|
||||
void createFolder(const Path& path);
|
||||
|
||||
void saveFile(const Path&, uint8_t* data, uint32_t size);
|
||||
uint8_t* readFile(const Path&, uint32_t* size);
|
||||
void deleteFile(const Path&);
|
||||
|
||||
// Refactor----
|
||||
void compressFiles(std::vector<Path> files, const Path& path);
|
||||
std::vector<Path> getFiles(const Path& path,
|
||||
const std::string& extension);
|
||||
// Refactor----
|
||||
} // namespace DataStore
|
||||
} // namespace Deer
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Components.h"
|
||||
#include "DeerCore/Log.h"
|
||||
#include "DeerCore/Resource.h"
|
||||
#include "DeerCore/Tools/Memory.h"
|
||||
|
||||
#include "entt/entt.hpp"
|
||||
@ -60,7 +61,7 @@ namespace Deer {
|
||||
private:
|
||||
uint16_t m_mainCamera = 0;
|
||||
|
||||
std::stack<u_int32_t> unused_entities_spaces;
|
||||
std::stack<u_int16_t> unused_entities_spaces;
|
||||
std::vector<Entity> entities;
|
||||
|
||||
friend class Entity;
|
||||
|
||||
140
Deer/Include/DeerCore/Resource.h
Normal file
140
Deer/Include/DeerCore/Resource.h
Normal file
@ -0,0 +1,140 @@
|
||||
#pragma once
|
||||
#include "DeerCore/DataManagment.h"
|
||||
#include "DeerCore/Log.h"
|
||||
#include "DeerCore/Tools/Memory.h"
|
||||
#include "DeerCore/Tools/Path.h"
|
||||
#include "DeerCore/Tools/TypeDefs.h"
|
||||
|
||||
#include <cxxabi.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Deer {
|
||||
template <typename T>
|
||||
class ResourceManager;
|
||||
|
||||
template <typename T>
|
||||
class Resource {
|
||||
public:
|
||||
int32_t getResourceId() const { return resourceId; }
|
||||
|
||||
bool isValid() const { return ResourceManager<T>::isValid(*this); }
|
||||
T& getData() { return ResourceManager<T>::getResourceData(*this); }
|
||||
|
||||
const std::string& getStorageId() const { return ResourceManager<T>::getStorageId(*this); }
|
||||
|
||||
inline explicit operator bool() const { return resourceId >= 0; }
|
||||
|
||||
static Resource<T> unsafeFromId(int32_t id) {
|
||||
Resource<T> res;
|
||||
res.resourceId = id;
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
// -1 = no resource loaded
|
||||
int32_t resourceId = -1;
|
||||
friend ResourceManager<T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ResourceBuilder {
|
||||
public:
|
||||
using BaseDataType = char;
|
||||
static Scope<T> buildResource(const BaseDataType& baseData) {
|
||||
static_assert(sizeof(T) == 0, "ResourceBuilder must be specialized for this type T");
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ResourceManager {
|
||||
private:
|
||||
struct ResourceData {
|
||||
public:
|
||||
ResourceData(const std::string& _resourceId, Scope<T>&& _data)
|
||||
: storageId(_resourceId), data(std::move(_data)) {}
|
||||
|
||||
Scope<T> data;
|
||||
const std::string storageId;
|
||||
};
|
||||
|
||||
static std::vector<ResourceData> resources;
|
||||
static std::unordered_map<std::string, Resource<T>> resourceCache;
|
||||
|
||||
public:
|
||||
template <typename DataSource>
|
||||
static Resource<T> loadResource(const std::string& storageId) {
|
||||
if (resourceCache.contains(storageId))
|
||||
return resourceCache[storageId];
|
||||
|
||||
using ResourceBuilderBaseDataType = typename ResourceBuilder<T>::BaseDataType;
|
||||
Scope<T> data;
|
||||
|
||||
if constexpr (!std::is_void_v<ResourceBuilderBaseDataType>) {
|
||||
Scope<ResourceBuilderBaseDataType> baseData = DataManager<DataSource>::template load<ResourceBuilderBaseDataType>(storageId);
|
||||
if (!baseData) {
|
||||
const char* baseDataType = abi::__cxa_demangle(typeid(ResourceBuilderBaseDataType).name(), 0, 0, nullptr);
|
||||
const char* dataType = abi::__cxa_demangle(typeid(T).name(), 0, 0, nullptr);
|
||||
DEER_CORE_ERROR("Error loading base resource {} for resource {} with id {}", baseDataType, dataType, storageId.c_str());
|
||||
return Resource<T>();
|
||||
}
|
||||
data = ResourceBuilder<T>::buildResource(*baseData.get());
|
||||
} else {
|
||||
data = ResourceBuilder<T>::buildResource(); // No base data
|
||||
}
|
||||
|
||||
Resource<T> resource = Resource<T>::unsafeFromId(resources.size());
|
||||
resources.push_back({storageId, std::move(data)});
|
||||
resourceCache[storageId] = resource;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
static Resource<T> getResource(const std::string& storageId) {
|
||||
if (resourceCache.contains(storageId))
|
||||
return resourceCache[storageId];
|
||||
|
||||
return Resource<T>();
|
||||
}
|
||||
|
||||
static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, const std::string& storageId) {
|
||||
if (resourceCache.contains(storageId))
|
||||
return resourceCache[storageId];
|
||||
|
||||
Scope<T> data = ResourceBuilder<T>::buildResource(resourceData);
|
||||
|
||||
Resource<T> resource = Resource<T>::unsafeFromId(resources.size());
|
||||
resources.push_back({storageId, std::move(data)});
|
||||
resourceCache[storageId] = resource;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
static void unloadResources() {
|
||||
resourceCache.clear();
|
||||
resources.clear();
|
||||
}
|
||||
|
||||
static inline bool isValid(Resource<T> res) {
|
||||
return res.resourceId >= 0 && res.resourceId < static_cast<int32_t>(resources.size());
|
||||
}
|
||||
|
||||
static inline const std::string& getStorageId(Resource<T> res) {
|
||||
const static std::string invalid("NULL");
|
||||
if (!isValid(res))
|
||||
return invalid;
|
||||
|
||||
return resources[res.resourceId].storageId;
|
||||
}
|
||||
|
||||
static T& getResourceData(Resource<T> res) {
|
||||
return *resources[res.resourceId].data;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::vector<typename ResourceManager<T>::ResourceData> ResourceManager<T>::resources;
|
||||
template <typename T>
|
||||
std::unordered_map<std::string, Resource<T>> ResourceManager<T>::resourceCache;
|
||||
} // namespace Deer
|
||||
@ -35,7 +35,7 @@ namespace Deer {
|
||||
std::string baseTypeName;
|
||||
std::string moduleName;
|
||||
std::vector<SystemEvent> events;
|
||||
SystemDescription(const std::string& _baseTypeName = "", const std::string& _moduleName = "", const std::vector<SystemEvent>& _events = {}) : baseTypeName(_baseTypeName), moduleName(_moduleName), events(_events) {}
|
||||
SystemDescription(const std::string& _baseTypeName, const std::string& _moduleName, const std::vector<SystemEvent>& _events = {}) : baseTypeName(_baseTypeName), moduleName(_moduleName), events(_events) {}
|
||||
};
|
||||
|
||||
// Functions called by Engine
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#include "cereal/cereal.hpp"
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
#include "DeerRender/Mesh.h"
|
||||
#include "DeerRender/Shader.h"
|
||||
|
||||
#include "DeerRender/Tools/Memory.h"
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
namespace Deer {
|
||||
struct WorldSerializationSettings {
|
||||
#ifdef DEER_RENDER
|
||||
bool includeServer = false;
|
||||
bool includeClient = true;
|
||||
|
||||
std::function<Scope<MeshData>(const Path&)> meshLoadingFunction = nullptr;
|
||||
std::function<Scope<ShaderData>(const Path&)> shaderLoadingFunction = nullptr;
|
||||
#else
|
||||
bool includeServer = true;
|
||||
bool includeClient = false;
|
||||
#endif
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& archive) {
|
||||
archive(CEREAL_NVP(includeServer));
|
||||
archive(CEREAL_NVP(includeClient));
|
||||
}
|
||||
};
|
||||
} // namespace Deer
|
||||
@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
#include "DeerCore/Tools/Path.h"
|
||||
|
||||
namespace Deer {
|
||||
@ -8,9 +7,8 @@ namespace Deer {
|
||||
|
||||
namespace Universe {
|
||||
World* createWorld(const WorldSettings&);
|
||||
World* loadWorldFromJson(const WorldSettings&, WorldSerializationSettings&, const Path&);
|
||||
|
||||
void saveWorldInJson(World*, WorldSerializationSettings& serializationSettings, const Path& path);
|
||||
void saveWorldInJson(World*, const Path& path);
|
||||
|
||||
void destroyAllWorlds();
|
||||
void flushDestroyedWorlds();
|
||||
|
||||
@ -1,78 +1,2 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Tools/Memory.h"
|
||||
#include "DeerCore/Tools/TypeDefs.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Deer {
|
||||
|
||||
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
|
||||
#include "DeerCore/DataManagment.h"
|
||||
@ -1,140 +1,2 @@
|
||||
#pragma once
|
||||
#include "DeerRender/DataManagment.h"
|
||||
#include "DeerRender/Log.h"
|
||||
#include "DeerRender/Tools/Memory.h"
|
||||
#include "DeerRender/Tools/Path.h"
|
||||
#include "DeerRender/Tools/TypeDefs.h"
|
||||
|
||||
#include <cxxabi.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Deer {
|
||||
template <typename T>
|
||||
class ResourceManager;
|
||||
|
||||
template <typename T>
|
||||
class Resource {
|
||||
public:
|
||||
int32_t getResourceId() const { return resourceId; }
|
||||
|
||||
bool isValid() const { return ResourceManager<T>::isValid(*this); }
|
||||
T& getData() { return ResourceManager<T>::getResourceData(*this); }
|
||||
|
||||
const std::string& getStorageId() const { return ResourceManager<T>::getStorageId(*this); }
|
||||
|
||||
inline explicit operator bool() const { return resourceId >= 0; }
|
||||
|
||||
static Resource<T> unsafeFromId(int32_t id) {
|
||||
Resource<T> res;
|
||||
res.resourceId = id;
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
// -1 = no resource loaded
|
||||
int32_t resourceId = -1;
|
||||
friend ResourceManager<T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ResourceBuilder {
|
||||
public:
|
||||
using BaseDataType = char;
|
||||
static Scope<T> buildResource(const BaseDataType& baseData) {
|
||||
static_assert(sizeof(T) == 0, "ResourceBuilder must be specialized for this type T");
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ResourceManager {
|
||||
private:
|
||||
struct ResourceData {
|
||||
public:
|
||||
ResourceData(const std::string& _resourceId, Scope<T>&& _data)
|
||||
: storageId(_resourceId), data(std::move(_data)) {}
|
||||
|
||||
Scope<T> data;
|
||||
const std::string storageId;
|
||||
};
|
||||
|
||||
static std::vector<ResourceData> resources;
|
||||
static std::unordered_map<std::string, Resource<T>> resourceCache;
|
||||
|
||||
public:
|
||||
template <typename DataSource>
|
||||
static Resource<T> loadResource(const std::string& storageId) {
|
||||
if (resourceCache.contains(storageId))
|
||||
return resourceCache[storageId];
|
||||
|
||||
using ResourceBuilderBaseDataType = typename ResourceBuilder<T>::BaseDataType;
|
||||
Scope<T> data;
|
||||
|
||||
if constexpr (!std::is_void_v<ResourceBuilderBaseDataType>) {
|
||||
Scope<ResourceBuilderBaseDataType> baseData = DataManager<DataSource>::template load<ResourceBuilderBaseDataType>(storageId);
|
||||
if (!baseData) {
|
||||
const char* baseDataType = abi::__cxa_demangle(typeid(ResourceBuilderBaseDataType).name(), 0, 0, nullptr);
|
||||
const char* dataType = abi::__cxa_demangle(typeid(T).name(), 0, 0, nullptr);
|
||||
DEER_CORE_ERROR("Error loading base resource {} for resource {} with id {}", baseDataType, dataType, storageId.c_str());
|
||||
return Resource<T>();
|
||||
}
|
||||
data = ResourceBuilder<T>::buildResource(*baseData.get());
|
||||
} else {
|
||||
data = ResourceBuilder<T>::buildResource(); // No base data
|
||||
}
|
||||
|
||||
Resource<T> resource = Resource<T>::unsafeFromId(resources.size());
|
||||
resources.push_back({storageId, std::move(data)});
|
||||
resourceCache[storageId] = resource;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
static Resource<T> getResource(const std::string& storageId) {
|
||||
if (resourceCache.contains(storageId))
|
||||
return resourceCache[storageId];
|
||||
|
||||
return Resource<T>();
|
||||
}
|
||||
|
||||
static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, const std::string& storageId) {
|
||||
if (resourceCache.contains(storageId))
|
||||
return resourceCache[storageId];
|
||||
|
||||
Scope<T> data = ResourceBuilder<T>::buildResource(resourceData);
|
||||
|
||||
Resource<T> resource = Resource<T>::unsafeFromId(resources.size());
|
||||
resources.push_back({storageId, std::move(data)});
|
||||
resourceCache[storageId] = resource;
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
static void unloadResources() {
|
||||
resourceCache.clear();
|
||||
resources.clear();
|
||||
}
|
||||
|
||||
static inline bool isValid(Resource<T> res) {
|
||||
return res.resourceId >= 0 && res.resourceId < static_cast<int32_t>(resources.size());
|
||||
}
|
||||
|
||||
static inline const std::string& getStorageId(Resource<T> res) {
|
||||
const static std::string invalid("NULL");
|
||||
if (!isValid(res))
|
||||
return invalid;
|
||||
|
||||
return resources[res.resourceId].storageId;
|
||||
}
|
||||
|
||||
static T& getResourceData(Resource<T> res) {
|
||||
return *resources[res.resourceId].data;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::vector<typename ResourceManager<T>::ResourceData> ResourceManager<T>::resources;
|
||||
template <typename T>
|
||||
std::unordered_map<std::string, Resource<T>> ResourceManager<T>::resourceCache;
|
||||
} // namespace Deer
|
||||
#include "DeerCore/Resource.h"
|
||||
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
|
||||
#include "DeerCore/Components.h"
|
||||
|
||||
#include "DeerCore/Serialization/Core/QuatSerialization.h"
|
||||
#include "DeerCore/Serialization/Core/Vec3Serialization.h"
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
|
||||
namespace Deer {
|
||||
struct TransformComponentSerialization {
|
||||
WorldSerializationSettings& settings;
|
||||
TransformComponent& component;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& archive) {
|
||||
archive(cereal::make_nvp("Position", component.position));
|
||||
archive(cereal::make_nvp("Scale", component.scale));
|
||||
archive(cereal::make_nvp("Rotation", component.rotation));
|
||||
}
|
||||
};
|
||||
} // namespace Deer
|
||||
@ -1,109 +0,0 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
|
||||
#include "DeerCore/EntityEnviroment.h"
|
||||
#include "DeerCore/Serialization/Entity.h"
|
||||
|
||||
#include "DeerCore/Serialization/Components/TransformComponent.h"
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
#include "DeerRender/Serialization/Components/MeshComponentSerialization.h"
|
||||
#include "DeerRender/Serialization/Components/ShaderComponentSerialization.h"
|
||||
#endif
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace Deer {
|
||||
struct EntitySerialization {
|
||||
WorldSerializationSettings& settings;
|
||||
EntityEnvironment* entityEnvironment;
|
||||
uint32_t entityId;
|
||||
|
||||
template <class Archive, class T, class S>
|
||||
void saveComponent(Archive& archive, Entity& entity, const char* name) const {
|
||||
std::string containsComponentString = "Contains_";
|
||||
containsComponentString += name;
|
||||
|
||||
bool hasComponent = entity.hasComponent<T>();
|
||||
archive(cereal::make_nvp(containsComponentString.c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
S serialization{
|
||||
.component = entity.getComponent<T>(),
|
||||
.settings = settings};
|
||||
|
||||
archive(cereal::make_nvp(name, serialization));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive, class T, class S>
|
||||
void loadComponent(Archive& archive, Entity& entity, const char* name) {
|
||||
std::string containsComponentString = "Contains_";
|
||||
containsComponentString += name;
|
||||
|
||||
bool hasComponent;
|
||||
archive(cereal::make_nvp(containsComponentString.c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
S serialization{
|
||||
.component = entity.addComponent<T>(),
|
||||
.settings = settings};
|
||||
|
||||
archive(cereal::make_nvp(name, serialization));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void save(Archive& archive) const {
|
||||
Entity& entity = entityEnvironment->getEntity(entityId);
|
||||
|
||||
TagComponent& tag = entity.getComponent<TagComponent>();
|
||||
RelationshipComponent& relation = entity.getComponent<RelationshipComponent>();
|
||||
|
||||
archive(cereal::make_nvp("Id", entityId));
|
||||
archive(cereal::make_nvp("Tag", tag.tag));
|
||||
archive(cereal::make_nvp("NetworkBehaviour", tag.networkBehaviour));
|
||||
archive(cereal::make_nvp("Parent", relation.parent_id));
|
||||
|
||||
TransformComponentSerialization transformSerialization{
|
||||
.settings = settings,
|
||||
.component = entity.getComponent<TransformComponent>()};
|
||||
archive(cereal::make_nvp("TransformComponent", transformSerialization));
|
||||
|
||||
if (settings.includeClient) {
|
||||
#ifdef DEER_RENDER
|
||||
saveComponent<Archive, MeshComponent, MeshComponentSerialization>(archive, entity, "MeshComponent");
|
||||
saveComponent<Archive, ShaderComponent, ShaderComponentSerialization>(archive, entity, "ShaderComponent");
|
||||
#else
|
||||
DEER_CORE_ERROR("Can not include client on Deer Core Headless Compile");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load(Archive& archive) {
|
||||
archive(cereal::make_nvp("Id", entityId));
|
||||
Entity& entity = entityEnvironment->createEntityWithId(entityId);
|
||||
|
||||
TagComponent& tag = entity.getComponent<TagComponent>();
|
||||
RelationshipComponent& relation = entity.getComponent<RelationshipComponent>();
|
||||
|
||||
archive(cereal::make_nvp("Tag", tag.tag));
|
||||
archive(cereal::make_nvp("NetworkBehaviour", tag.networkBehaviour));
|
||||
archive(cereal::make_nvp("Parent", tag.networkBehaviour));
|
||||
|
||||
TransformComponentSerialization transformSerialization{
|
||||
.settings = settings,
|
||||
.component = entity.getComponent<TransformComponent>()};
|
||||
archive(cereal::make_nvp("TransformComponent", transformSerialization));
|
||||
|
||||
if (settings.includeClient) {
|
||||
#ifdef DEER_RENDER
|
||||
loadComponent<Archive, MeshComponent, MeshComponentSerialization>(archive, entity, "MeshComponent");
|
||||
loadComponent<Archive, ShaderComponent, ShaderComponentSerialization>(archive, entity, "ShaderComponent");
|
||||
#else
|
||||
DEER_CORE_ERROR("Can not include client on Deer Core Headless Compile");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Deer
|
||||
@ -1,82 +0,0 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
|
||||
#include "DeerCore/EntityEnviroment.h"
|
||||
#include "DeerCore/Serialization/Entity.h"
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
#include "cereal/types/vector.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Deer {
|
||||
struct EntityEnvironmentSerialization {
|
||||
WorldSerializationSettings& settings;
|
||||
EntityEnvironment* entityEnvironment;
|
||||
|
||||
template <class Archive>
|
||||
void save(Archive& archive) const {
|
||||
std::vector<EntitySerialization> entities;
|
||||
|
||||
uint32_t entityIndex = 0;
|
||||
size_t remainingEntities = entityEnvironment->getEntityCount();
|
||||
while (remainingEntities > 0) {
|
||||
if (!entityEnvironment->entityExists(entityIndex)) {
|
||||
entityIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
Entity& entity = entityEnvironment->getEntity(entityIndex);
|
||||
if (!entity.isValidNetworkBehaviour() && !(settings.includeClient && settings.includeServer)) {
|
||||
remainingEntities--;
|
||||
entityIndex++;
|
||||
}
|
||||
|
||||
EntityNetworkBehaviour networkBehaviour = entity.getForcedNetworkBehaviour();
|
||||
if (networkBehaviour == EntityNetworkBehaviour::CLIENT && !settings.includeClient) {
|
||||
remainingEntities--;
|
||||
entityIndex++;
|
||||
}
|
||||
|
||||
if (networkBehaviour == EntityNetworkBehaviour::SERVER && !settings.includeServer) {
|
||||
remainingEntities--;
|
||||
entityIndex++;
|
||||
}
|
||||
|
||||
EntitySerialization entityS{
|
||||
.settings = settings,
|
||||
.entityEnvironment = entityEnvironment,
|
||||
.entityId = entityIndex};
|
||||
|
||||
entities.push_back(entityS);
|
||||
|
||||
remainingEntities--;
|
||||
entityIndex++;
|
||||
}
|
||||
|
||||
archive(cereal::make_size_tag(entities.size()));
|
||||
for (EntitySerialization& entityS : entities)
|
||||
archive(entityS);
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load(Archive& archive) {
|
||||
size_t entitySize;
|
||||
archive(cereal::make_size_tag(entitySize));
|
||||
|
||||
std::vector<uint32_t> entities;
|
||||
for (size_t i = 0; i < entitySize; i++) {
|
||||
EntitySerialization entityS{.settings = settings, .entityEnvironment = entityEnvironment};
|
||||
archive(entityS);
|
||||
|
||||
entities.push_back(entityS.entityId);
|
||||
}
|
||||
|
||||
for (uint32_t entity_id : entities) {
|
||||
Entity& entity = entityEnvironment->getEntity(entity_id);
|
||||
RelationshipComponent& tag = entity.getComponent<RelationshipComponent>();
|
||||
entity.setParent(entityEnvironment->getEntity(tag.parent_id));
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Deer
|
||||
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Serialization/EntityEnvironment.h"
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
|
||||
namespace Deer {
|
||||
class World;
|
||||
|
||||
struct WorldSerialization {
|
||||
WorldSerializationSettings& settings;
|
||||
World* world;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& archive) {
|
||||
EntityEnvironmentSerialization entityEnvironment{
|
||||
.settings = settings,
|
||||
.entityEnvironment = world->entityEnvironment.get()};
|
||||
|
||||
archive(cereal::make_nvp("EntityEnvironment", entityEnvironment));
|
||||
}
|
||||
};
|
||||
} // namespace Deer
|
||||
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Components.h"
|
||||
|
||||
namespace Deer {
|
||||
// RELATIONSHIP COMPONENT
|
||||
template <class Archive>
|
||||
void serialize(Archive& archive, RelationshipComponent& relationship) {
|
||||
archive(cereal::make_nvp("parentId", relationship.parent_id));
|
||||
|
||||
archive(cereal::make_size_tag(
|
||||
static_cast<cereal::size_type>(relationship.getChildCount())));
|
||||
for (int i = 0; i < relationship.getChildCount(); i++)
|
||||
archive(relationship.getChildId(i));
|
||||
}
|
||||
} // namespace Deer
|
||||
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Components.h"
|
||||
|
||||
namespace Deer {
|
||||
|
||||
// TRANSFORM COMPONENT
|
||||
template <class Archive>
|
||||
void serialize(Archive& archive,
|
||||
TransformComponent& transform) {
|
||||
|
||||
archive(cereal::make_nvp("position", transform.position));
|
||||
archive(cereal::make_nvp("scale", transform.scale));
|
||||
archive(cereal::make_nvp("rotation", transform.rotation));
|
||||
}
|
||||
|
||||
} // namespace Deer
|
||||
72
Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerialization.h
Executable file
72
Deer/src/DeerCore/Universe/Serialization/Entity/EntitySerialization.h
Executable file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Components.h"
|
||||
#include "DeerCore/EntityEnviroment.h"
|
||||
|
||||
#include "EntitySerializationStruct.h"
|
||||
|
||||
namespace Deer {
|
||||
template <class Archive, typename T>
|
||||
void saveComponent(Archive& archive, Entity const& m_entity) {
|
||||
bool hasComponent = m_entity.hasComponent<T>();
|
||||
archive(cereal::make_nvp(("contains_" + typedef(T).get_name()).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
const T& component = m_entity.getComponent<T>();
|
||||
archive(cereal::make_nvp(typedef(T).get_name(), component));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive, typename T>
|
||||
void loadComponent(Archive& archive, Entity const& m_entity) {
|
||||
bool hasComponent;
|
||||
archive(cereal::make_nvp(("contains_" + typedef(T).get_name()).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
T& component = m_entity.addComponent<T>();
|
||||
archive(cereal::make_nvp(typedef(T).get_name(), component));
|
||||
}
|
||||
}
|
||||
|
||||
// ENTITY
|
||||
template <class Archive>
|
||||
void save(Archive& archive, EntitySerializationStruct const& m_entity) {
|
||||
const Entity& entity = m_entity.env->getEntity(m_entity.entityID);
|
||||
|
||||
const TagComponent& name = entity.getComponent<TagComponent>();
|
||||
archive(cereal::make_nvp("id", m_entity.entityID));
|
||||
archive(cereal::make_nvp("name", name.tag));
|
||||
|
||||
const TransformComponent& transform = entity.getComponent<TransformComponent>();
|
||||
archive(cereal::make_nvp("transform", transform));
|
||||
|
||||
const RelationshipComponent& relation = entity.getComponent<RelationshipComponent>();
|
||||
archive(cereal::make_nvp("relationship", relation));
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
if (!is_server_serialization) {
|
||||
saveComponent<Archive, MeshComponent>(archive, "meshRenderComponent", entity);
|
||||
saveComponent<Archive, CameraComponent>(archive, "cameraComponent", entity);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load(Archive& archive, EntitySerializationStruct& m_entity) {
|
||||
uint16_t id;
|
||||
std::string name;
|
||||
archive(cereal::make_nvp("id", id));
|
||||
archive(cereal::make_nvp("name", name));
|
||||
|
||||
Entity& entity = m_entity.env->createEntityWithId(id);
|
||||
archive(cereal::make_nvp("transform", entity.getComponent<TransformComponent>()));
|
||||
|
||||
RelationshipComponent& rc = entity.getComponent<RelationshipComponent>();
|
||||
archive(cereal::make_nvp("relationship", rc));
|
||||
entity.setParent(m_entity.env->getEntity(rc.parent_id));
|
||||
#ifdef DEER_RENDER
|
||||
if (!is_server_serialization) {
|
||||
loadComponent<Archive, MeshComponent>(archive, "meshRenderComponent", entity);
|
||||
loadComponent<Archive, CameraComponent>(archive, "cameraComponent", entity);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Deer
|
||||
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace Deer {
|
||||
class EntityEnvironment;
|
||||
struct EntitySerializationStruct {
|
||||
uint32_t entityID;
|
||||
EntityEnvironment* env;
|
||||
};
|
||||
} // namespace Deer
|
||||
57
Deer/src/DeerCore/Universe/Serialization/EnvironmentSerialization.h
Executable file
57
Deer/src/DeerCore/Universe/Serialization/EnvironmentSerialization.h
Executable file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "DeerCore/EntityEnviroment.h"
|
||||
#include "EntitySerializationStruct.h"
|
||||
|
||||
namespace Deer {
|
||||
struct EntityEnvironmentEntity {
|
||||
EntityEnvironment& environment;
|
||||
EntityEnvironmentEntity(EntityEnvironment& env) : environment(env) {}
|
||||
};
|
||||
|
||||
template <class Archive>
|
||||
void save(Archive& archive, const Deer::EntityEnvironment& environment) {
|
||||
EntityEnvironmentEntity envEnt(const_cast<Deer::EntityEnvironment&>(environment));
|
||||
archive(cereal::make_nvp("entities", envEnt));
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load(Archive& archive, Deer::EntityEnvironment& environment) {
|
||||
EntityEnvironmentEntity envEnt(environment);
|
||||
archive(cereal::make_nvp("entities", envEnt));
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void save(Archive& archive, EntityEnvironmentEntity const& m_entities) {
|
||||
archive(cereal::make_size_tag(static_cast<cereal::size_type>(
|
||||
m_entities.entityEnvironment->getEntityCount())));
|
||||
|
||||
for (uint16_t i = 0; i < m_entities.entityEnvironment->getEntityCount(); i++) {
|
||||
while (!m_entities.entityEnvironment->entityExists(i)) {
|
||||
i++;
|
||||
}
|
||||
|
||||
EntitySerializationStruct serializationStruct;
|
||||
serializationStruct.env =
|
||||
const_cast<EntityEnvironment*>(&m_entities.environment);
|
||||
serializationStruct.entityID = i;
|
||||
|
||||
archive(serializationStruct);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load(Archive& archive, EntityEnvironmentEntity& m_entities) {
|
||||
cereal::size_type size;
|
||||
archive(cereal::make_size_tag(size));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
EntitySerializationStruct serializationStruct;
|
||||
serializationStruct.env = &m_entities.environment;
|
||||
|
||||
archive(serializationStruct);
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
||||
4
Deer/src/DeerCore/Universe/Serialization/Serialization.cpp
Executable file
4
Deer/src/DeerCore/Universe/Serialization/Serialization.cpp
Executable file
@ -0,0 +1,4 @@
|
||||
|
||||
namespace Deer {
|
||||
bool is_server_serialization = false;
|
||||
}
|
||||
27
Deer/src/DeerCore/Universe/Serialization/Serialization.h
Executable file
27
Deer/src/DeerCore/Universe/Serialization/Serialization.h
Executable file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
#include "cereal/types/string.hpp"
|
||||
#include "cereal/types/vector.hpp"
|
||||
|
||||
// Serialization Vars
|
||||
#include "DeerCore/World/Serialization/SerializationGlobalVars.h"
|
||||
|
||||
// GENERICS
|
||||
#include "DeerCore/World/Serialization/QuatSerialization.h"
|
||||
#include "DeerCore/World/Serialization/Vec3Serialization.h"
|
||||
|
||||
// SCENE SPECIFIC
|
||||
#include "DeerCore/World/Serialization/EntityEnvironmentSerialization.h"
|
||||
#include "DeerCore/World/Serialization/EntitySerialization.h"
|
||||
|
||||
// COMPONENTS SPECIFIC
|
||||
#include "DeerCore/World/Serialization/Components/RelationshipComponentSerialization.h"
|
||||
#include "DeerCore/World/Serialization/Components/TransformComponentSerialization.h"
|
||||
|
||||
// RENDER SPECIFIC
|
||||
#ifdef DEER_RENDER
|
||||
#include "DeerRender/World/Serialization/Components/CameraSerializationComponent.h"
|
||||
#include "DeerRender/World/Serialization/Components/MeshRenderComponentSerialization.h"
|
||||
#include "DeerRender/World/Serialization/Components/TextureBindingSerializationComponent.h"
|
||||
#endif
|
||||
7
Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.cpp
Executable file
7
Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.cpp
Executable file
@ -0,0 +1,7 @@
|
||||
#include "SerializationGlobalVars.h"
|
||||
|
||||
namespace Deer {
|
||||
|
||||
bool is_server_serialization = false;
|
||||
|
||||
}
|
||||
5
Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.h
Executable file
5
Deer/src/DeerCore/Universe/Serialization/SerializationGlobalVars.h
Executable file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace Deer {
|
||||
extern bool is_server_serialization;
|
||||
}
|
||||
9
Deer/src/DeerCore/Universe/Serialization/Settings.h
Normal file
9
Deer/src/DeerCore/Universe/Serialization/Settings.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
namespace Deer {
|
||||
namespace Serialization {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
12
Deer/src/DeerCore/Universe/Serialization/World.h
Normal file
12
Deer/src/DeerCore/Universe/Serialization/World.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "DeerCore/World.h"
|
||||
#include "DeerCore/EntityEnviroment.h"
|
||||
|
||||
namespace Deer {
|
||||
namespace Universe {
|
||||
template <class Archive>
|
||||
void save(Archive& archive, World const& world) {
|
||||
World
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,35 +1,12 @@
|
||||
#include "DeerCore/Universe.h"
|
||||
#include "DeerCore/World.h"
|
||||
#include "DeerCore/Log.h"
|
||||
|
||||
#include "DeerCore/Serialization/World.h"
|
||||
#include "cereal/cereal.hpp"
|
||||
#include "cereal/archives/json.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace Deer {
|
||||
void Universe::saveWorldInJson(World* world, WorldSerializationSettings& serializationSettings, const Path& path) {
|
||||
std::ofstream file(path);
|
||||
cereal::JSONOutputArchive archive(file);
|
||||
|
||||
|
||||
WorldSerialization worldSerialization{
|
||||
.settings = serializationSettings,
|
||||
.world = world};
|
||||
|
||||
archive(cereal::make_nvp("SerializationSettings", serializationSettings));
|
||||
archive(cereal::make_nvp("World", worldSerialization));
|
||||
}
|
||||
|
||||
World* Universe::loadWorldFromJson(const WorldSettings& worldSettings, WorldSerializationSettings& serializationSettings, const Path& path) {
|
||||
std::ifstream file(path);
|
||||
cereal::JSONInputArchive archive(file);
|
||||
|
||||
World* world = Universe::createWorld(worldSettings);
|
||||
WorldSerialization worldSerialization{
|
||||
.settings = serializationSettings,
|
||||
.world = world};
|
||||
|
||||
archive(cereal::make_nvp("SerializationSettings", serializationSettings));
|
||||
archive(cereal::make_nvp("World", worldSerialization));
|
||||
|
||||
return world;
|
||||
}
|
||||
} // namespace Deer
|
||||
@ -81,7 +81,7 @@ namespace Deer {
|
||||
|
||||
entities.push_back({});
|
||||
} else {
|
||||
static std::stack<uint32_t> unused_entities_spaces_cache;
|
||||
static std::stack<uint16_t> unused_entities_spaces_cache;
|
||||
|
||||
// This code its to remove a specific element from a stack
|
||||
// We pop the stack until we find the id or we empty it to
|
||||
|
||||
@ -20,7 +20,7 @@ namespace Deer {
|
||||
}
|
||||
|
||||
World::~World() {
|
||||
DEER_CORE_ASSERT(executingState == WorldState::ReadyToDestroy, "Invalid executing state while destroying world");
|
||||
DEER_CORE_ASSERT(executingState == WorldState::Stopped, "Invalid executing state while destroying world");
|
||||
}
|
||||
|
||||
void World::stopExecution() {
|
||||
|
||||
@ -65,10 +65,6 @@ namespace Deer {
|
||||
RenderCommand::init();
|
||||
RenderUtils::initializeRenderUtils();
|
||||
|
||||
Builtin::cube();
|
||||
Builtin::simpleShader();
|
||||
Builtin::sphere();
|
||||
|
||||
ImGuiLayer::init(*window);
|
||||
}
|
||||
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
|
||||
#include "DeerRender/Components.h"
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
|
||||
namespace Deer {
|
||||
struct MeshComponentSerialization {
|
||||
WorldSerializationSettings& settings;
|
||||
MeshComponent& component;
|
||||
|
||||
template <class Archive>
|
||||
void save(Archive& archive) const {
|
||||
archive(cereal::make_nvp("IsActive", component.active));
|
||||
archive(cereal::make_nvp("Mesh", component.mesh.getStorageId()));
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load(Archive& archive) {
|
||||
std::string storageId;
|
||||
|
||||
archive(cereal::make_nvp("IsActive", component.active));
|
||||
archive(cereal::make_nvp("Mesh", storageId));
|
||||
|
||||
Scope<MeshData> meshData = settings.meshLoadingFunction(storageId);
|
||||
|
||||
Resource<GPUMesh> mesh = ResourceManager<GPUMesh>::loadResourceFromData(*meshData.get(), storageId);
|
||||
component.mesh = mesh;
|
||||
}
|
||||
};
|
||||
} // namespace Deer
|
||||
@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
|
||||
#include "DeerRender/Components.h"
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
|
||||
namespace Deer {
|
||||
struct ShaderComponentSerialization {
|
||||
WorldSerializationSettings& settings;
|
||||
ShaderComponent& component;
|
||||
|
||||
template <class Archive>
|
||||
void save(Archive& archive) const {
|
||||
archive(cereal::make_nvp("Shader", component.shader.getStorageId()));
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load(Archive& archive) {
|
||||
std::string storageId;
|
||||
|
||||
archive(cereal::make_nvp("Shader", storageId));
|
||||
|
||||
Scope<ShaderData> shaderData = settings.shaderLoadingFunction(storageId);
|
||||
|
||||
Resource<Shader> shader = ResourceManager<Shader>::loadResourceFromData(*shaderData.get(), storageId);
|
||||
component.shader = shader;
|
||||
}
|
||||
};
|
||||
} // namespace Deer
|
||||
@ -5,13 +5,9 @@
|
||||
int main(int, char**);
|
||||
|
||||
namespace Deer {
|
||||
class World;
|
||||
|
||||
namespace DeerStudio {
|
||||
extern World* world;
|
||||
|
||||
void worldUpdate(World&);
|
||||
void worldRender(World&);
|
||||
void onRender();
|
||||
void onUpdate();
|
||||
|
||||
void onEvent(Event& e);
|
||||
void main();
|
||||
@ -20,6 +16,5 @@ namespace Deer {
|
||||
|
||||
// Other
|
||||
void onPanelMenuBar();
|
||||
void worldManagerMenu();
|
||||
} // namespace DeerStudio
|
||||
} // namespace Deer
|
||||
|
||||
@ -24,5 +24,6 @@ namespace Deer {
|
||||
CScriptDictionary* setResourceMetadata(std::string& resource);
|
||||
|
||||
ResourceType getResourceType(std::string&);
|
||||
|
||||
} // namespace StudioAPI
|
||||
} // namespace Deer
|
||||
@ -4,8 +4,7 @@ namespace Deer {
|
||||
class World;
|
||||
|
||||
namespace StudioPanel {
|
||||
void init();
|
||||
void setWorld(World*);
|
||||
void init(World*);
|
||||
|
||||
void update();
|
||||
void render();
|
||||
|
||||
@ -16,7 +16,7 @@ namespace Deer {
|
||||
class FrameBuffer;
|
||||
|
||||
namespace DeerStudio {
|
||||
World* world;
|
||||
Universe::WorldHandle mainWorld;
|
||||
|
||||
void onUpdate();
|
||||
void onRender();
|
||||
@ -29,7 +29,6 @@ namespace Deer {
|
||||
void main() {
|
||||
Engine::init();
|
||||
Engine::setEventCallback(DeerStudio::onEvent);
|
||||
StudioPanel::init();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
|
||||
initializeFonts();
|
||||
@ -42,12 +41,10 @@ namespace Deer {
|
||||
.renderFrequency = 166,
|
||||
};
|
||||
|
||||
world = Universe::createWorld(worldSettings);
|
||||
mainWorld = Universe::createWorld(worldSettings);
|
||||
StudioPanel::init(&Universe::getWorld(mainWorld));
|
||||
|
||||
while (world) {
|
||||
StudioPanel::setWorld(world);
|
||||
world->execute();
|
||||
}
|
||||
Universe::getWorld(mainWorld).execute();
|
||||
|
||||
Engine::shutdown();
|
||||
} // namespace DeerStudio
|
||||
@ -83,7 +80,8 @@ namespace Deer {
|
||||
}
|
||||
|
||||
static bool p_open = true;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,
|
||||
ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::Begin("DockSpace Demo", &p_open, window_flags);
|
||||
@ -95,17 +93,17 @@ namespace Deer {
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::BeginMenu("World")) {
|
||||
DeerStudio::worldManagerMenu();
|
||||
if (ImGui::BeginMenu("Panel")) {
|
||||
onPanelMenuBar();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Reload Editor")) {
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (world.getExecutionState() == Deer::WorldState::Executing)
|
||||
StudioPanel::render();
|
||||
StudioPanel::render();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
@ -119,11 +117,10 @@ namespace Deer {
|
||||
}
|
||||
|
||||
bool onWindowCloseEvent(WindowCloseEvent&) {
|
||||
world->stopExecution();
|
||||
world = nullptr;
|
||||
Universe::getWorld(mainWorld).stopExecution();
|
||||
return true;
|
||||
}
|
||||
} // namespace DeerStudio
|
||||
} // namespace Deer
|
||||
|
||||
int main(int argc, char** args) { Deer::DeerStudio::main(); }
|
||||
int main(int argc, char** args) { Deer::DeerStudio::main(); }
|
||||
|
||||
@ -13,15 +13,12 @@ namespace Deer {
|
||||
void renderSystem(ScriptSystem* system);
|
||||
} // namespace StudioPanel
|
||||
|
||||
void StudioPanel::init() {
|
||||
void StudioPanel::init(World* world) {
|
||||
StudioScripting::registerStudioScripting();
|
||||
Scripting::registerInterface("Panel");
|
||||
Scripting::registerInterfaceFunction("Panel", "onImGui", Scripting::EventType::void_event);
|
||||
|
||||
Scripting::compileFiles("Editor/Scripts", "Editor");
|
||||
}
|
||||
|
||||
void StudioPanel::setWorld(World* world) {
|
||||
Scripting::SystemDescription systemDescription("Panel", "Editor");
|
||||
systemDescription.events.push_back(Scripting::SystemEvent("onInit", Scripting::EventType::void_event));
|
||||
systemDescription.events.push_back(Scripting::SystemEvent("onShutdown", Scripting::EventType::void_event));
|
||||
@ -70,6 +67,5 @@ namespace Deer {
|
||||
|
||||
void StudioPanel::shutdown() {
|
||||
editorInstance->executeOnGroup_voidEvent(1);
|
||||
studioPanelEnvironment.release();
|
||||
}
|
||||
} // namespace Deer
|
||||
@ -1,47 +0,0 @@
|
||||
#include "DeerCore/Serialization/WorldSettings.h"
|
||||
#include "DeerCore/Tools/Memory.h"
|
||||
#include "DeerCore/Universe.h"
|
||||
|
||||
#include "DeerStudio/EditorDataImporter.h"
|
||||
#include "DeerStudio/EditorDataSource.h"
|
||||
#include "DeerStudio/StudioPanel.h"
|
||||
|
||||
#include "DeerCore/World.h"
|
||||
#include "DeerStudio/DeerStudio.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace Deer {
|
||||
template <typename T>
|
||||
Scope<T> loadResourceData(const Path& storageId) {
|
||||
StorageData storageData = StorageBackend<EditorDataSource>::loadData(storageId);
|
||||
return storageData.deserialize<EditorDataImporter, T>();
|
||||
}
|
||||
|
||||
void DeerStudio::worldManagerMenu() {
|
||||
if (ImGui::MenuItem("Save world")) {
|
||||
WorldSerializationSettings serializationSettings{
|
||||
.includeServer = true,
|
||||
.includeClient = true};
|
||||
Universe::saveWorldInJson(world, serializationSettings, "Worlds/world.json");
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Load world")) {
|
||||
StudioPanel::shutdown();
|
||||
world->destroy();
|
||||
|
||||
WorldSettings worldSettings = {
|
||||
.updateCallback = worldUpdate,
|
||||
.updateFrequency = 60,
|
||||
.renderCallback = worldRender,
|
||||
.renderFrequency = 166,
|
||||
};
|
||||
|
||||
WorldSerializationSettings serializationSettings{
|
||||
.meshLoadingFunction = loadResourceData<MeshData>,
|
||||
.shaderLoadingFunction = loadResourceData<ShaderData>};
|
||||
|
||||
World* world_new = Universe::loadWorldFromJson(worldSettings, serializationSettings, "Worlds/world.json");
|
||||
world = world_new;
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
||||
@ -1,135 +0,0 @@
|
||||
{
|
||||
"SerializationSettings": {
|
||||
"includeServer": true,
|
||||
"includeClient": true
|
||||
},
|
||||
"World": {
|
||||
"EntityEnvironment": [
|
||||
{
|
||||
"Id": 0,
|
||||
"Tag": "root",
|
||||
"NetworkBehaviour": 0,
|
||||
"Parent": 0,
|
||||
"TransformComponent": {
|
||||
"Position": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"Scale": {
|
||||
"x": 1.0,
|
||||
"y": 1.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"Rotation": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0,
|
||||
"w": 1.0
|
||||
}
|
||||
},
|
||||
"Contains_MeshComponent": false,
|
||||
"Contains_ShaderComponent": false
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"Tag": "node",
|
||||
"NetworkBehaviour": 0,
|
||||
"Parent": 0,
|
||||
"TransformComponent": {
|
||||
"Position": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"Scale": {
|
||||
"x": 1.0,
|
||||
"y": 1.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"Rotation": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0,
|
||||
"w": 1.0
|
||||
}
|
||||
},
|
||||
"Contains_MeshComponent": true,
|
||||
"MeshComponent": {
|
||||
"IsActive": true,
|
||||
"Mesh": "Builtin:Cube"
|
||||
},
|
||||
"Contains_ShaderComponent": true,
|
||||
"ShaderComponent": {
|
||||
"Shader": "Builtin:SimpleShader"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Tag": "node",
|
||||
"NetworkBehaviour": 0,
|
||||
"Parent": 0,
|
||||
"TransformComponent": {
|
||||
"Position": {
|
||||
"x": 2.299999952316284,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"Scale": {
|
||||
"x": 1.0,
|
||||
"y": 1.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"Rotation": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0,
|
||||
"w": 1.0
|
||||
}
|
||||
},
|
||||
"Contains_MeshComponent": true,
|
||||
"MeshComponent": {
|
||||
"IsActive": true,
|
||||
"Mesh": "Builtin:Sphere"
|
||||
},
|
||||
"Contains_ShaderComponent": true,
|
||||
"ShaderComponent": {
|
||||
"Shader": "Builtin:SimpleShader"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"Tag": "node",
|
||||
"NetworkBehaviour": 0,
|
||||
"Parent": 0,
|
||||
"TransformComponent": {
|
||||
"Position": {
|
||||
"x": -3.700000047683716,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"Scale": {
|
||||
"x": 1.0,
|
||||
"y": 1.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"Rotation": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0,
|
||||
"w": 1.0
|
||||
}
|
||||
},
|
||||
"Contains_MeshComponent": true,
|
||||
"MeshComponent": {
|
||||
"IsActive": true,
|
||||
"Mesh": "train-locomotive-a.obj"
|
||||
},
|
||||
"Contains_ShaderComponent": true,
|
||||
"ShaderComponent": {
|
||||
"Shader": "shader_darkBlue.glsl"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
16
imgui.ini
16
imgui.ini
@ -1,6 +1,6 @@
|
||||
[Window][DockSpace Demo]
|
||||
Pos=0,0
|
||||
Size=2560,1371
|
||||
Size=1920,1011
|
||||
Collapsed=0
|
||||
|
||||
[Window][Debug##Default]
|
||||
@ -10,30 +10,30 @@ Collapsed=0
|
||||
|
||||
[Window][ViewportPanel]
|
||||
Pos=561,26
|
||||
Size=1574,853
|
||||
Size=934,493
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][PropertiesPanel]
|
||||
Pos=2137,26
|
||||
Size=423,853
|
||||
Pos=1497,26
|
||||
Size=423,493
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][ResourceExplorer]
|
||||
Pos=0,881
|
||||
Size=2560,490
|
||||
Pos=0,521
|
||||
Size=1920,490
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][TreePanel]
|
||||
Pos=0,26
|
||||
Size=559,853
|
||||
Size=559,493
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,26 Size=2560,1345 Split=Y
|
||||
DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,26 Size=1920,985 Split=Y
|
||||
DockNode ID=0x00000003 Parent=0x0AC2E849 SizeRef=1920,493 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=559,985 Selected=0x16E3C1E7
|
||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1359,985 Split=X
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user