PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
component_storage.h
1#pragma once
2
4#include "pixelbullet/core/containers/sparse_set.h"
5#include "pixelbullet/serialization/node.h"
6#include "pixelbullet/serialization/serialization_result.h"
7
8#include <cstdint>
9#include <functional>
10#include <string>
11#include <string_view>
12#include <typeinfo>
13#include <utility>
14
15namespace pixelbullet
16{
18{
19 virtual ~ComponentStorageBase() = default;
20 virtual void Serialize(Node& node) const = 0;
21 virtual void Deserialize(const Node& node) = 0;
22 virtual void DeserializeComponent(uint32_t entity, const Node& node) = 0;
23 [[nodiscard]] virtual SerializationResult TryDeserializeComponent(uint32_t entity, const Node& node,
24 std::string_view diagnostic_path) = 0;
25 virtual void Clear() = 0;
26 virtual void RemoveComponent(uint32_t entity) = 0;
27};
28
29template <typename T>
30struct ComponentStorage : public ComponentStorageBase
31{
32 using SafeDeserializeFn = std::function<SerializationResult(T&, const Node&, std::string_view)>;
33
34 ComponentStorage() = default;
35
36 explicit ComponentStorage(SafeDeserializeFn safe_deserialize)
37 : safe_deserialize_(std::move(safe_deserialize))
38 {
39 }
40
41 SparseSet<T> components;
42
43 void Serialize(Node& node) const override
44 {
45 node.set_type(NodeType::Array);
46 auto& properties = node.properties();
47 properties.clear();
48 for (const auto& entry : components)
49 {
50 Node entry_node;
51 entry_node["entity"] << entry.id;
52 Node component_node;
53 component_node << entry.value;
54 entry_node["component"] = component_node;
55 properties.push_back({ "", entry_node });
56 }
57 }
58
59 void Deserialize(const Node& node) override
60 {
61 ASSERT(node.type() == NodeType::Array || node.type() == NodeType::Null, "Expected component storage data to be an array");
62 for (const auto& [key, entry_node] : node.properties())
63 {
64 (void)key;
65 uint32_t entity = 0;
66 entry_node["entity"] >> entity;
67 DeserializeComponent(entity, entry_node["component"]);
68 }
69 }
70
71 void DeserializeComponent(const uint32_t entity, const Node& node) override
72 {
73 T component{};
74 node >> component;
75 components.insert_or_assign(entity, std::move(component));
76 }
77
78 [[nodiscard]] SerializationResult TryDeserializeComponent(const uint32_t entity, const Node& node,
79 const std::string_view diagnostic_path) override
80 {
81 T component{};
82 if (!safe_deserialize_)
83 {
85 false,
86 "Component type '" + std::string(typeid(T).name()) + "' does not support safe deserialization.",
87 { SerializationDiagnostic{ .path = std::string(diagnostic_path),
88 .message = "Component type does not support safe deserialization." } },
89 };
90 }
91
92 if (const SerializationResult result = safe_deserialize_(component, node, diagnostic_path); !result)
93 {
94 return result;
95 }
96
97 components.insert_or_assign(entity, std::move(component));
98 return SerializationResult{ true, {} };
99 }
100
101 void Clear() override
102 {
103 components.clear();
104 }
105
106 void RemoveComponent(uint32_t entity) override
107 {
108 components.erase(entity);
109 }
110
111private:
112 SafeDeserializeFn safe_deserialize_;
113};
114} // namespace pixelbullet
Provides assertion and panic mechanisms with optional custom formatting.
#define ASSERT(condition,...)
Asserts that a condition is true.
Definition assert.h:142
Represents a hierarchical node capable of storing various data types and supporting YAML serializatio...
Definition node.h:49
Definition sparse_set.h:16
Definition component_storage.h:18
Definition serialization_result.h:9
Definition serialization_result.h:17