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.
This commit is contained in:
Juan Linietsky 2017-09-14 19:38:38 -03:00
parent 9488f06e4a
commit d3c1f2a7f6
5 changed files with 179 additions and 28 deletions

View File

@ -476,19 +476,66 @@ void EditorExportPlatform::_edit_filter_list(Set<String> &r_list, const String &
memdelete(da);
}
Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata) {
void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &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<String> &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<String> &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<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
Ref<EditorExportPlatform> platform = p_preset->get_platform();
List<String> feature_list;
platform->get_preset_features(p_preset, &feature_list);
//figure out features
Set<String> features;
PoolVector<String> features_pv;
for (List<String>::Element *E = feature_list.front(); E; E = E->next()) {
features.insert(E->get());
features_pv.push_back(E->get());
}
Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
//figure out paths of files that will be exported
Set<String> paths;
Vector<String> 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<EditorExportPreset> &
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<uint8_t> array = FileAccess::get_file_as_array(path);
p_func(p_udata, path, array, idx, total);
if (do_export) {
Vector<uint8_t> 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<EditorExportPreset> &
}
}
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<uint8_t> 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<EditorExportPlugin> &p_plugin) {
if (export_plugins.find(p_plugin) == 1) {
export_plugins.push_back(p_plugin);
}
}
void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) {
export_plugins.erase(p_plugin);
}
Vector<Ref<EditorExportPlugin> > EditorExport::get_export_plugins() {
return export_plugins;
}
void EditorExport::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {

View File

@ -124,6 +124,7 @@ class EditorExportPlatform : public Reference {
public:
typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &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<Texture> get_logo() const = 0;
Error export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata);
Error export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = NULL);
Error save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path);
@ -219,11 +220,47 @@ public:
EditorExportPlatform();
};
class EditorExportPlugin : public Reference {
GDCLASS(EditorExportPlugin, Reference)
friend class EditorExportPlatform;
Vector<String> shared_objects;
struct ExtraFile {
String path;
Vector<uint8_t> data;
bool remap;
};
Vector<ExtraFile> 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<String> &p_features);
protected:
void add_file(const String &p_path, const Vector<uint8_t> &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<String> &p_features);
static void _bind_methods();
public:
EditorExportPlugin();
};
class EditorExport : public Node {
GDCLASS(EditorExport, Node);
Vector<Ref<EditorExportPlatform> > export_platforms;
Vector<Ref<EditorExportPreset> > export_presets;
Vector<Ref<EditorExportPlugin> > export_plugins;
Timer *save_timer;
bool block_save;
@ -251,6 +288,10 @@ public:
Ref<EditorExportPreset> get_export_preset(int p_idx);
void remove_export_preset(int p_idx);
void add_export_plugin(const Ref<EditorExportPlugin> &p_plugin);
void remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin);
Vector<Ref<EditorExportPlugin> > get_export_plugins();
void load_config();
bool poll_export_platforms();

View File

@ -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<EditorFileSystemDirectory>();
ClassDB::register_virtual_class<ScriptEditor>();
ClassDB::register_virtual_class<EditorInterface>();
ClassDB::register_class<EditorExportPlugin>();
// FIXME: Is this stuff obsolete, or should it be ported to new APIs?
//ClassDB::register_class<EditorExportPlugin>();
//ClassDB::register_class<EditorScenePostImport>();
//ClassDB::register_type<EditorImportExport>();
}
@ -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);

View File

@ -530,6 +530,14 @@ void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin> &p_importe
EditorFileSystem::get_singleton()->scan();
}
void EditorPlugin::add_export_plugin(const Ref<EditorExportPlugin> &p_exporter) {
EditorExport::get_singleton()->add_export_plugin(p_exporter);
}
void EditorPlugin::remove_export_plugin(const Ref<EditorExportPlugin> &p_exporter) {
EditorExport::get_singleton()->remove_export_plugin(p_exporter);
}
void EditorPlugin::set_window_layout(Ref<ConfigFile> 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);

View File

@ -191,6 +191,9 @@ public:
void add_import_plugin(const Ref<EditorImportPlugin> &p_importer);
void remove_import_plugin(const Ref<EditorImportPlugin> &p_importer);
void add_export_plugin(const Ref<EditorExportPlugin> &p_exporter);
void remove_export_plugin(const Ref<EditorExportPlugin> &p_exporter);
EditorPlugin();
virtual ~EditorPlugin();
};