From 3b8234655db6c223bf20e9cd9e8bfc149fb18c6a Mon Sep 17 00:00:00 2001
From: NukeBird <nukebird.dev@gmail.com>
Date: Sat, 15 Feb 2025 22:33:02 +0300
Subject: [PATCH] Bye-bye entity wrapper

---
 tests/zecsy.cpp | 81 ++++++++++++++++++++------------------------
 zecsy.hpp       | 90 ++++++-------------------------------------------
 2 files changed, 46 insertions(+), 125 deletions(-)

diff --git a/tests/zecsy.cpp b/tests/zecsy.cpp
index ca2b8e7..c94ebba 100644
--- a/tests/zecsy.cpp
+++ b/tests/zecsy.cpp
@@ -15,7 +15,6 @@ TEST_CASE("Create a single entity and verify its existence")
     auto e = w.make_entity();
     
     REQUIRE(w.is_alive(e));
-    REQUIRE(e.is_alive());
 }
 
 TEST_CASE("Destroy an entity and ensure it no longer exists in the world")
@@ -26,7 +25,6 @@ TEST_CASE("Destroy an entity and ensure it no longer exists in the world")
     w.destroy_entity(e);
     
     REQUIRE_FALSE(w.is_alive(e));
-    REQUIRE_FALSE(e.is_alive());
 }
 
 TEST_CASE("Entity #0 should be reserved and never used")
@@ -36,8 +34,7 @@ TEST_CASE("Entity #0 should be reserved and never used")
     auto e = w.make_entity();
 
     REQUIRE(e != 0);
-    REQUIRE(entity() == 0);
-    REQUIRE_FALSE(entity().is_alive());
+    REQUIRE_FALSE(w.is_alive(0));
 }
 
 struct ChoosenOne
@@ -52,7 +49,6 @@ TEST_CASE("Entity shouldn't have a component that wasn't attached to it")
     auto e = w.make_entity();
 
     REQUIRE_FALSE(w.has<ChoosenOne>(e));
-    REQUIRE_FALSE(e.has<ChoosenOne>());
 }
 
 TEST_CASE("Attempt of getting non-owned component should throw")
@@ -62,7 +58,6 @@ TEST_CASE("Attempt of getting non-owned component should throw")
     auto e = w.make_entity();
 
     REQUIRE_THROWS(w.get<ChoosenOne>(e));
-    REQUIRE_THROWS(e.get<ChoosenOne>());
 }
 
 TEST_CASE("Attach a simple component to an entity and verify it is correctly associated")
@@ -70,15 +65,13 @@ TEST_CASE("Attach a simple component to an entity and verify it is correctly ass
     world w;
 
     auto e1 = w.make_entity();
-    e1.set(ChoosenOne{});
+    w.set(e1, ChoosenOne{});
 
-    REQUIRE(e1.has<ChoosenOne>());
     REQUIRE(w.has<ChoosenOne>(e1));
 
     auto e2 = w.make_entity();
     w.set(e2, ChoosenOne{});
 
-    REQUIRE(e2.has<ChoosenOne>());
     REQUIRE(w.has<ChoosenOne>(e2));
 }
  
@@ -92,13 +85,13 @@ TEST_CASE("Retrieve a component from an entity and verify its data matches what
     world w;
 
     auto e = w.make_entity();
-    e.set(Name{"zecsy!"});
+    w.set(e, Name{"zecsy!"});
 
-    REQUIRE(e.get<Name>().value == "zecsy!");
+    REQUIRE(w.get<Name>(e).value == "zecsy!");
 
-    e.get<Name>().value = "super-zecsy!";
+    w.get<Name>(e).value = "super-zecsy!";
 
-    REQUIRE(e.get<Name>().value == "super-zecsy!");
+    REQUIRE(w.get<Name>(e).value == "super-zecsy!");
 }
 
 TEST_CASE("Remove a component from an entity and verify it is no longer attached")
