diff --git a/core/scene.jai b/core/scene.jai index ef8a64e..134c232 100644 --- a/core/scene.jai +++ b/core/scene.jai @@ -6,6 +6,7 @@ #placeholder delete_entity; #placeholder serialize_entity; #placeholder deserialize_entity; +#placeholder duplicate_entity; MAX_CACHED_PILES :: 8; last_unnamed_scene_id := 0; diff --git a/editor/editor_ui.jai b/editor/editor_ui.jai index d28aebd..19630eb 100644 --- a/editor/editor_ui.jai +++ b/editor/editor_ui.jai @@ -264,30 +264,23 @@ base_editor_update :: () { engine.editor.selected_entities.count = 0; } + + if key_pressed(.CTRL) && key_down(.D) { + duplicated_entities: [..] *Entity; + duplicated_entities.allocator = temp; + + for e: engine.editor.selected_entities { + array_add(*duplicated_entities, duplicate_entity(e)); + } + + engine.editor.selected_entities.count = 0; + + for e: duplicated_entities { + array_add(*engine.editor.selected_entities, e); + } + } } - //if entity != null { - // // @Incomplete:@Incomplete: Duplicate - // //if key_pressed(.CTRL) && key_down(.D) { - // // make_directory_if_it_does_not_exist("../temp"); - // // save_entity(entity, "../temp/", "temp"); - // // duplicated := load_entity(editor_scene, "../temp/temp.ent"); - // // entity = duplicated; - // //} - - // // DELETE - // // DELETE - // //if key_down(.DELETE) || key_down(.BACKSPACE) { - // // delete_entity(entity); - // // entity = null; - // // editor.transform_gizmo.selected_axis = .NONE; - // //} - //} - - //if key_pressed(.CTRL) && key_down(.Z) { - // editor_undo(); - //} - if engine.mode == .EDITING { if key_pressed(.MOUSE_RIGHT) { set_show_cursor(false); diff --git a/metaprogram.jai b/metaprogram.jai index 8f1fbba..986ec94 100644 --- a/metaprogram.jai +++ b/metaprogram.jai @@ -132,6 +132,32 @@ generate_member_deserialization :: (type: *Type_Info_Struct, builder: *String_Bu } } +generate_member_copy :: (type: *Type_Info_Struct, builder: *String_Builder, path: string = "") { + for type.members { + if should_serialize(type, it) { + new_path : string; + if path.count == 0 { + new_path = it.name; + } else { + new_path = tprint("%1.%2", path, it.name); + } + + if it.type.type == { + case .STRUCT; { + info_struct := cast(*Type_Info_Struct) it.type; + generate_member_copy(info_struct, builder, new_path); + } + case .BOOL; #through; + case .FLOAT; #through; + case .ENUM; #through; + case .INTEGER; { + print_to_builder(builder, "\tcopy.% = e.%;\n", new_path, new_path); + } + } + } + } +} + generate_serialize_procedure_for_entity :: (code_struct: *Code_Struct) { name := code_struct.defined_type.name; @@ -162,6 +188,18 @@ generate_serialize_procedure_for_entity :: (code_struct: *Code_Struct) { print_to_builder(*deserialize, "}\n"); array_add(*entity_serialize_proc_string, builder_to_string(*deserialize)); + + // Duplicate + duplicate : String_Builder; + print_to_builder(*duplicate, "duplicate_entity :: (e: *%) -> *% {\n", name, name); + print_to_builder(*duplicate, "\tcopy := new_%();\n", to_lower_copy_new(name,,allocator=temp)); + + generate_member_copy(code_struct.defined_type, *duplicate); + + print_to_builder(*duplicate, "\treturn copy;\n"); + print_to_builder(*duplicate, "}\n"); + + array_add(*entity_serialize_proc_string, builder_to_string(*duplicate)); } note_struct :: (code_struct: *Code_Struct) { @@ -280,6 +318,17 @@ generate_code :: (w: Workspace) { add_build_string(build_string, w); } + { + builder: String_Builder; + + for entity_type_names { + print_to_builder(*builder, "\tcase %1; return duplicate_entity(cast(*%1)e);\n", it); + } + + build_string := sprint(DUPLICATE_ENTITY, builder_to_string(*builder)); + add_build_string(build_string, w); + } + { builder: String_Builder; @@ -384,6 +433,16 @@ deserialize_entity :: (scene: *Scene, id: Entity_Id, path: string) -> *Entity { return e; } + +DONE +DUPLICATE_ENTITY :: #string DONE +duplicate_entity :: (e: *Entity) -> *Entity { + if e.type == { + %1 + } + + return e; +} DONE INIT_SCENE :: #string DONE