Minor - Implements scene saving and loading - V12.10.0
Adds scene saving and loading functionality, using a component factory for dynamic component creation and serialization. This allows users to save and load the state of entities, including their components and textures. A new component factory is introduced to register and create different component types. Each component implements serialization and deserialization methods, which are used to store and restore the component's state. A new .ker scene file format is introduced to serialize entity data and to load it back into memory to restore the scene. Also adds a DemoScene_V12.9.0.ker file to showcase the engine.
This commit is contained in:
54
enginecustom/src/inc/system/ecs/ComponentFactory.h
Normal file
54
enginecustom/src/inc/system/ecs/ComponentFactory.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// ComponentFactory.h
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "entity.h"
|
||||
#include "component.h"
|
||||
#include "components/identity_component.h"
|
||||
#include "components/render_component.h"
|
||||
#include "components/transform_component.h"
|
||||
#include "components/physics_component.h"
|
||||
#include "components/shader_component.h"
|
||||
#include "components/model_path_component.h"
|
||||
|
||||
class ComponentFactory {
|
||||
public:
|
||||
static ComponentFactory& Get() {
|
||||
static ComponentFactory instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void EnregistrerComposant(const std::string& typeName) {
|
||||
m_creators[typeName] = [](std::shared_ptr<ecs::Entity> entity) -> std::shared_ptr<ecs::Component> {
|
||||
return entity->AddComponent<T>();
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<ecs::Component> CreerComposant(const std::string& typeName,
|
||||
std::shared_ptr<ecs::Entity> entity) {
|
||||
auto it = m_creators.find(typeName);
|
||||
if (it != m_creators.end()) {
|
||||
return it->second(entity);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::function<std::shared_ptr<ecs::Component>(std::shared_ptr<ecs::Entity>)>> m_creators;
|
||||
};
|
||||
|
||||
// Fonction d'initialisation pour enregistrer tous les composants
|
||||
inline void EnregistrerTousLesComposants() {
|
||||
auto& factory = ComponentFactory::Get();
|
||||
factory.EnregistrerComposant<ecs::TransformComponent>("TransformComponent");
|
||||
factory.EnregistrerComposant<ecs::PhysicsComponent>("PhysicsComponent");
|
||||
factory.EnregistrerComposant<ecs::ShaderComponent>("ShaderComponent");
|
||||
factory.EnregistrerComposant<ecs::ModelPathComponent>("ModelPathComponent");
|
||||
factory.EnregistrerComposant<ecs::IdentityComponent>("IdentityComponent");
|
||||
factory.EnregistrerComposant<ecs::RenderComponent>("RenderComponent");
|
||||
// Ajouter d'autres composants ici
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#include <sstream>
|
||||
|
||||
#include "../component.h"
|
||||
#include <string>
|
||||
|
||||
@@ -94,13 +96,15 @@ public:
|
||||
|
||||
/**
|
||||
* Serialize the component to a string.
|
||||
* Format: "id:name:type"
|
||||
* Format: "IdentityComponent:id:name:type"
|
||||
* @return A string representation of the component.
|
||||
*/
|
||||
std::string Serialize() const override
|
||||
{
|
||||
std::string Serialize() const override {
|
||||
std::stringstream ss;
|
||||
ss << m_id << ":" << m_name << ":" << ObjectTypeToString(m_type);
|
||||
ss << "IdentityComponent:"
|
||||
<< GetId() << ":"
|
||||
<< GetName() << ":"
|
||||
<< ObjectTypeToString(GetType());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -110,31 +114,24 @@ public:
|
||||
* @param data The string data to deserialize from.
|
||||
* @return True if deserialization was successful, otherwise false.
|
||||
*/
|
||||
bool Deserialize(const std::string& data) override
|
||||
{
|
||||
bool Deserialize(const std::string& data) override {
|
||||
std::stringstream ss(data);
|
||||
std::string segment;
|
||||
std::vector<std::string> segments;
|
||||
|
||||
while (std::getline(ss, segment, ':'))
|
||||
{
|
||||
segments.push_back(segment);
|
||||
}
|
||||
|
||||
if (segments.empty()) return false;
|
||||
if (segments.size() != 3) return false;
|
||||
|
||||
try
|
||||
{
|
||||
m_id = std::stoi(segments[0]);
|
||||
m_name = segments[1];
|
||||
m_type = StringToObjectType(segments[2]);
|
||||
return true;
|
||||
} catch (const std::exception&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string type;
|
||||
std::getline(ss, type, ':');
|
||||
|
||||
if (type != "IdentityComponent") return false;
|
||||
|
||||
std::string token, name, objectTypeStr;
|
||||
int id;
|
||||
|
||||
std::getline(ss, token, ':'); id = std::stoi(token);
|
||||
std::getline(ss, name, ':');
|
||||
std::getline(ss, objectTypeStr);
|
||||
|
||||
SetId(id);
|
||||
SetName(name);
|
||||
SetType(StringToObjectType(objectTypeStr));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,37 @@ public:
|
||||
* @param path The path to set as a std::wstring.
|
||||
*/
|
||||
void SetPath(const std::wstring& path) { m_path = path; }
|
||||
|
||||
std::string convert_w_string_to_string(const std::wstring& wstr) const
|
||||
{
|
||||
if (wstr.empty()) return std::string();
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
|
||||
std::string str(size_needed, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0], size_needed, NULL, NULL);
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string Serialize() const override {
|
||||
std::stringstream ss;
|
||||
ss << "ModelPathComponent:"
|
||||
<< convert_w_string_to_string(m_path);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& data) override {
|
||||
std::stringstream ss(data);
|
||||
std::string type;
|
||||
std::getline(ss, type, ':');
|
||||
|
||||
if (type != "ModelPathComponent") return false;
|
||||
|
||||
std::string modelPath;
|
||||
std::getline(ss, modelPath);
|
||||
|
||||
SetPath(std::wstring(modelPath.begin(), modelPath.end()));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::wstring m_path;
|
||||
|
||||
@@ -195,6 +195,44 @@ public:
|
||||
* @return The current position as an XMVECTOR.
|
||||
*/
|
||||
|
||||
std::string Serialize() const override
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "PhysicsComponent:"
|
||||
<< GetMass() << ":"
|
||||
<< GetBoundingRadius() << ":"
|
||||
<< (IsPhysicsEnabled() ? "1" : "0") << ":"
|
||||
<< (IsGravityEnabled() ? "1" : "0") << ":"
|
||||
<< (IsGrounded() ? "1" : "0");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& data) override
|
||||
{
|
||||
std::stringstream ss(data);
|
||||
std::string type;
|
||||
std::getline(ss, type, ':');
|
||||
|
||||
if (type != "PhysicsComponent") return false;
|
||||
|
||||
std::string token;
|
||||
float mass, boundingRadius;
|
||||
bool physicsEnabled, gravityEnabled, isGrounded;
|
||||
|
||||
std::getline(ss, token, ':'); mass = std::stof(token);
|
||||
std::getline(ss, token, ':'); boundingRadius = std::stof(token);
|
||||
std::getline(ss, token, ':'); physicsEnabled = (token == "1");
|
||||
std::getline(ss, token, ':'); gravityEnabled = (token == "1");
|
||||
std::getline(ss, token, ':'); isGrounded = (token == "1");
|
||||
|
||||
SetMass(mass);
|
||||
SetBoundingRadius(boundingRadius);
|
||||
SetPhysicsEnabled(physicsEnabled);
|
||||
SetGravityEnabled(gravityEnabled);
|
||||
SetGrounded(isGrounded);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
XMVECTOR m_Velocity;
|
||||
XMVECTOR m_Acceleration;
|
||||
|
||||
@@ -186,6 +186,28 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
std::string Serialize() const override {
|
||||
if (!m_model) return "RenderComponent:NoModel";
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "RenderComponent:HasModel";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& data) override {
|
||||
std::stringstream ss(data);
|
||||
std::string type;
|
||||
std::getline(ss, type, ':');
|
||||
|
||||
if (type != "RenderComponent") return false;
|
||||
|
||||
std::string hasModel;
|
||||
std::getline(ss, hasModel);
|
||||
|
||||
// Le mod<6F>le sera charg<72> s<>par<61>ment
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<model_class> m_model;
|
||||
std::string m_modelFilePath;
|
||||
|
||||
@@ -88,6 +88,28 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
std::string Serialize() const override
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "ShaderComponent:"
|
||||
<< ShaderTypeToString(GetActiveShader());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& data) override {
|
||||
std::stringstream ss(data);
|
||||
std::string type;
|
||||
std::getline(ss, type, ':');
|
||||
|
||||
if (type != "ShaderComponent") return false;
|
||||
|
||||
std::string shaderTypeStr;
|
||||
std::getline(ss, shaderTypeStr);
|
||||
|
||||
SetActiveShader(StringToShaderType(shaderTypeStr));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
ShaderType m_activeShader;
|
||||
};
|
||||
|
||||
@@ -153,6 +153,50 @@ public:
|
||||
*/
|
||||
void SetTranslateMatrix(XMMATRIX matrix) { m_TranslateMatrix = matrix; UpdateWorldMatrix(); }
|
||||
|
||||
std::string Serialize() const override
|
||||
{
|
||||
XMFLOAT3 position, rotation, scale;
|
||||
XMStoreFloat3(&position, GetPosition());
|
||||
XMStoreFloat3(&rotation, GetRotation());
|
||||
XMStoreFloat3(&scale, GetScale());
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "TransformComponent:"
|
||||
<< position.x << ":" << position.y << ":" << position.z << ":"
|
||||
<< rotation.x << ":" << rotation.y << ":" << rotation.z << ":"
|
||||
<< scale.x << ":" << scale.y << ":" << scale.z;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& data) override
|
||||
{
|
||||
std::stringstream ss(data);
|
||||
std::string type;
|
||||
std::getline(ss, type, ':');
|
||||
|
||||
if (type != "TransformComponent") return false;
|
||||
|
||||
std::string token;
|
||||
XMFLOAT3 position, rotation, scale;
|
||||
|
||||
std::getline(ss, token, ':'); position.x = std::stof(token);
|
||||
std::getline(ss, token, ':'); position.y = std::stof(token);
|
||||
std::getline(ss, token, ':'); position.z = std::stof(token);
|
||||
|
||||
std::getline(ss, token, ':'); rotation.x = std::stof(token);
|
||||
std::getline(ss, token, ':'); rotation.y = std::stof(token);
|
||||
std::getline(ss, token, ':'); rotation.z = std::stof(token);
|
||||
|
||||
std::getline(ss, token, ':'); scale.x = std::stof(token);
|
||||
std::getline(ss, token, ':'); scale.y = std::stof(token);
|
||||
std::getline(ss, token, ':'); scale.z = std::stof(token);
|
||||
|
||||
SetPosition(XMLoadFloat3(&position));
|
||||
SetRotation(XMLoadFloat3(&rotation));
|
||||
SetScale(XMLoadFloat3(&scale));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
XMMATRIX m_ScaleMatrix;
|
||||
XMMATRIX m_RotateMatrix;
|
||||
|
||||
Reference in New Issue
Block a user