Skip to content

Commit

Permalink
refactor(ecs): remove pack/unpack methods
Browse files Browse the repository at this point in the history
  • Loading branch information
RiscadoA committed Nov 19, 2023
1 parent 4e26cd9 commit 11b4030
Show file tree
Hide file tree
Showing 13 changed files with 9 additions and 232 deletions.
16 changes: 0 additions & 16 deletions core/include/cubos/core/ecs/component/manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,6 @@ namespace cubos::core::ecs
/// @copydoc storage(std::size_t)
const IStorage* storage(std::size_t id) const;

/// @brief Creates a package from a component of an entity.
/// @param id Entity index.
/// @param componentId Component identifier.
/// @param context Optional context to use for serialization.
/// @return Package containing the component.
data::old::Package pack(uint32_t id, std::size_t componentId, data::old::Context* context) const;

/// @brief Inserts a component into an entity, by unpacking a package.
/// @param id Entity index.
/// @param componentId Component identifier.
/// @param package Package to unpack.
/// @param context Optional context to use for deserialization.
/// @return Whether the unpacking was successful.
bool unpack(uint32_t id, std::size_t componentId, const data::old::Package& package,
data::old::Context* context);

private:
struct Entry
{
Expand Down
1 change: 1 addition & 0 deletions core/include/cubos/core/ecs/component/registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <optional>

#include <cubos/core/data/old/deserializer.hpp>
#include <cubos/core/data/old/serializer.hpp>
#include <cubos/core/ecs/blueprint.hpp>
#include <cubos/core/ecs/component/storage.hpp>
#include <cubos/core/memory/type_map.hpp>
Expand Down
43 changes: 0 additions & 43 deletions core/include/cubos/core/ecs/component/storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

#pragma once

#include <cubos/core/data/old/package.hpp>
#include <cubos/core/data/old/serialization_map.hpp>
#include <cubos/core/ecs/entity/manager.hpp>

namespace cubos::core::ecs
Expand Down Expand Up @@ -39,23 +37,6 @@ namespace cubos::core::ecs
/// @param index Index of the value to be retrieved.
/// @return Pointer to the value.
virtual const void* get(uint32_t index) const = 0;

/// @brief Packages a value. If the value doesn't exist, undefined behavior will occur.
/// @param index Index of the value to package.
/// @param context Optional context used for serialization.
/// @return Packaged value.
virtual data::old::Package pack(uint32_t index, data::old::Context* context) const = 0;

/// @brief Unpackages a value.
/// @param index Index of the value to unpackage.
/// @param package Package to unpackage.
/// @param context Optional context used for deserialization.
/// @return Whether the unpackaging was successful.
virtual bool unpack(uint32_t index, const data::old::Package& package, data::old::Context* context) = 0;

/// @brief Gets the type the components being stored here.
/// @return Component type.
virtual std::type_index type() const = 0;
};

/// @brief Abstract container for a component type @p T.
Expand All @@ -67,29 +48,5 @@ namespace cubos::core::ecs
public:
/// @brief Component type.
using Type = T;

// Implementation.

inline data::old::Package pack(uint32_t index, data::old::Context* context) const override
{
return data::old::Package::from(*static_cast<const T*>(this->get(index)), context);
}

inline bool unpack(uint32_t index, const data::old::Package& package, data::old::Context* context) override
{
T value;
if (package.into(value, context))
{
this->insert(index, &value);
return true;
}

return false;
}

inline std::type_index type() const override
{
return std::type_index(typeid(T));
}
};
} // namespace cubos::core::ecs
2 changes: 2 additions & 0 deletions core/include/cubos/core/ecs/resource/manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

#pragma once

#include <functional>
#include <shared_mutex>
#include <typeindex>
#include <unordered_map>
#include <utility>

#include <cubos/core/ecs/world.hpp>
#include <cubos/core/log.hpp>

