summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/io/resource_format_binary.cpp7
-rw-r--r--core/io/resource_format_binary.h1
-rw-r--r--core/math/math_funcs.h10
-rw-r--r--core/object.cpp2
-rw-r--r--core/undo_redo.cpp32
5 files changed, 32 insertions, 20 deletions
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index d2c656b8eb..6c48942d72 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -1501,7 +1501,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
if (!resource_set.has(res)) {
f->store_32(OBJECT_EMPTY);
- ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
+ ERR_EXPLAIN("Resource was not pre cached for the resource section, most likely due to circular refedence.");
ERR_FAIL();
}
@@ -1650,6 +1650,10 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
return;
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
+ if (res->get_path() == path) {
+ ERR_PRINTS("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded.");
+ return;
+ }
int idx = external_resources.size();
external_resources[res] = idx;
return;
@@ -1774,6 +1778,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
takeover_paths = false;
local_path = p_path.get_base_dir();
+ path = ProjectSettings::get_singleton()->localize_path(p_path);
_find_resources(p_resource, true);
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index c3c477b805..a4894e4033 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -114,6 +114,7 @@ public:
class ResourceFormatSaverBinaryInstance {
String local_path;
+ String path;
bool relative_paths;
bool bundle_resources;
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 629002ced6..f2234d5dd6 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -217,17 +217,17 @@ public:
static _ALWAYS_INLINE_ double round(double p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
- static _ALWAYS_INLINE_ int wrapi(int value, int min, int max) {
- int rng = max - min;
- return min + ((((value - min) % rng) + rng) % rng);
+ static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
+ int64_t rng = max - min;
+ return (rng != 0) ? min + ((((value - min) % rng) + rng) % rng) : min;
}
static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) {
double rng = max - min;
- return value - (rng * Math::floor((value - min) / rng));
+ return (!is_equal_approx(rng, 0.0)) ? value - (rng * Math::floor((value - min) / rng)) : min;
}
static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) {
float rng = max - min;
- return value - (rng * Math::floor((value - min) / rng));
+ return (!is_equal_approx(rng, 0.0f)) ? value - (rng * Math::floor((value - min) / rng)) : min;
}
// double only, as these functions are mainly used by the editor and not performance-critical,
diff --git a/core/object.cpp b/core/object.cpp
index 4e0416ccb0..c46ecc5193 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1014,7 +1014,7 @@ void Object::set_script(const RefPtr &p_script) {
}
}
- _change_notify("script");
+ _change_notify(); //scripts may add variables, so refresh is desired
emit_signal(CoreStringNames::get_singleton()->script_changed);
}
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 40ccd95758..00894b41d8 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -63,37 +63,43 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
_discard_redo();
// Check if the merge operation is valid
- if (p_mode == MERGE_ENDS && actions.size() && actions[actions.size() - 1].name == p_name && actions[actions.size() - 1].last_tick + 800 > ticks) {
+ if (p_mode != MERGE_DISABLE && actions.size() && actions[actions.size() - 1].name == p_name && actions[actions.size() - 1].last_tick + 800 > ticks) {
current_action = actions.size() - 2;
- // Clear all do ops from last action, and delete all object references
- List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
+ if (p_mode == MERGE_ENDS) {
- while (E) {
+ // Clear all do ops from last action, and delete all object references
+ List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
- if (E->get().type == Operation::TYPE_REFERENCE) {
+ while (E) {
- Object *obj = ObjectDB::get_instance(E->get().object);
+ if (E->get().type == Operation::TYPE_REFERENCE) {
- if (obj)
- memdelete(obj);
- }
+ Object *obj = ObjectDB::get_instance(E->get().object);
+
+ if (obj)
+ memdelete(obj);
+ }
- E = E->next();
- actions.write[current_action + 1].do_ops.pop_front();
+ E = E->next();
+ actions.write[current_action + 1].do_ops.pop_front();
+ }
}
actions.write[actions.size() - 1].last_tick = ticks;
+
+ merge_mode = p_mode;
+
} else {
Action new_action;
new_action.name = p_name;
new_action.last_tick = ticks;
actions.push_back(new_action);
- }
- merge_mode = p_mode;
+ merge_mode = MERGE_DISABLE;
+ }
}
action_level++;