Skip to content

Commit abd565e

Browse files
committed
Merge pull request #104844 from Ivorforce/gdsoftclass
Add and require `GDSOFTCLASS` for `Object` subclasses that want to cast but do not use `GDCLASS`.
2 parents 7ba2ebd + fa0a3c9 commit abd565e

File tree

16 files changed

+98
-69
lines changed

16 files changed

+98
-69
lines changed

core/extension/gdextension_library_loader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "core/os/shared_object.h"
3838

3939
class GDExtensionLibraryLoader : public GDExtensionLoader {
40+
GDSOFTCLASS(GDExtensionLibraryLoader, GDExtensionLoader);
41+
4042
friend class GDExtensionManager;
4143
friend class GDExtension;
4244

core/extension/gdextension_loader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
class GDExtension;
3636

3737
class GDExtensionLoader : public RefCounted {
38+
GDSOFTCLASS(GDExtensionLoader, GDExtensionLoader);
39+
3840
public:
3941
virtual Error open_library(const String &p_path) = 0;
4042
virtual Error initialize(GDExtensionInterfaceGetProcAddress p_get_proc_address, const Ref<GDExtension> &p_extension, GDExtensionInitialization *r_initialization) = 0;

core/io/plist.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class PList : public RefCounted {
8383
/*************************************************************************/
8484

8585
class PListNode : public RefCounted {
86+
GDSOFTCLASS(PListNode, RefCounted);
87+
8688
static int _asn1_size_len(uint8_t p_len_octets);
8789

8890
public:

core/object/object.h

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -389,13 +389,29 @@ struct ObjectGDExtension {
389389
* much alone defines the object model.
390390
*/
391391

392+
// This is a barebones version of GDCLASS,
393+
// only intended for simple classes deriving from Object
394+
// so that they can support the `Object::cast_to()` method.
395+
#define GDSOFTCLASS(m_class, m_inherits) \
396+
public: \
397+
typedef m_class self_type; \
398+
static _FORCE_INLINE_ void *get_class_ptr_static() { \
399+
static int ptr; \
400+
return &ptr; \
401+
} \
402+
virtual bool is_class_ptr(void *p_ptr) const override { \
403+
return (p_ptr == get_class_ptr_static()) || m_inherits::is_class_ptr(p_ptr); \
404+
} \
405+
\
406+
private:
407+
392408
#define GDCLASS(m_class, m_inherits) \
409+
GDSOFTCLASS(m_class, m_inherits) \
393410
private: \
394411
void operator=(const m_class &p_rval) {} \
395412
friend class ::ClassDB; \
396413
\
397414
public: \
398-
typedef m_class self_type; \
399415
static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \
400416
virtual String get_class() const override { \
401417
if (_get_extension()) { \
@@ -410,10 +426,6 @@ public:
410426
} \
411427
return &_class_name_static; \
412428
} \
413-
static _FORCE_INLINE_ void *get_class_ptr_static() { \
414-
static int ptr; \
415-
return &ptr; \
416-
} \
417429
static _FORCE_INLINE_ String get_class_static() { \
418430
return String(#m_class); \
419431
} \
@@ -430,10 +442,6 @@ public:
430442
} \
431443
return (p_class == (#m_class)) ? true : m_inherits::is_class(p_class); \
432444
} \
433-
virtual bool is_class_ptr(void *p_ptr) const override { \
434-
return (p_ptr == get_class_ptr_static()) ? true : m_inherits::is_class_ptr(p_ptr); \
435-
} \
436-
\
437445
static void get_valid_parents_static(List<String> *p_parents) { \
438446
if (m_class::_get_valid_parents_static != m_inherits::_get_valid_parents_static) { \
439447
m_class::_get_valid_parents_static(p_parents); \
@@ -443,9 +451,6 @@ public:
443451
} \
444452
\
445453
protected: \
446-
virtual bool _derives_from(const std::type_info &p_type_info) const override { \
447-
return typeid(m_class) == p_type_info || m_inherits::_derives_from(p_type_info); \
448-
} \
449454
_FORCE_INLINE_ static void (*_get_bind_methods())() { \
450455
return &m_class::_bind_methods; \
451456
} \
@@ -774,12 +779,6 @@ class Object {
774779
mutable VirtualMethodTracker *virtual_method_list = nullptr;
775780
#endif
776781

777-
virtual bool _derives_from(const std::type_info &p_type_info) const {
778-
// This could just be false because nobody would reasonably ask if an Object subclass derives from Object,
779-
// but it would be wrong if somebody actually does ask. It's not too slow to check anyway.
780-
return typeid(Object) == p_type_info;
781-
}
782-
783782
public: // Should be protected, but bug in clang++.
784783
static void initialize_class();
785784
_FORCE_INLINE_ static void register_custom_data_to_otdb() {}
@@ -802,23 +801,15 @@ class Object {
802801
// This is like dynamic_cast, but faster.
803802
// The reason is that we can assume no virtual and multiple inheritance.
804803
static_assert(std::is_base_of_v<Object, T>, "T must be derived from Object");
805-
if constexpr (std::is_same_v<std::decay_t<T>, typename T::self_type>) {
806-
return p_object && p_object->_derives_from(typeid(T)) ? static_cast<T *>(p_object) : nullptr;
807-
} else {
808-
// T does not use GDCLASS, must fall back to dynamic_cast.
809-
return p_object ? dynamic_cast<T *>(p_object) : nullptr;
810-
}
804+
static_assert(std::is_same_v<std::decay_t<T>, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS");
805+
return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast<T *>(p_object) : nullptr;
811806
}
812807

813808
template <typename T>
814809
static const T *cast_to(const Object *p_object) {
815810
static_assert(std::is_base_of_v<Object, T>, "T must be derived from Object");
816-
if constexpr (std::is_same_v<std::decay_t<T>, typename T::self_type>) {
817-
return p_object && p_object->_derives_from(typeid(T)) ? static_cast<const T *>(p_object) : nullptr;
818-
} else {
819-
// T does not use GDCLASS, must fall back to dynamic_cast.
820-
return p_object ? dynamic_cast<const T *>(p_object) : nullptr;
821-
}
811+
static_assert(std::is_same_v<std::decay_t<T>, typename T::self_type>, "T must use GDCLASS or GDSOFTCLASS");
812+
return p_object && p_object->is_class_ptr(T::get_class_ptr_static()) ? static_cast<const T *>(p_object) : nullptr;
822813
}
823814

824815
enum {

editor/export/codesign.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class CodeSignCodeResources {
113113
/*************************************************************************/
114114

115115
class CodeSignBlob : public RefCounted {
116+
GDSOFTCLASS(CodeSignBlob, RefCounted);
117+
116118
public:
117119
virtual PackedByteArray get_hash_sha1() const = 0;
118120
virtual PackedByteArray get_hash_sha256() const = 0;

modules/camera/camera_feed_linux.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
struct StreamingBuffer;
4141

4242
class CameraFeedLinux : public CameraFeed {
43+
GDSOFTCLASS(CameraFeedLinux, CameraFeed);
44+
4345
private:
4446
SafeFlag exit_flag;
4547
Thread *thread = nullptr;
@@ -64,12 +66,12 @@ class CameraFeedLinux : public CameraFeed {
6466

6567
public:
6668
String get_device_name() const;
67-
bool activate_feed();
68-
void deactivate_feed();
69-
bool set_format(int p_index, const Dictionary &p_parameters);
70-
Array get_formats() const;
71-
FeedFormat get_format() const;
69+
bool activate_feed() override;
70+
void deactivate_feed() override;
71+
bool set_format(int p_index, const Dictionary &p_parameters) override;
72+
Array get_formats() const override;
73+
FeedFormat get_format() const override;
7274

7375
CameraFeedLinux(const String &p_device_name);
74-
virtual ~CameraFeedLinux();
76+
~CameraFeedLinux() override;
7577
};

modules/camera/camera_macos.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include "servers/camera_server.h"
3737

3838
class CameraMacOS : public CameraServer {
39+
GDSOFTCLASS(CameraMacOS, CameraServer);
40+
3941
public:
4042
CameraMacOS() = default;
4143

modules/camera/camera_macos.mm

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM
195195
// CameraFeedMacOS - Subclass for camera feeds in macOS
196196

197197
class CameraFeedMacOS : public CameraFeed {
198+
GDSOFTCLASS(CameraFeedMacOS, CameraFeed);
199+
198200
private:
199201
AVCaptureDevice *device;
200202
MyCaptureSession *capture_session;
@@ -206,8 +208,8 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM
206208

207209
void set_device(AVCaptureDevice *p_device);
208210

209-
bool activate_feed();
210-
void deactivate_feed();
211+
bool activate_feed() override;
212+
void deactivate_feed() override;
211213
};
212214

213215
AVCaptureDevice *CameraFeedMacOS::get_device() const {

modules/gdscript/gdscript_cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class GDScriptAnalyzer;
4141
class GDScriptParser;
4242

4343
class GDScriptParserRef : public RefCounted {
44+
GDSOFTCLASS(GDScriptParserRef, RefCounted);
45+
4446
public:
4547
enum Status {
4648
EMPTY,

modules/mbedtls/crypto_mbedtls.h

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
class CryptoMbedTLS;
4040
class TLSContextMbedTLS;
4141
class CryptoKeyMbedTLS : public CryptoKey {
42+
GDSOFTCLASS(CryptoKeyMbedTLS, CryptoKey);
43+
4244
private:
4345
mbedtls_pk_context pkey;
4446
int locks = 0;
@@ -51,17 +53,17 @@ class CryptoKeyMbedTLS : public CryptoKey {
5153
static void make_default() { CryptoKey::_create = create; }
5254
static void finalize() { CryptoKey::_create = nullptr; }
5355

54-
virtual Error load(const String &p_path, bool p_public_only);
55-
virtual Error save(const String &p_path, bool p_public_only);
56-
virtual String save_to_string(bool p_public_only);
57-
virtual Error load_from_string(const String &p_string_key, bool p_public_only);
58-
virtual bool is_public_only() const { return public_only; }
56+
Error load(const String &p_path, bool p_public_only) override;
57+
Error save(const String &p_path, bool p_public_only) override;
58+
String save_to_string(bool p_public_only) override;
59+
Error load_from_string(const String &p_string_key, bool p_public_only) override;
60+
bool is_public_only() const override { return public_only; }
5961

6062
CryptoKeyMbedTLS() {
6163
mbedtls_pk_init(&pkey);
6264
locks = 0;
6365
}
64-
~CryptoKeyMbedTLS() {
66+
~CryptoKeyMbedTLS() override {
6567
mbedtls_pk_free(&pkey);
6668
}
6769

@@ -73,6 +75,8 @@ class CryptoKeyMbedTLS : public CryptoKey {
7375
};
7476

7577
class X509CertificateMbedTLS : public X509Certificate {
78+
GDSOFTCLASS(X509CertificateMbedTLS, X509Certificate);
79+
7680
private:
7781
mbedtls_x509_crt cert;
7882
int locks;
@@ -82,17 +86,17 @@ class X509CertificateMbedTLS : public X509Certificate {
8286
static void make_default() { X509Certificate::_create = create; }
8387
static void finalize() { X509Certificate::_create = nullptr; }
8488

85-
virtual Error load(const String &p_path);
86-
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len);
87-
virtual Error save(const String &p_path);
88-
virtual String save_to_string();
89-
virtual Error load_from_string(const String &p_string_key);
89+
Error load(const String &p_path) override;
90+
Error load_from_memory(const uint8_t *p_buffer, int p_len) override;
91+
Error save(const String &p_path) override;
92+
String save_to_string() override;
93+
Error load_from_string(const String &p_string_key) override;
9094

9195
X509CertificateMbedTLS() {
9296
mbedtls_x509_crt_init(&cert);
9397
locks = 0;
9498
}
95-
~X509CertificateMbedTLS() {
99+
~X509CertificateMbedTLS() override {
96100
mbedtls_x509_crt_free(&cert);
97101
}
98102

@@ -116,12 +120,12 @@ class HMACContextMbedTLS : public HMACContext {
116120

117121
static bool is_md_type_allowed(mbedtls_md_type_t p_md_type);
118122

119-
virtual Error start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key);
120-
virtual Error update(const PackedByteArray &p_data);
121-
virtual PackedByteArray finish();
123+
Error start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key) override;
124+
Error update(const PackedByteArray &p_data) override;
125+
PackedByteArray finish() override;
122126

123127
HMACContextMbedTLS() {}
124-
~HMACContextMbedTLS();
128+
~HMACContextMbedTLS() override;
125129
};
126130

127131
class CryptoMbedTLS : public Crypto {
@@ -138,14 +142,14 @@ class CryptoMbedTLS : public Crypto {
138142
static void load_default_certificates(const String &p_path);
139143
static mbedtls_md_type_t md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size);
140144

141-
virtual PackedByteArray generate_random_bytes(int p_bytes);
142-
virtual Ref<CryptoKey> generate_rsa(int p_bytes);
143-
virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, const String &p_issuer_name, const String &p_not_before, const String &p_not_after);
144-
virtual Vector<uint8_t> sign(HashingContext::HashType p_hash_type, const Vector<uint8_t> &p_hash, Ref<CryptoKey> p_key);
145-
virtual bool verify(HashingContext::HashType p_hash_type, const Vector<uint8_t> &p_hash, const Vector<uint8_t> &p_signature, Ref<CryptoKey> p_key);
146-
virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, const Vector<uint8_t> &p_plaintext);
147-
virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, const Vector<uint8_t> &p_ciphertext);
145+
PackedByteArray generate_random_bytes(int p_bytes) override;
146+
Ref<CryptoKey> generate_rsa(int p_bytes) override;
147+
Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, const String &p_issuer_name, const String &p_not_before, const String &p_not_after) override;
148+
Vector<uint8_t> sign(HashingContext::HashType p_hash_type, const Vector<uint8_t> &p_hash, Ref<CryptoKey> p_key) override;
149+
bool verify(HashingContext::HashType p_hash_type, const Vector<uint8_t> &p_hash, const Vector<uint8_t> &p_signature, Ref<CryptoKey> p_key) override;
150+
Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, const Vector<uint8_t> &p_plaintext) override;
151+
Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, const Vector<uint8_t> &p_ciphertext) override;
148152

149153
CryptoMbedTLS();
150-
~CryptoMbedTLS();
154+
~CryptoMbedTLS() override;
151155
};

0 commit comments

Comments
 (0)