namespace cubos::core::ecs
{
Expand Down
1 change: 1 addition & 0 deletions core/include/cubos/core/ecs/system/commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <unordered_map>
#include <unordered_set>

#include <cubos/core/data/old/serialization_map.hpp>
#include <cubos/core/ecs/entity/hash.hpp>
#include <cubos/core/ecs/world.hpp>
#include <cubos/core/memory/any_value.hpp>
Expand Down
1 change: 1 addition & 0 deletions core/include/cubos/core/ecs/system/system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <functional>
#include <typeindex>
#include <unordered_set>
#include <variant>

#include <cubos/core/ecs/system/accessors.hpp>
#include <cubos/core/ecs/system/commands.hpp>
Expand Down
17 changes: 1 addition & 16 deletions core/include/cubos/core/ecs/world.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <cubos/core/ecs/entity/manager.hpp>
#include <cubos/core/ecs/resource/manager.hpp>
#include <cubos/core/log.hpp>
#include <cubos/core/reflection/external/cstring.hpp>
#include <cubos/core/reflection/external/string.hpp>
#include <cubos/core/reflection/external/string_view.hpp>
#include <cubos/core/reflection/type.hpp>
Expand Down Expand Up @@ -96,22 +97,6 @@ namespace cubos::core::ecs
/// @copydoc components(Entity)
ConstComponents components(Entity entity) const;

/// @brief Creates a package from the components of an entity.
/// @param entity Entity identifier.
/// @param context Optional context for serializing the components.
/// @return Package containing the components of the entity.
data::old::Package pack(Entity entity, data::old::Context* context = nullptr) const;

/// @brief Unpacks components specified in a package into an entity.
///
/// Removes any components that are already present in the entity.
///
/// @param entity Entity identifier.
/// @param package Package to unpack.
/// @param context Optional context for deserializing the components.
/// @return Whether the package was unpacked successfully.
bool unpack(Entity entity, const data::old::Package& package, data::old::Context* context = nullptr);

/// @brief Returns an iterator which points to the first entity of the world.
/// @return Iterator.
Iterator begin() const;
Expand Down
12 changes: 1 addition & 11 deletions core/src/cubos/core/ecs/component/manager.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cubos/core/ecs/component/manager.hpp>
#include <cubos/core/ecs/component/registry.hpp>
#include <cubos/core/log.hpp>
#include <cubos/core/reflection/external/primitives.hpp>
#include <cubos/core/reflection/external/string.hpp>
#include <cubos/core/reflection/type.hpp>
Expand Down Expand Up @@ -74,14 +75,3 @@ ComponentManager::Entry::Entry(std::unique_ptr<IStorage> storage)
{
this->mutex = std::make_unique<std::shared_mutex>();
}

data::old::Package ComponentManager::pack(uint32_t id, std::size_t componentId, data::old::Context* context) const
{
return mEntries[componentId - 1].storage->pack(id, context);
}

bool ComponentManager::unpack(uint32_t id, std::size_t componentId, const data::old::Package& package,
data::old::Context* context)
{
return mEntries[componentId - 1].storage->unpack(id, package, context);
}
59 changes: 0 additions & 59 deletions core/src/cubos/core/ecs/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,65 +45,6 @@ World::ConstComponents World::components(Entity entity) const
return ConstComponents{*this, entity};
}

data::old::Package World::pack(Entity entity, data::old::Context* context) const
{
CUBOS_ASSERT(this->isAlive(entity), "Entity is not alive");

Entity::Mask mask = mEntityManager.getMask(entity);

auto pkg = data::old::Package(data::old::Package::Type::Object);
for (std::size_t i = 1; i < mask.size(); ++i)
{
if (mask.test(i))
{
auto name = mComponentManager.getType(i).name();
pkg.fields().push_back({name, mComponentManager.pack(entity.index, i, context)});
}
}

return pkg;
}

bool World::unpack(Entity entity, const data::old::Package& package, data::old::Context* context)
{
if (package.type() != data::old::Package::Type::Object)
{
CUBOS_ERROR("Entities must be packaged as objects");
return false;
}

// Remove all existing components.
mComponentManager.removeAll(entity.index);

Entity::Mask mask{1};
bool success = true;

for (const auto& field : package.fields())
{
const auto* type = Registry::type(field.first);
if (type == nullptr)
{
CUBOS_ERROR("Unknown component type '{}'", field.first);
success = false;
continue;
}

auto id = mComponentManager.getID(*type);
if (mComponentManager.unpack(entity.index, id, field.second, context))
{
mask.set(id);
}
else
{
CUBOS_ERROR("Could not unpack component '{}'", field.first);
success = false;
}
}

mEntityManager.setMask(entity, mask);
return success;
}

