From d3c1f2a7f69a54652a2a07eaca402db2ee489132 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 14 Sep 2017 19:38:38 -0300 Subject: [PATCH] Re-Added export plugins with a more interesting API, as well as the ability to do path remapping. Also added ability to tell the exporter that a shared object needs to be bundled in the build. --- editor/editor_export.cpp | 110 +++++++++++++++++++++++++++++++++++++-- editor/editor_export.h | 43 ++++++++++++++- editor/editor_node.cpp | 41 +++++++-------- editor/editor_plugin.cpp | 10 ++++ editor/editor_plugin.h | 3 ++ 5 files changed, 179 insertions(+), 28 deletions(-) diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 8623b9acdba..a55ede7e418 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -476,19 +476,66 @@ void EditorExportPlatform::_edit_filter_list(Set &r_list, const String & memdelete(da); } -Error EditorExportPlatform::export_project_files(const Ref &p_preset, EditorExportSaveFunction p_func, void *p_udata) { +void EditorExportPlugin::add_file(const String &p_path, const Vector &p_file, bool p_remap) { + + ExtraFile ef; + ef.data = p_file; + ef.path = p_path; + ef.remap = p_remap; + extra_files.push_back(ef); +} + +void EditorExportPlugin::add_shared_object(const String &p_path) { + + shared_objects.push_back(p_path); +} + +void EditorExportPlugin::_export_file_script(const String &p_path, const PoolVector &p_features) { + + if (get_script_instance()) { + get_script_instance()->call("_export_file", p_path, p_features); + } +} + +void EditorExportPlugin::_export_file(const String &p_path, const Set &p_features) { +} + +void EditorExportPlugin::skip() { + + skipped = true; +} + +void EditorExportPlugin::_bind_methods() { + + ClassDB::bind_method(D_METHOD("add_shared_object", "path"), &EditorExportPlugin::add_shared_object); + ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file); + ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip); + + BIND_VMETHOD(MethodInfo("_export_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::POOL_STRING_ARRAY, "features"))); +} + +EditorExportPlugin::EditorExportPlugin() { + skipped = false; +} + +Error EditorExportPlatform::export_project_files(const Ref &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) { Ref platform = p_preset->get_platform(); List feature_list; platform->get_preset_features(p_preset, &feature_list); //figure out features Set features; + PoolVector features_pv; for (List::Element *E = feature_list.front(); E; E = E->next()) { features.insert(E->get()); + features_pv.push_back(E->get()); } + Vector > export_plugins = EditorExport::get_singleton()->get_export_plugins(); + //figure out paths of files that will be exported Set paths; + Vector path_remaps; if (p_preset->get_export_filter() == EditorExportPreset::EXPORT_ALL_RESOURCES) { //find stuff @@ -551,9 +598,42 @@ Error EditorExportPlatform::export_project_files(const Ref & p_func(p_udata, path + ".import", array, idx, total); } else { + + bool do_export = true; + for (int i = 0; i < export_plugins.size(); i++) { + if (export_plugins[i]->get_script_instance()) { //script based + export_plugins[i]->_export_file_script(path, features_pv); + } else { + export_plugins[i]->_export_file(path, features); + } + if (p_so_func) { + for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) { + p_so_func(p_udata, export_plugins[i]->shared_objects[j]); + } + } + + for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) { + p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total); + if (export_plugins[i]->extra_files[j].remap) { + do_export = false; //if remap, do not + path_remaps.push_back(path); + path_remaps.push_back(export_plugins[i]->extra_files[j].path); + } + } + + if (export_plugins[i]->skipped) { + do_export = false; + } + export_plugins[i]->_clear(); + + if (!do_export) + break; //apologies, not exporting + } //just store it as it comes - Vector array = FileAccess::get_file_as_array(path); - p_func(p_udata, path, array, idx, total); + if (do_export) { + Vector array = FileAccess::get_file_as_array(path); + p_func(p_udata, path, array, idx, total); + } } idx++; @@ -575,9 +655,14 @@ Error EditorExportPlatform::export_project_files(const Ref & } } + ProjectSettings::CustomMap custom_map; + if (path_remaps.size()) { + custom_map["path_remap/remapped_paths"] = path_remaps; + } + String config_file = "project.binary"; String engine_cfb = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp" + config_file; - ProjectSettings::get_singleton()->save_custom(engine_cfb, ProjectSettings::CustomMap(), custom_list); + ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list); Vector data = FileAccess::get_file_as_array(engine_cfb); p_func(p_udata, "res://" + config_file, data, idx, total); @@ -867,6 +952,23 @@ void EditorExport::remove_export_preset(int p_idx) { export_presets.remove(p_idx); } +void EditorExport::add_export_plugin(const Ref &p_plugin) { + + if (export_plugins.find(p_plugin) == 1) { + export_plugins.push_back(p_plugin); + } +} + +void EditorExport::remove_export_plugin(const Ref &p_plugin) { + + export_plugins.erase(p_plugin); +} + +Vector > EditorExport::get_export_plugins() { + + return export_plugins; +} + void EditorExport::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { diff --git a/editor/editor_export.h b/editor/editor_export.h index 3b99c68c854..6b8164681f5 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -124,6 +124,7 @@ class EditorExportPlatform : public Reference { public: typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector &p_data, int p_file, int p_total); + typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const String &p_path); private: struct SavedData { @@ -189,7 +190,7 @@ public: virtual String get_name() const = 0; virtual Ref get_logo() const = 0; - Error export_project_files(const Ref &p_preset, EditorExportSaveFunction p_func, void *p_udata); + Error export_project_files(const Ref &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = NULL); Error save_pack(const Ref &p_preset, const String &p_path); Error save_zip(const Ref &p_preset, const String &p_path); @@ -219,11 +220,47 @@ public: EditorExportPlatform(); }; +class EditorExportPlugin : public Reference { + GDCLASS(EditorExportPlugin, Reference) + + friend class EditorExportPlatform; + + Vector shared_objects; + struct ExtraFile { + String path; + Vector data; + bool remap; + }; + Vector extra_files; + bool skipped; + + _FORCE_INLINE_ void _clear() { + shared_objects.clear(); + extra_files.clear(); + skipped = false; + } + + void _export_file_script(const String &p_path, const PoolVector &p_features); + +protected: + void add_file(const String &p_path, const Vector &p_file, bool p_remap); + void add_shared_object(const String &p_path); + void skip(); + + virtual void _export_file(const String &p_path, const Set &p_features); + + static void _bind_methods(); + +public: + EditorExportPlugin(); +}; + class EditorExport : public Node { GDCLASS(EditorExport, Node); Vector > export_platforms; Vector > export_presets; + Vector > export_plugins; Timer *save_timer; bool block_save; @@ -251,6 +288,10 @@ public: Ref get_export_preset(int p_idx); void remove_export_preset(int p_idx); + void add_export_plugin(const Ref &p_plugin); + void remove_export_plugin(const Ref &p_plugin); + Vector > get_export_plugins(); + void load_config(); bool poll_export_platforms(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 4bcf5a49e67..3f0520379ab 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -254,7 +254,7 @@ void EditorNode::_notification(int p_what) { get_tree()->get_root()->set_as_audio_listener_2d(false); get_tree()->set_auto_accept_quit(false); get_tree()->connect("files_dropped", this, "_dropped_files"); - property_editable_warning->set_icon(gui_base->get_icon("NodeWarning","EditorIcons")); + property_editable_warning->set_icon(gui_base->get_icon("NodeWarning", "EditorIcons")); } if (p_what == NOTIFICATION_EXIT_TREE) { @@ -1436,18 +1436,18 @@ void EditorNode::_edit_current() { EditorNode::get_singleton()->get_import_dock()->set_edit_path(current_res->get_path()); int subr_idx = current_res->get_path().find("::"); - if (subr_idx!=-1) { - String base_path=current_res->get_path().substr(0,subr_idx); - if (FileAccess::exists(base_path+".import")) { - editable_warning=TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); + if (subr_idx != -1) { + String base_path = current_res->get_path().substr(0, subr_idx); + if (FileAccess::exists(base_path + ".import")) { + editable_warning = TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } else { - if (!get_edited_scene() || get_edited_scene()->get_filename()!=base_path) { - editable_warning=TTR("This resource belongs to a scene that was instanced or inherited.\nChanges to it will not be kept when saving the current scene."); + if (!get_edited_scene() || get_edited_scene()->get_filename() != base_path) { + editable_warning = TTR("This resource belongs to a scene that was instanced or inherited.\nChanges to it will not be kept when saving the current scene."); } } - } else if (current_res->get_path().is_resource_file()){ - if (FileAccess::exists(current_res->get_path()+".import")) { - editable_warning=TTR("This resource was imported, so it's not editable. Change it's settings in the import panel and re-import."); + } else if (current_res->get_path().is_resource_file()) { + if (FileAccess::exists(current_res->get_path() + ".import")) { + editable_warning = TTR("This resource was imported, so it's not editable. Change it's settings in the import panel and re-import."); } } } else if (is_node) { @@ -1465,10 +1465,10 @@ void EditorNode::_edit_current() { } object_menu->get_popup()->clear(); - if (get_edited_scene() && get_edited_scene()->get_filename()!=String()) { + if (get_edited_scene() && get_edited_scene()->get_filename() != String()) { String source_scene = get_edited_scene()->get_filename(); - if (FileAccess::exists(source_scene+".import")) { - editable_warning=TTR("This scene was imported, so changes to it will not be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); + if (FileAccess::exists(source_scene + ".import")) { + editable_warning = TTR("This scene was imported, so changes to it will not be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } } @@ -1478,10 +1478,9 @@ void EditorNode::_edit_current() { node_dock->set_node(NULL); } - if (editable_warning!=String()) { + if (editable_warning != String()) { property_editable_warning->show(); //hide by default property_editable_warning_dialog->set_text(editable_warning); - } /* Take care of PLUGIN EDITOR */ @@ -3252,9 +3251,9 @@ void EditorNode::register_editor_types() { ClassDB::register_class(); ClassDB::register_virtual_class(); ClassDB::register_virtual_class(); + ClassDB::register_class(); // FIXME: Is this stuff obsolete, or should it be ported to new APIs? - //ClassDB::register_class(); //ClassDB::register_class(); //ClassDB::register_type(); } @@ -4511,8 +4510,6 @@ void EditorNode::_bind_methods() { ClassDB::bind_method("_toggle_distraction_free_mode", &EditorNode::_toggle_distraction_free_mode); ClassDB::bind_method("_property_editable_warning_pressed", &EditorNode::_property_editable_warning_pressed); - - ClassDB::bind_method(D_METHOD("get_gui_base"), &EditorNode::get_gui_base); ClassDB::bind_method(D_METHOD("_bottom_panel_switch"), &EditorNode::_bottom_panel_switch); @@ -5273,14 +5270,13 @@ EditorNode::EditorNode() { search_bar->add_child(clear_button); clear_button->connect("pressed", this, "_clear_search_box"); - property_editable_warning = memnew (Button); + property_editable_warning = memnew(Button); property_editable_warning->set_text(TTR("Changes may be lost!")); prop_editor_base->add_child(property_editable_warning); - property_editable_warning_dialog = memnew( AcceptDialog ); + property_editable_warning_dialog = memnew(AcceptDialog); gui_base->add_child(property_editable_warning_dialog); property_editable_warning->hide(); - property_editable_warning->connect("pressed",this,"_property_editable_warning_pressed"); - + property_editable_warning->connect("pressed", this, "_property_editable_warning_pressed"); property_editor = memnew(PropertyEditor); property_editor->set_autoclear(true); @@ -5302,7 +5298,6 @@ EditorNode::EditorNode() { dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(import_dock); import_dock->set_name(TTR("Import")); - bool use_single_dock_column = (OS::get_singleton()->get_screen_size(OS::get_singleton()->get_current_screen()).x < 1200); node_dock = memnew(NodeDock); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 86acfcc50e2..246599be11c 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -530,6 +530,14 @@ void EditorPlugin::remove_import_plugin(const Ref &p_importe EditorFileSystem::get_singleton()->scan(); } +void EditorPlugin::add_export_plugin(const Ref &p_exporter) { + EditorExport::get_singleton()->add_export_plugin(p_exporter); +} + +void EditorPlugin::remove_export_plugin(const Ref &p_exporter) { + EditorExport::get_singleton()->remove_export_plugin(p_exporter); +} + void EditorPlugin::set_window_layout(Ref p_layout) { if (get_script_instance() && get_script_instance()->has_method("set_window_layout")) { @@ -585,6 +593,8 @@ void EditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("queue_save_layout"), &EditorPlugin::queue_save_layout); ClassDB::bind_method(D_METHOD("add_import_plugin", "importer"), &EditorPlugin::add_import_plugin); ClassDB::bind_method(D_METHOD("remove_import_plugin", "importer"), &EditorPlugin::remove_import_plugin); + ClassDB::bind_method(D_METHOD("add_export_plugin", "exporter"), &EditorPlugin::add_export_plugin); + ClassDB::bind_method(D_METHOD("remove_export_plugin", "exporter"), &EditorPlugin::remove_export_plugin); ClassDB::bind_method(D_METHOD("set_input_event_forwarding_always_enabled"), &EditorPlugin::set_input_event_forwarding_always_enabled); ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorPlugin::get_editor_interface); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 99328f8149f..18530e9ce46 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -191,6 +191,9 @@ public: void add_import_plugin(const Ref &p_importer); void remove_import_plugin(const Ref &p_importer); + void add_export_plugin(const Ref &p_exporter); + void remove_export_plugin(const Ref &p_exporter); + EditorPlugin(); virtual ~EditorPlugin(); };