refactoring for how entities will be defined in code
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 26 Jan 2022 03:34:35 +0000 (21:34 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 26 Jan 2022 03:34:35 +0000 (21:34 -0600)
src/entity/manager.onyx
src/entity/player.onyx
src/main.onyx

index 1de9e4c8ccf781ffd25044fab01d5ca645714886..ab3ab42ba5cad1c0aa7dcc28d8a66dd42afa3aba 100644 (file)
@@ -2,14 +2,12 @@
 use package core
 use package glfw3
 
-Entity_Vtable :: struct {
+Entity_Handles :: struct {
     update : (entity: ^Entity, dt: f32) -> void = null_proc;
     draw   : (entity: ^Entity) -> void          = null_proc;
 }
 
 Entity :: struct {
-    use vtable: ^Entity_Vtable;
-
     id: u32;
     type: type_expr;
 
@@ -17,18 +15,21 @@ Entity :: struct {
 }
 
 IsEntity :: interface (e: $E) {
-    { e } -> ^Entity;
+    { e }         -> ^Entity;
+    { e.handles } -> Entity_Handles;
 }
 
 Entity_Manager :: struct {
     // The allocator for these entity pointers is assumed to be the
     // context allocator.
     entities: [..] ^Entity;
+    entity_types: Map(type_expr, Entity_Handles);
 
     next_entity_id: u32;
 
-    update   :: entity_manager_update;
     register :: entity_manager_register;
+    add      :: entity_manager_add;
+    update   :: entity_manager_update;
     draw     :: entity_manager_draw;
 }
 
@@ -36,6 +37,7 @@ entity_manager_make :: () -> Entity_Manager {
     em: Entity_Manager;
 
     array.init(^em.entities, 4);
+    map.init(^em.entity_types);
 
     // Entity ID 0 is reserved as a "empty / null" entity
     em.next_entity_id = 1;
@@ -43,7 +45,15 @@ entity_manager_make :: () -> Entity_Manager {
     return em;
 }
 
-entity_manager_register :: (use this: ^Entity_Manager, entity: ^$T) -> u32 where IsEntity(^T) {
+entity_manager_register :: (use this: ^Entity_Manager, $entity_type: type_expr) where IsEntity(^entity_type) {
+    if !entity_types->has(entity_type) {
+        entity_types[entity_type] = entity_type.handles;
+    }
+}
+
+entity_manager_add :: (use this: ^Entity_Manager, entity: ^$T) -> u32 where IsEntity(^T) {
+    this->register(T);
+
     entity.type = T;
     entity.id = next_entity_id;
     next_entity_id += 1;
@@ -54,22 +64,20 @@ entity_manager_register :: (use this: ^Entity_Manager, entity: ^$T) -> u32 where
 
 entity_manager_update :: (use this: ^Entity_Manager, dt: f32) {
     for entities {
-        if it.vtable == null do continue;
+        vtable := ^entity_types[it.type];
+        if vtable == null do continue;
 
-        if it.update != null_proc {
-            it->update(dt);
-        }
+        vtable.update(it, dt);
     }
 }
 
 entity_manager_draw :: (use this: ^Entity_Manager) {
     // Entities should be sorted by z-order.
     for entities {
-        if it.vtable == null do continue;
+        vtable := ^entity_types[it.type];
+        if vtable == null do continue;
 
-        if it.draw != null_proc {
-            it->draw();
-        }
+        vtable.draw(it);
     }
 }
 
index 8135d8d14d3e3081286a03a7f9369915d8f574bc..bd1b9b679fa57c63ac9f63a364f7df4212900c8f 100644 (file)
@@ -3,29 +3,28 @@ use package core
 use package glfw3
 
 Player :: struct {
-    use entity: Entity;
-}
+    handles :: Entity_Handles.{ update, draw }
 
-player_make :: () -> ^Player {
-    player := new(Player);
-    player.vtable = ^player_vtable;
-
-    player.pos = .{0,0};
-    return player;
-}
-
-player_update :: (use this: ^Player, dt: f32) {
-    if is_key_down(GLFW_KEY_W) do pos.y -= 200 * dt; 
-    if is_key_down(GLFW_KEY_S) do pos.y += 200 * dt; 
-    if is_key_down(GLFW_KEY_A) do pos.x -= 200 * dt; 
-    if is_key_down(GLFW_KEY_D) do pos.x += 200 * dt; 
-}
+    use entity: Entity;
 
-player_draw :: (use this: ^Player) {
-    immediate_set_color(.{1,1,1});
-    immediate_image(^player_texture, pos.x, pos.y, 64, 64);
+    make :: () -> ^Player {
+        player := new(Player);
+        player.pos = .{0,0};
+        return player;
+    }
+
+    update :: (use this: ^Player, dt: f32) {
+        if is_key_down(GLFW_KEY_W) do pos.y -= 200 * dt; 
+        if is_key_down(GLFW_KEY_S) do pos.y += 200 * dt; 
+        if is_key_down(GLFW_KEY_A) do pos.x -= 200 * dt; 
+        if is_key_down(GLFW_KEY_D) do pos.x += 200 * dt; 
+    }
+
+    draw :: (use this: ^Player) {
+        immediate_set_color(.{1,1,1});
+        immediate_image(^player_texture, pos.x, pos.y, 64, 64);
+    }
 }
 
-#local player_vtable := Entity_Vtable.{ update=player_update, draw=player_draw };
 
 player_texture: Texture;
index f82f9cf10a9bb12b692e71798a26835cfbe84448..bc23eb8f795b6d5ccd1fb554a6b2c841cc7c3317 100644 (file)
@@ -38,8 +38,8 @@ init :: () {
     main_font = font_lookup(.{"./assets/fonts/calibri.ttf", 32});
 
     entity_manager = entity_manager_make();
-    player := player_make();
-    entity_manager->register(player);
+    player := Player.make();
+    entity_manager->add(player);
 }
 
 update :: (dt: f32) {