Serializer now has a nice register function
This commit is contained in:
parent
a6e5deb502
commit
96ad0de01a
|
@ -7,9 +7,10 @@
|
||||||
|
|
||||||
namespace ecs::lua {
|
namespace ecs::lua {
|
||||||
struct LuaWrapper : Component {
|
struct LuaWrapper : Component {
|
||||||
LuaWrapper(sol::object object) : _object(object) {}
|
LuaWrapper(sol::object _object) : object(_object) {}
|
||||||
|
LuaWrapper() {}
|
||||||
|
|
||||||
sol::object _object;
|
sol::object object;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Constructor, typename... Args>
|
template <typename T, typename... Constructor, typename... Args>
|
||||||
|
|
|
@ -5,6 +5,9 @@ namespace ecs::lua {
|
||||||
sol::table ecs = lua.create_table("ecs");
|
sol::table ecs = lua.create_table("ecs");
|
||||||
|
|
||||||
ecs.new_usertype<Entity>("Entity",
|
ecs.new_usertype<Entity>("Entity",
|
||||||
|
"__tostring", [] (Entity* thiz) {
|
||||||
|
return uuids::to_string(thiz->uuid);
|
||||||
|
},
|
||||||
"add_component", [] (Entity* thiz, std::string name, Component* component) {
|
"add_component", [] (Entity* thiz, std::string name, Component* component) {
|
||||||
return thiz->add_component(ComponentID::get_id({name})[0], component);
|
return thiz->add_component(ComponentID::get_id({name})[0], component);
|
||||||
},
|
},
|
||||||
|
@ -33,7 +36,10 @@ namespace ecs::lua {
|
||||||
);
|
);
|
||||||
|
|
||||||
ecs.new_usertype<Manager>("Manager",
|
ecs.new_usertype<Manager>("Manager",
|
||||||
"create_entity", &Manager::create_entity,
|
"create_entity", [] (Manager* thiz) {
|
||||||
|
// @todo Allow to construct with given uuid
|
||||||
|
return thiz->create_entity();
|
||||||
|
},
|
||||||
"view", [] (Manager* thiz, sol::variadic_args args) {
|
"view", [] (Manager* thiz, sol::variadic_args args) {
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
for (std::string name : args) {
|
for (std::string name : args) {
|
||||||
|
@ -44,7 +50,7 @@ namespace ecs::lua {
|
||||||
);
|
);
|
||||||
|
|
||||||
register_component<LuaWrapper, sol::object>(lua,
|
register_component<LuaWrapper, sol::object>(lua,
|
||||||
"object", &LuaWrapper::_object
|
"object", &LuaWrapper::object
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
62
ecs-serial/include/ecs-serial.h
Normal file
62
ecs-serial/include/ecs-serial.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#pragma once
|
||||||
|
#include "ecs.h"
|
||||||
|
|
||||||
|
#include "iohelper/write.h"
|
||||||
|
#include "iohelper/read.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace ecs::serial {
|
||||||
|
namespace internal {
|
||||||
|
extern std::unordered_map<size_t, std::tuple<std::function<void(std::ostream&, ecs::Component*)>, std::function<void(std::istream&, ecs::Component*)>, std::function<ecs::Component*()>>> functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void serialize_member(std::ostream&, T*) {
|
||||||
|
// We reached the end
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename M, typename... Args>
|
||||||
|
void serialize_member(std::ostream& os, T* t, M T::*m, Args... args) {
|
||||||
|
iohelper::write<M>(os, t->*m);
|
||||||
|
|
||||||
|
serialize_member(os, t, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void deserialize_member(std::istream&, T*) {
|
||||||
|
// We reached the end
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename M, typename... Args>
|
||||||
|
void deserialize_member(std::istream& is, T* t, M T::*m, Args... args) {
|
||||||
|
t->*m = iohelper::read<M>(is);
|
||||||
|
|
||||||
|
deserialize_member(is, t, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo Allow for custom serializers and deserializers (maybe for this we do need a difference between update and new)
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
void register_component(Args... args) {
|
||||||
|
// Serialize component
|
||||||
|
auto func1 = [args...] (std::ostream& os, ecs::Component* component) {
|
||||||
|
T* t = (T*)component;
|
||||||
|
serialize_member(os, t, args...);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deserialize component
|
||||||
|
auto func2 = [args...] (std::istream& is, ecs::Component* component) {
|
||||||
|
T* t = (T*)component;
|
||||||
|
deserialize_member(is, t, args...);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto func3 = [] () -> Component* {
|
||||||
|
return new T();
|
||||||
|
};
|
||||||
|
|
||||||
|
internal::functions.insert({ComponentID::id<T>, {func1, func2, func3}});
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize(std::ostream& os, Entity* entity);
|
||||||
|
void deserialize(std::istream& is, Manager& manager);
|
||||||
|
}
|
|
@ -1,147 +1,63 @@
|
||||||
#include <iostream>
|
#include "ecs-serial.h"
|
||||||
|
|
||||||
#include "ecs.h"
|
|
||||||
|
|
||||||
#include "iohelper/memstream.h"
|
namespace ecs::serial {
|
||||||
#include "iohelper/write.h"
|
std::unordered_map<size_t, std::tuple<std::function<void(std::ostream&, ecs::Component*)>, std::function<void(std::istream&, ecs::Component*)>, std::function<ecs::Component*()>>> internal::functions;
|
||||||
#include "iohelper/read.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
void serialize(std::ostream& os, Entity* entity) {
|
||||||
|
auto uuid_data = reinterpret_cast<const uint8_t*>(entity->uuid.as_bytes().data());
|
||||||
|
iohelper::write_vector<uint8_t>(os, std::vector<uint8_t>(uuid_data, uuid_data + 16), false);
|
||||||
|
|
||||||
struct Position : ecs::Component {
|
auto components = entity->get_components();
|
||||||
Position(float x, float y) : _x(x), _y(y) {}
|
iohelper::write_length(os, components.size());
|
||||||
|
for (auto [id, component] : components) {
|
||||||
float _x;
|
iohelper::write_length(os, id);
|
||||||
float _y;
|
// @todo What if the function does not exist?
|
||||||
};
|
std::get<0>(internal::functions[id])(os, component);
|
||||||
|
|
||||||
struct Velocity : ecs::Component{
|
|
||||||
Velocity(float vx, float vy) : _vx(vx), _vy(vy) {}
|
|
||||||
|
|
||||||
float _vx;
|
|
||||||
float _vy;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<size_t, std::pair<std::function<std::vector<uint8_t>(ecs::Component*)>, std::function<ecs::Component*(std::vector<uint8_t>)>>> _functions;
|
|
||||||
|
|
||||||
// @todo Add deserializer stuff
|
|
||||||
template <typename T>
|
|
||||||
void register_component(std::function<std::vector<uint8_t>(ecs::Component*)> serializer, std::function<ecs::Component*(std::vector<uint8_t>)> deserializer) {
|
|
||||||
_functions.insert({ecs::ComponentID::id<T>, {serializer, deserializer}});
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Marker : uint8_t {
|
|
||||||
ENTITY,
|
|
||||||
COMPONENT,
|
|
||||||
END
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, const char* argv) {
|
|
||||||
ecs::Manager manager;
|
|
||||||
|
|
||||||
register_component<Position>([] (ecs::Component* component) {
|
|
||||||
Position* pos = (Position*)component;
|
|
||||||
std::vector<uint8_t> data;
|
|
||||||
iohelper::omemstream stream(data);
|
|
||||||
|
|
||||||
iohelper::write<float>(stream, pos->_x);
|
|
||||||
iohelper::write<float>(stream, pos->_y);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}, [] (std::vector<uint8_t> data) {
|
|
||||||
iohelper::imemstream stream(data);
|
|
||||||
float x = iohelper::read<float>(stream);
|
|
||||||
float y = iohelper::read<float>(stream);
|
|
||||||
return new Position(x, y);
|
|
||||||
});
|
|
||||||
|
|
||||||
register_component<Velocity>([] (ecs::Component* component) {
|
|
||||||
Velocity* vel = (Velocity*)component;
|
|
||||||
std::vector<uint8_t> data;
|
|
||||||
iohelper::omemstream stream(data);
|
|
||||||
|
|
||||||
iohelper::write<float>(stream, vel->_vx);
|
|
||||||
iohelper::write<float>(stream, vel->_vy);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}, [] (std::vector<uint8_t> data) {
|
|
||||||
iohelper::imemstream stream(data);
|
|
||||||
float vx = iohelper::read<float>(stream);
|
|
||||||
float vy = iohelper::read<float>(stream);
|
|
||||||
return new Velocity(vx, vy);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
// Create entities and store them
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
// We can create entities
|
|
||||||
ecs::Entity* entity = manager.create_entity();
|
|
||||||
// Then we can add components to them
|
|
||||||
entity->add_component<Position>(0.0f, 0.0f);
|
|
||||||
if (i % 2 == 0) {
|
|
||||||
entity->add_component<Velocity>(0.1f, 0.2f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.view<Position, Velocity>().for_each([] (ecs::Entity*, Position* pos, Velocity* vel) {
|
void deserialize(std::istream& is, Manager& manager) {
|
||||||
pos->_x += vel->_vx;
|
auto uuid_vector = iohelper::read_vector<uint8_t>(is, 16);
|
||||||
pos->_y += vel->_vy;
|
uuids::uuid uuid(uuid_vector.begin(), uuid_vector.end());
|
||||||
});
|
if (manager.has_entity(uuid)) {
|
||||||
|
// Update existing entity
|
||||||
std::ofstream file("entities", std::ios::out | std::ios::trunc);
|
Entity* entity = manager.get_entity(uuid);
|
||||||
for (auto [uuid, entity] : manager.view<>()) {
|
size_t component_count = iohelper::read_length(is);
|
||||||
iohelper::write<uint8_t>(file, (uint8_t)Marker::ENTITY);
|
// std::cout << "Updating " << component_count << " components in entity: " << uuid << '\n';
|
||||||
// iohelper::write_length(file, uuid);
|
for (size_t i = 0; i < component_count; ++i) {
|
||||||
auto uuid_data = reinterpret_cast<const uint8_t*>(uuid.as_bytes().data());
|
size_t id = iohelper::read_length(is);
|
||||||
iohelper::write_vector<uint8_t>(file, std::vector<uint8_t>(uuid_data, uuid_data + 16), false);
|
// @todo We also need to be able to remove components
|
||||||
for (auto [id, component] : entity->get_components()) {
|
// Sending a component with length 0 -> remove component
|
||||||
iohelper::write<uint8_t>(file, (uint8_t)Marker::COMPONENT);
|
// However we might have components that have no data and are just like tags
|
||||||
iohelper::write_length(file, id);
|
// So maybe instead if we send MAX_INT or something like that
|
||||||
auto data = _functions[id].first(component);
|
// Or we send a flag in front
|
||||||
iohelper::write_vector<uint8_t>(file, data);
|
// @todo What if the function does not exist?
|
||||||
}
|
if (entity->has_components({id})) {
|
||||||
}
|
// Update the component
|
||||||
iohelper::write<uint8_t>(file, (uint8_t)Marker::END);
|
std::cout << "Updating component: " << id << '\n';
|
||||||
file.close();
|
Component* component = entity->get_component(id);
|
||||||
|
std::get<1>(internal::functions[id])(is, component);
|
||||||
} else {
|
} else {
|
||||||
// Load entities from disk as a test
|
// Add new component
|
||||||
std::ifstream file("entities", std::ios::in);
|
std::cout << "Adding component: " << id << '\n';
|
||||||
bool loop = true;
|
Component* component = std::get<2>(internal::functions[id])();
|
||||||
ecs::Entity* entity = nullptr;
|
std::get<1>(internal::functions[id])(is, component);
|
||||||
while (loop) {
|
entity->add_component(id, component);
|
||||||
Marker marker = (Marker)iohelper::read<uint8_t>(file);
|
|
||||||
switch (marker) {
|
|
||||||
case Marker::ENTITY: {
|
|
||||||
// size_t uuid = iohelper::read_length(file);
|
|
||||||
auto uuid_vector = iohelper::read_vector<uint8_t>(file, 16);
|
|
||||||
entity = manager.create_entity(uuids::uuid(uuid_vector.begin(), uuid_vector.end()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Marker::COMPONENT: {
|
|
||||||
size_t id = iohelper::read_length(file);
|
|
||||||
std::vector<uint8_t> data = iohelper::read_vector<uint8_t>(file);
|
|
||||||
entity->add_component(id, _functions[id].second(data));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Marker::END:
|
|
||||||
loop = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (false) {
|
// Create new entity
|
||||||
auto ent = manager.get_entity(uuids::uuid::from_string("6d58fdb5-6d8c-4e6f-89d4-f7d7b184f463").value());
|
Entity* entity = manager.create_entity(uuid);
|
||||||
if (ent->has_components<Position>()) {
|
size_t component_count = iohelper::read_length(is);
|
||||||
auto pos = ent->get_component<Position>();
|
// std::cout << "Creating entity with " << component_count << " components: " << uuid << '\n';
|
||||||
pos->_x = 1.2f;
|
for (size_t i = 0; i < component_count; ++i) {
|
||||||
pos->_y = 3.4f;
|
size_t id = iohelper::read_length(is);
|
||||||
|
std::cout << "Adding component: " << id << '\n';
|
||||||
|
Component* component = std::get<2>(internal::functions[id])();
|
||||||
|
std::get<1>(internal::functions[id])(is, component);
|
||||||
|
entity->add_component(id, component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.view<Position>().for_each([] (ecs::Entity* entity, Position* pos) {
|
|
||||||
std::cout << "uuid: " << entity->uuid << '\n';
|
|
||||||
std::cout << "x: " << pos->_x << '\n';
|
|
||||||
std::cout << "y: " << pos->_y << '\n';
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,11 @@ namespace ecs {
|
||||||
Entity* create_entity(uuids::uuid uuid);
|
Entity* create_entity(uuids::uuid uuid);
|
||||||
Entity* create_entity();
|
Entity* create_entity();
|
||||||
|
|
||||||
|
bool has_entity(uuids::uuid uuid) {
|
||||||
|
// @todo c++20 has .contains()
|
||||||
|
return _entities.count(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
Entity* get_entity(uuids::uuid uuid) {
|
Entity* get_entity(uuids::uuid uuid) {
|
||||||
auto it = _entities.find(uuid);
|
auto it = _entities.find(uuid);
|
||||||
if (it == _entities.end()) {
|
if (it == _entities.end()) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ lib "ecs-lua"
|
||||||
|
|
||||||
subfile("../iohelper/flint.lua", "iohelper")
|
subfile("../iohelper/flint.lua", "iohelper")
|
||||||
|
|
||||||
executable "ecs-serial"
|
lib "ecs-serial"
|
||||||
path "ecs-serial"
|
path "ecs-serial"
|
||||||
|
|
||||||
dependency("ecs", "iohelper")
|
dependency("ecs", "iohelper")
|
||||||
|
@ -35,5 +35,6 @@ executable "test"
|
||||||
path "test"
|
path "test"
|
||||||
|
|
||||||
dependency "ecs-lua"
|
dependency "ecs-lua"
|
||||||
|
dependency "ecs-serial"
|
||||||
|
|
||||||
run_target "test"
|
run_target "test"
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
#include "ecs-lua.h"
|
#include "ecs-lua.h"
|
||||||
|
#include "ecs-serial.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
struct Position : ecs::Component {
|
struct Position : ecs::Component {
|
||||||
Position(float x, float y) : _x(x), _y(y) {}
|
Position(float _x, float _y) : x(_x), y(_y) {}
|
||||||
|
Position() {}
|
||||||
|
|
||||||
float _x;
|
float x;
|
||||||
float _y;
|
float y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Velocity : ecs::Component{
|
struct Velocity : ecs::Component {
|
||||||
Velocity(float vx, float vy) : _vx(vx), _vy(vy) {}
|
Velocity(float _x, float _y) : x(_x), y(_y) {}
|
||||||
|
Velocity() {}
|
||||||
|
|
||||||
float _vx;
|
float x;
|
||||||
float _vy;
|
float y;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -23,15 +27,29 @@ int main() {
|
||||||
ecs::lua::init(lua);
|
ecs::lua::init(lua);
|
||||||
|
|
||||||
ecs::lua::register_component<Position, float, float>(lua,
|
ecs::lua::register_component<Position, float, float>(lua,
|
||||||
"x", &Position::_x,
|
"x", &Position::x,
|
||||||
"y", &Position::_y
|
"y", &Position::y
|
||||||
|
);
|
||||||
|
ecs::serial::register_component<Position>(
|
||||||
|
&Position::x,
|
||||||
|
&Position::y
|
||||||
);
|
);
|
||||||
|
|
||||||
ecs::lua::register_component<Velocity, float, float>(lua,
|
ecs::lua::register_component<Velocity, float, float>(lua,
|
||||||
"vx", &Velocity::_vx,
|
"x", &Velocity::x,
|
||||||
"vy", &Velocity::_vy
|
"y", &Velocity::y
|
||||||
|
);
|
||||||
|
ecs::serial::register_component<Velocity>(
|
||||||
|
&Velocity::x,
|
||||||
|
&Velocity::y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ecs::serial::register_component<ecs::lua::LuaWrapper>(
|
||||||
|
// @todo We need to create a read and write function for sol::object
|
||||||
|
// &ecs::lua::LuaWrapper::object
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
// This manages all our entities
|
// This manages all our entities
|
||||||
ecs::Manager manager;
|
ecs::Manager manager;
|
||||||
|
|
||||||
|
@ -60,8 +78,8 @@ int main() {
|
||||||
print("x: " .. pos.x)
|
print("x: " .. pos.x)
|
||||||
print("y: " .. pos.y)
|
print("y: " .. pos.y)
|
||||||
vel = ent:get_component("Velocity")
|
vel = ent:get_component("Velocity")
|
||||||
print("v_x: " .. vel.vx)
|
print("v_x: " .. vel.x)
|
||||||
print("v_y: " .. vel.vy)
|
print("v_y: " .. vel.y)
|
||||||
|
|
||||||
print("View test")
|
print("View test")
|
||||||
view = manager:view("Position", "Velocity")
|
view = manager:view("Position", "Velocity")
|
||||||
|
@ -69,14 +87,16 @@ int main() {
|
||||||
pos = ent:get_component("Position")
|
pos = ent:get_component("Position")
|
||||||
vel = ent:get_component("Velocity")
|
vel = ent:get_component("Velocity")
|
||||||
|
|
||||||
pos.x = pos.x + vel.vx
|
pos.x = pos.x + vel.x
|
||||||
pos.y = pos.y + vel.vy
|
pos.y = pos.y + vel.y
|
||||||
|
|
||||||
|
print(ent)
|
||||||
|
|
||||||
print("x: " .. pos.x)
|
print("x: " .. pos.x)
|
||||||
print("y: " .. pos.y)
|
print("y: " .. pos.y)
|
||||||
|
|
||||||
print("v_x: " .. vel.vx)
|
print("v_x: " .. vel.x)
|
||||||
print("v_y: " .. vel.vy)
|
print("v_y: " .. vel.y)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- @todo Implement this
|
-- @todo Implement this
|
||||||
|
@ -118,27 +138,94 @@ int main() {
|
||||||
|
|
||||||
std::cout << "Update position\n";
|
std::cout << "Update position\n";
|
||||||
manager.view<Position, Velocity>().for_each([](ecs::Entity*, Position* pos, Velocity* vel) {
|
manager.view<Position, Velocity>().for_each([](ecs::Entity*, Position* pos, Velocity* vel) {
|
||||||
pos->_x += vel->_vx;
|
pos->x += vel->x;
|
||||||
pos->_y += vel->_vy;
|
pos->y += vel->y;
|
||||||
});
|
});
|
||||||
|
|
||||||
std::cout << "Show position!\n";
|
std::cout << "Show position!\n";
|
||||||
manager.view<Position>().for_each([](ecs::Entity*, Position* pos) {
|
manager.view<Position>().for_each([](ecs::Entity*, Position* pos) {
|
||||||
std::cout << "X: " << pos->_x << '\n';
|
std::cout << "X: " << pos->x << '\n';
|
||||||
std::cout << "Y: " << pos->_y << '\n';
|
std::cout << "Y: " << pos->y << '\n';
|
||||||
});
|
});
|
||||||
|
|
||||||
// These are really just an internal api that should not be used
|
// These are really just an internal api that should not be used
|
||||||
for (auto [uuid, entity] : manager.view(ecs::ComponentID::get_id({"Random"}))) {
|
for (auto [uuid, entity] : manager.view(ecs::ComponentID::get_id({"Random"}))) {
|
||||||
sol::table random = ((ecs::lua::LuaWrapper*)entity->get_component(ecs::ComponentID::get_id({"Random"})[0]))->_object;
|
sol::table random = ((ecs::lua::LuaWrapper*)entity->get_component(ecs::ComponentID::get_id({"Random"})[0]))->object;
|
||||||
|
|
||||||
random["a"] = 21;
|
random["a"] = 21;
|
||||||
std::cout << random["a"].get<std::string>() << '\n';
|
std::cout << random["a"].get<std::string>() << '\n';
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto [uuid, entity] : manager.view(ecs::ComponentID::get_id({"Random"}))) {
|
for (auto [uuid, entity] : manager.view(ecs::ComponentID::get_id({"Random"}))) {
|
||||||
sol::table random = ((ecs::lua::LuaWrapper*)entity->get_component(ecs::ComponentID::get_id({"Random"})[0]))->_object;
|
sol::table random = ((ecs::lua::LuaWrapper*)entity->get_component(ecs::ComponentID::get_id({"Random"})[0]))->object;
|
||||||
|
|
||||||
std::cout << random["a"].get<std::string>() << '\n';
|
std::cout << random["a"].get<std::string>() << '\n';
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::cout << "STORE\n";
|
||||||
|
ecs::Manager manager;
|
||||||
|
|
||||||
|
// Create entities and store them
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
// We can create entities
|
||||||
|
ecs::Entity* entity = manager.create_entity();
|
||||||
|
// Then we can add components to them
|
||||||
|
entity->add_component<Position>(0.0f, 0.0f);
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
entity->add_component<Velocity>(0.1f, 0.2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.view<Position, Velocity>().for_each([] (ecs::Entity*, Position* pos, Velocity* vel) {
|
||||||
|
pos->x += vel->x;
|
||||||
|
pos->y += vel->y;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::ofstream file("entities", std::ios::out | std::ios::trunc);
|
||||||
|
iohelper::write_length(file, manager.view<>().size());
|
||||||
|
for (auto [uuid, entity] : manager.view<>()) {
|
||||||
|
ecs::serial::serialize(file, entity);
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
manager.view<Position>().for_each([] (ecs::Entity* entity, Position* pos) {
|
||||||
|
std::cout << "uuid: " << entity->uuid << '\n';
|
||||||
|
std::cout << "x: " << pos->x << '\n';
|
||||||
|
std::cout << "y: " << pos->y << '\n';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::cout << "LOAD\n";
|
||||||
|
ecs::Manager manager;
|
||||||
|
|
||||||
|
// Load entities from disk as a test
|
||||||
|
std::ifstream file("entities", std::ios::in);
|
||||||
|
|
||||||
|
size_t count = iohelper::read_length(file);
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
ecs::serial::deserialize(file, manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.seekg(0, std::ios::beg);
|
||||||
|
iohelper::read_length(file);
|
||||||
|
ecs::serial::deserialize(file, manager);
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
auto ent = manager.get_entity(uuids::uuid::from_string("6d58fdb5-6d8c-4e6f-89d4-f7d7b184f463").value());
|
||||||
|
if (ent->has_components<Position>()) {
|
||||||
|
auto pos = ent->get_component<Position>();
|
||||||
|
pos->x = 1.2f;
|
||||||
|
pos->y = 3.4f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.view<Position>().for_each([] (ecs::Entity* entity, Position* pos) {
|
||||||
|
std::cout << "uuid: " << entity->uuid << '\n';
|
||||||
|
std::cout << "x: " << pos->x << '\n';
|
||||||
|
std::cout << "y: " << pos->y << '\n';
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user