Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added system for deprecating methods, properties, signals and constants. #23023

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions core/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "class_db.h"

#include "core/deprecation_manager.h"
#include "core/engine.h"
#include "core/os/mutex.h"
#include "core/version.h"
Expand Down Expand Up @@ -718,7 +719,7 @@ int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p

int *constant = type->constant_map.getptr(p_name);
if (constant) {

TEST_CONSTANT_DEPRECATED(type->name, p_name);
if (p_success)
*p_success = true;
return *constant;
Expand Down Expand Up @@ -746,8 +747,10 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S

List<StringName> &constants_list = type->enum_map.get(*k);
const List<StringName>::Element *found = constants_list.find(p_name);
if (found)
if (found) {
TEST_CONSTANT_DEPRECATED(type->name, p_name);
return *k;
}
}

if (p_no_inheritance)
Expand Down Expand Up @@ -996,6 +999,7 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
TEST_PROPERTY_DEPRECATED(check->name, p_property);

if (!psg->setter) {
if (r_valid)
Expand Down Expand Up @@ -1042,6 +1046,7 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
TEST_PROPERTY_DEPRECATED(check->name, p_property);
Piet-G marked this conversation as resolved.
Show resolved Hide resolved
if (!psg->getter)
return true; //return true but do nothing

Expand All @@ -1066,7 +1071,7 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia

const int *c = check->constant_map.getptr(p_property);
if (c) {

TEST_CONSTANT_DEPRECATED(check->name, p_property);
r_value = *c;
return true;
}
Expand Down
1 change: 0 additions & 1 deletion core/class_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,6 @@ class ClassDB {
#else

#define BIND_VMETHOD(m_method)

#endif

#endif // CLASS_DB_H
87 changes: 87 additions & 0 deletions core/deprecation_manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "deprecation_manager.h"
#include "core/class_db.h"

#ifdef DEBUG_ENABLED

DeprecationInfo::DeprecationInfo() :
warned(false),
custom_warning("") {
}

DeprecationInfo::DeprecationInfo(String p_custom_warning) :
warned(false),
custom_warning(p_custom_warning) {
}

HashMap<String, DeprecationManager::ClassInfo> DeprecationManager::classes;

void DeprecationManager::warn_deprecated(const StringName &p_name, const StringName &p_type, const DeprecationInfo &p_info) {
String warning = "The " + p_type + " '" + p_name + "' has been deprecated and will be removed in the future.";

if (!p_info.custom_warning.empty())
warning = warning + " " + p_info.custom_warning;

WARN_PRINTS(warning);
}

void DeprecationManager::deprecate_method(const StringName &p_class, const StringName &p_method, DeprecationInfo p_info) {
classes[p_class].deprecated_methods[p_method] = p_info;
}

void DeprecationManager::deprecate_constant(const StringName &p_class, const StringName &p_constant, DeprecationInfo p_info) {
classes[p_class].deprecated_constants[p_constant] = p_info;
}

void DeprecationManager::deprecate_signal(const StringName &p_class, const StringName &p_signal, DeprecationInfo p_info) {
classes[p_class].deprecated_signals[p_signal] = p_info;
}

void DeprecationManager::deprecate_property(const StringName &p_class, const StringName &p_property, DeprecationInfo p_info) {
classes[p_class].deprecated_properties[p_property] = p_info;
}

void DeprecationManager::test_method_deprecated(const StringName &p_class, const StringName &p_method_name) {
if (classes[p_class].deprecated_methods.has(p_method_name)) {
DeprecationInfo *info = &classes[p_class].deprecated_properties[p_method_name];

if (!info->warned) {
warn_deprecated(p_method_name, "method", *info);
info->warned = true;
}
}
}

void DeprecationManager::test_constant_deprecated(const StringName &p_class, const StringName &p_const) {
if (classes[p_class].deprecated_constants.has(p_const)) {
DeprecationInfo *info = &classes[p_class].deprecated_constants[p_const];

if (!info->warned) {
warn_deprecated(p_const, "constant", *info);
info->warned = true;
}
}
}

void DeprecationManager::test_property_deprecated(const StringName &p_class, const StringName &p_property) {
if (classes[p_class].deprecated_properties.has(p_property)) {
DeprecationInfo *info = &classes[p_class].deprecated_properties[p_property];

if (!info->warned) {
warn_deprecated(p_property, "property", *info);
info->warned = true;
}
}
}

void DeprecationManager::test_signal_deprecated(const StringName &p_class, const StringName &p_signal) {
if (classes[p_class].deprecated_signals.has(p_signal)) {
DeprecationInfo *info = &classes[p_class].deprecated_signals[p_signal];

if (!info->warned) {
warn_deprecated(p_signal, "signal", *info);
info->warned = true;
}
}
}

#endif
72 changes: 72 additions & 0 deletions core/deprecation_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "core/hash_map.h"
#include "core/ustring.h"

#ifndef DEPRECATION_MANAGER_H
#define DEPRECATION_MANAGER_H

#ifdef DEBUG_ENABLED

struct DeprecationInfo {
bool warned;
String custom_warning;

DeprecationInfo();
DeprecationInfo(String p_custom_message);
};

class DeprecationManager {
struct ClassInfo {
HashMap<String, DeprecationInfo> deprecated_methods;
HashMap<String, DeprecationInfo> deprecated_properties;
HashMap<String, DeprecationInfo> deprecated_constants;
HashMap<String, DeprecationInfo> deprecated_signals;
};

static HashMap<String, ClassInfo> classes;
static HashMap<int, DeprecationInfo> deprecated_methods;

public:
static void warn_deprecated(const StringName &p_name, const StringName &p_type, const DeprecationInfo &p_info);
static void deprecate_method(const StringName &p_class, const StringName &p_method, DeprecationInfo p_info);
static void deprecate_property(const StringName &p_class, const StringName &p_property, DeprecationInfo p_info);
static void deprecate_constant(const StringName &p_class, const StringName &p_const, DeprecationInfo p_info);
static void deprecate_signal(const StringName &p_class, const StringName &p_signal, DeprecationInfo p_info);
static void test_method_deprecated(const StringName &p_class, const StringName &p_method_name);
static void test_constant_deprecated(const StringName &p_class, const StringName &p_const);
static void test_property_deprecated(const StringName &p_class, const StringName &p_property);
static void test_signal_deprecated(const StringName &p_class, const StringName &p_signal);
};

#define DEPRECATE_METHOD(p_method, p_info) \
DeprecationManager::deprecate_method(get_class_static(), p_method, p_info);
#define DEPRECATE_PROPERTY(p_property, p_info) \
DeprecationManager::deprecate_property(get_class_static(), p_property, p_info);
#define DEPRECATE_SIGNAL(p_signal, p_info) \
DeprecationManager::deprecate_signal(get_class_static(), p_signal, p_info);
#define DEPRECATE_CONSTANT(p_const, p_info) \
DeprecationManager::deprecate_constant(get_class_static(), #p_const, p_info);

#define TEST_METHOD_DEPRECATED(p_class_name, p_method_name) \
DeprecationManager::test_method_deprecated(p_class_name, p_method_name);
#define TEST_CONSTANT_DEPRECATED(p_class_name, p_const) \
DeprecationManager::test_constant_deprecated(p_class_name, p_const);
#define TEST_SIGNAL_DEPRECATED(p_class_name, p_signal) \
DeprecationManager::test_signal_deprecated(p_class_name, p_signal);
#define TEST_PROPERTY_DEPRECATED(p_class_name, p_property) \
DeprecationManager::test_property_deprecated(p_class_name, p_property);

#else

#define DEPRECATE_METHOD(p_method, p_info)
#define DEPRECATE_PROPERTY(p_property, p_info)
#define DEPRECATE_SIGNAL(p_signal, p_info)
#define DEPRECATE_CONSTANT(p_const, p_info)

#define TEST_METHOD_DEPRECATED(p_class_name, p_method_name)
#define TEST_CONSTANT_DEPRECATED(p_class_name, p_const)
#define TEST_SIGNAL_DEPRECATED(p_class_name, p_signal)
#define TEST_PROPERTY_DEPRECATED(p_class_name, p_property)

#endif

#endif // DEPRECATION_MANAGER_H
5 changes: 4 additions & 1 deletion core/make_binders.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
T *instance=Object::cast_to<T>(p_object);
r_error.error=Variant::CallError::CALL_OK;
#ifdef DEBUG_METHODS_ENABLED

TEST_METHOD_DEPRECATED(get_instance_class(), get_name());

ERR_FAIL_COND_V(!instance,Variant());
if (p_arg_count>get_argument_count()) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
Expand Down Expand Up @@ -121,6 +122,8 @@ class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
r_error.error=Variant::CallError::CALL_OK;
#ifdef DEBUG_METHODS_ENABLED

TEST_METHOD_DEPRECATED(get_instance_class(), get_name());

ERR_FAIL_COND_V(!instance,Variant());
if (p_arg_count>get_argument_count()) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
Expand Down
2 changes: 1 addition & 1 deletion core/method_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
#ifndef METHOD_BIND_H
#define METHOD_BIND_H

#include "core/deprecation_manager.h"
#include "core/list.h"
#include "core/method_ptrcall.h"
#include "core/object.h"
#include "core/variant.h"

#include <stdio.h>

/**
Expand Down
14 changes: 13 additions & 1 deletion core/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,17 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
ERR_EXPLAIN("In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'");
ERR_FAIL_COND_V(!signal_is_valid, ERR_INVALID_PARAMETER);
}

#ifdef DEBUG_METHODS_ENABLED
StringName class_name = get_class_name();

while (class_name != StringName()) {
TEST_SIGNAL_DEPRECATED(class_name, p_signal);

class_name = ClassDB::get_parent_class_nocheck(class_name);
}
#endif

signal_map[p_signal] = Signal();
s = &signal_map[p_signal];
}
Expand Down Expand Up @@ -1651,7 +1662,8 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) {
_clear_internal_resource_paths(d[E->get()]);
}
} break;
default: {}
default: {
}
}
}

Expand Down