Streamlined library and reworked the way runtime components work
This commit is contained in:
@@ -41,32 +41,25 @@ namespace ecs::serial {
|
||||
template <typename T, typename... Args>
|
||||
void register_component(Args... args) {
|
||||
// Serialize component
|
||||
auto func1 = [args...] (std::ostream& os, ecs::Component* component) {
|
||||
auto serialize = [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) {
|
||||
auto deserialize = [args...] (std::istream& is, ecs::Component* component) {
|
||||
T* t = (T*)component;
|
||||
deserialize_member(is, t, args...);
|
||||
};
|
||||
|
||||
auto func3 = [] () -> Component* {
|
||||
auto create = [] () -> Component* {
|
||||
return new T();
|
||||
};
|
||||
|
||||
internal::functions.insert({ComponentID::id<T>, {func1, func2, func3}});
|
||||
internal::functions.insert({ComponentID::id<T>, {serialize, deserialize, create}});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void register_component_custom(std::function<void(std::ostream&, ecs::Component*)> func1, std::function<void(std::istream&, Component*)> func2) {
|
||||
auto func3 = [] () -> Component* {
|
||||
return new T();
|
||||
};
|
||||
|
||||
internal::functions.insert({ComponentID::id<T>, {func1, func2, func3}});
|
||||
}
|
||||
void register_component_custom(size_t id, std::function<void(std::ostream&, ecs::Component*)> serialize, std::function<void(std::istream&, Component*)> deserialize, std::function<ecs::Component*()> create);
|
||||
|
||||
void serialize(std::ostream& os, Entity* entity);
|
||||
void deserialize(std::istream& is, Manager& manager);
|
||||
|
||||
@@ -12,6 +12,10 @@ namespace ecs::serial {
|
||||
|
||||
std::unordered_map<size_t, size_t> conversion;
|
||||
|
||||
void register_component_custom(size_t id, std::function<void(std::ostream&, ecs::Component*)> serialize, std::function<void(std::istream&, Component*)> deserialize, std::function<ecs::Component*()> create) {
|
||||
internal::functions.insert({id, {serialize, deserialize, create}});
|
||||
}
|
||||
|
||||
void serialize(std::ostream& os, Entity* entity) {
|
||||
auto uuid_data = reinterpret_cast<const uint8_t*>(entity->uuid.as_bytes().data());
|
||||
io::write<std::vector<uint8_t>>(os, std::vector<uint8_t>(uuid_data, uuid_data + 16), false);
|
||||
@@ -19,28 +23,13 @@ namespace ecs::serial {
|
||||
auto components = entity->get_components();
|
||||
io::write<size_t>(os, components.size());
|
||||
for (auto [id, component] : components) {
|
||||
if (!component->_runtime) {
|
||||
auto functions = internal::functions.find(id);
|
||||
if (functions == internal::functions.end()) {
|
||||
throw std::runtime_error("No known serializer for id");
|
||||
}
|
||||
|
||||
io::write<size_t>(os, id);
|
||||
io::write<bool>(os, false);
|
||||
std::get<0>(internal::functions[id])(os, component);
|
||||
} else {
|
||||
auto new_id = component->_id;
|
||||
auto functions = internal::functions.find(new_id);
|
||||
|
||||
if (functions == internal::functions.end()) {
|
||||
throw std::runtime_error("No known serializer for id");
|
||||
}
|
||||
|
||||
io::write<size_t>(os, new_id);
|
||||
io::write<bool>(os, true);
|
||||
io::write<size_t>(os, id);
|
||||
std::get<0>(internal::functions[new_id])(os, component);
|
||||
auto functions = internal::functions.find(id);
|
||||
if (functions == internal::functions.end()) {
|
||||
throw std::runtime_error("No known serializer for id");
|
||||
}
|
||||
|
||||
io::write<size_t>(os, id);
|
||||
std::get<0>(internal::functions[id])(os, component);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,12 +49,7 @@ namespace ecs::serial {
|
||||
size_t component_count = io::read<size_t>(is);
|
||||
// std::cout << "Updating " << component_count << " components in entity: " << uuid << '\n';
|
||||
for (size_t i = 0; i < component_count; ++i) {
|
||||
size_t new_id = conversion[io::read<size_t>(is)];
|
||||
bool runtime = io::read<bool>(is);
|
||||
size_t id = new_id;
|
||||
if (runtime) {
|
||||
id = conversion[io::read<size_t>(is)];
|
||||
}
|
||||
size_t id = conversion[io::read<size_t>(is)];
|
||||
|
||||
// @todo We also need to be able to remove components
|
||||
// Sending a component with length 0 -> remove component
|
||||
@@ -75,22 +59,14 @@ namespace ecs::serial {
|
||||
// @todo What if the function does not exist?
|
||||
if (entity->has_components({id})) {
|
||||
// Update the component
|
||||
std::cout << "Updating component: " << id << " [" << ComponentID::get_name(id) << "]";
|
||||
if (new_id != id) {
|
||||
std::cout << " (base: " << new_id << " [" << ComponentID::get_name(new_id) << "])";
|
||||
}
|
||||
std::cout << '\n';
|
||||
std::cout << "Updating component: " << id << " [" << ComponentID::reverse_resolve(id) << "]\n";
|
||||
Component* component = entity->get_component(id);
|
||||
// @note We do not have to check if this exists as the entity already has the component
|
||||
std::get<1>(internal::functions[new_id])(is, component);
|
||||
std::get<1>(internal::functions[id])(is, component);
|
||||
} else {
|
||||
// Add new component
|
||||
std::cout << "Adding component: " << id << " [" << ComponentID::get_name(id) << "]";
|
||||
if (new_id != id) {
|
||||
std::cout << " (base: " << new_id << " [" << ComponentID::get_name(new_id) << "])";
|
||||
}
|
||||
std::cout << '\n';
|
||||
auto func = internal::functions.find(new_id);
|
||||
std::cout << "Adding component: " << id << " [" << ComponentID::reverse_resolve(id) << "]\n";
|
||||
auto func = internal::functions.find(id);
|
||||
if (func == internal::functions.end()) {
|
||||
throw std::runtime_error("No known serializers for component");
|
||||
}
|
||||
@@ -102,7 +78,7 @@ namespace ecs::serial {
|
||||
}
|
||||
|
||||
void serialize_ids(std::ostream& os) {
|
||||
auto& ids = ComponentID::_ids();
|
||||
auto& ids = ComponentID::get_map();
|
||||
|
||||
io::write<size_t>(os, ids.size());
|
||||
for (auto& [name, id] : ids) {
|
||||
@@ -117,7 +93,7 @@ namespace ecs::serial {
|
||||
std::string name = io::read<std::string>(is);
|
||||
size_t id = io::read<size_t>(is);
|
||||
|
||||
conversion[id] = ComponentID::get_id({name})[0];
|
||||
conversion[id] = ComponentID::resolve(name);
|
||||
}
|
||||
|
||||
for (auto [remote_id, local_id] : conversion) {
|
||||
|
||||
Reference in New Issue
Block a user