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;
Entity :: struct {
id: Entity_ID;
flags: Entity_Flags;
- schematic := "Custom";
+ schematic: type_expr;
pos: Vector2;
Entity_Schematic :: struct {
create: (^Entity_Manager) -> ^Entity;
+ type := void; // This will be filled out at runtime.
}
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;
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;
}
#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);
}
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;
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;
}