entities know what schematic created them
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 26 Feb 2022 03:16:35 +0000 (21:16 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 26 Feb 2022 03:16:35 +0000 (21:16 -0600)
src/entity/editor.onyx
src/entity/manager.onyx
src/entity/store.onyx

index 49701c03f4cbd6cd1469cce135312e360f729de1..25a74f0b85346125f1ebeb3d451668dfb8e13db4 100644 (file)
@@ -55,8 +55,9 @@ editor_update :: (dt: f32) {
     mouse_pos := mouse_get_position_vector();
 
     if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) && mouse_pos.x < ~~window_width - sidebar_width && mouse_pos.y > menubar_height {
-        entity_create := scene.schematics.entries[active_index].value;
-        entity := entity_create(^scene);
+        schematic := scene.schematics.entries[active_index].value;
+        entity := schematic.create(^scene);
+        entity.schematic = schematic.type;
         scene->add(entity);
 
         entity.pos = mouse_pos;
index d69f3cf804a17a9cc2b3befcdcef56c3807a66f1..4448519ad89a5cfde29177fb1f720459f480674b 100644 (file)
@@ -46,7 +46,7 @@ InteractableComponent :: struct {
 Entity :: struct {
     id: Entity_ID;
     flags: Entity_Flags;
-    schematic := "Custom";
+    schematic: type_expr;
 
     pos:  Vector2;
 
@@ -76,6 +76,7 @@ Entity_Flags :: enum #flags {
 
 Entity_Schematic :: struct {
     create: (^Entity_Manager) -> ^Entity;
+    type := void; // This will be filled out at runtime.
 }
 
 Entity_Manager :: struct {
@@ -85,7 +86,7 @@ Entity_Manager :: struct {
     entities: [..] ^Entity;
     entity_map: Map(Entity_ID, ^Entity);
 
-    schematics: Map(str, (^Entity_Manager) -> ^Entity);
+    schematics: Map(str, ^Entity_Schematic);
 
     next_entity_id: Entity_ID;
 
@@ -102,6 +103,8 @@ Entity_Manager :: struct {
     create_component :: entity_manager_create_component;
     create_and_add :: entity_manager_create_and_add;
 
+    create_from_schematic :: entity_manager_create_from_schematic;
+
     load_from_file :: entity_manager_load_from_file;
     save_to_file   :: entity_manager_save_to_file;
 }
@@ -122,15 +125,22 @@ entity_manager_create :: () -> Entity_Manager {
 #local entity_manager_load_schematics :: (use this: ^Entity_Manager) {
     use type_info;
 
+    index := 0;
     for type_table {
+        defer index += 1;
         if it.kind != .Struct do continue;
 
         s_info := cast(^Type_Info_Struct) it;
         for^ s_info.tags {
             if it.type == Entity_Schematic {
                 schematic := cast(^Entity_Schematic) it.data;
+
+                // This is (mostly) safe to do as this data is in static memory
+                // and is not shared with any other type info.
+                schematic.type = cast(type_expr) index;
+
                 // This is safe to use as the key, as a struct's name exists in static memory.
-                schematics[s_info.name] = schematic.create;
+                schematics[s_info.name] = schematic;
 
                 debug_log(.Debug, "Discovered schematic: '{}'", s_info.name);
             }
@@ -159,6 +169,15 @@ entity_manager_make :: (use this: ^Entity_Manager) -> ^Entity {
     return entity;
 }
 
+entity_manager_create_from_schematic :: (use this: ^Entity_Manager, schematic_name: str) -> ^Entity {
+    schematic := schematics[schematic_name];
+    if schematic == null do return null;
+
+    entity := schematic.create(this);
+    entity.schematic = schematic.type;
+    return entity;
+}
+
 entity_manager_create_component :: (use this: ^Entity_Manager, $component_type: type_expr) -> ^component_type where IsComponent(^component_type) {
     comp := new(component_type, allocator=entity_allocator);
     comp.type = component_type;
index 74bb53cf99d4138aa781e64855d5ebcf241aba80..5c05ceee3a69e460965fa883b614798109efa5ab 100644 (file)
@@ -106,16 +106,15 @@ entity_manager_load_from_file :: (use this: ^Entity_Manager, filename: str) {
 
             entity_kind := string.advance(line)
                         |> (x => str.{x.data, x.count - 1})(); // In the grossest way possible remove one character from the end.
-            
-            schematic := schematics[entity_kind];
-            if schematic == null_proc {
+
+            debug_log(.Debug, "Creating entity from schematic: {}.", entity_kind);
+            current_entity = this->create_from_schematic(entity_kind);
+            if current_entity == null {
                 debug_log(.Error, "Unknown entity kind '{}' on line {}.", entity_kind, line_number);
                 current_entity = null;
                 continue;
             }
 
-            debug_log(.Debug, "Creating entity from schematic: {}.", entity_kind);
-            current_entity = schematic(this);
             continue;
         }