diff options
-rw-r--r-- | core/core_bind.cpp | 3 | ||||
-rw-r--r-- | doc/classes/OS.xml | 1 | ||||
-rw-r--r-- | editor/editor_export.cpp | 58 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 10 | ||||
-rw-r--r-- | modules/gdnative/include/gdnative/gdnative.h | 4 | ||||
-rw-r--r-- | scene/gui/control.cpp | 3 | ||||
-rw-r--r-- | scene/main/node.cpp | 11 |
7 files changed, 64 insertions, 26 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp index e7a77384da..2d6b8e5666 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -373,6 +373,9 @@ Dictionary _OS::get_time(bool utc) const { * @return epoch calculated */ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const { + // if datetime is an empty Dictionary throws an error + ERR_FAIL_COND_V_MSG(datetime.is_empty(), 0, "Invalid datetime Dictionary: Dictionary is empty"); + // Bunch of conversion constants static const unsigned int SECONDS_PER_MINUTE = 60; static const unsigned int MINUTES_PER_HOUR = 60; diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 057a2b8d1a..548147beab 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -367,6 +367,7 @@ <description> Gets an epoch time value from a dictionary of time values. [code]datetime[/code] must be populated with the following keys: [code]year[/code], [code]month[/code], [code]day[/code], [code]hour[/code], [code]minute[/code], [code]second[/code]. + If the dictionary is empty [code]0[/code] is returned. You can pass the output from [method get_datetime_from_unix_time] directly into this function. Daylight Savings Time ([code]dst[/code]), if present, is ignored. </description> </method> diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 4f60258d95..7f5f51cf70 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -301,6 +301,8 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) } Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { + ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export."); + PackData *pd = (PackData *)p_userdata; SavedData sd; @@ -368,6 +370,8 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa } Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { + ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export."); + String path = p_path.replace_first("res://", ""); ZipData *zd = (ZipData *)p_userdata; @@ -824,17 +828,25 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } } + Error err = OK; Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); + for (int i = 0; i < export_plugins.size(); i++) { export_plugins.write[i]->set_export_preset(p_preset); 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]); + err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]); + if (err != OK) { + return err; + } } } 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, 0, paths.size(), enc_in_filters, enc_ex_filters, key); + err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size(), enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } } export_plugins.write[i]->_clear(); @@ -856,7 +868,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & //file is imported, replace by what it imports Ref<ConfigFile> config; config.instance(); - Error err = config->load(path + ".import"); + err = config->load(path + ".import"); if (err != OK) { ERR_PRINT("Could not parse: '" + path + "', not exported."); continue; @@ -920,12 +932,18 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } 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]); + err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]); + if (err != OK) { + return err; + } } } 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, enc_in_filters, enc_ex_filters, key); + err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } if (export_plugins[i]->extra_files[j].remap) { do_export = false; //if remap, do not path_remaps.push_back(path); @@ -945,7 +963,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & //just store it as it comes if (do_export) { Vector<uint8_t> array = FileAccess::get_file_as_array(path); - p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } } } @@ -981,7 +1002,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & new_file.write[j] = utf8[j]; } - p_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } } } else { //old remap mode, will still work, but it's unused because it's not multiple pck export friendly @@ -994,11 +1018,17 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image"); if (icon != String() && FileAccess::exists(icon)) { Vector<uint8_t> array = FileAccess::get_file_as_array(icon); - p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_func(p_udata, icon, array, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } } if (splash != String() && FileAccess::exists(splash) && icon != splash) { Vector<uint8_t> array = FileAccess::get_file_as_array(splash); - p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_func(p_udata, splash, array, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } } // Store text server data if exists. @@ -1006,7 +1036,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & String ts_data = "res://" + TS->get_support_data_filename(); if (FileAccess::exists(ts_data)) { Vector<uint8_t> array = FileAccess::get_file_as_array(ts_data); - p_func(p_udata, ts_data, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_func(p_udata, ts_data, array, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } } } @@ -1016,9 +1049,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); DirAccess::remove_file_or_error(engine_cfb); - p_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key); - - return OK; + return p_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key); } Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObject &p_so) { @@ -1052,6 +1083,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c if (err != OK) { DirAccess::remove_file_or_error(tmppath); + ERR_PRINT("Failed to export project files"); return err; } diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 16a0576af4..2cdab83d90 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -685,7 +685,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { editor_data->get_undo_redo().add_do_method(editor_selection, "clear"); Node *dupsingle = nullptr; - List<Node *> editable_children; selection.sort_custom<Node::Comparator>(); @@ -701,10 +700,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Map<const Node *, Node *> duplimap; Node *dup = node->duplicate_from_editor(duplimap); - if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node)) { - editable_children.push_back(dup); - } - ERR_CONTINUE(!dup); if (selection.size() == 1) { @@ -739,11 +734,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (dupsingle) { editor->push_item(dupsingle); } - - for (List<Node *>::Element *E = editable_children.back(); E; E = E->prev()) { - _toggle_editable_children(E->get()); - } - } break; case TOOL_REPARENT: { if (!profile_allow_editing) { diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index a4ed7ebb8c..9af9226a79 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -53,7 +53,9 @@ extern "C" { #endif // This is for libraries *using* the header, NOT GODOT EXPOSING STUFF!! -#ifdef _WIN32 +#ifdef __GNUC__ +#define GDN_EXPORT __attribute__((visibility("default"))) +#elif defined(_WIN32) #define GDN_EXPORT __declspec(dllexport) #else #define GDN_EXPORT diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index bff3024e38..f188e63743 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -73,6 +73,9 @@ Dictionary Control::_edit_get_state() const { } void Control::_edit_set_state(const Dictionary &p_state) { + ERR_FAIL_COND((p_state.size() <= 0) || + !p_state.has("rotation") || !p_state.has("scale") || + !p_state.has("pivot") || !p_state.has("anchors") || !p_state.has("offsets")); Dictionary state = p_state; set_rotation(state["rotation"]); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 137e1726f9..4c6bcb10b2 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2051,19 +2051,26 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const // Since nodes in the instanced hierarchy won't be duplicated explicitly, we need to make an inventory // of all the nodes in the tree of the instanced scene in order to transfer the values of the properties + Vector<const Node *> instance_roots; + instance_roots.push_back(this); + for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { for (int i = 0; i < N->get()->get_child_count(); ++i) { Node *descendant = N->get()->get_child(i); // Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later // but remember non-instanced nodes that are hidden below instanced ones - if (descendant->data.owner != this) { - if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) { + if (!instance_roots.has(descendant->get_owner())) { + if (descendant->get_parent() && descendant->get_parent() != this && descendant->data.owner != descendant->get_parent()) { hidden_roots.push_back(descendant); } continue; } node_tree.push_back(descendant); + + if (descendant->get_filename() != "" && instance_roots.has(descendant->get_owner())) { + instance_roots.push_back(descendant); + } } } } |