@@ -106,12 +99,12 @@ TEST_CASE("Remove a component from an entity and verify it is no longer attached
     world w;
 
     auto e = w.make_entity();
-    e.set(ChoosenOne{});
-    REQUIRE_NOTHROW(e.remove<ChoosenOne>());
+    w.set(e, ChoosenOne{});
+    REQUIRE_NOTHROW(w.remove<ChoosenOne>(e));
 
-    REQUIRE_FALSE(e.has<ChoosenOne>());
+    REQUIRE_FALSE(w.has<ChoosenOne>(e));
 
-    e.set(ChoosenOne{});
+    w.set(e, ChoosenOne{});
     REQUIRE_NOTHROW(w.remove<ChoosenOne>(e));
 
     REQUIRE_FALSE(w.has<ChoosenOne>(e));
@@ -120,7 +113,7 @@ TEST_CASE("Remove a component from an entity and verify it is no longer attached
 TEST_CASE("Addresses of removed components should be reused")
 {
     world w; 
-    std::vector<entity> entities;
+    std::vector<entity_id> entities;
     std::vector<ChoosenOne*> addr;
 
     const int N = 4;
@@ -130,27 +123,27 @@ TEST_CASE("Addresses of removed components should be reused")
         for(int j = 0; j < N; ++j)
         {
             entities.emplace_back(w.make_entity());
-            entities.back().set<ChoosenOne>();
+            w.set<ChoosenOne>(entities.back());
         }
 
         if(addr.empty())
         {
             for(int j = 0; j < N; ++j)
             {
-                addr.emplace_back(&entities[j].get<ChoosenOne>());
+                addr.emplace_back(&w.get<ChoosenOne>(entities[j]));
             }
         }
         else 
         {
             for(int j = 0; j < N; ++j)
             {
-                REQUIRE(&entities[j].get<ChoosenOne>() == addr[j]);
+                REQUIRE(&w.get<ChoosenOne>(entities[j]) == addr[j]);
             }
         }
 
         for(auto e: entities)
         {
-            e.remove<ChoosenOne>();
+            w.remove<ChoosenOne>(e);
         }
         entities.clear();
     }
@@ -161,17 +154,15 @@ TEST_CASE("Attach multiple components to an entity and verify all are correctly
     world w;
 
     auto e = w.make_entity();
-    e.set(ChoosenOne{}, Name{"zecsy"});
+    w.set(e, ChoosenOne{}, Name{"zecsy"});
 
-    REQUIRE(e.has<ChoosenOne, Name>());
     REQUIRE(w.has<ChoosenOne, Name>(e));
 
-    e.remove<ChoosenOne, Name>();
+    w.remove<ChoosenOne, Name>(e);
 
-    REQUIRE_FALSE(e.has<ChoosenOne, Name>());
     REQUIRE_FALSE(w.has<ChoosenOne, Name>(e));
-    REQUIRE_FALSE(e.has<ChoosenOne>());
-    REQUIRE_FALSE(e.has<Name>());
+    REQUIRE_FALSE(w.has<ChoosenOne>(e));
+    REQUIRE_FALSE(w.has<Name>(e));
 }
 
 TEST_CASE("Create a simple system that processes entities with a specific component and verify it executes correctly")
@@ -184,11 +175,11 @@ TEST_CASE("Create a simple system that processes entities with a specific compon
     world w;
     auto e0 = w.make_entity(), e1 = w.make_entity();
 
-    e0.set<Component>(); //or e0.set(Component{})
-    e1.set(Component{20});
+    w.set<Component>(e0); //or e0.set(Component{})
+    w.set(e1, Component{20});
 
-    REQUIRE(e0.get<Component>().value == 0);
-    REQUIRE(e1.get<Component>().value == 20);
+    REQUIRE(w.get<Component>(e0).value == 0);
+    REQUIRE(w.get<Component>(e1).value == 20);
    
     /*
      * Really wanna deduce it to w.query([](Component&){}),
@@ -199,8 +190,8 @@ TEST_CASE("Create a simple system that processes entities with a specific compon
         c.value++;
     });
 
-    REQUIRE(e0.get<Component>().value == 1);
-    REQUIRE(e1.get<Component>().value == 21);
+    REQUIRE(w.get<Component>(e0).value == 1);
+    REQUIRE(w.get<Component>(e1).value == 21);
 }
 
 TEST_CASE("Test a system’s ability to query and process only entities with a specific combination of components")
@@ -218,18 +209,18 @@ TEST_CASE("Test a system’s ability to query and process only entities with a s
     world w;
 
     auto e0 = w.make_entity();
-    e0.set(C0{}, C1{});
+    w.set(e0, C0{}, C1{});
 
     auto e1 = w.make_entity();
-    e1.set(C0{});
+    w.set(e1, C0{});
 
     auto e2 = w.make_entity();
-    e2.set(C1{});
+    w.set(e2, C1{});
 
     int count = 0;
 
-    REQUIRE(e0.get<C0>().value == 0);
-    REQUIRE(e0.get<C1>().value == 10);
+    REQUIRE(w.get<C0>(e0).value == 0);
+    REQUIRE(w.get<C1>(e0).value == 10);
 
     w.query<C0, C1>([&count](C0& c0, C1& c1)
     {
@@ -237,12 +228,12 @@ TEST_CASE("Test a system’s ability to query and process only entities with a s
         c1.value++;
     });
 
-    REQUIRE(e0.get<C0>().value == 1);
-    REQUIRE(e0.get<C1>().value == 11);
+    REQUIRE(w.get<C0>(e0).value == 1);
+    REQUIRE(w.get<C1>(e0).value == 11);
 
-    REQUIRE(e1.get<C0>().value == 0);
-    REQUIRE(e2.get<C1>().value == 10);
+    REQUIRE(w.get<C0>(e1).value == 0);
+    REQUIRE(w.get<C1>(e2).value == 10);
 
-    REQUIRE_FALSE(e1.has<C1>());
-    REQUIRE_FALSE(e2.has<C0>());
+    REQUIRE_FALSE(w.has<C1>(e1));
+    REQUIRE_FALSE(w.has<C0>(e2));
 }
diff --git a/zecsy.hpp b/zecsy.hpp
index 7008783..0a2faf7 100644
--- a/zecsy.hpp
+++ b/zecsy.hpp
@@ -1,8 +1,6 @@
 #pragma once
-#include <catch2/internal/catch_console_colour.hpp>
 #include <cstdint>
 #include <format>
-#include <functional>
 #include <queue>
 #include <stdexcept>
 #include <typeindex>
@@ -22,36 +20,7 @@ namespace zecsy
      */
     using entities_set = std::set<entity_id>; 
 
-    class entity final
-    {
-    public:
-        entity(class world* w, entity_id id);
-
-        entity() = default;
-        operator entity_id() const;
-
-        bool is_alive() const;
-
-        template<typename... T>
-        bool has() const;
-
-        template<typename T>
-        T& get();
-
-        template<typename... T>
-        void set();
-
-        template<typename... T>
-        void set(const T&... comps);
-
-        template<typename... T>
-        void remove();
-    private:
-        entity_id id = 0;
-        class world* w = nullptr;
-    };
-
-    class component_storage
+    class component_storage final
     {
     public:
         template<typename T>
@@ -104,7 +73,7 @@ namespace zecsy
     class world final
     {
     public:
-        entity make_entity();
+        entity_id make_entity();
         void destroy_entity(entity_id e);
         bool is_alive(entity_id e) const; 
 
@@ -131,27 +100,12 @@ namespace zecsy
         component_storage storage;
     };
 
-    inline entity::entity(class world* w, entity_id id): w(w), id(id)
-    {
-
-    }
-
-    inline entity::operator entity_id() const 
-    {
-        return id;
-    }
-
-    inline bool entity::is_alive() const
-    {
-        return w && w->is_alive(id);
-    }
-
-    inline entity world::make_entity()
+    inline entity_id world::make_entity()
     {
         auto id = ++entity_counter;
         alive_entities.emplace(id);
 
-        return entity(this, id);
+        return id;
     }
 
     inline void world::destroy_entity(entity_id e)
@@ -191,30 +145,12 @@ namespace zecsy
         return *ptr;
     }
 
-    template<typename... T>
-    inline bool entity::has() const
-    {
-        return w->has<T...>(id);    
-    }
-
     template<typename T>
     inline T& world::get(entity_id e)
     {
         return storage.get<T>(e);
     }
 
-    template<typename T>
-    inline T& entity::get()
-    {
-        return w->get<T>(id);
-    }
-
-    template<typename... T>
-    inline void entity::set()
-    {
-        (set(T{}), ...);
-    }
-
     template<typename T>
     inline void component_storage::set(entity_id e, const T& comp)
     {
@@ -246,6 +182,12 @@ namespace zecsy
         indices_dict[typeid(T)][e] = index;
     }
     
+    template<typename T>
+    inline void component_storage::set(entity_id e)
+    {
+        set(e, T{});
+    }
+
     template<typename... T>
     inline void world::set(entity_id e)
     {
@@ -258,12 +200,6 @@ namespace zecsy
         storage.set(e, comps...);
     }
 
-    template<typename... T>
-    inline void entity::set(const T&... comps)
-    {
-        w->set(id, comps...);
-    }
-
     template<typename T>
     inline void component_storage::remove(entity_id e)
     {
@@ -283,12 +219,6 @@ namespace zecsy
         storage.remove<T...>(e);
     }
 
-    template<typename... T>
-    inline void entity::remove()
-    {
-        w->remove<T...>(id);
-    }
-
     template<typename... T>
     inline bool world::has(entity_id e) const
     {