summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/type_info.h19
-rw-r--r--doc/classes/Variant.xml13
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp19
3 files changed, 32 insertions, 19 deletions
diff --git a/core/type_info.h b/core/type_info.h
index d85a63ee42..61ec7b2f20 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -83,15 +83,13 @@ enum Metadata {
};
}
+// If the compiler fails because it's trying to instantiate the primary 'GetTypeInfo' template
+// instead of one of the specializations, it's most likely because the type 'T' is not supported.
+// If 'T' is a class that inherits 'Object', make sure it can see the actual class declaration
+// instead of a forward declaration. You can always forward declare 'T' in a header file, and then
+// include the actual declaration of 'T' in the source file where 'GetTypeInfo<T>' is instantiated.
template <class T, typename = void>
-struct GetTypeInfo {
- static const Variant::Type VARIANT_TYPE = Variant::NIL;
- static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
- static inline PropertyInfo get_class_info() {
- ERR_PRINT("GetTypeInfo fallback. Bug!");
- return PropertyInfo(); // Not "Nil", this is an error
- }
-};
+struct GetTypeInfo;
#define MAKE_TYPE_INFO(m_type, m_var_type) \
template <> \
@@ -283,10 +281,7 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
return GetTypeInfo<T>::get_class_info().class_name;
}
-#define CLASS_INFO(m_type) \
- (GetTypeInfo<m_type *>::VARIANT_TYPE != Variant::NIL ? \
- GetTypeInfo<m_type *>::get_class_info() : \
- GetTypeInfo<m_type>::get_class_info())
+#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
#else
diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml
index eb07c70cc6..522e131b45 100644
--- a/doc/classes/Variant.xml
+++ b/doc/classes/Variant.xml
@@ -5,6 +5,19 @@
</brief_description>
<description>
A Variant takes up only 20 bytes and can store almost any engine datatype inside of it. Variants are rarely used to hold information for long periods of time. Instead, they are used mainly for communication, editing, serialization and moving data around.
+ A Variant:
+ - Can store almost any datatype.
+ - Can perform operations between many variants. GDScript uses Variant as its atomic/native datatype.
+ - Can be hashed, so it can be compared quickly to other variants.
+ - Can be used to convert safely between datatypes.
+ - Can be used to abstract calling methods and their arguments. Godot exports all its functions through variants.
+ - Can be used to defer calls or move data between threads.
+ - Can be serialized as binary and stored to disk, or transferred via network.
+ - Can be serialized to text and use it for printing values and editable settings.
+ - Can work as an exported property, so the editor can edit it universally.
+ - Can be used for dictionaries, arrays, parsers, etc.
+ [b]Containers ([Array] and [Dictionary]):[/b] Both are implemented using variants. A [Dictionary] can match any datatype used as key to any other datatype. An [Array] just holds an array of Variants. Of course, a Variant can also hold a [Dictionary] and an [Array] inside, making it even more flexible.
+ Modifications to a container will modify all references to it. A [Mutex] should be created to lock it if multi-threaded access is desired.
</description>
<tutorials>
</tutorials>
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 2497f083b5..571bf598f3 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -602,12 +602,12 @@ bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type) {
String GDMono::update_api_assemblies_from_prebuilt() {
-#define FAIL_REASON(m_out_of_sync, m_prebuilt_exist) \
+#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \
( \
(m_out_of_sync ? \
String("The assembly is invalidated") : \
String("The assembly was not found")) + \
- (m_prebuilt_exist ? \
+ (m_prebuilt_exists ? \
String(" and the prebuilt assemblies are missing") : \
String(" and we failed to copy the prebuilt assemblies")))
@@ -619,16 +619,18 @@ String GDMono::update_api_assemblies_from_prebuilt() {
if (!api_assembly_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path))
return String(); // No update needed
+ print_verbose("Updating API assemblies");
+
String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
String prebuilt_core_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
String prebuilt_editor_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
if (!FileAccess::exists(prebuilt_core_dll_path) || !FileAccess::exists(prebuilt_editor_dll_path))
- return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exist: */ false);
+ return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ false);
// Copy the prebuilt Api
if (!copy_prebuilt_api_assembly(APIAssembly::API_CORE) || !copy_prebuilt_api_assembly(APIAssembly::API_EDITOR))
- return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exist: */ true);
+ return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exists: */ true);
return String(); // Updated successfully
@@ -699,9 +701,6 @@ bool GDMono::_try_load_api_assemblies() {
return false;
}
- if (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)
- return false;
-
#ifdef TOOLS_ENABLED
if (!_load_editor_api_assembly()) {
if (OS::get_singleton()->is_stdout_verbose())
@@ -713,6 +712,12 @@ bool GDMono::_try_load_api_assemblies() {
return false;
#endif
+ // Check if the core API assembly is out of sync only after trying to load the
+ // editor API assembly. Otherwise, if both assemblies are out of sync, we would
+ // only update the former as we won't know the latter also needs to be updated.
+ if (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)
+ return false;
+
return true;
}