summaryrefslogtreecommitdiff
path: root/core/object
diff options
context:
space:
mode:
Diffstat (limited to 'core/object')
-rw-r--r--core/object/class_db.cpp23
-rw-r--r--core/object/class_db.h29
-rw-r--r--core/object/message_queue.cpp12
-rw-r--r--core/object/method_bind.cpp9
-rw-r--r--core/object/method_bind.h38
-rw-r--r--core/object/object.cpp2
-rw-r--r--core/object/script_language.cpp4
-rw-r--r--core/object/undo_redo.cpp46
-rw-r--r--core/object/undo_redo.h5
9 files changed, 72 insertions, 96 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 8ba46e49eb..4b3c8b123f 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -37,8 +37,6 @@
#define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock);
#define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock);
-#ifdef DEBUG_METHODS_ENABLED
-
MethodDefinition D_METHOD(const char *p_name) {
MethodDefinition md;
md.name = StaticCString::create(p_name);
@@ -226,8 +224,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
return md;
}
-#endif
-
ClassDB::APIType ClassDB::current_api = API_CORE;
void ClassDB::set_current_api(APIType p_api) {
@@ -529,7 +525,7 @@ Object *ClassDB::instantiate(const StringName &p_class) {
}
ERR_FAIL_COND_V_MSG(!ti, nullptr, "Cannot get class '" + String(p_class) + "'.");
ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled.");
- ERR_FAIL_COND_V(!ti->creation_func, nullptr);
+ ERR_FAIL_COND_V_MSG(!ti->creation_func, nullptr, "Class '" + String(p_class) + "' or its base class cannot be instantiated.");
}
#ifdef TOOLS_ENABLED
if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) {
@@ -589,7 +585,6 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit
}
}
-#ifdef DEBUG_METHODS_ENABLED
static MethodInfo info_from_bind(MethodBind *p_method) {
MethodInfo minfo;
minfo.name = p_method->get_name();
@@ -610,7 +605,6 @@ static MethodInfo info_from_bind(MethodBind *p_method) {
return minfo;
}
-#endif
void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) {
OBJTYPE_RLOCK;
@@ -650,9 +644,8 @@ void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_met
while ((K = type->method_map.next(K))) {
MethodBind *m = type->method_map[*K];
- MethodInfo mi;
- mi.name = m->get_name();
- p_methods->push_back(mi);
+ MethodInfo minfo = info_from_bind(m);
+ p_methods->push_back(minfo);
}
#endif
@@ -698,9 +691,8 @@ bool ClassDB::get_method_info(const StringName &p_class, const StringName &p_met
if (type->method_map.has(p_method)) {
if (r_info) {
MethodBind *m = type->method_map[p_method];
- MethodInfo mi;
- mi.name = m->get_name();
- *r_info = mi;
+ MethodInfo minfo = info_from_bind(m);
+ *r_info = minfo;
}
return true;
}
@@ -1411,13 +1403,8 @@ void ClassDB::bind_method_custom(const StringName &p_class, MethodBind *p_method
type->method_map[p_method->get_name()] = p_method;
}
-#ifdef DEBUG_METHODS_ENABLED
MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) {
StringName mdname = method_name.name;
-#else
-MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount) {
- StringName mdname = StaticCString::create(method_name);
-#endif
OBJTYPE_WLOCK;
ERR_FAIL_COND_V(!p_bind, nullptr);
diff --git a/core/object/class_db.h b/core/object/class_db.h
index 3a1cbf8559..d9eec4e4a8 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -45,8 +45,6 @@
#define DEFVAL(m_defval) (m_defval)
-#ifdef DEBUG_METHODS_ENABLED
-
struct MethodDefinition {
StringName name;
Vector<StringName> args;
@@ -72,26 +70,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13);
-#else
-
-//#define NO_VARIADIC_MACROS
-
-#ifdef NO_VARIADIC_MACROS
-
-static _FORCE_INLINE_ const char *D_METHOD(const char *m_name, ...) {
- return m_name;
-}
-
-#else
-
-// When DEBUG_METHODS_ENABLED is set this will let the engine know
-// the argument names for easier debugging.
-#define D_METHOD(m_c, ...) m_c
-
-#endif
-
-#endif
-
class ClassDB {
public:
enum APIType {
@@ -156,11 +134,7 @@ public:
static HashMap<StringName, StringName> resource_base_extensions;
static HashMap<StringName, StringName> compat_classes;
-#ifdef DEBUG_METHODS_ENABLED
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
-#else
- static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount);
-#endif
static APIType current_api;
@@ -190,6 +164,7 @@ public:
t->creation_func = &creator<T>;
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
+ t->api = current_api;
T::register_custom_data_to_otdb();
}
@@ -201,6 +176,7 @@ public:
ERR_FAIL_COND(!t);
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
+ t->api = current_api;
//nothing
}
@@ -221,6 +197,7 @@ public:
t->creation_func = &_create_ptr_func<T>;
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
+ t->api = current_api;
T::register_custom_data_to_otdb();
}
diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp
index 4751c69f1e..736e940846 100644
--- a/core/object/message_queue.cpp
+++ b/core/object/message_queue.cpp
@@ -227,16 +227,16 @@ void MessageQueue::statistics() {
print_line("TOTAL BYTES: " + itos(buffer_end));
print_line("NULL count: " + itos(null_count));
- for (Map<StringName, int>::Element *E = set_count.front(); E; E = E->next()) {
- print_line("SET " + E->key() + ": " + itos(E->get()));
+ for (const KeyValue<StringName, int> &E : set_count) {
+ print_line("SET " + E.key + ": " + itos(E.value));
}
- for (Map<Callable, int>::Element *E = call_count.front(); E; E = E->next()) {
- print_line("CALL " + E->key() + ": " + itos(E->get()));
+ for (const KeyValue<Callable, int> &E : call_count) {
+ print_line("CALL " + E.key + ": " + itos(E.value));
}
- for (Map<int, int>::Element *E = notify_count.front(); E; E = E->next()) {
- print_line("NOTIFY " + itos(E->key()) + ": " + itos(E->get()));
+ for (const KeyValue<int, int> &E : notify_count) {
+ print_line("NOTIFY " + itos(E.key) + ": " + itos(E.value));
}
}
diff --git a/core/object/method_bind.cpp b/core/object/method_bind.cpp
index c53104fe3f..d1d8b075fe 100644
--- a/core/object/method_bind.cpp
+++ b/core/object/method_bind.cpp
@@ -63,12 +63,15 @@ uint32_t MethodBind::get_hash() const {
return hash;
}
-#ifdef DEBUG_METHODS_ENABLED
PropertyInfo MethodBind::get_argument_info(int p_argument) const {
ERR_FAIL_INDEX_V(p_argument, get_argument_count(), PropertyInfo());
PropertyInfo info = _gen_argument_type_info(p_argument);
+#ifdef DEBUG_METHODS_ENABLED
info.name = p_argument < arg_names.size() ? String(arg_names[p_argument]) : String("arg" + itos(p_argument));
+#else
+ info.name = String("arg" + itos(p_argument));
+#endif
return info;
}
@@ -76,7 +79,6 @@ PropertyInfo MethodBind::get_return_info() const {
return _gen_argument_type_info(-1);
}
-#endif
void MethodBind::_set_const(bool p_const) {
_const = p_const;
}
@@ -109,7 +111,6 @@ void MethodBind::set_default_arguments(const Vector<Variant> &p_defargs) {
default_argument_count = default_arguments.size();
}
-#ifdef DEBUG_METHODS_ENABLED
void MethodBind::_generate_argument_types(int p_count) {
set_argument_count(p_count);
@@ -123,8 +124,6 @@ void MethodBind::_generate_argument_types(int p_count) {
argument_types = argt;
}
-#endif
-
MethodBind::MethodBind() {
static int last_id = 0;
method_id = last_id++;
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index b0b379873e..ee003099a0 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -64,18 +64,16 @@ class MethodBind {
bool _returns = false;
protected:
-#ifdef DEBUG_METHODS_ENABLED
Variant::Type *argument_types = nullptr;
+#ifdef DEBUG_METHODS_ENABLED
Vector<StringName> arg_names;
#endif
void _set_const(bool p_const);
void _set_returns(bool p_returns);
-#ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const = 0;
virtual PropertyInfo _gen_argument_type_info(int p_arg) const = 0;
void _generate_argument_types(int p_count);
-#endif
void set_argument_count(int p_count) { argument_count = p_count; }
public:
@@ -102,7 +100,6 @@ public:
}
}
-#ifdef DEBUG_METHODS_ENABLED
_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
return argument_types[p_argument + 1];
@@ -111,6 +108,7 @@ public:
PropertyInfo get_argument_info(int p_argument) const;
PropertyInfo get_return_info() const;
+#ifdef DEBUG_METHODS_ENABLED
void set_argument_names(const Vector<StringName> &p_names); // Set by ClassDB, can't be inferred otherwise.
Vector<StringName> get_argument_names() const;
@@ -149,12 +147,9 @@ public:
protected:
NativeCall call_method = nullptr;
-#ifdef DEBUG_METHODS_ENABLED
MethodInfo arguments;
-#endif
public:
-#ifdef DEBUG_METHODS_ENABLED
virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
if (p_arg < 0) {
return arguments.return_val;
@@ -169,13 +164,10 @@ public:
return _gen_argument_type_info(p_arg).type;
}
+#ifdef DEBUG_METHODS_ENABLED
virtual GodotTypeInfo::Metadata get_argument_meta(int) const {
return GodotTypeInfo::METADATA_NONE;
}
-#else
- virtual Variant::Type _gen_argument_type(int p_arg) const {
- return Variant::NIL;
- }
#endif
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
@@ -185,25 +177,29 @@ public:
void set_method_info(const MethodInfo &p_info, bool p_return_nil_is_variant) {
set_argument_count(p_info.arguments.size());
-#ifdef DEBUG_METHODS_ENABLED
Variant::Type *at = memnew_arr(Variant::Type, p_info.arguments.size() + 1);
at[0] = p_info.return_val.type;
if (p_info.arguments.size()) {
+#ifdef DEBUG_METHODS_ENABLED
Vector<StringName> names;
names.resize(p_info.arguments.size());
+#endif
for (int i = 0; i < p_info.arguments.size(); i++) {
at[i + 1] = p_info.arguments[i].type;
+#ifdef DEBUG_METHODS_ENABLED
names.write[i] = p_info.arguments[i].name;
+#endif
}
+#ifdef DEBUG_METHODS_ENABLED
set_argument_names(names);
+#endif
}
argument_types = at;
arguments = p_info;
if (p_return_nil_is_variant) {
arguments.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
}
-#endif
}
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
@@ -248,7 +244,6 @@ class MethodBindT : public MethodBind {
void (MB_T::*method)(P...);
protected:
-#ifdef DEBUG_METHODS_ENABLED
// GCC raises warnings in the case P = {} as the comparison is always false...
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
@@ -270,7 +265,6 @@ protected:
call_get_argument_type_info<P...>(p_arg, pi);
return pi;
}
-#endif
public:
#ifdef DEBUG_METHODS_ENABLED
@@ -298,9 +292,7 @@ public:
MethodBindT(void (MB_T::*p_method)(P...)) {
method = p_method;
-#ifdef DEBUG_METHODS_ENABLED
_generate_argument_types(sizeof...(P));
-#endif
set_argument_count(sizeof...(P));
}
};
@@ -327,7 +319,6 @@ class MethodBindTC : public MethodBind {
void (MB_T::*method)(P...) const;
protected:
-#ifdef DEBUG_METHODS_ENABLED
// GCC raises warnings in the case P = {} as the comparison is always false...
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
@@ -349,7 +340,6 @@ protected:
call_get_argument_type_info<P...>(p_arg, pi);
return pi;
}
-#endif
public:
#ifdef DEBUG_METHODS_ENABLED
@@ -378,9 +368,7 @@ public:
MethodBindTC(void (MB_T::*p_method)(P...) const) {
method = p_method;
_set_const(true);
-#ifdef DEBUG_METHODS_ENABLED
_generate_argument_types(sizeof...(P));
-#endif
set_argument_count(sizeof...(P));
}
};
@@ -408,7 +396,6 @@ class MethodBindTR : public MethodBind {
(P...);
protected:
-#ifdef DEBUG_METHODS_ENABLED
// GCC raises warnings in the case P = {} as the comparison is always false...
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
@@ -434,7 +421,6 @@ protected:
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
-#endif
public:
#ifdef DEBUG_METHODS_ENABLED
@@ -468,9 +454,7 @@ public:
MethodBindTR(R (MB_T::*p_method)(P...)) {
method = p_method;
_set_returns(true);
-#ifdef DEBUG_METHODS_ENABLED
_generate_argument_types(sizeof...(P));
-#endif
set_argument_count(sizeof...(P));
}
};
@@ -499,7 +483,6 @@ class MethodBindTRC : public MethodBind {
(P...) const;
protected:
-#ifdef DEBUG_METHODS_ENABLED
// GCC raises warnings in the case P = {} as the comparison is always false...
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
@@ -525,7 +508,6 @@ protected:
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
-#endif
public:
#ifdef DEBUG_METHODS_ENABLED
@@ -560,9 +542,7 @@ public:
method = p_method;
_set_returns(true);
_set_const(true);
-#ifdef DEBUG_METHODS_ENABLED
_generate_argument_types(sizeof...(P));
-#endif
set_argument_count(sizeof...(P));
}
};
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 3335942fb3..b5797a4633 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1409,7 +1409,7 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
if (!p_force) {
slot->reference_count--; // by default is zero, if it was not referenced it will go below it
- if (slot->reference_count >= 0) {
+ if (slot->reference_count > 0) {
return;
}
}
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index 0fb8c7350c..b0ce46ca2b 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -93,8 +93,8 @@ Dictionary Script::_get_script_constant_map() {
Dictionary ret;
Map<StringName, Variant> map;
get_constants(&map);
- for (Map<StringName, Variant>::Element *E = map.front(); E; E = E->next()) {
- ret[E->key()] = E->value();
+ for (const KeyValue<StringName, Variant> &E : map) {
+ ret[E.key] = E.value;
}
return ret;
}
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp
index b7d2bac96d..9c84c2add7 100644
--- a/core/object/undo_redo.cpp
+++ b/core/object/undo_redo.cpp
@@ -32,6 +32,7 @@
#include "core/io/resource.h"
#include "core/os/os.h"
+#include "core/templates/local_vector.h"
void UndoRedo::_discard_redo() {
if (current_action == actions.size() - 1) {
@@ -85,10 +86,17 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
current_action = actions.size() - 2;
if (p_mode == MERGE_ENDS) {
- // Clear all do ops from last action, and delete all object references
- List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
+ // Clear all do ops from last action if they are not forced kept
+ LocalVector<List<Operation>::Element *> to_remove;
+ for (List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front(); E; E = E->next()) {
+ if (!E->get().force_keep_in_merge_ends) {
+ to_remove.push_back(E);
+ }
+ }
- while (E) {
+ for (unsigned int i = 0; i < to_remove.size(); i++) {
+ List<Operation>::Element *E = to_remove[i];
+ // Delete all object references
if (E->get().type == Operation::TYPE_REFERENCE) {
Object *obj = ObjectDB::get_instance(E->get().object);
@@ -96,9 +104,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
memdelete(obj);
}
}
-
- E = E->next();
- actions.write[current_action + 1].do_ops.pop_front();
+ E->erase();
}
}
@@ -117,6 +123,8 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
}
action_level++;
+
+ force_keep_in_merge_ends = false;
}
void UndoRedo::add_do_method(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) {
@@ -146,7 +154,7 @@ void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VAR
ERR_FAIL_COND((current_action + 1) >= actions.size());
// No undo if the merge mode is MERGE_ENDS
- if (merge_mode == MERGE_ENDS) {
+ if (!force_keep_in_merge_ends && merge_mode == MERGE_ENDS) {
return;
}
@@ -157,6 +165,7 @@ void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VAR
}
undo_op.type = Operation::TYPE_METHOD;
+ undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends;
undo_op.name = p_method;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
@@ -187,7 +196,7 @@ void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property,
ERR_FAIL_COND((current_action + 1) >= actions.size());
// No undo if the merge mode is MERGE_ENDS
- if (merge_mode == MERGE_ENDS) {
+ if (!force_keep_in_merge_ends && merge_mode == MERGE_ENDS) {
return;
}
@@ -198,6 +207,7 @@ void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property,
}
undo_op.type = Operation::TYPE_PROPERTY;
+ undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends;
undo_op.name = p_property;
undo_op.args[0] = p_value;
actions.write[current_action + 1].undo_ops.push_back(undo_op);
@@ -223,7 +233,7 @@ void UndoRedo::add_undo_reference(Object *p_object) {
ERR_FAIL_COND((current_action + 1) >= actions.size());
// No undo if the merge mode is MERGE_ENDS
- if (merge_mode == MERGE_ENDS) {
+ if (!force_keep_in_merge_ends && merge_mode == MERGE_ENDS) {
return;
}
@@ -234,9 +244,24 @@ void UndoRedo::add_undo_reference(Object *p_object) {
}
undo_op.type = Operation::TYPE_REFERENCE;
+ undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends;
actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
+void UndoRedo::start_force_keep_in_merge_ends() {
+ ERR_FAIL_COND(action_level <= 0);
+ ERR_FAIL_COND((current_action + 1) >= actions.size());
+
+ force_keep_in_merge_ends = true;
+}
+
+void UndoRedo::end_force_keep_in_merge_ends() {
+ ERR_FAIL_COND(action_level <= 0);
+ ERR_FAIL_COND((current_action + 1) >= actions.size());
+
+ force_keep_in_merge_ends = false;
+}
+
void UndoRedo::_pop_history_tail() {
_discard_redo();
@@ -538,6 +563,9 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_do_reference", "object"), &UndoRedo::add_do_reference);
ClassDB::bind_method(D_METHOD("add_undo_reference", "object"), &UndoRedo::add_undo_reference);
+ ClassDB::bind_method(D_METHOD("start_force_keep_in_merge_ends"), &UndoRedo::start_force_keep_in_merge_ends);
+ ClassDB::bind_method(D_METHOD("end_force_keep_in_merge_ends"), &UndoRedo::end_force_keep_in_merge_ends);
+
ClassDB::bind_method(D_METHOD("get_history_count"), &UndoRedo::get_history_count);
ClassDB::bind_method(D_METHOD("get_current_action"), &UndoRedo::get_current_action);
ClassDB::bind_method(D_METHOD("get_action_name", "id"), &UndoRedo::get_action_name);
diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h
index d1ce252d86..a757d154e2 100644
--- a/core/object/undo_redo.h
+++ b/core/object/undo_redo.h
@@ -61,6 +61,7 @@ private:
};
Type type;
+ bool force_keep_in_merge_ends;
Ref<RefCounted> ref;
ObjectID object;
StringName name;
@@ -76,6 +77,7 @@ private:
Vector<Action> actions;
int current_action = -1;
+ bool force_keep_in_merge_ends = false;
int action_level = 0;
MergeMode merge_mode = MERGE_DISABLE;
bool merging = false;
@@ -109,6 +111,9 @@ public:
void add_do_reference(Object *p_object);
void add_undo_reference(Object *p_object);
+ void start_force_keep_in_merge_ends();
+ void end_force_keep_in_merge_ends();
+
bool is_committing_action() const;
void commit_action(bool p_execute = true);