World::Iterator World::begin() const
{
return mEntityManager.begin();
Expand Down
13 changes: 1 addition & 12 deletions core/tests/ecs/blueprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#include "utils.hpp"

using cubos::core::data::old::Package;
using cubos::core::data::old::Unpackager;
using cubos::core::ecs::Blueprint;
using cubos::core::ecs::CommandBuffer;
using cubos::core::ecs::Commands;
Expand Down Expand Up @@ -51,16 +49,7 @@ TEST_CASE("ecs::Blueprint")
auto bar = blueprint.create("bar");
auto baz = blueprint.create("baz");
blueprint.add(baz, IntegerComponent{2});

// Add a ParentComponent to "baz" with id = "bar", using a deserializer.
{
// Pack the identifier of "bar".
auto barPkg = Package::from(bar);

// Unpack the identifier of "bar" into a ParentComponent.
Unpackager unpackager{barPkg};
Registry::create("ParentComponent", unpackager, blueprint, baz);
}
blueprint.add(baz, ParentComponent{bar});

SUBCASE("spawn the blueprint")
{
Expand Down
21 changes: 0 additions & 21 deletions core/tests/ecs/registry.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
#include <doctest/doctest.h>

#include <cubos/core/ecs/blueprint.hpp>
#include <cubos/core/ecs/component/registry.hpp>
#include <cubos/core/ecs/component/vec_storage.hpp>
#include <cubos/core/ecs/system/commands.hpp>
#include <cubos/core/reflection/external/primitives.hpp>

#include "utils.hpp"

using cubos::core::data::old::Package;
using cubos::core::data::old::Unpackager;
using cubos::core::ecs::Blueprint;
using cubos::core::ecs::CommandBuffer;
using cubos::core::ecs::Commands;
using cubos::core::ecs::Registry;
Expand All @@ -23,8 +19,6 @@ TEST_CASE("ecs::Registry")
World world{};
CommandBuffer cmdBuffer{world};
Commands cmds{cmdBuffer};
Blueprint blueprint{};
auto entity = blueprint.create("entity");

// Initially type int isn't registered.
CHECK(Registry::type("int") == nullptr);
Expand All @@ -37,19 +31,4 @@ TEST_CASE("ecs::Registry")
// Create a storage for it and check if its of the correct type.
auto storage = Registry::createStorage(reflect<int>());
CHECK(dynamic_cast<VecStorage<int>*>(storage.get()) != nullptr);

// Instantiate the component into a blueprint, from a package.
auto pkg = Package::from<int>(42);
Unpackager unpackager{pkg};
REQUIRE(Registry::create("int", unpackager, blueprint, entity));

// Spawn the blueprint into the world.
world.registerComponent<int>();
entity = cmds.spawn(blueprint).entity("entity");
cmdBuffer.commit();

// Package the entity and check if the component was correctly instantiated.
pkg = world.pack(entity);
REQUIRE(pkg.fields().size() == 1);
CHECK(pkg.field("int").get<int>() == 42);
}
54 changes: 0 additions & 54 deletions core/tests/ecs/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#include "utils.hpp"

using cubos::core::data::old::Package;
using cubos::core::ecs::Entity;
using cubos::core::ecs::World;

Expand Down Expand Up @@ -82,59 +81,6 @@ TEST_CASE("ecs::World")
CHECK(destroyed);
}

SUBCASE("add and remove components through pack and unpack")
{
// Create an entity.
auto foo = world.create();

// Add an integer component.
auto pkg = world.pack(foo);
pkg.fields().emplace_back("IntegerComponent", Package::from(1));
CHECK(world.unpack(foo, pkg));
CHECK(world.components(foo).has<IntegerComponent>());
CHECK_FALSE(world.components(foo).has<ParentComponent>());

// Check if the component was added.
pkg = world.pack(foo);
CHECK(pkg.fields().size() == 1);
CHECK(pkg.field("IntegerComponent").get<int>() == 1);

// Remove the integer component and add a parent component.
pkg.removeField("IntegerComponent");
pkg.fields().emplace_back("ParentComponent", Package::from(Entity{}));
CHECK(world.unpack(foo, pkg));
CHECK_FALSE(world.components(foo).has<IntegerComponent>());
CHECK(world.components(foo).has<ParentComponent>());

// Check if the component was added.
pkg = world.pack(foo);
CHECK(pkg.fields().size() == 1);
CHECK(pkg.field("ParentComponent").get<Entity>().isNull());
}

SUBCASE("change a component through pack and unpack")
{
// Create an entity which has an integer component and a parent component.
auto bar = world.create();
auto foo = world.create();
world.components(foo).add(IntegerComponent{0}).add(ParentComponent{bar});
CHECK(world.components(foo).has<IntegerComponent>());
CHECK(world.components(foo).has<ParentComponent>());

// Change the value of the integer component.
auto pkg = world.pack(foo);
pkg.field("IntegerComponent").set<int>(1);
CHECK(world.unpack(foo, pkg));
CHECK(world.components(foo).has<IntegerComponent>());
CHECK(world.components(foo).has<ParentComponent>());

// Check if the value was changed.
pkg = world.pack(foo);
CHECK(pkg.fields().size() == 2);
CHECK(pkg.field("IntegerComponent").get<int>() == 1);
CHECK(pkg.field("ParentComponent").get<Entity>() == bar);
}

SUBCASE("components are correctly destructed when their entity is destroyed")
{
bool destroyed = false;
Expand Down
1 change: 1 addition & 0 deletions engine/src/cubos/engine/scene/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cubos/core/ecs/component/registry.hpp>
#include <cubos/core/ecs/entity/hash.hpp>
#include <cubos/core/log.hpp>
#include <cubos/core/reflection/external/cstring.hpp>
#include <cubos/core/reflection/external/string.hpp>
#include <cubos/core/reflection/external/unordered_map.hpp>

Expand Down

0 comments on commit 11b4030

Please sign in to comment.