diff options
Diffstat (limited to 'modules')
119 files changed, 5051 insertions, 477 deletions
diff --git a/modules/csg/doc_classes/CSGPolygon3D.xml b/modules/csg/doc_classes/CSGPolygon3D.xml index 338adc9b52..5d35c04e25 100644 --- a/modules/csg/doc_classes/CSGPolygon3D.xml +++ b/modules/csg/doc_classes/CSGPolygon3D.xml @@ -39,7 +39,7 @@ When [member mode] is [constant MODE_PATH], the location of the [Path3D] object used to extrude the [member polygon]. </member> <member name="path_rotation" type="int" setter="set_path_rotation" getter="get_path_rotation" enum="CSGPolygon3D.PathRotation"> - When [member mode] is [constant MODE_PATH], the [enum PathRotation] method used to rotate the [member polygon] as it is extruded. + When [member mode] is [constant MODE_PATH], the path rotation method used to rotate the [member polygon] as it is extruded. </member> <member name="path_simplify_angle" type="float" setter="set_path_simplify_angle" getter="get_path_simplify_angle"> When [member mode] is [constant MODE_PATH], extrusions that are less than this angle, will be merged together to reduce polygon count. diff --git a/modules/csg/editor/csg_gizmos.cpp b/modules/csg/editor/csg_gizmos.cpp index ebf0f5a91f..ea7b6d225e 100644 --- a/modules/csg/editor/csg_gizmos.cpp +++ b/modules/csg/editor/csg_gizmos.cpp @@ -44,7 +44,7 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() { helper.instantiate(); - Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.0, 0.4, 1, 0.15)); + Color gizmo_color = EDITOR_DEF_RST("editors/3d_gizmos/gizmo_colors/csg", Color(0.0, 0.4, 1, 0.15)); create_material("shape_union_material", gizmo_color); create_material("shape_union_solid_material", gizmo_color); gizmo_color.invert(); diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index 7baf8506a6..b2de6b656e 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -55,7 +55,39 @@ enum DDSFourCC { DDFCC_BC4U = PF_FOURCC("BC4U"), DDFCC_ATI2 = PF_FOURCC("ATI2"), DDFCC_BC5U = PF_FOURCC("BC5U"), - DDFCC_A2XY = PF_FOURCC("A2XY") + DDFCC_A2XY = PF_FOURCC("A2XY"), + DDFCC_DX10 = PF_FOURCC("DX10"), + DDFCC_R16F = 111, + DDFCC_RG16F = 112, + DDFCC_RGBA16F = 113, + DDFCC_R32F = 114, + DDFCC_RG32F = 115, + DDFCC_RGBA32F = 116 +}; + +// Reference: https://learn.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format +enum DXGIFormat { + DXGI_R32G32B32A32_FLOAT = 2, + DXGI_R16G16B16A16_FLOAT = 10, + DXGI_R32G32_FLOAT = 16, + DXGI_R10G10B10A2_UNORM = 24, + DXGI_R8G8B8A8_UNORM = 28, + DXGI_R16G16_FLOAT = 34, + DXGI_R32_FLOAT = 41, + DXGI_R16_FLOAT = 54, + DXGI_R9G9B9E5 = 67, + DXGI_BC1_UNORM = 71, + DXGI_BC2_UNORM = 74, + DXGI_BC3_UNORM = 77, + DXGI_BC4_UNORM = 80, + DXGI_BC5_UNORM = 83, + DXGI_B5G6R5_UNORM = 85, + DXGI_B5G5R5A1_UNORM = 86, + DXGI_B8G8R8A8_UNORM = 87, + DXGI_BC6H_UF16 = 95, + DXGI_BC6H_SF16 = 96, + DXGI_BC7_UNORM = 98, + DXGI_B4G4R4A4_UNORM = 115 }; // The legacy bitmasked format names here represent the actual data layout in the files, @@ -66,6 +98,16 @@ enum DDSFormat { DDS_DXT5, DDS_ATI1, DDS_ATI2, + DDS_BC6U, + DDS_BC6S, + DDS_BC7U, + DDS_R16F, + DDS_RG16F, + DDS_RGBA16F, + DDS_R32F, + DDS_RG32F, + DDS_RGBA32F, + DDS_RGB9E5, DDS_BGRA8, DDS_BGR8, DDS_RGBA8, @@ -73,6 +115,8 @@ enum DDSFormat { DDS_BGR5A1, DDS_BGR565, DDS_BGR10A2, + DDS_RGB10A2, + DDS_BGRA4, DDS_LUMINANCE, DDS_LUMINANCE_ALPHA, DDS_MAX @@ -92,6 +136,16 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "DXT5/BC3", true, 4, 16, Image::FORMAT_DXT5 }, { "ATI1/BC4", true, 4, 8, Image::FORMAT_RGTC_R }, { "ATI2/A2XY/BC5", true, 4, 16, Image::FORMAT_RGTC_RG }, + { "BC6U", true, 4, 16, Image::FORMAT_BPTC_RGBFU }, + { "BC6S", true, 4, 16, Image::FORMAT_BPTC_RGBF }, + { "BC7U", true, 4, 16, Image::FORMAT_BPTC_RGBA }, + { "R16F", false, 1, 2, Image::FORMAT_RH }, + { "RG16F", false, 1, 4, Image::FORMAT_RGH }, + { "RGBA16F", false, 1, 8, Image::FORMAT_RGBAH }, + { "R32F", false, 1, 4, Image::FORMAT_RF }, + { "RG32F", false, 1, 8, Image::FORMAT_RGF }, + { "RGBA32F", false, 1, 16, Image::FORMAT_RGBAF }, + { "RGB9E5", false, 1, 4, Image::FORMAT_RGBE9995 }, { "BGRA8", false, 1, 4, Image::FORMAT_RGBA8 }, { "BGR8", false, 1, 3, Image::FORMAT_RGB8 }, { "RGBA8", false, 1, 4, Image::FORMAT_RGBA8 }, @@ -99,10 +153,84 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "BGR5A1", false, 1, 2, Image::FORMAT_RGBA8 }, { "BGR565", false, 1, 2, Image::FORMAT_RGB8 }, { "BGR10A2", false, 1, 4, Image::FORMAT_RGBA8 }, + { "RGB10A2", false, 1, 4, Image::FORMAT_RGBA8 }, + { "BGRA4", false, 1, 2, Image::FORMAT_RGBA8 }, { "GRAYSCALE", false, 1, 1, Image::FORMAT_L8 }, { "GRAYSCALE_ALPHA", false, 1, 2, Image::FORMAT_LA8 } }; +static DDSFormat dxgi_to_dds_format(uint32_t p_dxgi_format) { + switch (p_dxgi_format) { + case DXGI_R32G32B32A32_FLOAT: { + return DDS_RGBA32F; + } + case DXGI_R16G16B16A16_FLOAT: { + return DDS_RGBA16F; + } + case DXGI_R32G32_FLOAT: { + return DDS_RG32F; + } + case DXGI_R10G10B10A2_UNORM: { + return DDS_RGB10A2; + } + case DXGI_R8G8B8A8_UNORM: { + return DDS_RGBA8; + } + case DXGI_R16G16_FLOAT: { + return DDS_RG16F; + } + case DXGI_R32_FLOAT: { + return DDS_R32F; + } + case DXGI_R16_FLOAT: { + return DDS_R16F; + } + case DXGI_R9G9B9E5: { + return DDS_RGB9E5; + } + case DXGI_BC1_UNORM: { + return DDS_DXT1; + } + case DXGI_BC2_UNORM: { + return DDS_DXT3; + } + case DXGI_BC3_UNORM: { + return DDS_DXT5; + } + case DXGI_BC4_UNORM: { + return DDS_ATI1; + } + case DXGI_BC5_UNORM: { + return DDS_ATI2; + } + case DXGI_B5G6R5_UNORM: { + return DDS_BGR565; + } + case DXGI_B5G5R5A1_UNORM: { + return DDS_BGR5A1; + } + case DXGI_B8G8R8A8_UNORM: { + return DDS_BGRA8; + } + case DXGI_BC6H_UF16: { + return DDS_BC6U; + } + case DXGI_BC6H_SF16: { + return DDS_BC6S; + } + case DXGI_BC7_UNORM: { + return DDS_BC7U; + } + case DXGI_B4G4R4A4_UNORM: { + return DDS_BGRA4; + } + + default: { + return DDS_MAX; + } + } +} + Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_CANT_OPEN; @@ -186,6 +314,33 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig case DDFCC_A2XY: { dds_format = DDS_ATI2; } break; + case DDFCC_R16F: { + dds_format = DDS_R16F; + } break; + case DDFCC_RG16F: { + dds_format = DDS_RG16F; + } break; + case DDFCC_RGBA16F: { + dds_format = DDS_RGBA16F; + } break; + case DDFCC_R32F: { + dds_format = DDS_R32F; + } break; + case DDFCC_RG32F: { + dds_format = DDS_RG32F; + } break; + case DDFCC_RGBA32F: { + dds_format = DDS_RGBA32F; + } break; + case DDFCC_DX10: { + uint32_t dxgi_format = f->get_32(); + /* uint32_t dimension = */ f->get_32(); + /* uint32_t misc_flags_1 = */ f->get_32(); + /* uint32_t array_size = */ f->get_32(); + /* uint32_t misc_flags_2 = */ f->get_32(); + + dds_format = dxgi_to_dds_format(dxgi_format); + } break; default: { ERR_FAIL_V_MSG(Ref<Resource>(), "Unrecognized or unsupported FourCC in DDS '" + p_path + "'."); @@ -204,6 +359,10 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig dds_format = DDS_BGR5A1; } else if (format_rgb_bits == 32 && format_red_mask == 0x3ff00000 && format_green_mask == 0xffc00 && format_blue_mask == 0x3ff && format_alpha_mask == 0xc0000000) { dds_format = DDS_BGR10A2; + } else if (format_rgb_bits == 32 && format_red_mask == 0x3ff && format_green_mask == 0xffc00 && format_blue_mask == 0x3ff00000 && format_alpha_mask == 0xc0000000) { + dds_format = DDS_RGB10A2; + } else if (format_rgb_bits == 16 && format_red_mask == 0xf00 && format_green_mask == 0xf0 && format_blue_mask == 0xf && format_alpha_mask == 0xf000) { + dds_format = DDS_BGRA4; } } else { @@ -245,8 +404,11 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig // BC compressed. uint32_t size = MAX(info.divisor, w) / info.divisor * MAX(info.divisor, h) / info.divisor * info.block_size; - ERR_FAIL_COND_V(size != pitch, Ref<Resource>()); - ERR_FAIL_COND_V(!(flags & DDSD_LINEARSIZE), Ref<Resource>()); + if (flags & DDSD_LINEARSIZE) { + ERR_FAIL_COND_V_MSG(size != pitch, Ref<Resource>(), "DDS header flags specify that a linear size of the top-level image is present, but the specified size does not match the expected value."); + } else { + ERR_FAIL_COND_V_MSG(pitch != 0, Ref<Resource>(), "DDS header flags specify that no linear size will given for the top-level image, but a non-zero linear size value is present in the header."); + } for (uint32_t i = 1; i < mipmaps; i++) { w = MAX(1u, w >> 1); @@ -273,7 +435,7 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig // Calculate the space these formats will take up after decoding. if (dds_format == DDS_BGR565) { size = size * 3 / 2; - } else if (dds_format == DDS_BGR5A1) { + } else if (dds_format == DDS_BGR5A1 || dds_format == DDS_BGRA4) { size = size * 2; } @@ -321,6 +483,49 @@ Ref<Resource> ResourceFormatDDS::load(const String &p_path, const String &p_orig } } break; + case DDS_BGRA4: { + // To RGBA8. + int colcount = size / 4; + + for (int i = colcount - 1; i >= 0; i--) { + int src_ofs = i * 2; + int dst_ofs = i * 4; + + uint8_t b = wb[src_ofs] & 0x0F; + uint8_t g = wb[src_ofs] & 0xF0; + uint8_t r = wb[src_ofs + 1] & 0x0F; + uint8_t a = wb[src_ofs + 1] & 0xF0; + + wb[dst_ofs] = (r << 4) | r; + wb[dst_ofs + 1] = g | (g >> 4); + wb[dst_ofs + 2] = (b << 4) | b; + wb[dst_ofs + 3] = a | (a >> 4); + } + + } break; + case DDS_RGB10A2: { + // To RGBA8. + int colcount = size / 4; + + for (int i = 0; i < colcount; i++) { + int ofs = i * 4; + + uint32_t w32 = uint32_t(wb[ofs + 0]) | (uint32_t(wb[ofs + 1]) << 8) | (uint32_t(wb[ofs + 2]) << 16) | (uint32_t(wb[ofs + 3]) << 24); + + // This method follows the 'standard' way of decoding 10-bit dds files, + // which means the ones created with DirectXTex will be loaded incorrectly. + uint8_t a = (w32 & 0xc0000000) >> 24; + uint8_t r = (w32 & 0x3ff) >> 2; + uint8_t g = (w32 & 0xffc00) >> 12; + uint8_t b = (w32 & 0x3ff00000) >> 22; + + wb[ofs + 0] = r; + wb[ofs + 1] = g; + wb[ofs + 2] = b; + wb[ofs + 3] = a == 0xc0 ? 255 : a; // 0xc0 should be opaque. + } + + } break; case DDS_BGR10A2: { // To RGBA8. int colcount = size / 4; diff --git a/modules/etcpak/SCsub b/modules/etcpak/SCsub index 2d3b69be75..3a4bff8e87 100644 --- a/modules/etcpak/SCsub +++ b/modules/etcpak/SCsub @@ -13,6 +13,7 @@ thirdparty_dir = "#thirdparty/etcpak/" thirdparty_sources = [ "Dither.cpp", "ProcessDxtc.cpp", + "ProcessRgtc.cpp", "ProcessRGB.cpp", "Tables.cpp", ] diff --git a/modules/etcpak/image_compress_etcpak.cpp b/modules/etcpak/image_compress_etcpak.cpp index 14cce2686c..f528b92cf2 100644 --- a/modules/etcpak/image_compress_etcpak.cpp +++ b/modules/etcpak/image_compress_etcpak.cpp @@ -35,6 +35,7 @@ #include <ProcessDxtc.hpp> #include <ProcessRGB.hpp> +#include <ProcessRgtc.hpp> EtcpakType _determine_etc_type(Image::UsedChannels p_channels) { switch (p_channels) { @@ -62,9 +63,9 @@ EtcpakType _determine_dxt_type(Image::UsedChannels p_channels) { case Image::USED_CHANNELS_LA: return EtcpakType::ETCPAK_TYPE_DXT5; case Image::USED_CHANNELS_R: - return EtcpakType::ETCPAK_TYPE_DXT5; + return EtcpakType::ETCPAK_TYPE_RGTC_R; case Image::USED_CHANNELS_RG: - return EtcpakType::ETCPAK_TYPE_DXT5_RA_AS_RG; + return EtcpakType::ETCPAK_TYPE_RGTC_RG; case Image::USED_CHANNELS_RGB: return EtcpakType::ETCPAK_TYPE_DXT1; case Image::USED_CHANNELS_RGBA: @@ -127,6 +128,10 @@ void _compress_etcpak(EtcpakType p_compresstype, Image *r_img) { r_img->convert_rg_to_ra_rgba8(); } else if (p_compresstype == EtcpakType::ETCPAK_TYPE_DXT5) { target_format = Image::FORMAT_DXT5; + } else if (p_compresstype == EtcpakType::ETCPAK_TYPE_RGTC_R) { + target_format = Image::FORMAT_RGTC_R; + } else if (p_compresstype == EtcpakType::ETCPAK_TYPE_RGTC_RG) { + target_format = Image::FORMAT_RGTC_RG; } else { ERR_FAIL_MSG("Invalid or unsupported etcpak compression format, not ETC or DXT."); } @@ -229,6 +234,10 @@ void _compress_etcpak(EtcpakType p_compresstype, Image *r_img) { CompressDxt1Dither(src_mip_read, dest_mip_write, blocks, mip_w); } else if (p_compresstype == EtcpakType::ETCPAK_TYPE_DXT5 || p_compresstype == EtcpakType::ETCPAK_TYPE_DXT5_RA_AS_RG) { CompressDxt5(src_mip_read, dest_mip_write, blocks, mip_w); + } else if (p_compresstype == EtcpakType::ETCPAK_TYPE_RGTC_RG) { + CompressRgtcRG(src_mip_read, dest_mip_write, blocks, mip_w); + } else if (p_compresstype == EtcpakType::ETCPAK_TYPE_RGTC_R) { + CompressRgtcR(src_mip_read, dest_mip_write, blocks, mip_w); } else { ERR_FAIL_MSG("etcpak: Invalid or unsupported compression format."); } diff --git a/modules/etcpak/image_compress_etcpak.h b/modules/etcpak/image_compress_etcpak.h index ff267631a6..ff8bb635b4 100644 --- a/modules/etcpak/image_compress_etcpak.h +++ b/modules/etcpak/image_compress_etcpak.h @@ -41,6 +41,8 @@ enum class EtcpakType { ETCPAK_TYPE_DXT1, ETCPAK_TYPE_DXT5, ETCPAK_TYPE_DXT5_RA_AS_RG, + ETCPAK_TYPE_RGTC_R, + ETCPAK_TYPE_RGTC_RG, }; void _compress_etc1(Image *r_img); diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 3da6bcf10c..933bfba5ba 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -148,7 +148,7 @@ <return type="int" /> <param index="0" name="var" type="Variant" /> <description> - Returns the length of the given Variant [param var]. The length can be the character count of a [String], the element count of any array type or the size of a [Dictionary]. For every other Variant type, a run-time error is generated and execution is stopped. + Returns the length of the given Variant [param var]. The length can be the character count of a [String] or [StringName], the element count of any array type, or the size of a [Dictionary]. For every other Variant type, a run-time error is generated and execution is stopped. [codeblock] a = [1, 2, 3, 4] len(a) # Returns 4 @@ -162,7 +162,7 @@ <return type="Resource" /> <param index="0" name="path" type="String" /> <description> - Returns a [Resource] from the filesystem located at the absolute [param path]. Unless it's already referenced elsewhere (such as in another script or in the scene), the resource is loaded from disk on function call, which might cause a slight delay, especially when loading large scenes. To avoid unnecessary delays when loading something multiple times, either store the resource in a variable or use [method preload]. + Returns a [Resource] from the filesystem located at the absolute [param path]. Unless it's already referenced elsewhere (such as in another script or in the scene), the resource is loaded from disk on function call, which might cause a slight delay, especially when loading large scenes. To avoid unnecessary delays when loading something multiple times, either store the resource in a variable or use [method preload]. This method is equivalent of using [method ResourceLoader.load] with [constant ResourceLoader.CACHE_MODE_REUSE]. [b]Note:[/b] Resource paths can be obtained by right-clicking on a resource in the FileSystem dock and choosing "Copy Path", or by dragging the file from the FileSystem dock into the current script. [codeblock] # Load a scene called "main" located in the root of the project directory and cache it in a variable. diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp index 9128f104b8..f55b00ebe1 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp @@ -80,7 +80,7 @@ bool GDScriptEditorTranslationParserPlugin::_is_constant_string(const GDScriptPa void GDScriptEditorTranslationParserPlugin::_traverse_class(const GDScriptParser::ClassNode *p_class) { for (int i = 0; i < p_class->members.size(); i++) { const GDScriptParser::ClassNode::Member &m = p_class->members[i]; - // There are 7 types of Member, but only class, function and variable can contain translatable strings. + // Other member types can't contain translatable strings. switch (m.type) { case GDScriptParser::ClassNode::Member::CLASS: _traverse_class(m.m_class); @@ -89,7 +89,11 @@ void GDScriptEditorTranslationParserPlugin::_traverse_class(const GDScriptParser _traverse_function(m.function); break; case GDScriptParser::ClassNode::Member::VARIABLE: - _read_variable(m.variable); + _assess_expression(m.variable->initializer); + if (m.variable->property == GDScriptParser::VariableNode::PROP_INLINE) { + _traverse_function(m.variable->setter); + _traverse_function(m.variable->getter); + } break; default: break; @@ -98,11 +102,14 @@ void GDScriptEditorTranslationParserPlugin::_traverse_class(const GDScriptParser } void GDScriptEditorTranslationParserPlugin::_traverse_function(const GDScriptParser::FunctionNode *p_func) { - _traverse_block(p_func->body); -} + if (!p_func) { + return; + } -void GDScriptEditorTranslationParserPlugin::_read_variable(const GDScriptParser::VariableNode *p_var) { - _assess_expression(p_var->initializer); + for (int i = 0; i < p_func->parameters.size(); i++) { + _assess_expression(p_func->parameters[i]->initializer); + } + _traverse_block(p_func->body); } void GDScriptEditorTranslationParserPlugin::_traverse_block(const GDScriptParser::SuiteNode *p_suite) { @@ -114,53 +121,51 @@ void GDScriptEditorTranslationParserPlugin::_traverse_block(const GDScriptParser for (int i = 0; i < statements.size(); i++) { const GDScriptParser::Node *statement = statements[i]; - // Statements with Node type constant, break, continue, pass, breakpoint are skipped because they can't contain translatable strings. + // BREAK, BREAKPOINT, CONSTANT, CONTINUE, and PASS are skipped because they can't contain translatable strings. switch (statement->type) { - case GDScriptParser::Node::VARIABLE: - _assess_expression(static_cast<const GDScriptParser::VariableNode *>(statement)->initializer); - break; + case GDScriptParser::Node::ASSERT: { + const GDScriptParser::AssertNode *assert_node = static_cast<const GDScriptParser::AssertNode *>(statement); + _assess_expression(assert_node->condition); + _assess_expression(assert_node->message); + } break; + case GDScriptParser::Node::ASSIGNMENT: { + _assess_assignment(static_cast<const GDScriptParser::AssignmentNode *>(statement)); + } break; + case GDScriptParser::Node::FOR: { + const GDScriptParser::ForNode *for_node = static_cast<const GDScriptParser::ForNode *>(statement); + _assess_expression(for_node->list); + _traverse_block(for_node->loop); + } break; case GDScriptParser::Node::IF: { const GDScriptParser::IfNode *if_node = static_cast<const GDScriptParser::IfNode *>(statement); _assess_expression(if_node->condition); - //FIXME : if the elif logic is changed in GDScriptParser, then this probably will have to change as well. See GDScriptParser::TreePrinter::print_if(). _traverse_block(if_node->true_block); _traverse_block(if_node->false_block); - break; - } - case GDScriptParser::Node::FOR: { - const GDScriptParser::ForNode *for_node = static_cast<const GDScriptParser::ForNode *>(statement); - _assess_expression(for_node->list); - _traverse_block(for_node->loop); - break; - } - case GDScriptParser::Node::WHILE: { - const GDScriptParser::WhileNode *while_node = static_cast<const GDScriptParser::WhileNode *>(statement); - _assess_expression(while_node->condition); - _traverse_block(while_node->loop); - break; - } + } break; case GDScriptParser::Node::MATCH: { const GDScriptParser::MatchNode *match_node = static_cast<const GDScriptParser::MatchNode *>(statement); _assess_expression(match_node->test); for (int j = 0; j < match_node->branches.size(); j++) { + _traverse_block(match_node->branches[j]->guard_body); _traverse_block(match_node->branches[j]->block); } - break; - } - case GDScriptParser::Node::RETURN: + } break; + case GDScriptParser::Node::RETURN: { _assess_expression(static_cast<const GDScriptParser::ReturnNode *>(statement)->return_value); - break; - case GDScriptParser::Node::ASSERT: - _assess_expression((static_cast<const GDScriptParser::AssertNode *>(statement))->condition); - break; - case GDScriptParser::Node::ASSIGNMENT: - _assess_assignment(static_cast<const GDScriptParser::AssignmentNode *>(statement)); - break; - default: + } break; + case GDScriptParser::Node::VARIABLE: { + _assess_expression(static_cast<const GDScriptParser::VariableNode *>(statement)->initializer); + } break; + case GDScriptParser::Node::WHILE: { + const GDScriptParser::WhileNode *while_node = static_cast<const GDScriptParser::WhileNode *>(statement); + _assess_expression(while_node->condition); + _traverse_block(while_node->loop); + } break; + default: { if (statement->is_expression()) { _assess_expression(static_cast<const GDScriptParser::ExpressionNode *>(statement)); } - break; + } break; } } } @@ -172,25 +177,25 @@ void GDScriptEditorTranslationParserPlugin::_assess_expression(const GDScriptPar return; } - // ExpressionNode of type await, cast, get_node, identifier, literal, preload, self, subscript, unary are ignored as they can't be CallNode - // containing translation strings. + // GET_NODE, IDENTIFIER, LITERAL, PRELOAD, SELF, and TYPE are skipped because they can't contain translatable strings. switch (p_expression->type) { case GDScriptParser::Node::ARRAY: { const GDScriptParser::ArrayNode *array_node = static_cast<const GDScriptParser::ArrayNode *>(p_expression); for (int i = 0; i < array_node->elements.size(); i++) { _assess_expression(array_node->elements[i]); } - break; - } - case GDScriptParser::Node::ASSIGNMENT: + } break; + case GDScriptParser::Node::ASSIGNMENT: { _assess_assignment(static_cast<const GDScriptParser::AssignmentNode *>(p_expression)); - break; + } break; + case GDScriptParser::Node::AWAIT: { + _assess_expression(static_cast<const GDScriptParser::AwaitNode *>(p_expression)->to_await); + } break; case GDScriptParser::Node::BINARY_OPERATOR: { const GDScriptParser::BinaryOpNode *binary_op_node = static_cast<const GDScriptParser::BinaryOpNode *>(p_expression); _assess_expression(binary_op_node->left_operand); _assess_expression(binary_op_node->right_operand); - break; - } + } break; case GDScriptParser::Node::CALL: { const GDScriptParser::CallNode *call_node = static_cast<const GDScriptParser::CallNode *>(p_expression); _extract_from_call(call_node); @@ -198,23 +203,40 @@ void GDScriptEditorTranslationParserPlugin::_assess_expression(const GDScriptPar _assess_expression(call_node->arguments[i]); } } break; + case GDScriptParser::Node::CAST: { + _assess_expression(static_cast<const GDScriptParser::CastNode *>(p_expression)->operand); + } break; case GDScriptParser::Node::DICTIONARY: { const GDScriptParser::DictionaryNode *dict_node = static_cast<const GDScriptParser::DictionaryNode *>(p_expression); for (int i = 0; i < dict_node->elements.size(); i++) { _assess_expression(dict_node->elements[i].key); _assess_expression(dict_node->elements[i].value); } - break; - } + } break; + case GDScriptParser::Node::LAMBDA: { + _traverse_function(static_cast<const GDScriptParser::LambdaNode *>(p_expression)->function); + } break; + case GDScriptParser::Node::SUBSCRIPT: { + const GDScriptParser::SubscriptNode *subscript_node = static_cast<const GDScriptParser::SubscriptNode *>(p_expression); + _assess_expression(subscript_node->base); + if (!subscript_node->is_attribute) { + _assess_expression(subscript_node->index); + } + } break; case GDScriptParser::Node::TERNARY_OPERATOR: { const GDScriptParser::TernaryOpNode *ternary_op_node = static_cast<const GDScriptParser::TernaryOpNode *>(p_expression); _assess_expression(ternary_op_node->condition); _assess_expression(ternary_op_node->true_expr); _assess_expression(ternary_op_node->false_expr); - break; - } - default: - break; + } break; + case GDScriptParser::Node::TYPE_TEST: { + _assess_expression(static_cast<const GDScriptParser::TypeTestNode *>(p_expression)->operand); + } break; + case GDScriptParser::Node::UNARY_OPERATOR: { + _assess_expression(static_cast<const GDScriptParser::UnaryOpNode *>(p_expression)->operand); + } break; + default: { + } break; } } diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h index 580c2a80cd..fab79a925f 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h @@ -59,7 +59,6 @@ class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlug void _traverse_function(const GDScriptParser::FunctionNode *p_func); void _traverse_block(const GDScriptParser::SuiteNode *p_suite); - void _read_variable(const GDScriptParser::VariableNode *p_var); void _assess_expression(const GDScriptParser::ExpressionNode *p_expression); void _assess_assignment(const GDScriptParser::AssignmentNode *p_assignment); void _extract_from_call(const GDScriptParser::CallNode *p_call); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index ec1682d470..a999acd1bd 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1117,8 +1117,7 @@ GDScript *GDScript::find_class(const String &p_qualified_name) { // Starts at index 1 because index 0 was handled above. for (int i = 1; result != nullptr && i < class_names.size(); i++) { - String current_name = class_names[i]; - if (HashMap<StringName, Ref<GDScript>>::Iterator E = result->subclasses.find(current_name)) { + if (HashMap<StringName, Ref<GDScript>>::Iterator E = result->subclasses.find(class_names[i])) { result = E->value.ptr(); } else { // Couldn't find inner class. @@ -1156,8 +1155,8 @@ RBSet<GDScript *> GDScript::get_dependencies() { return dependencies; } -RBSet<GDScript *> GDScript::get_inverted_dependencies() { - RBSet<GDScript *> inverted_dependencies; +HashMap<GDScript *, RBSet<GDScript *>> GDScript::get_all_dependencies() { + HashMap<GDScript *, RBSet<GDScript *>> all_dependencies; List<GDScript *> scripts; { @@ -1171,51 +1170,42 @@ RBSet<GDScript *> GDScript::get_inverted_dependencies() { } for (GDScript *scr : scripts) { - if (scr == nullptr || scr == this || scr->destructing) { + if (scr == nullptr || scr->destructing) { continue; } - - RBSet<GDScript *> scr_dependencies = scr->get_dependencies(); - if (scr_dependencies.has(this)) { - inverted_dependencies.insert(scr); - } + all_dependencies.insert(scr, scr->get_dependencies()); } - return inverted_dependencies; + return all_dependencies; } RBSet<GDScript *> GDScript::get_must_clear_dependencies() { RBSet<GDScript *> dependencies = get_dependencies(); RBSet<GDScript *> must_clear_dependencies; - HashMap<GDScript *, RBSet<GDScript *>> inverted_dependencies; - - for (GDScript *E : dependencies) { - inverted_dependencies.insert(E, E->get_inverted_dependencies()); - } + HashMap<GDScript *, RBSet<GDScript *>> all_dependencies = get_all_dependencies(); RBSet<GDScript *> cant_clear; - for (KeyValue<GDScript *, RBSet<GDScript *>> &E : inverted_dependencies) { + for (KeyValue<GDScript *, RBSet<GDScript *>> &E : all_dependencies) { + if (dependencies.has(E.key)) { + continue; + } for (GDScript *F : E.value) { - if (!dependencies.has(F)) { - cant_clear.insert(E.key); - for (GDScript *G : E.key->get_dependencies()) { - cant_clear.insert(G); - } - break; + if (dependencies.has(F)) { + cant_clear.insert(F); } } } - for (KeyValue<GDScript *, RBSet<GDScript *>> &E : inverted_dependencies) { - if (cant_clear.has(E.key) || ScriptServer::is_global_class(E.key->get_fully_qualified_name())) { + for (GDScript *E : dependencies) { + if (cant_clear.has(E) || ScriptServer::is_global_class(E->get_fully_qualified_name())) { continue; } - must_clear_dependencies.insert(E.key); + must_clear_dependencies.insert(E); } cant_clear.clear(); dependencies.clear(); - inverted_dependencies.clear(); + all_dependencies.clear(); return must_clear_dependencies; } @@ -2230,6 +2220,8 @@ void GDScriptLanguage::profiling_start() { elem->self()->profile.last_frame_call_count = 0; elem->self()->profile.last_frame_self_time = 0; elem->self()->profile.last_frame_total_time = 0; + elem->self()->profile.native_calls.clear(); + elem->self()->profile.last_native_calls.clear(); elem = elem->next(); } @@ -2237,6 +2229,13 @@ void GDScriptLanguage::profiling_start() { #endif } +void GDScriptLanguage::profiling_set_save_native_calls(bool p_enable) { +#ifdef DEBUG_ENABLED + MutexLock lock(mutex); + profile_native_calls = p_enable; +#endif +} + void GDScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED MutexLock lock(this->mutex); @@ -2251,17 +2250,32 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, MutexLock lock(this->mutex); + profiling_collate_native_call_data(true); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { if (current >= p_info_max) { break; } + int last_non_internal = current; p_info_arr[current].call_count = elem->self()->profile.call_count.get(); p_info_arr[current].self_time = elem->self()->profile.self_time.get(); p_info_arr[current].total_time = elem->self()->profile.total_time.get(); p_info_arr[current].signature = elem->self()->profile.signature; - elem = elem->next(); current++; + + int nat_time = 0; + HashMap<String, GDScriptFunction::Profile::NativeProfile>::ConstIterator nat_calls = elem->self()->profile.native_calls.begin(); + while (nat_calls) { + p_info_arr[current].call_count = nat_calls->value.call_count; + p_info_arr[current].total_time = nat_calls->value.total_time; + p_info_arr[current].self_time = nat_calls->value.total_time; + p_info_arr[current].signature = nat_calls->value.signature; + nat_time += nat_calls->value.total_time; + current++; + ++nat_calls; + } + p_info_arr[last_non_internal].internal_time = nat_time; + elem = elem->next(); } #endif @@ -2274,17 +2288,33 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ #ifdef DEBUG_ENABLED MutexLock lock(this->mutex); + profiling_collate_native_call_data(false); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { if (current >= p_info_max) { break; } if (elem->self()->profile.last_frame_call_count > 0) { + int last_non_internal = current; p_info_arr[current].call_count = elem->self()->profile.last_frame_call_count; p_info_arr[current].self_time = elem->self()->profile.last_frame_self_time; p_info_arr[current].total_time = elem->self()->profile.last_frame_total_time; p_info_arr[current].signature = elem->self()->profile.signature; current++; + + int nat_time = 0; + HashMap<String, GDScriptFunction::Profile::NativeProfile>::ConstIterator nat_calls = elem->self()->profile.last_native_calls.begin(); + while (nat_calls) { + p_info_arr[current].call_count = nat_calls->value.call_count; + p_info_arr[current].total_time = nat_calls->value.total_time; + p_info_arr[current].self_time = nat_calls->value.total_time; + p_info_arr[current].internal_time = nat_calls->value.total_time; + p_info_arr[current].signature = nat_calls->value.signature; + nat_time += nat_calls->value.total_time; + current++; + ++nat_calls; + } + p_info_arr[last_non_internal].internal_time = nat_time; } elem = elem->next(); } @@ -2293,6 +2323,33 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ return current; } +void GDScriptLanguage::profiling_collate_native_call_data(bool p_accumulated) { +#ifdef DEBUG_ENABLED + // The same native call can be called from multiple functions, so join them together here. + // Only use the name of the function (ie signature.split[2]). + HashMap<String, GDScriptFunction::Profile::NativeProfile *> seen_nat_calls; + SelfList<GDScriptFunction> *elem = function_list.first(); + while (elem) { + HashMap<String, GDScriptFunction::Profile::NativeProfile> *nat_calls = p_accumulated ? &elem->self()->profile.native_calls : &elem->self()->profile.last_native_calls; + HashMap<String, GDScriptFunction::Profile::NativeProfile>::Iterator it = nat_calls->begin(); + + while (it != nat_calls->end()) { + Vector<String> sig = it->value.signature.split("::"); + HashMap<String, GDScriptFunction::Profile::NativeProfile *>::ConstIterator already_found = seen_nat_calls.find(sig[2]); + if (already_found) { + already_found->value->total_time += it->value.total_time; + already_found->value->call_count += it->value.call_count; + elem->self()->profile.last_native_calls.remove(it); + } else { + seen_nat_calls.insert(sig[2], &it->value); + } + ++it; + } + elem = elem->next(); + } +#endif +} + struct GDScriptDepSort { //must support sorting so inheritance works properly (parent must be reloaded first) bool operator()(const Ref<GDScript> &A, const Ref<GDScript> &B) const { @@ -2492,9 +2549,11 @@ void GDScriptLanguage::frame() { elem->self()->profile.last_frame_call_count = elem->self()->profile.frame_call_count.get(); elem->self()->profile.last_frame_self_time = elem->self()->profile.frame_self_time.get(); elem->self()->profile.last_frame_total_time = elem->self()->profile.frame_total_time.get(); + elem->self()->profile.last_native_calls = elem->self()->profile.native_calls; elem->self()->profile.frame_call_count.set(0); elem->self()->profile.frame_self_time.set(0); elem->self()->profile.frame_total_time.set(0); + elem->self()->profile.native_calls.clear(); elem = elem->next(); } } diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index aba4d7e721..31811bba47 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -254,7 +254,7 @@ public: const Ref<GDScriptNativeClass> &get_native() const { return native; } RBSet<GDScript *> get_dependencies(); - RBSet<GDScript *> get_inverted_dependencies(); + HashMap<GDScript *, RBSet<GDScript *>> get_all_dependencies(); RBSet<GDScript *> get_must_clear_dependencies(); virtual bool has_script_signal(const StringName &p_signal) const override; @@ -439,6 +439,7 @@ class GDScriptLanguage : public ScriptLanguage { SelfList<GDScriptFunction>::List function_list; bool profiling; + bool profile_native_calls; uint64_t script_frame_time; HashMap<String, ObjectID> orphan_subclasses; @@ -590,6 +591,8 @@ public: virtual void profiling_start() override; virtual void profiling_stop() override; + virtual void profiling_set_save_native_calls(bool p_enable) override; + void profiling_collate_native_call_data(bool p_accumulated); virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override; virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 55bd0f97d5..cf537bde16 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3658,6 +3658,10 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod return; } } + if (Variant::has_builtin_method(base.builtin_type, name)) { + p_identifier->set_datatype(make_callable_type(Variant::get_builtin_method_info(base.builtin_type, name))); + return; + } if (base.is_hard_type()) { #ifdef SUGGEST_GODOT4_RENAMES String rename_hint = String(); @@ -3777,6 +3781,60 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod } } + // Check non-GDScript scripts. + Ref<Script> script_type = base.script_type; + + if (base_class == nullptr && script_type.is_valid()) { + List<PropertyInfo> property_list; + script_type->get_script_property_list(&property_list); + + for (const PropertyInfo &property_info : property_list) { + if (property_info.name != p_identifier->name) { + continue; + } + + const GDScriptParser::DataType property_type = GDScriptAnalyzer::type_from_property(property_info, false, false); + + p_identifier->set_datatype(property_type); + p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_VARIABLE; + return; + } + + MethodInfo method_info = script_type->get_method_info(p_identifier->name); + + if (method_info.name == p_identifier->name) { + p_identifier->set_datatype(make_callable_type(method_info)); + p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_FUNCTION; + return; + } + + List<MethodInfo> signal_list; + script_type->get_script_signal_list(&signal_list); + + for (const MethodInfo &signal_info : signal_list) { + if (signal_info.name != p_identifier->name) { + continue; + } + + const GDScriptParser::DataType signal_type = make_signal_type(signal_info); + + p_identifier->set_datatype(signal_type); + p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_SIGNAL; + return; + } + + HashMap<StringName, Variant> constant_map; + script_type->get_constants(&constant_map); + + if (constant_map.has(p_identifier->name)) { + Variant constant = constant_map.get(p_identifier->name); + + p_identifier->set_datatype(make_builtin_meta_type(constant.get_type())); + p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT; + return; + } + } + // Check native members. No need for native class recursion because Node exposes all Object's properties. const StringName &native = base.native_type; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index faaff53344..87617cafab 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2610,6 +2610,64 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c r_arghint = _make_arguments_hint(info, p_argidx); } + if (p_argidx == 1 && p_context.node && p_context.node->type == GDScriptParser::Node::CALL && ClassDB::is_parent_class(class_name, SNAME("Tween")) && p_method == SNAME("tween_property")) { + // Get tweened objects properties. + GDScriptParser::ExpressionNode *tweened_object = static_cast<GDScriptParser::CallNode *>(p_context.node)->arguments[0]; + StringName native_type = tweened_object->datatype.native_type; + switch (tweened_object->datatype.kind) { + case GDScriptParser::DataType::SCRIPT: { + Ref<Script> script = tweened_object->datatype.script_type; + native_type = script->get_instance_base_type(); + int n = 0; + while (script.is_valid()) { + List<PropertyInfo> properties; + script->get_script_property_list(&properties); + for (const PropertyInfo &E : properties) { + if (E.usage & (PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_INTERNAL)) { + continue; + } + ScriptLanguage::CodeCompletionOption option(E.name.quote(quote_style), ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, ScriptLanguage::CodeCompletionLocation::LOCATION_LOCAL + n); + r_result.insert(option.display, option); + } + script = script->get_base_script(); + n++; + } + } break; + case GDScriptParser::DataType::CLASS: { + GDScriptParser::ClassNode *clss = tweened_object->datatype.class_type; + native_type = clss->base_type.native_type; + int n = 0; + while (clss) { + for (GDScriptParser::ClassNode::Member member : clss->members) { + if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) { + ScriptLanguage::CodeCompletionOption option(member.get_name().quote(quote_style), ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, ScriptLanguage::CodeCompletionLocation::LOCATION_LOCAL + n); + r_result.insert(option.display, option); + } + } + if (clss->base_type.kind == GDScriptParser::DataType::Kind::CLASS) { + clss = clss->base_type.class_type; + n++; + } else { + native_type = clss->base_type.native_type; + clss = nullptr; + } + } + } break; + default: + break; + } + + List<PropertyInfo> properties; + ClassDB::get_property_list(native_type, &properties); + for (const PropertyInfo &E : properties) { + if (E.usage & (PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_INTERNAL)) { + continue; + } + ScriptLanguage::CodeCompletionOption option(E.name.quote(quote_style), ScriptLanguage::CODE_COMPLETION_KIND_MEMBER); + r_result.insert(option.display, option); + } + } + if (p_argidx == 0 && ClassDB::is_parent_class(class_name, SNAME("Node")) && (p_method == SNAME("get_node") || p_method == SNAME("has_node"))) { // Get autoloads List<PropertyInfo> props; @@ -2676,10 +2734,6 @@ static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, co if (p_context.base == nullptr) { return false; } - if (p_subscript->base->datatype.type_source == GDScriptParser::DataType::ANNOTATED_EXPLICIT) { - // Annotated type takes precedence. - return false; - } const GDScriptParser::GetNodeNode *get_node = nullptr; @@ -2689,6 +2743,11 @@ static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, co } break; case GDScriptParser::Node::IDENTIFIER: { + if (p_subscript->base->datatype.type_source == GDScriptParser::DataType::ANNOTATED_EXPLICIT) { + // Annotated type takes precedence. + return false; + } + const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(p_subscript->base); switch (identifier_node->source) { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index e63fa17cfe..177c68533e 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -474,6 +474,13 @@ private: uint64_t last_frame_call_count = 0; uint64_t last_frame_self_time = 0; uint64_t last_frame_total_time = 0; + typedef struct NativeProfile { + uint64_t call_count; + uint64_t total_time; + String signature; + } NativeProfile; + HashMap<String, NativeProfile> native_calls; + HashMap<String, NativeProfile> last_native_calls; } profile; #endif @@ -514,6 +521,7 @@ public: void debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const; #ifdef DEBUG_ENABLED + void _profile_native_call(uint64_t p_t_taken, const String &p_function_name, const String &p_instance_class_name = String()); void disassemble(const Vector<String> &p_code_lines) const; #endif diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index ea7abc9ded..f3a4f2eaa6 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -73,8 +73,11 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) { HashMap<String, String> GDScriptParser::theme_color_names; #endif +HashMap<StringName, GDScriptParser::AnnotationInfo> GDScriptParser::valid_annotations; + void GDScriptParser::cleanup() { builtin_types.clear(); + valid_annotations.clear(); } void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const { @@ -89,41 +92,42 @@ bool GDScriptParser::annotation_exists(const String &p_annotation_name) const { GDScriptParser::GDScriptParser() { // Register valid annotations. - // TODO: Should this be static? - register_annotation(MethodInfo("@tool"), AnnotationInfo::SCRIPT, &GDScriptParser::tool_annotation); - register_annotation(MethodInfo("@icon", PropertyInfo(Variant::STRING, "icon_path")), AnnotationInfo::SCRIPT, &GDScriptParser::icon_annotation); - register_annotation(MethodInfo("@static_unload"), AnnotationInfo::SCRIPT, &GDScriptParser::static_unload_annotation); - - register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation); - // Export annotations. - register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>); - register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::NIL>, varray(), true); - register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FILE, Variant::STRING>, varray(""), true); - register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_DIR, Variant::STRING>); - register_annotation(MethodInfo("@export_global_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_FILE, Variant::STRING>, varray(""), true); - register_annotation(MethodInfo("@export_global_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_DIR, Variant::STRING>); - register_annotation(MethodInfo("@export_multiline"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_MULTILINE_TEXT, Variant::STRING>); - register_annotation(MethodInfo("@export_placeholder", PropertyInfo(Variant::STRING, "placeholder")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_PLACEHOLDER_TEXT, Variant::STRING>); - register_annotation(MethodInfo("@export_range", PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max"), PropertyInfo(Variant::FLOAT, "step"), PropertyInfo(Variant::STRING, "extra_hints")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_RANGE, Variant::FLOAT>, varray(1.0, ""), true); - register_annotation(MethodInfo("@export_exp_easing", PropertyInfo(Variant::STRING, "hints")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_EXP_EASING, Variant::FLOAT>, varray(""), true); - register_annotation(MethodInfo("@export_color_no_alpha"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_COLOR_NO_ALPHA, Variant::COLOR>); - register_annotation(MethodInfo("@export_node_path", PropertyInfo(Variant::STRING, "type")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NODE_PATH_VALID_TYPES, Variant::NODE_PATH>, varray(""), true); - register_annotation(MethodInfo("@export_flags", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FLAGS, Variant::INT>, varray(), true); - register_annotation(MethodInfo("@export_flags_2d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_RENDER, Variant::INT>); - register_annotation(MethodInfo("@export_flags_2d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_PHYSICS, Variant::INT>); - register_annotation(MethodInfo("@export_flags_2d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_NAVIGATION, Variant::INT>); - register_annotation(MethodInfo("@export_flags_3d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_RENDER, Variant::INT>); - register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>); - register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>); - register_annotation(MethodInfo("@export_flags_avoidance"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_AVOIDANCE, Variant::INT>); - // Export grouping annotations. - register_annotation(MethodInfo("@export_category", PropertyInfo(Variant::STRING, "name")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_CATEGORY>); - register_annotation(MethodInfo("@export_group", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_GROUP>, varray("")); - register_annotation(MethodInfo("@export_subgroup", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_SUBGROUP>, varray("")); - // Warning annotations. - register_annotation(MethodInfo("@warning_ignore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, varray(), true); - // Networking. - register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::rpc_annotation, varray("authority", "call_remote", "unreliable", 0)); + if (unlikely(valid_annotations.is_empty())) { + register_annotation(MethodInfo("@tool"), AnnotationInfo::SCRIPT, &GDScriptParser::tool_annotation); + register_annotation(MethodInfo("@icon", PropertyInfo(Variant::STRING, "icon_path")), AnnotationInfo::SCRIPT, &GDScriptParser::icon_annotation); + register_annotation(MethodInfo("@static_unload"), AnnotationInfo::SCRIPT, &GDScriptParser::static_unload_annotation); + + register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation); + // Export annotations. + register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>); + register_annotation(MethodInfo("@export_enum", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::NIL>, varray(), true); + register_annotation(MethodInfo("@export_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FILE, Variant::STRING>, varray(""), true); + register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_DIR, Variant::STRING>); + register_annotation(MethodInfo("@export_global_file", PropertyInfo(Variant::STRING, "filter")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_FILE, Variant::STRING>, varray(""), true); + register_annotation(MethodInfo("@export_global_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_GLOBAL_DIR, Variant::STRING>); + register_annotation(MethodInfo("@export_multiline"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_MULTILINE_TEXT, Variant::STRING>); + register_annotation(MethodInfo("@export_placeholder", PropertyInfo(Variant::STRING, "placeholder")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_PLACEHOLDER_TEXT, Variant::STRING>); + register_annotation(MethodInfo("@export_range", PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max"), PropertyInfo(Variant::FLOAT, "step"), PropertyInfo(Variant::STRING, "extra_hints")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_RANGE, Variant::FLOAT>, varray(1.0, ""), true); + register_annotation(MethodInfo("@export_exp_easing", PropertyInfo(Variant::STRING, "hints")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_EXP_EASING, Variant::FLOAT>, varray(""), true); + register_annotation(MethodInfo("@export_color_no_alpha"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_COLOR_NO_ALPHA, Variant::COLOR>); + register_annotation(MethodInfo("@export_node_path", PropertyInfo(Variant::STRING, "type")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NODE_PATH_VALID_TYPES, Variant::NODE_PATH>, varray(""), true); + register_annotation(MethodInfo("@export_flags", PropertyInfo(Variant::STRING, "names")), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FLAGS, Variant::INT>, varray(), true); + register_annotation(MethodInfo("@export_flags_2d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_RENDER, Variant::INT>); + register_annotation(MethodInfo("@export_flags_2d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_PHYSICS, Variant::INT>); + register_annotation(MethodInfo("@export_flags_2d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_2D_NAVIGATION, Variant::INT>); + register_annotation(MethodInfo("@export_flags_3d_render"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_RENDER, Variant::INT>); + register_annotation(MethodInfo("@export_flags_3d_physics"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_PHYSICS, Variant::INT>); + register_annotation(MethodInfo("@export_flags_3d_navigation"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_3D_NAVIGATION, Variant::INT>); + register_annotation(MethodInfo("@export_flags_avoidance"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_LAYERS_AVOIDANCE, Variant::INT>); + // Export grouping annotations. + register_annotation(MethodInfo("@export_category", PropertyInfo(Variant::STRING, "name")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_CATEGORY>); + register_annotation(MethodInfo("@export_group", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_GROUP>, varray("")); + register_annotation(MethodInfo("@export_subgroup", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "prefix")), AnnotationInfo::STANDALONE, &GDScriptParser::export_group_annotations<PROPERTY_USAGE_SUBGROUP>, varray("")); + // Warning annotations. + register_annotation(MethodInfo("@warning_ignore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, varray(), true); + // Networking. + register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::rpc_annotation, varray("authority", "call_remote", "unreliable", 0)); + } #ifdef DEBUG_ENABLED is_ignoring_warnings = !(bool)GLOBAL_GET("debug/gdscript/warnings/enable"); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index f48ad48de0..88b5bdc43f 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1370,7 +1370,7 @@ private: AnnotationAction apply = nullptr; MethodInfo info; }; - HashMap<StringName, AnnotationInfo> valid_annotations; + static HashMap<StringName, AnnotationInfo> valid_annotations; List<AnnotationNode *> annotation_stack; typedef ExpressionNode *(GDScriptParser::*ParseFunction)(ExpressionNode *p_previous_operand, bool p_can_assign); @@ -1470,7 +1470,7 @@ private: SuiteNode *parse_suite(const String &p_context, SuiteNode *p_suite = nullptr, bool p_for_lambda = false); // Annotations AnnotationNode *parse_annotation(uint32_t p_valid_targets); - bool register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, const Vector<Variant> &p_default_arguments = Vector<Variant>(), bool p_is_vararg = false); + static bool register_annotation(const MethodInfo &p_info, uint32_t p_target_kinds, AnnotationAction p_apply, const Vector<Variant> &p_default_arguments = Vector<Variant>(), bool p_is_vararg = false); bool validate_annotation_arguments(AnnotationNode *p_annotation); void clear_unused_annotations(); bool tool_annotation(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class); diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index 40c564c36b..f8cb460e40 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -194,9 +194,9 @@ struct GDScriptUtilityFunctionsDefinitions { // Calculate how many. int count = 0; if (incr > 0) { - count = ((to - from - 1) / incr) + 1; + count = Math::division_round_up(to - from, incr); } else { - count = ((from - to - 1) / -incr) + 1; + count = Math::division_round_up(from - to, -incr); } Error err = arr.resize(count); @@ -470,7 +470,8 @@ struct GDScriptUtilityFunctionsDefinitions { static inline void len(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { VALIDATE_ARG_COUNT(1); switch (p_args[0]->get_type()) { - case Variant::STRING: { + case Variant::STRING: + case Variant::STRING_NAME: { String d = *p_args[0]; *r_ret = d.length(); } break; diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 2c0b8df9ac..3abfc7f8e3 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -36,6 +36,18 @@ #include "core/os/os.h" #ifdef DEBUG_ENABLED + +static bool _profile_count_as_native(const Object *p_base_obj, const StringName &p_methodname) { + if (!p_base_obj) { + return false; + } + StringName cname = p_base_obj->get_class_name(); + if ((p_methodname == "new" && cname == "GDScript") || p_methodname == "call") { + return false; + } + return ClassDB::class_exists(cname) && ClassDB::has_method(cname, p_methodname, false); +} + static String _get_element_type(Variant::Type builtin_type, const StringName &native_type, const Ref<Script> &script_type) { if (script_type.is_valid() && script_type->is_valid()) { return GDScript::debug_get_script_name(script_type); @@ -84,6 +96,18 @@ static String _get_var_type(const Variant *p_var) { return basestr; } + +void GDScriptFunction::_profile_native_call(uint64_t p_t_taken, const String &p_func_name, const String &p_instance_class_name) { + HashMap<String, Profile::NativeProfile>::Iterator inner_prof = profile.native_calls.find(p_func_name); + if (inner_prof) { + inner_prof->value.call_count += 1; + } else { + String sig = vformat("%s::0::%s%s%s", get_script()->get_script_path(), p_instance_class_name, p_instance_class_name.is_empty() ? "" : ".", p_func_name); + inner_prof = profile.native_calls.insert(p_func_name, Profile::NativeProfile{ 1, 0, sig }); + } + inner_prof->value.total_time += p_t_taken; +} + #endif // DEBUG_ENABLED Variant GDScriptFunction::_get_default_variant_for_data_type(const GDScriptDataType &p_data_type) { @@ -631,9 +655,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } bool exit_ok = false; bool awaited = false; -#endif - -#ifdef DEBUG_ENABLED int variant_address_limits[ADDR_TYPE_MAX] = { _stack_size, _constant_count, p_instance ? p_instance->members.size() : 0 }; #endif @@ -1661,16 +1682,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (GDScriptLanguage::get_singleton()->profiling) { call_time = OS::get_singleton()->get_ticks_usec(); } - + Variant::Type base_type = base->get_type(); + Object *base_obj = base->get_validated_object(); + StringName base_class = base_obj ? base_obj->get_class_name() : StringName(); #endif + Callable::CallError err; if (call_ret) { GET_INSTRUCTION_ARG(ret, argc + 1); -#ifdef DEBUG_ENABLED - Variant::Type base_type = base->get_type(); - Object *base_obj = base->get_validated_object(); - StringName base_class = base_obj ? base_obj->get_class_name() : StringName(); -#endif base->callp(*methodname, (const Variant **)argptrs, argc, *ret, err); #ifdef DEBUG_ENABLED if (ret->get_type() == Variant::NIL) { @@ -1704,8 +1723,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a base->callp(*methodname, (const Variant **)argptrs, argc, ret, err); } #ifdef DEBUG_ENABLED + if (GDScriptLanguage::get_singleton()->profiling) { - function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; + uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time; + if (GDScriptLanguage::get_singleton()->profile_native_calls && _profile_count_as_native(base_obj, *methodname)) { + _profile_native_call(t_taken, *methodname, base_class); + } + function_call_time += t_taken; } if (err.error != Callable::CallError::CALL_OK) { @@ -1782,8 +1806,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED uint64_t call_time = 0; - - if (GDScriptLanguage::get_singleton()->profiling) { + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { call_time = OS::get_singleton()->get_ticks_usec(); } #endif @@ -1797,8 +1820,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->profiling) { - function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; + + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { + uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time; + _profile_native_call(t_taken, method->get_name(), method->get_instance_class()); + function_call_time += t_taken; } if (err.error != Callable::CallError::CALL_OK) { @@ -1851,22 +1877,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a const Variant **argptrs = const_cast<const Variant **>(instruction_args); -#ifdef DEBUG_ENABLED - uint64_t call_time = 0; - - if (GDScriptLanguage::get_singleton()->profiling) { - call_time = OS::get_singleton()->get_ticks_usec(); - } -#endif - Callable::CallError err; Variant::call_static(builtin_type, *methodname, argptrs, argc, *ret, err); #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->profiling) { - function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; - } - if (err.error != Callable::CallError::CALL_OK) { err_text = _get_call_error(err, "static function '" + methodname->operator String() + "' in type '" + Variant::get_type_name(builtin_type) + "'", argptrs); OPCODE_BREAK; @@ -1895,8 +1909,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED uint64_t call_time = 0; - - if (GDScriptLanguage::get_singleton()->profiling) { + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { call_time = OS::get_singleton()->get_ticks_usec(); } #endif @@ -1905,15 +1918,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a *ret = method->call(nullptr, argptrs, argc, err); #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->profiling) { - function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { + uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time; + _profile_native_call(t_taken, method->get_name(), method->get_instance_class()); + function_call_time += t_taken; } +#endif if (err.error != Callable::CallError::CALL_OK) { err_text = _get_call_error(err, "static function '" + method->get_name().operator String() + "' in type '" + method->get_instance_class().operator String() + "'", argptrs); OPCODE_BREAK; } -#endif ip += 3; } @@ -1951,8 +1966,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED uint64_t call_time = 0; - - if (GDScriptLanguage::get_singleton()->profiling) { + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { call_time = OS::get_singleton()->get_ticks_usec(); } #endif @@ -1961,10 +1975,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a method->validated_call(base_obj, (const Variant **)argptrs, ret); #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->profiling) { - function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { + uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time; + _profile_native_call(t_taken, method->get_name(), method->get_instance_class()); + function_call_time += t_taken; } #endif + ip += 3; } DISPATCH_OPCODE; @@ -1998,8 +2015,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Variant **argptrs = instruction_args; #ifdef DEBUG_ENABLED uint64_t call_time = 0; - - if (GDScriptLanguage::get_singleton()->profiling) { + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { call_time = OS::get_singleton()->get_ticks_usec(); } #endif @@ -2009,10 +2025,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a method->validated_call(base_obj, (const Variant **)argptrs, nullptr); #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->profiling) { - function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; + if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) { + uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time; + _profile_native_call(t_taken, method->get_name(), method->get_instance_class()); + function_call_time += t_taken; } #endif + ip += 3; } DISPATCH_OPCODE; @@ -2033,22 +2052,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Variant::ValidatedBuiltInMethod method = _builtin_methods_ptr[_code_ptr[ip + 2]]; Variant **argptrs = instruction_args; -#ifdef DEBUG_ENABLED - uint64_t call_time = 0; - if (GDScriptLanguage::get_singleton()->profiling) { - call_time = OS::get_singleton()->get_ticks_usec(); - } -#endif - GET_INSTRUCTION_ARG(ret, argc + 1); method(base, (const Variant **)argptrs, argc, ret); -#ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->profiling) { - function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; - } -#endif - ip += 3; } DISPATCH_OPCODE; diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 44f605232d..0b1371851b 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -315,9 +315,8 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) { Vector<String> param_symbols = query.split(SYMBOL_SEPERATOR, false); if (param_symbols.size() >= 2) { - String class_ = param_symbols[0]; - StringName class_name = class_; - String member_name = param_symbols[param_symbols.size() - 1]; + StringName class_name = param_symbols[0]; + const String &member_name = param_symbols[param_symbols.size() - 1]; String inner_class_name; if (param_symbols.size() >= 3) { inner_class_name = param_symbols[1]; diff --git a/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.gd b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.gd new file mode 100644 index 0000000000..e4016c0119 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.gd @@ -0,0 +1,6 @@ +func test(): + var array: Array = [1, 2, 3] + print(array) + var callable: Callable = array.clear + callable.call() + print(array) diff --git a/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.out b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.out new file mode 100644 index 0000000000..c4182b38e9 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/builtin_method_as_callable.out @@ -0,0 +1,3 @@ +GDTEST_OK +[1, 2, 3] +[] diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index 7fe3a57880..d7e5ddd32c 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -67,6 +67,13 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage } else { // use defaults } + } else if (capabilities->device_family == RenderingDevice::DeviceFamily::DEVICE_DIRECTX) { + // NIR-DXIL is Vulkan 1.1-conformant. + ClientVersion = glslang::EShTargetVulkan_1_1; + // The SPIR-V part of Mesa supports 1.6, but: + // - SPIRV-Reflect won't be able to parse the compute workgroup size. + // - We want to play it safe with NIR-DXIL. + TargetVersion = glslang::EShTargetSpv_1_3; } else { // once we support other backends we'll need to do something here if (r_error) { diff --git a/modules/gltf/doc_classes/GLTFDocument.xml b/modules/gltf/doc_classes/GLTFDocument.xml index f5066ba4f1..1b52a82298 100644 --- a/modules/gltf/doc_classes/GLTFDocument.xml +++ b/modules/gltf/doc_classes/GLTFDocument.xml @@ -84,7 +84,7 @@ <param index="1" name="path" type="String" /> <description> Takes a [GLTFState] object through the [param state] parameter and writes a glTF file to the filesystem. - [b]Note:[/b] The extension of the glTF file determines if it is a .glb binary file or a .gltf file. + [b]Note:[/b] The extension of the glTF file determines if it is a .glb binary file or a .gltf text file. </description> </method> </methods> diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp index 83c7f463df..6975bc1228 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp @@ -32,12 +32,14 @@ #ifdef TOOLS_ENABLED -#include "../gltf_document.h" +#include "editor_scene_exporter_gltf_settings.h" #include "editor/editor_file_system.h" +#include "editor/editor_inspector.h" #include "editor/editor_node.h" +#include "editor/editor_scale.h" #include "editor/gui/editor_file_dialog.h" -#include "scene/gui/popup_menu.h" +#include "editor/import/scene_import_settings.h" String SceneExporterGLTFPlugin::get_name() const { return "ConvertGLTF2"; @@ -48,59 +50,72 @@ bool SceneExporterGLTFPlugin::has_main_screen() const { } SceneExporterGLTFPlugin::SceneExporterGLTFPlugin() { - file_export_lib = memnew(EditorFileDialog); - EditorNode::get_singleton()->get_gui_base()->add_child(file_export_lib); - file_export_lib->connect("file_selected", callable_mp(this, &SceneExporterGLTFPlugin::_gltf2_dialog_action)); - file_export_lib->set_title(TTR("Export Library")); - file_export_lib->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); - file_export_lib->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - file_export_lib->clear_filters(); - file_export_lib->add_filter("*.glb"); - file_export_lib->add_filter("*.gltf"); - file_export_lib->set_title(TTR("Export Scene to glTF 2.0 File")); - + _gltf_document.instantiate(); + // Set up the file dialog. + _file_dialog = memnew(EditorFileDialog); + _file_dialog->connect("file_selected", callable_mp(this, &SceneExporterGLTFPlugin::_export_scene_as_gltf)); + _file_dialog->set_title(TTR("Export Library")); + _file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); + _file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + _file_dialog->clear_filters(); + _file_dialog->add_filter("*.glb"); + _file_dialog->add_filter("*.gltf"); + _file_dialog->set_title(TTR("Export Scene to glTF 2.0 File")); + EditorNode::get_singleton()->get_gui_base()->add_child(_file_dialog); + // Set up the export settings menu. + _export_settings.instantiate(); + _export_settings->generate_property_list(_gltf_document); + _settings_inspector = memnew(EditorInspector); + _settings_inspector->set_custom_minimum_size(Size2(350, 300) * EDSCALE); + _file_dialog->add_side_menu(_settings_inspector, TTR("Export Settings:")); + // Add a button to the Scene -> Export menu to pop up the settings dialog. PopupMenu *menu = get_export_as_menu(); int idx = menu->get_item_count(); menu->add_item(TTR("glTF 2.0 Scene...")); - menu->set_item_metadata(idx, callable_mp(this, &SceneExporterGLTFPlugin::convert_scene_to_gltf2)); + menu->set_item_metadata(idx, callable_mp(this, &SceneExporterGLTFPlugin::_popup_gltf_export_dialog)); +} + +void SceneExporterGLTFPlugin::_popup_gltf_export_dialog() { + Node *root = EditorNode::get_singleton()->get_tree()->get_edited_scene_root(); + if (!root) { + EditorNode::get_singleton()->show_accept(TTR("This operation can't be done without a scene."), TTR("OK")); + return; + } + // Set the file dialog's file name to the scene name. + String filename = String(root->get_scene_file_path().get_file().get_basename()); + if (filename.is_empty()) { + filename = root->get_name(); + } + _file_dialog->set_current_file(filename + String(".gltf")); + // Generate and refresh the export settings. + _export_settings->generate_property_list(_gltf_document); + _settings_inspector->edit(nullptr); + _settings_inspector->edit(_export_settings.ptr()); + // Show the file dialog. + _file_dialog->popup_centered_ratio(); } -void SceneExporterGLTFPlugin::_gltf2_dialog_action(String p_file) { +void SceneExporterGLTFPlugin::_export_scene_as_gltf(const String &p_file_path) { Node *root = EditorNode::get_singleton()->get_tree()->get_edited_scene_root(); if (!root) { EditorNode::get_singleton()->show_accept(TTR("This operation can't be done without a scene."), TTR("OK")); return; } List<String> deps; - Ref<GLTFDocument> doc; - doc.instantiate(); Ref<GLTFState> state; state.instantiate(); + state->set_copyright(_export_settings->get_copyright()); int32_t flags = 0; flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS; - Error err = doc->append_from_scene(root, state, flags); + Error err = _gltf_document->append_from_scene(root, state, flags); if (err != OK) { ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err))); } - err = doc->write_to_filesystem(state, p_file); + err = _gltf_document->write_to_filesystem(state, p_file_path); if (err != OK) { ERR_PRINT(vformat("glTF2 save scene error %s.", itos(err))); } EditorFileSystem::get_singleton()->scan_changes(); } -void SceneExporterGLTFPlugin::convert_scene_to_gltf2() { - Node *root = EditorNode::get_singleton()->get_tree()->get_edited_scene_root(); - if (!root) { - EditorNode::get_singleton()->show_accept(TTR("This operation can't be done without a scene."), TTR("OK")); - return; - } - String filename = String(root->get_scene_file_path().get_file().get_basename()); - if (filename.is_empty()) { - filename = root->get_name(); - } - file_export_lib->set_current_file(filename + String(".gltf")); - file_export_lib->popup_centered_ratio(); -} - #endif // TOOLS_ENABLED diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h index f92b3c5180..683ff6d4f6 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h +++ b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.h @@ -33,18 +33,23 @@ #ifdef TOOLS_ENABLED -#include "editor_scene_importer_gltf.h" +#include "../gltf_document.h" +#include "editor_scene_exporter_gltf_settings.h" #include "editor/editor_plugin.h" class EditorFileDialog; +class EditorInspector; class SceneExporterGLTFPlugin : public EditorPlugin { GDCLASS(SceneExporterGLTFPlugin, EditorPlugin); - EditorFileDialog *file_export_lib = nullptr; - void _gltf2_dialog_action(String p_file); - void convert_scene_to_gltf2(); + Ref<GLTFDocument> _gltf_document; + Ref<EditorSceneExporterGLTFSettings> _export_settings; + EditorInspector *_settings_inspector = nullptr; + EditorFileDialog *_file_dialog = nullptr; + void _popup_gltf_export_dialog(); + void _export_scene_as_gltf(const String &p_file_path); public: virtual String get_name() const override; diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp new file mode 100644 index 0000000000..b0283b0c55 --- /dev/null +++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp @@ -0,0 +1,176 @@ +/**************************************************************************/ +/* editor_scene_exporter_gltf_settings.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "editor_scene_exporter_gltf_settings.h" + +const uint32_t PROP_EDITOR_SCRIPT_VAR = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE; + +bool EditorSceneExporterGLTFSettings::_set(const StringName &p_name, const Variant &p_value) { + String name_str = String(p_name); + if (name_str.contains("/")) { + return _set_extension_setting(name_str, p_value); + } + if (p_name == StringName("image_format")) { + _document->set_image_format(p_value); + emit_signal("property_list_changed"); + return true; + } + if (p_name == StringName("lossy_quality")) { + _document->set_lossy_quality(p_value); + return true; + } + if (p_name == StringName("root_node_mode")) { + _document->set_root_node_mode((GLTFDocument::RootNodeMode)(int64_t)p_value); + return true; + } + return false; +} + +bool EditorSceneExporterGLTFSettings::_get(const StringName &p_name, Variant &r_ret) const { + String name_str = String(p_name); + if (name_str.contains("/")) { + return _get_extension_setting(name_str, r_ret); + } + if (p_name == StringName("image_format")) { + r_ret = _document->get_image_format(); + return true; + } + if (p_name == StringName("lossy_quality")) { + r_ret = _document->get_lossy_quality(); + return true; + } + if (p_name == StringName("root_node_mode")) { + r_ret = _document->get_root_node_mode(); + return true; + } + return false; +} + +void EditorSceneExporterGLTFSettings::_get_property_list(List<PropertyInfo> *p_list) const { + for (PropertyInfo prop : _property_list) { + if (prop.name == "lossy_quality") { + String image_format = get("image_format"); + bool is_image_format_lossy = image_format == "JPEG" || image_format.findn("Lossy") != -1; + prop.usage = is_image_format_lossy ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_STORAGE; + } + p_list->push_back(prop); + } +} + +bool EditorSceneExporterGLTFSettings::_set_extension_setting(const String &p_name_str, const Variant &p_value) { + PackedStringArray split = String(p_name_str).split("/", true, 1); + if (!_config_name_to_extension_map.has(split[0])) { + return false; + } + Ref<GLTFDocumentExtension> extension = _config_name_to_extension_map[split[0]]; + bool valid; + extension->set(split[1], p_value, &valid); + return valid; +} + +bool EditorSceneExporterGLTFSettings::_get_extension_setting(const String &p_name_str, Variant &r_ret) const { + PackedStringArray split = String(p_name_str).split("/", true, 1); + if (!_config_name_to_extension_map.has(split[0])) { + return false; + } + Ref<GLTFDocumentExtension> extension = _config_name_to_extension_map[split[0]]; + bool valid; + r_ret = extension->get(split[1], &valid); + return valid; +} + +String get_friendly_config_prefix(Ref<GLTFDocumentExtension> p_extension) { + String config_prefix = p_extension->get_name(); + if (!config_prefix.is_empty()) { + return config_prefix; + } + const String class_name = p_extension->get_class_name(); + config_prefix = class_name.trim_prefix("GLTFDocumentExtension").capitalize(); + if (!config_prefix.is_empty()) { + return config_prefix; + } + PackedStringArray supported_extensions = p_extension->get_supported_extensions(); + if (supported_extensions.size() > 0) { + return supported_extensions[0]; + } + return "Unknown GLTFDocumentExtension"; +} + +// Run this before popping up the export settings, because the extensions may have changed. +void EditorSceneExporterGLTFSettings::generate_property_list(Ref<GLTFDocument> p_document) { + _property_list.clear(); + _document = p_document; + String image_format_hint_string = "None,PNG,JPEG"; + // Add properties from all document extensions. + for (Ref<GLTFDocumentExtension> &extension : GLTFDocument::get_all_gltf_document_extensions()) { + const String config_prefix = get_friendly_config_prefix(extension); + _config_name_to_extension_map[config_prefix] = extension; + // If the extension allows saving in different image formats, add to the enum. + PackedStringArray saveable_image_formats = extension->get_saveable_image_formats(); + for (int i = 0; i < saveable_image_formats.size(); i++) { + image_format_hint_string += "," + saveable_image_formats[i]; + } + // Look through the extension's properties and find the relevant ones. + List<PropertyInfo> ext_prop_list; + extension->get_property_list(&ext_prop_list); + for (const PropertyInfo &prop : ext_prop_list) { + // We only want properties that will show up in the exporter + // settings list. Exclude Resource's properties, as they are + // not relevant to the exporter. Include any user-defined script + // variables exposed to the editor (PROP_EDITOR_SCRIPT_VAR). + if ((prop.usage & PROP_EDITOR_SCRIPT_VAR) == PROP_EDITOR_SCRIPT_VAR) { + PropertyInfo ext_prop = prop; + ext_prop.name = config_prefix + "/" + prop.name; + _property_list.push_back(ext_prop); + } + } + } + // Add top-level properties (in addition to what _bind_methods registers). + PropertyInfo image_format_prop = PropertyInfo(Variant::STRING, "image_format", PROPERTY_HINT_ENUM, image_format_hint_string); + _property_list.push_back(image_format_prop); + PropertyInfo lossy_quality_prop = PropertyInfo(Variant::FLOAT, "lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"); + _property_list.push_back(lossy_quality_prop); + PropertyInfo root_node_mode_prop = PropertyInfo(Variant::INT, "root_node_mode", PROPERTY_HINT_ENUM, "Single Root,Keep Root,Multi Root"); + _property_list.push_back(root_node_mode_prop); +} + +String EditorSceneExporterGLTFSettings::get_copyright() const { + return _copyright; +} + +void EditorSceneExporterGLTFSettings::set_copyright(const String &p_copyright) { + _copyright = p_copyright; +} + +void EditorSceneExporterGLTFSettings::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_copyright"), &EditorSceneExporterGLTFSettings::get_copyright); + ClassDB::bind_method(D_METHOD("set_copyright", "copyright"), &EditorSceneExporterGLTFSettings::set_copyright); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "copyright", PROPERTY_HINT_PLACEHOLDER_TEXT, "Example: 2014 Godette"), "set_copyright", "get_copyright"); +} diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.h b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h new file mode 100644 index 0000000000..6032932367 --- /dev/null +++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h @@ -0,0 +1,64 @@ +/**************************************************************************/ +/* editor_scene_exporter_gltf_settings.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef EDITOR_SCENE_EXPORTER_GLTF_SETTINGS_H +#define EDITOR_SCENE_EXPORTER_GLTF_SETTINGS_H + +#ifdef TOOLS_ENABLED + +#include "../gltf_document.h" + +class EditorSceneExporterGLTFSettings : public RefCounted { + GDCLASS(EditorSceneExporterGLTFSettings, RefCounted); + List<PropertyInfo> _property_list; + Ref<GLTFDocument> _document; + HashMap<String, Ref<GLTFDocumentExtension>> _config_name_to_extension_map; + + String _copyright; + +protected: + static void _bind_methods(); + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + bool _set_extension_setting(const String &p_name_str, const Variant &p_value); + bool _get_extension_setting(const String &p_name_str, Variant &r_ret) const; + +public: + void generate_property_list(Ref<GLTFDocument> p_document); + + String get_copyright() const; + void set_copyright(const String &p_copyright); +}; + +#endif // TOOLS_ENABLED + +#endif // EDITOR_SCENE_EXPORTER_GLTF_SETTINGS_H diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 4060f7f626..030c3f88b0 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -3658,141 +3658,143 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) { mr["metallicFactor"] = base_material->get_metallic(); mr["roughnessFactor"] = base_material->get_roughness(); - bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid(); - bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid(); - bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid(); - if (has_ao || has_roughness || has_metalness) { - Dictionary mrt; - Ref<Texture2D> roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS); - BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel(); - Ref<Texture2D> metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC); - BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel(); - Ref<Texture2D> ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION); - BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel(); - Ref<ImageTexture> orm_texture; - orm_texture.instantiate(); - Ref<Image> orm_image; - orm_image.instantiate(); - int32_t height = 0; - int32_t width = 0; - Ref<Image> ao_image; - if (has_ao) { - height = ao_texture->get_height(); - width = ao_texture->get_width(); - ao_image = ao_texture->get_image(); - Ref<ImageTexture> img_tex = ao_image; - if (img_tex.is_valid()) { - ao_image = img_tex->get_image(); - } - if (ao_image->is_compressed()) { - ao_image->decompress(); - } - } - Ref<Image> roughness_image; - if (has_roughness) { - height = roughness_texture->get_height(); - width = roughness_texture->get_width(); - roughness_image = roughness_texture->get_image(); - Ref<ImageTexture> img_tex = roughness_image; - if (img_tex.is_valid()) { - roughness_image = img_tex->get_image(); - } - if (roughness_image->is_compressed()) { - roughness_image->decompress(); - } - } - Ref<Image> metallness_image; - if (has_metalness) { - height = metallic_texture->get_height(); - width = metallic_texture->get_width(); - metallness_image = metallic_texture->get_image(); - Ref<ImageTexture> img_tex = metallness_image; - if (img_tex.is_valid()) { - metallness_image = img_tex->get_image(); - } - if (metallness_image->is_compressed()) { - metallness_image->decompress(); + if (_image_format != "None") { + bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid(); + bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid(); + bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid(); + if (has_ao || has_roughness || has_metalness) { + Dictionary mrt; + Ref<Texture2D> roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS); + BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel(); + Ref<Texture2D> metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC); + BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel(); + Ref<Texture2D> ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION); + BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel(); + Ref<ImageTexture> orm_texture; + orm_texture.instantiate(); + Ref<Image> orm_image; + orm_image.instantiate(); + int32_t height = 0; + int32_t width = 0; + Ref<Image> ao_image; + if (has_ao) { + height = ao_texture->get_height(); + width = ao_texture->get_width(); + ao_image = ao_texture->get_image(); + Ref<ImageTexture> img_tex = ao_image; + if (img_tex.is_valid()) { + ao_image = img_tex->get_image(); + } + if (ao_image->is_compressed()) { + ao_image->decompress(); + } } - } - Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO); - if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) { - height = albedo_texture->get_height(); - width = albedo_texture->get_width(); - } - orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8); - if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) { - ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS); - } - if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) { - roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); - } - if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) { - metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); - } - for (int32_t h = 0; h < height; h++) { - for (int32_t w = 0; w < width; w++) { - Color c = Color(1.0f, 1.0f, 1.0f); - if (has_ao) { - if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) { - c.r = ao_image->get_pixel(w, h).r; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) { - c.r = ao_image->get_pixel(w, h).g; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) { - c.r = ao_image->get_pixel(w, h).b; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) { - c.r = ao_image->get_pixel(w, h).a; - } + Ref<Image> roughness_image; + if (has_roughness) { + height = roughness_texture->get_height(); + width = roughness_texture->get_width(); + roughness_image = roughness_texture->get_image(); + Ref<ImageTexture> img_tex = roughness_image; + if (img_tex.is_valid()) { + roughness_image = img_tex->get_image(); } - if (has_roughness) { - if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).r; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).g; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).b; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).a; - } + if (roughness_image->is_compressed()) { + roughness_image->decompress(); + } + } + Ref<Image> metallness_image; + if (has_metalness) { + height = metallic_texture->get_height(); + width = metallic_texture->get_width(); + metallness_image = metallic_texture->get_image(); + Ref<ImageTexture> img_tex = metallness_image; + if (img_tex.is_valid()) { + metallness_image = img_tex->get_image(); + } + if (metallness_image->is_compressed()) { + metallness_image->decompress(); } - if (has_metalness) { - if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).r; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).g; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).b; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).a; + } + Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO); + if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) { + height = albedo_texture->get_height(); + width = albedo_texture->get_width(); + } + orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8); + if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) { + ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS); + } + if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) { + roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); + } + if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) { + metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); + } + for (int32_t h = 0; h < height; h++) { + for (int32_t w = 0; w < width; w++) { + Color c = Color(1.0f, 1.0f, 1.0f); + if (has_ao) { + if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) { + c.r = ao_image->get_pixel(w, h).r; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) { + c.r = ao_image->get_pixel(w, h).g; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) { + c.r = ao_image->get_pixel(w, h).b; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) { + c.r = ao_image->get_pixel(w, h).a; + } } + if (has_roughness) { + if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).r; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).g; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).b; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).a; + } + } + if (has_metalness) { + if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).r; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).g; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).b; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).a; + } + } + orm_image->set_pixel(w, h, c); } - orm_image->set_pixel(w, h, c); } - } - orm_image->generate_mipmaps(); - orm_texture->set_image(orm_image); - GLTFTextureIndex orm_texture_index = -1; - if (has_ao || has_roughness || has_metalness) { - orm_texture->set_name(material->get_name() + "_orm"); - orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT)); - } - if (has_ao) { - Dictionary occt; - occt["index"] = orm_texture_index; - d["occlusionTexture"] = occt; - } - if (has_roughness || has_metalness) { - mrt["index"] = orm_texture_index; - Dictionary extensions = _serialize_texture_transform_uv1(material); - if (!extensions.is_empty()) { - mrt["extensions"] = extensions; - p_state->use_khr_texture_transform = true; + orm_image->generate_mipmaps(); + orm_texture->set_image(orm_image); + GLTFTextureIndex orm_texture_index = -1; + if (has_ao || has_roughness || has_metalness) { + orm_texture->set_name(material->get_name() + "_orm"); + orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT)); + } + if (has_ao) { + Dictionary occt; + occt["index"] = orm_texture_index; + d["occlusionTexture"] = occt; + } + if (has_roughness || has_metalness) { + mrt["index"] = orm_texture_index; + Dictionary extensions = _serialize_texture_transform_uv1(material); + if (!extensions.is_empty()) { + mrt["extensions"] = extensions; + p_state->use_khr_texture_transform = true; + } + mr["metallicRoughnessTexture"] = mrt; } - mr["metallicRoughnessTexture"] = mrt; } } d["pbrMetallicRoughness"] = mr; - if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING)) { + if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING) && _image_format != "None") { Dictionary nt; Ref<ImageTexture> tex; tex.instantiate(); @@ -3845,7 +3847,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) { d["emissiveFactor"] = arr; } - if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) { + if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION) && _image_format != "None") { Dictionary et; Ref<Texture2D> emission_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_EMISSION); GLTFTextureIndex gltf_texture_index = -1; @@ -7336,6 +7338,10 @@ void GLTFDocument::unregister_all_gltf_document_extensions() { all_document_extensions.clear(); } +Vector<Ref<GLTFDocumentExtension>> GLTFDocument::get_all_gltf_document_extensions() { + return all_document_extensions; +} + PackedByteArray GLTFDocument::_serialize_glb_buffer(Ref<GLTFState> p_state, Error *r_err) { Error err = _encode_buffer_glb(p_state, ""); if (r_err) { diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 7e378fe94d..f321bb7111 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -86,6 +86,7 @@ public: static void register_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension, bool p_first_priority = false); static void unregister_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension); static void unregister_all_gltf_document_extensions(); + static Vector<Ref<GLTFDocumentExtension>> get_all_gltf_document_extensions(); void set_naming_version(int p_version); int get_naming_version() const; diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index e05979efbc..348ac5194c 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -155,7 +155,6 @@ class GridMap : public Node3D { Ref<PhysicsMaterial> physics_material; bool bake_navigation = false; RID map_override; - uint32_t navigation_layers = 1; Transform3D last_transform; diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index a4ecb767a7..74dc54641d 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -756,7 +756,7 @@ LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref<RDShade rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1); push_constant.region_ofs[0] = 0; push_constant.region_ofs[1] = 0; - Vector3i group_size((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1); //restore group size + Vector3i group_size(Math::division_round_up(atlas_size.x, 8), Math::division_round_up(atlas_size.y, 8), 1); //restore group size for (int i = 0; i < atlas_slices; i++) { push_constant.atlas_slice = i; @@ -939,8 +939,8 @@ LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Ref<RDSh // We use a region with 1/4 the amount of pixels if we're denoising SH lightmaps, as // all four of them are denoised in the shader in one dispatch. const int max_region_size = p_bake_sh ? 512 : 1024; - int x_regions = (p_atlas_size.width - 1) / max_region_size + 1; - int y_regions = (p_atlas_size.height - 1) / max_region_size + 1; + int x_regions = Math::division_round_up(p_atlas_size.width, max_region_size); + int y_regions = Math::division_round_up(p_atlas_size.height, max_region_size); for (int s = 0; s < p_atlas_slices; s++) { p_push_constant.atlas_slice = s; @@ -958,7 +958,7 @@ LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Ref<RDSh p_rd->compute_list_bind_uniform_set(compute_list, p_compute_base_uniform_set, 0); p_rd->compute_list_bind_uniform_set(compute_list, denoise_uniform_set, 1); p_rd->compute_list_set_push_constant(compute_list, &p_push_constant, sizeof(PushConstant)); - p_rd->compute_list_dispatch(compute_list, (w - 1) / 8 + 1, (h - 1) / 8 + 1, 1); + p_rd->compute_list_dispatch(compute_list, Math::division_round_up(w, 8), Math::division_round_up(h, 8), 1); p_rd->compute_list_end(); p_rd->submit(); @@ -1399,7 +1399,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d rd->free(compute_shader_secondary); \ rd->free(compute_shader_light_probes); - Vector3i group_size((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1); + Vector3i group_size(Math::division_round_up(atlas_size.x, 8), Math::division_round_up(atlas_size.y, 8), 1); rd->submit(); rd->sync(); @@ -1592,10 +1592,10 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size"))); int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_pass"); - int x_regions = (atlas_size.width - 1) / max_region_size + 1; - int y_regions = (atlas_size.height - 1) / max_region_size + 1; + int x_regions = Math::division_round_up(atlas_size.width, max_region_size); + int y_regions = Math::division_round_up(atlas_size.height, max_region_size); - int ray_iterations = (push_constant.ray_count - 1) / max_rays + 1; + int ray_iterations = Math::division_round_up((int32_t)push_constant.ray_count, max_rays); rd->submit(); rd->sync(); @@ -1614,7 +1614,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d push_constant.region_ofs[0] = x; push_constant.region_ofs[1] = y; - group_size = Vector3i((w - 1) / 8 + 1, (h - 1) / 8 + 1, 1); + group_size = Vector3i(Math::division_round_up(w, 8), Math::division_round_up(h, 8), 1); for (int k = 0; k < ray_iterations; k++) { RD::ComputeListID compute_list = rd->compute_list_begin(); @@ -1700,7 +1700,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d push_constant.probe_count = probe_positions.size(); int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_probe_pass"); - int ray_iterations = (push_constant.ray_count - 1) / max_rays + 1; + int ray_iterations = Math::division_round_up((int32_t)push_constant.ray_count, max_rays); for (int i = 0; i < ray_iterations; i++) { RD::ComputeListID compute_list = rd->compute_list_begin(); @@ -1711,7 +1711,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d push_constant.ray_from = i * max_rays; push_constant.ray_to = MIN((i + 1) * max_rays, int32_t(push_constant.ray_count)); rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); - rd->compute_list_dispatch(compute_list, (probe_positions.size() - 1) / 64 + 1, 1, 1); + rd->compute_list_dispatch(compute_list, Math::division_round_up(probe_positions.size(), 64), 1, 1); rd->compute_list_end(); //done rd->submit(); diff --git a/modules/minimp3/register_types.cpp b/modules/minimp3/register_types.cpp index 627d093bc1..c85f0b3389 100644 --- a/modules/minimp3/register_types.cpp +++ b/modules/minimp3/register_types.cpp @@ -52,8 +52,13 @@ void initialize_minimp3_module(ModuleInitializationLevel p_level) { ResourceFormatImporter::get_singleton()->add_importer(mp3_import); } + ClassDB::APIType prev_api = ClassDB::get_current_api(); + ClassDB::set_current_api(ClassDB::API_EDITOR); + // Required to document import options in the class reference. GDREGISTER_CLASS(ResourceImporterMP3); + + ClassDB::set_current_api(prev_api); #endif GDREGISTER_CLASS(AudioStreamMP3); diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index e381f0e840..401f5c62e5 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -463,6 +463,7 @@ public: /* PROFILING FUNCTIONS */ /* TODO */ void profiling_start() override {} /* TODO */ void profiling_stop() override {} + /* TODO */ void profiling_set_save_native_calls(bool p_enable) override {} /* TODO */ int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override { return 0; } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs new file mode 100644 index 0000000000..d75922481c --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Testing; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; +using Microsoft.CodeAnalysis.Text; + +namespace Godot.SourceGenerators.Tests; + +public static class CSharpSourceGeneratorVerifier<TSourceGenerator> +where TSourceGenerator : ISourceGenerator, new() +{ + public class Test : CSharpSourceGeneratorTest<TSourceGenerator, XUnitVerifier> + { + public Test() + { + ReferenceAssemblies = ReferenceAssemblies.Net.Net60; + + SolutionTransforms.Add((Solution solution, ProjectId projectId) => + { + Project project = solution.GetProject(projectId)! + .AddMetadataReference(Constants.GodotSharpAssembly.CreateMetadataReference()); + + return project.Solution; + }); + } + } + + public static Task Verify(string source, params string[] generatedSources) + { + return Verify(new string[] { source }, generatedSources); + } + + public static Task VerifyNoCompilerDiagnostics(string source, params string[] generatedSources) + { + return VerifyNoCompilerDiagnostics(new string[] { source }, generatedSources); + } + + public static Task Verify(ICollection<string> sources, params string[] generatedSources) + { + return MakeVerifier(sources, generatedSources).RunAsync(); + } + + public static Task VerifyNoCompilerDiagnostics(ICollection<string> sources, params string[] generatedSources) + { + var verifier = MakeVerifier(sources, generatedSources); + verifier.CompilerDiagnostics = CompilerDiagnostics.None; + return verifier.RunAsync(); + } + + public static Test MakeVerifier(ICollection<string> sources, ICollection<string> generatedSources) + { + var verifier = new Test(); + + verifier.TestState.AnalyzerConfigFiles.Add(("/.globalconfig", $""" + is_global = true + build_property.GodotProjectDir = {Constants.ExecutingAssemblyPath} + """)); + + verifier.TestState.Sources.AddRange(sources.Select(source => + { + return (source, SourceText.From(File.ReadAllText(Path.Combine(Constants.SourceFolderPath, source)))); + })); + + verifier.TestState.GeneratedSources.AddRange(generatedSources.Select(generatedSource => + { + return (FullGeneratedSourceName(generatedSource), SourceText.From(File.ReadAllText(Path.Combine(Constants.GeneratedSourceFolderPath, generatedSource)), Encoding.UTF8)); + })); + + return verifier; + } + + private static string FullGeneratedSourceName(string name) + { + var generatorType = typeof(TSourceGenerator); + return Path.Combine(generatorType.Namespace!, generatorType.FullName!, name); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Constants.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Constants.cs new file mode 100644 index 0000000000..783b1e4298 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Constants.cs @@ -0,0 +1,23 @@ +using System.IO; +using System.Reflection; + +namespace Godot.SourceGenerators.Tests; + +public static class Constants +{ + public static Assembly GodotSharpAssembly => typeof(GodotObject).Assembly; + + public static string ExecutingAssemblyPath { get; } + public static string SourceFolderPath { get; } + public static string GeneratedSourceFolderPath { get; } + + static Constants() + { + ExecutingAssemblyPath = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location!)!); + + var testDataPath = Path.Combine(ExecutingAssemblyPath, "TestData"); + + SourceFolderPath = Path.Combine(testDataPath, "Sources"); + GeneratedSourceFolderPath = Path.Combine(testDataPath, "GeneratedSources"); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Extensions.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Extensions.cs new file mode 100644 index 0000000000..6ff890e5d8 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Extensions.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using Microsoft.CodeAnalysis; + +namespace Godot.SourceGenerators.Tests; + +public static class Extensions +{ + public static MetadataReference CreateMetadataReference(this Assembly assembly) + { + return MetadataReference.CreateFromFile(assembly.Location); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Godot.SourceGenerators.Tests.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Godot.SourceGenerators.Tests.csproj new file mode 100644 index 0000000000..e39c14f049 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Godot.SourceGenerators.Tests.csproj @@ -0,0 +1,40 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net6.0</TargetFramework> + + <LangVersion>11</LangVersion> + + <Nullable>enable</Nullable> + <IsPackable>false</IsPackable> + <IsTestProject>true</IsTestProject> + </PropertyGroup> + + <PropertyGroup> + <DefaultItemExcludesInProjectFolder>$(DefaultItemExcludesInProjectFolder);TestData\**</DefaultItemExcludesInProjectFolder> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.XUnit" Version="1.1.1" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" /> + <PackageReference Include="xunit" Version="2.4.2" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5"> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + <PrivateAssets>all</PrivateAssets> + </PackageReference> + <PackageReference Include="coverlet.collector" Version="3.2.0"> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + <PrivateAssets>all</PrivateAssets> + </PackageReference> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\..\..\glue\GodotSharp\GodotSharp\GodotSharp.csproj" /> + <ProjectReference Include="..\Godot.SourceGenerators\Godot.SourceGenerators.csproj" /> + </ItemGroup> + + <ItemGroup> + <None Include="TestData\**\*.cs" CopyToOutputDirectory="PreserveNewest" /> + </ItemGroup> + +</Project> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptMethodsGeneratorTests.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptMethodsGeneratorTests.cs new file mode 100644 index 0000000000..294932eb9a --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptMethodsGeneratorTests.cs @@ -0,0 +1,24 @@ +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class ScriptMethodsGeneratorTests +{ + [Fact] + public async void Methods() + { + await CSharpSourceGeneratorVerifier<ScriptMethodsGenerator>.Verify( + "Methods.cs", + "Methods_ScriptMethods.generated.cs" + ); + } + + [Fact] + public async void ScriptBoilerplate() + { + await CSharpSourceGeneratorVerifier<ScriptMethodsGenerator>.Verify( + "ScriptBoilerplate.cs", + "ScriptBoilerplate_ScriptMethods.generated.cs", "OuterClass.NestedClass_ScriptMethods.generated.cs" + ); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPathAttributeGeneratorTests.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPathAttributeGeneratorTests.cs new file mode 100644 index 0000000000..b7ad4217aa --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPathAttributeGeneratorTests.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Microsoft.CodeAnalysis.Text; +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class ScriptPathAttributeGeneratorTests +{ + private static (string, SourceText) MakeAssemblyScriptTypesGeneratedSource(ICollection<string> types) + { + return ( + Path.Combine("Godot.SourceGenerators", "Godot.SourceGenerators.ScriptPathAttributeGenerator", "AssemblyScriptTypes.generated.cs"), + SourceText.From($$""" + [assembly:Godot.AssemblyHasScriptsAttribute(new System.Type[] {{{string.Join(", ", types.Select(type => $"typeof({type})"))}}})] + + """, Encoding.UTF8) + ); + } + + [Fact] + public async void ScriptBoilerplate() + { + var verifier = CSharpSourceGeneratorVerifier<ScriptPathAttributeGenerator>.MakeVerifier( + new string[] { "ScriptBoilerplate.cs" }, + new string[] { "ScriptBoilerplate_ScriptPath.generated.cs" } + ); + verifier.TestState.GeneratedSources.Add(MakeAssemblyScriptTypesGeneratedSource(new string[] { "global::ScriptBoilerplate" })); + await verifier.RunAsync(); + } + + [Fact] + public async void FooBar() + { + var verifier = CSharpSourceGeneratorVerifier<ScriptPathAttributeGenerator>.MakeVerifier( + new string[] { "Foo.cs", "Bar.cs" }, + new string[] { "Foo_ScriptPath.generated.cs", "Bar_ScriptPath.generated.cs" } + ); + verifier.TestState.GeneratedSources.Add(MakeAssemblyScriptTypesGeneratedSource(new string[] { "global::Foo", "global::Bar" })); + await verifier.RunAsync(); + } + + [Fact] + public async void Generic() + { + var verifier = CSharpSourceGeneratorVerifier<ScriptPathAttributeGenerator>.MakeVerifier( + new string[] { "Generic.cs" }, + new string[] { "Generic_ScriptPath.generated.cs" } + ); + verifier.TestState.GeneratedSources.Add(MakeAssemblyScriptTypesGeneratedSource(new string[] { "global::Generic" })); + await verifier.RunAsync(); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertiesGeneratorTests.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertiesGeneratorTests.cs new file mode 100644 index 0000000000..d20b354b9e --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertiesGeneratorTests.cs @@ -0,0 +1,60 @@ +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class ScriptPropertiesGeneratorTests +{ + [Fact] + public async void ExportedFields() + { + await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify( + new string[] { "ExportedFields.cs", "MoreExportedFields.cs" }, + new string[] { "ExportedFields_ScriptProperties.generated.cs" } + ); + } + + [Fact] + public async void ExportedProperties() + { + await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify( + "ExportedProperties.cs", + "ExportedProperties_ScriptProperties.generated.cs" + ); + } + + [Fact] + public async void OneWayPropertiesAllReadOnly() + { + await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify( + "AllReadOnly.cs", + "AllReadOnly_ScriptProperties.generated.cs" + ); + } + + [Fact] + public async void OneWayPropertiesAllWriteOnly() + { + await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify( + "AllWriteOnly.cs", + "AllWriteOnly_ScriptProperties.generated.cs" + ); + } + + [Fact] + public async void OneWayPropertiesMixedReadonlyWriteOnly() + { + await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify( + "MixedReadOnlyWriteOnly.cs", + "MixedReadOnlyWriteOnly_ScriptProperties.generated.cs" + ); + } + + [Fact] + public async void ScriptBoilerplate() + { + await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify( + "ScriptBoilerplate.cs", + "ScriptBoilerplate_ScriptProperties.generated.cs", "OuterClass.NestedClass_ScriptProperties.generated.cs" + ); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertyDefValGeneratorTests.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertyDefValGeneratorTests.cs new file mode 100644 index 0000000000..ae5fb86d77 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertyDefValGeneratorTests.cs @@ -0,0 +1,24 @@ +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class ScriptPropertyDefValGeneratorTests +{ + [Fact] + public async void ExportedFields() + { + await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify( + new string[] { "ExportedFields.cs", "MoreExportedFields.cs" }, + new string[] { "ExportedFields_ScriptPropertyDefVal.generated.cs" } + ); + } + + [Fact] + public async void ExportedProperties() + { + await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify( + "ExportedProperties.cs", + "ExportedProperties_ScriptPropertyDefVal.generated.cs" + ); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptSerializationGeneratorTests.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptSerializationGeneratorTests.cs new file mode 100644 index 0000000000..24cd446087 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptSerializationGeneratorTests.cs @@ -0,0 +1,15 @@ +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class ScriptSerializationGeneratorTests +{ + [Fact] + public async void ScriptBoilerplate() + { + await CSharpSourceGeneratorVerifier<ScriptSerializationGenerator>.VerifyNoCompilerDiagnostics( + "ScriptBoilerplate.cs", + "ScriptBoilerplate_ScriptSerialization.generated.cs", "OuterClass.NestedClass_ScriptSerialization.generated.cs" + ); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptSignalsGeneratorTests.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptSignalsGeneratorTests.cs new file mode 100644 index 0000000000..2a783cedce --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptSignalsGeneratorTests.cs @@ -0,0 +1,15 @@ +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class ScriptSignalsGeneratorTests +{ + [Fact] + public async void EventSignals() + { + await CSharpSourceGeneratorVerifier<ScriptSignalsGenerator>.Verify( + "EventSignals.cs", + "EventSignals_ScriptSignals.generated.cs" + ); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/.editorconfig b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/.editorconfig new file mode 100644 index 0000000000..9e2014e16c --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*.cs] +exclude = true +generated_code = true diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/AllReadOnly_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/AllReadOnly_ScriptProperties.generated.cs new file mode 100644 index 0000000000..db56ac30a3 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/AllReadOnly_ScriptProperties.generated.cs @@ -0,0 +1,66 @@ +using Godot; +using Godot.NativeInterop; + +partial class AllReadOnly +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the properties and fields contained in this class, for fast lookup. + /// </summary> + public new class PropertyName : global::Godot.GodotObject.PropertyName { + /// <summary> + /// Cached name for the 'readonly_auto_property' property. + /// </summary> + public new static readonly global::Godot.StringName readonly_auto_property = "readonly_auto_property"; + /// <summary> + /// Cached name for the 'readonly_property' property. + /// </summary> + public new static readonly global::Godot.StringName readonly_property = "readonly_property"; + /// <summary> + /// Cached name for the 'initonly_auto_property' property. + /// </summary> + public new static readonly global::Godot.StringName initonly_auto_property = "initonly_auto_property"; + /// <summary> + /// Cached name for the 'readonly_field' field. + /// </summary> + public new static readonly global::Godot.StringName readonly_field = "readonly_field"; + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value) + { + if (name == PropertyName.readonly_auto_property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.readonly_auto_property); + return true; + } + else if (name == PropertyName.readonly_property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.readonly_property); + return true; + } + else if (name == PropertyName.initonly_auto_property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.initonly_auto_property); + return true; + } + else if (name == PropertyName.readonly_field) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.readonly_field); + return true; + } + return base.GetGodotClassPropertyValue(name, out value); + } + /// <summary> + /// Get the property information for all the properties declared in this class. + /// This method is used by Godot to register the available properties in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList() + { + var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>(); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.readonly_field, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.readonly_auto_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.readonly_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.initonly_auto_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + return properties; + } +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/AllWriteOnly_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/AllWriteOnly_ScriptProperties.generated.cs new file mode 100644 index 0000000000..256420fe87 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/AllWriteOnly_ScriptProperties.generated.cs @@ -0,0 +1,58 @@ +using Godot; +using Godot.NativeInterop; + +partial class AllWriteOnly +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the properties and fields contained in this class, for fast lookup. + /// </summary> + public new class PropertyName : global::Godot.GodotObject.PropertyName { + /// <summary> + /// Cached name for the 'writeonly_property' property. + /// </summary> + public new static readonly global::Godot.StringName writeonly_property = "writeonly_property"; + /// <summary> + /// Cached name for the 'writeonly_backing_field' field. + /// </summary> + public new static readonly global::Godot.StringName writeonly_backing_field = "writeonly_backing_field"; + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value) + { + if (name == PropertyName.writeonly_property) { + this.writeonly_property = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value); + return true; + } + else if (name == PropertyName.writeonly_backing_field) { + this.writeonly_backing_field = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value); + return true; + } + return base.SetGodotClassPropertyValue(name, value); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value) + { + if (name == PropertyName.writeonly_backing_field) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<bool>(this.writeonly_backing_field); + return true; + } + return base.GetGodotClassPropertyValue(name, out value); + } + /// <summary> + /// Get the property information for all the properties declared in this class. + /// This method is used by Godot to register the available properties in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList() + { + var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>(); + properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.writeonly_backing_field, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.writeonly_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + return properties; + } +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Bar_ScriptPath.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Bar_ScriptPath.generated.cs new file mode 100644 index 0000000000..9096da1b42 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Bar_ScriptPath.generated.cs @@ -0,0 +1,5 @@ +using Godot; +[ScriptPathAttribute("res://Bar.cs")] +partial class Bar +{ +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs new file mode 100644 index 0000000000..b1c57e6b26 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs @@ -0,0 +1,54 @@ +using Godot; +using Godot.NativeInterop; + +partial class EventSignals +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the signals contained in this class, for fast lookup. + /// </summary> + public new class SignalName : global::Godot.GodotObject.SignalName { + /// <summary> + /// Cached name for the 'MySignal' signal. + /// </summary> + public new static readonly global::Godot.StringName MySignal = "MySignal"; + } + /// <summary> + /// Get the signal information for all the signals declared in this class. + /// This method is used by Godot to register the available signals in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo> GetGodotSignalList() + { + var signals = new global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>(1); + signals.Add(new(name: SignalName.MySignal, returnVal: new(type: (global::Godot.Variant.Type)0, name: "", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), flags: (global::Godot.MethodFlags)1, arguments: new() { new(type: (global::Godot.Variant.Type)4, name: "str", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), new(type: (global::Godot.Variant.Type)2, name: "num", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), }, defaultArguments: null)); + return signals; + } +#pragma warning restore CS0109 + private global::EventSignals.MySignalEventHandler backing_MySignal; + /// <inheritdoc cref="global::EventSignals.MySignalEventHandler"/> + public event global::EventSignals.MySignalEventHandler MySignal { + add => backing_MySignal += value; + remove => backing_MySignal -= value; +} + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override void RaiseGodotClassSignalCallbacks(in godot_string_name signal, NativeVariantPtrArgs args) + { + if (signal == SignalName.MySignal && args.Count == 2) { + backing_MySignal?.Invoke(global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(args[0]), global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(args[1])); + return; + } + base.RaiseGodotClassSignalCallbacks(signal, args); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool HasGodotClassSignal(in godot_string_name signal) + { + if (signal == SignalName.MySignal) { + return true; + } + return base.HasGodotClassSignal(signal); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptProperties.generated.cs new file mode 100644 index 0000000000..915c36525b --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptProperties.generated.cs @@ -0,0 +1,816 @@ +using Godot; +using Godot.NativeInterop; + +partial class ExportedFields +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the properties and fields contained in this class, for fast lookup. + /// </summary> + public new class PropertyName : global::Godot.GodotObject.PropertyName { + /// <summary> + /// Cached name for the 'field_Boolean' field. + /// </summary> + public new static readonly global::Godot.StringName field_Boolean = "field_Boolean"; + /// <summary> + /// Cached name for the 'field_Char' field. + /// </summary> + public new static readonly global::Godot.StringName field_Char = "field_Char"; + /// <summary> + /// Cached name for the 'field_SByte' field. + /// </summary> + public new static readonly global::Godot.StringName field_SByte = "field_SByte"; + /// <summary> + /// Cached name for the 'field_Int16' field. + /// </summary> + public new static readonly global::Godot.StringName field_Int16 = "field_Int16"; + /// <summary> + /// Cached name for the 'field_Int32' field. + /// </summary> + public new static readonly global::Godot.StringName field_Int32 = "field_Int32"; + /// <summary> + /// Cached name for the 'field_Int64' field. + /// </summary> + public new static readonly global::Godot.StringName field_Int64 = "field_Int64"; + /// <summary> + /// Cached name for the 'field_Byte' field. + /// </summary> + public new static readonly global::Godot.StringName field_Byte = "field_Byte"; + /// <summary> + /// Cached name for the 'field_UInt16' field. + /// </summary> + public new static readonly global::Godot.StringName field_UInt16 = "field_UInt16"; + /// <summary> + /// Cached name for the 'field_UInt32' field. + /// </summary> + public new static readonly global::Godot.StringName field_UInt32 = "field_UInt32"; + /// <summary> + /// Cached name for the 'field_UInt64' field. + /// </summary> + public new static readonly global::Godot.StringName field_UInt64 = "field_UInt64"; + /// <summary> + /// Cached name for the 'field_Single' field. + /// </summary> + public new static readonly global::Godot.StringName field_Single = "field_Single"; + /// <summary> + /// Cached name for the 'field_Double' field. + /// </summary> + public new static readonly global::Godot.StringName field_Double = "field_Double"; + /// <summary> + /// Cached name for the 'field_String' field. + /// </summary> + public new static readonly global::Godot.StringName field_String = "field_String"; + /// <summary> + /// Cached name for the 'field_Vector2' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector2 = "field_Vector2"; + /// <summary> + /// Cached name for the 'field_Vector2I' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector2I = "field_Vector2I"; + /// <summary> + /// Cached name for the 'field_Rect2' field. + /// </summary> + public new static readonly global::Godot.StringName field_Rect2 = "field_Rect2"; + /// <summary> + /// Cached name for the 'field_Rect2I' field. + /// </summary> + public new static readonly global::Godot.StringName field_Rect2I = "field_Rect2I"; + /// <summary> + /// Cached name for the 'field_Transform2D' field. + /// </summary> + public new static readonly global::Godot.StringName field_Transform2D = "field_Transform2D"; + /// <summary> + /// Cached name for the 'field_Vector3' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector3 = "field_Vector3"; + /// <summary> + /// Cached name for the 'field_Vector3I' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector3I = "field_Vector3I"; + /// <summary> + /// Cached name for the 'field_Basis' field. + /// </summary> + public new static readonly global::Godot.StringName field_Basis = "field_Basis"; + /// <summary> + /// Cached name for the 'field_Quaternion' field. + /// </summary> + public new static readonly global::Godot.StringName field_Quaternion = "field_Quaternion"; + /// <summary> + /// Cached name for the 'field_Transform3D' field. + /// </summary> + public new static readonly global::Godot.StringName field_Transform3D = "field_Transform3D"; + /// <summary> + /// Cached name for the 'field_Vector4' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector4 = "field_Vector4"; + /// <summary> + /// Cached name for the 'field_Vector4I' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector4I = "field_Vector4I"; + /// <summary> + /// Cached name for the 'field_Projection' field. + /// </summary> + public new static readonly global::Godot.StringName field_Projection = "field_Projection"; + /// <summary> + /// Cached name for the 'field_Aabb' field. + /// </summary> + public new static readonly global::Godot.StringName field_Aabb = "field_Aabb"; + /// <summary> + /// Cached name for the 'field_Color' field. + /// </summary> + public new static readonly global::Godot.StringName field_Color = "field_Color"; + /// <summary> + /// Cached name for the 'field_Plane' field. + /// </summary> + public new static readonly global::Godot.StringName field_Plane = "field_Plane"; + /// <summary> + /// Cached name for the 'field_Callable' field. + /// </summary> + public new static readonly global::Godot.StringName field_Callable = "field_Callable"; + /// <summary> + /// Cached name for the 'field_Signal' field. + /// </summary> + public new static readonly global::Godot.StringName field_Signal = "field_Signal"; + /// <summary> + /// Cached name for the 'field_Enum' field. + /// </summary> + public new static readonly global::Godot.StringName field_Enum = "field_Enum"; + /// <summary> + /// Cached name for the 'field_FlagsEnum' field. + /// </summary> + public new static readonly global::Godot.StringName field_FlagsEnum = "field_FlagsEnum"; + /// <summary> + /// Cached name for the 'field_ByteArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_ByteArray = "field_ByteArray"; + /// <summary> + /// Cached name for the 'field_Int32Array' field. + /// </summary> + public new static readonly global::Godot.StringName field_Int32Array = "field_Int32Array"; + /// <summary> + /// Cached name for the 'field_Int64Array' field. + /// </summary> + public new static readonly global::Godot.StringName field_Int64Array = "field_Int64Array"; + /// <summary> + /// Cached name for the 'field_SingleArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_SingleArray = "field_SingleArray"; + /// <summary> + /// Cached name for the 'field_DoubleArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_DoubleArray = "field_DoubleArray"; + /// <summary> + /// Cached name for the 'field_StringArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_StringArray = "field_StringArray"; + /// <summary> + /// Cached name for the 'field_StringArrayEnum' field. + /// </summary> + public new static readonly global::Godot.StringName field_StringArrayEnum = "field_StringArrayEnum"; + /// <summary> + /// Cached name for the 'field_Vector2Array' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector2Array = "field_Vector2Array"; + /// <summary> + /// Cached name for the 'field_Vector3Array' field. + /// </summary> + public new static readonly global::Godot.StringName field_Vector3Array = "field_Vector3Array"; + /// <summary> + /// Cached name for the 'field_ColorArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_ColorArray = "field_ColorArray"; + /// <summary> + /// Cached name for the 'field_GodotObjectOrDerivedArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_GodotObjectOrDerivedArray = "field_GodotObjectOrDerivedArray"; + /// <summary> + /// Cached name for the 'field_StringNameArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_StringNameArray = "field_StringNameArray"; + /// <summary> + /// Cached name for the 'field_NodePathArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_NodePathArray = "field_NodePathArray"; + /// <summary> + /// Cached name for the 'field_RidArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_RidArray = "field_RidArray"; + /// <summary> + /// Cached name for the 'field_empty_Int32Array' field. + /// </summary> + public new static readonly global::Godot.StringName field_empty_Int32Array = "field_empty_Int32Array"; + /// <summary> + /// Cached name for the 'field_array_from_list' field. + /// </summary> + public new static readonly global::Godot.StringName field_array_from_list = "field_array_from_list"; + /// <summary> + /// Cached name for the 'field_Variant' field. + /// </summary> + public new static readonly global::Godot.StringName field_Variant = "field_Variant"; + /// <summary> + /// Cached name for the 'field_GodotObjectOrDerived' field. + /// </summary> + public new static readonly global::Godot.StringName field_GodotObjectOrDerived = "field_GodotObjectOrDerived"; + /// <summary> + /// Cached name for the 'field_GodotResourceTexture' field. + /// </summary> + public new static readonly global::Godot.StringName field_GodotResourceTexture = "field_GodotResourceTexture"; + /// <summary> + /// Cached name for the 'field_StringName' field. + /// </summary> + public new static readonly global::Godot.StringName field_StringName = "field_StringName"; + /// <summary> + /// Cached name for the 'field_NodePath' field. + /// </summary> + public new static readonly global::Godot.StringName field_NodePath = "field_NodePath"; + /// <summary> + /// Cached name for the 'field_Rid' field. + /// </summary> + public new static readonly global::Godot.StringName field_Rid = "field_Rid"; + /// <summary> + /// Cached name for the 'field_GodotDictionary' field. + /// </summary> + public new static readonly global::Godot.StringName field_GodotDictionary = "field_GodotDictionary"; + /// <summary> + /// Cached name for the 'field_GodotArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_GodotArray = "field_GodotArray"; + /// <summary> + /// Cached name for the 'field_GodotGenericDictionary' field. + /// </summary> + public new static readonly global::Godot.StringName field_GodotGenericDictionary = "field_GodotGenericDictionary"; + /// <summary> + /// Cached name for the 'field_GodotGenericArray' field. + /// </summary> + public new static readonly global::Godot.StringName field_GodotGenericArray = "field_GodotGenericArray"; + /// <summary> + /// Cached name for the 'field_empty_Int64Array' field. + /// </summary> + public new static readonly global::Godot.StringName field_empty_Int64Array = "field_empty_Int64Array"; + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value) + { + if (name == PropertyName.field_Boolean) { + this.field_Boolean = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value); + return true; + } + else if (name == PropertyName.field_Char) { + this.field_Char = global::Godot.NativeInterop.VariantUtils.ConvertTo<char>(value); + return true; + } + else if (name == PropertyName.field_SByte) { + this.field_SByte = global::Godot.NativeInterop.VariantUtils.ConvertTo<sbyte>(value); + return true; + } + else if (name == PropertyName.field_Int16) { + this.field_Int16 = global::Godot.NativeInterop.VariantUtils.ConvertTo<short>(value); + return true; + } + else if (name == PropertyName.field_Int32) { + this.field_Int32 = global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(value); + return true; + } + else if (name == PropertyName.field_Int64) { + this.field_Int64 = global::Godot.NativeInterop.VariantUtils.ConvertTo<long>(value); + return true; + } + else if (name == PropertyName.field_Byte) { + this.field_Byte = global::Godot.NativeInterop.VariantUtils.ConvertTo<byte>(value); + return true; + } + else if (name == PropertyName.field_UInt16) { + this.field_UInt16 = global::Godot.NativeInterop.VariantUtils.ConvertTo<ushort>(value); + return true; + } + else if (name == PropertyName.field_UInt32) { + this.field_UInt32 = global::Godot.NativeInterop.VariantUtils.ConvertTo<uint>(value); + return true; + } + else if (name == PropertyName.field_UInt64) { + this.field_UInt64 = global::Godot.NativeInterop.VariantUtils.ConvertTo<ulong>(value); + return true; + } + else if (name == PropertyName.field_Single) { + this.field_Single = global::Godot.NativeInterop.VariantUtils.ConvertTo<float>(value); + return true; + } + else if (name == PropertyName.field_Double) { + this.field_Double = global::Godot.NativeInterop.VariantUtils.ConvertTo<double>(value); + return true; + } + else if (name == PropertyName.field_String) { + this.field_String = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.field_Vector2) { + this.field_Vector2 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector2>(value); + return true; + } + else if (name == PropertyName.field_Vector2I) { + this.field_Vector2I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector2I>(value); + return true; + } + else if (name == PropertyName.field_Rect2) { + this.field_Rect2 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rect2>(value); + return true; + } + else if (name == PropertyName.field_Rect2I) { + this.field_Rect2I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rect2I>(value); + return true; + } + else if (name == PropertyName.field_Transform2D) { + this.field_Transform2D = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Transform2D>(value); + return true; + } + else if (name == PropertyName.field_Vector3) { + this.field_Vector3 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector3>(value); + return true; + } + else if (name == PropertyName.field_Vector3I) { + this.field_Vector3I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector3I>(value); + return true; + } + else if (name == PropertyName.field_Basis) { + this.field_Basis = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Basis>(value); + return true; + } + else if (name == PropertyName.field_Quaternion) { + this.field_Quaternion = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Quaternion>(value); + return true; + } + else if (name == PropertyName.field_Transform3D) { + this.field_Transform3D = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Transform3D>(value); + return true; + } + else if (name == PropertyName.field_Vector4) { + this.field_Vector4 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector4>(value); + return true; + } + else if (name == PropertyName.field_Vector4I) { + this.field_Vector4I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector4I>(value); + return true; + } + else if (name == PropertyName.field_Projection) { + this.field_Projection = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Projection>(value); + return true; + } + else if (name == PropertyName.field_Aabb) { + this.field_Aabb = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Aabb>(value); + return true; + } + else if (name == PropertyName.field_Color) { + this.field_Color = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Color>(value); + return true; + } + else if (name == PropertyName.field_Plane) { + this.field_Plane = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Plane>(value); + return true; + } + else if (name == PropertyName.field_Callable) { + this.field_Callable = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Callable>(value); + return true; + } + else if (name == PropertyName.field_Signal) { + this.field_Signal = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Signal>(value); + return true; + } + else if (name == PropertyName.field_Enum) { + this.field_Enum = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::ExportedFields.MyEnum>(value); + return true; + } + else if (name == PropertyName.field_FlagsEnum) { + this.field_FlagsEnum = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::ExportedFields.MyFlagsEnum>(value); + return true; + } + else if (name == PropertyName.field_ByteArray) { + this.field_ByteArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<byte[]>(value); + return true; + } + else if (name == PropertyName.field_Int32Array) { + this.field_Int32Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<int[]>(value); + return true; + } + else if (name == PropertyName.field_Int64Array) { + this.field_Int64Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<long[]>(value); + return true; + } + else if (name == PropertyName.field_SingleArray) { + this.field_SingleArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<float[]>(value); + return true; + } + else if (name == PropertyName.field_DoubleArray) { + this.field_DoubleArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<double[]>(value); + return true; + } + else if (name == PropertyName.field_StringArray) { + this.field_StringArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<string[]>(value); + return true; + } + else if (name == PropertyName.field_StringArrayEnum) { + this.field_StringArrayEnum = global::Godot.NativeInterop.VariantUtils.ConvertTo<string[]>(value); + return true; + } + else if (name == PropertyName.field_Vector2Array) { + this.field_Vector2Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector2[]>(value); + return true; + } + else if (name == PropertyName.field_Vector3Array) { + this.field_Vector3Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector3[]>(value); + return true; + } + else if (name == PropertyName.field_ColorArray) { + this.field_ColorArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Color[]>(value); + return true; + } + else if (name == PropertyName.field_GodotObjectOrDerivedArray) { + this.field_GodotObjectOrDerivedArray = global::Godot.NativeInterop.VariantUtils.ConvertToSystemArrayOfGodotObject<global::Godot.GodotObject>(value); + return true; + } + else if (name == PropertyName.field_StringNameArray) { + this.field_StringNameArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.StringName[]>(value); + return true; + } + else if (name == PropertyName.field_NodePathArray) { + this.field_NodePathArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.NodePath[]>(value); + return true; + } + else if (name == PropertyName.field_RidArray) { + this.field_RidArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rid[]>(value); + return true; + } + else if (name == PropertyName.field_empty_Int32Array) { + this.field_empty_Int32Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<int[]>(value); + return true; + } + else if (name == PropertyName.field_array_from_list) { + this.field_array_from_list = global::Godot.NativeInterop.VariantUtils.ConvertTo<int[]>(value); + return true; + } + else if (name == PropertyName.field_Variant) { + this.field_Variant = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Variant>(value); + return true; + } + else if (name == PropertyName.field_GodotObjectOrDerived) { + this.field_GodotObjectOrDerived = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.GodotObject>(value); + return true; + } + else if (name == PropertyName.field_GodotResourceTexture) { + this.field_GodotResourceTexture = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Texture>(value); + return true; + } + else if (name == PropertyName.field_StringName) { + this.field_StringName = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.StringName>(value); + return true; + } + else if (name == PropertyName.field_NodePath) { + this.field_NodePath = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.NodePath>(value); + return true; + } + else if (name == PropertyName.field_Rid) { + this.field_Rid = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rid>(value); + return true; + } + else if (name == PropertyName.field_GodotDictionary) { + this.field_GodotDictionary = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Collections.Dictionary>(value); + return true; + } + else if (name == PropertyName.field_GodotArray) { + this.field_GodotArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Collections.Array>(value); + return true; + } + else if (name == PropertyName.field_GodotGenericDictionary) { + this.field_GodotGenericDictionary = global::Godot.NativeInterop.VariantUtils.ConvertToDictionary<string, bool>(value); + return true; + } + else if (name == PropertyName.field_GodotGenericArray) { + this.field_GodotGenericArray = global::Godot.NativeInterop.VariantUtils.ConvertToArray<int>(value); + return true; + } + else if (name == PropertyName.field_empty_Int64Array) { + this.field_empty_Int64Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<long[]>(value); + return true; + } + return base.SetGodotClassPropertyValue(name, value); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value) + { + if (name == PropertyName.field_Boolean) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<bool>(this.field_Boolean); + return true; + } + else if (name == PropertyName.field_Char) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<char>(this.field_Char); + return true; + } + else if (name == PropertyName.field_SByte) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<sbyte>(this.field_SByte); + return true; + } + else if (name == PropertyName.field_Int16) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<short>(this.field_Int16); + return true; + } + else if (name == PropertyName.field_Int32) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int>(this.field_Int32); + return true; + } + else if (name == PropertyName.field_Int64) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<long>(this.field_Int64); + return true; + } + else if (name == PropertyName.field_Byte) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<byte>(this.field_Byte); + return true; + } + else if (name == PropertyName.field_UInt16) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<ushort>(this.field_UInt16); + return true; + } + else if (name == PropertyName.field_UInt32) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<uint>(this.field_UInt32); + return true; + } + else if (name == PropertyName.field_UInt64) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<ulong>(this.field_UInt64); + return true; + } + else if (name == PropertyName.field_Single) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<float>(this.field_Single); + return true; + } + else if (name == PropertyName.field_Double) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<double>(this.field_Double); + return true; + } + else if (name == PropertyName.field_String) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.field_String); + return true; + } + else if (name == PropertyName.field_Vector2) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector2>(this.field_Vector2); + return true; + } + else if (name == PropertyName.field_Vector2I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector2I>(this.field_Vector2I); + return true; + } + else if (name == PropertyName.field_Rect2) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rect2>(this.field_Rect2); + return true; + } + else if (name == PropertyName.field_Rect2I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rect2I>(this.field_Rect2I); + return true; + } + else if (name == PropertyName.field_Transform2D) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Transform2D>(this.field_Transform2D); + return true; + } + else if (name == PropertyName.field_Vector3) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector3>(this.field_Vector3); + return true; + } + else if (name == PropertyName.field_Vector3I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector3I>(this.field_Vector3I); + return true; + } + else if (name == PropertyName.field_Basis) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Basis>(this.field_Basis); + return true; + } + else if (name == PropertyName.field_Quaternion) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Quaternion>(this.field_Quaternion); + return true; + } + else if (name == PropertyName.field_Transform3D) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Transform3D>(this.field_Transform3D); + return true; + } + else if (name == PropertyName.field_Vector4) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector4>(this.field_Vector4); + return true; + } + else if (name == PropertyName.field_Vector4I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector4I>(this.field_Vector4I); + return true; + } + else if (name == PropertyName.field_Projection) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Projection>(this.field_Projection); + return true; + } + else if (name == PropertyName.field_Aabb) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Aabb>(this.field_Aabb); + return true; + } + else if (name == PropertyName.field_Color) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Color>(this.field_Color); + return true; + } + else if (name == PropertyName.field_Plane) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Plane>(this.field_Plane); + return true; + } + else if (name == PropertyName.field_Callable) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Callable>(this.field_Callable); + return true; + } + else if (name == PropertyName.field_Signal) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Signal>(this.field_Signal); + return true; + } + else if (name == PropertyName.field_Enum) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::ExportedFields.MyEnum>(this.field_Enum); + return true; + } + else if (name == PropertyName.field_FlagsEnum) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::ExportedFields.MyFlagsEnum>(this.field_FlagsEnum); + return true; + } + else if (name == PropertyName.field_ByteArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<byte[]>(this.field_ByteArray); + return true; + } + else if (name == PropertyName.field_Int32Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int[]>(this.field_Int32Array); + return true; + } + else if (name == PropertyName.field_Int64Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<long[]>(this.field_Int64Array); + return true; + } + else if (name == PropertyName.field_SingleArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<float[]>(this.field_SingleArray); + return true; + } + else if (name == PropertyName.field_DoubleArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<double[]>(this.field_DoubleArray); + return true; + } + else if (name == PropertyName.field_StringArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string[]>(this.field_StringArray); + return true; + } + else if (name == PropertyName.field_StringArrayEnum) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string[]>(this.field_StringArrayEnum); + return true; + } + else if (name == PropertyName.field_Vector2Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector2[]>(this.field_Vector2Array); + return true; + } + else if (name == PropertyName.field_Vector3Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector3[]>(this.field_Vector3Array); + return true; + } + else if (name == PropertyName.field_ColorArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Color[]>(this.field_ColorArray); + return true; + } + else if (name == PropertyName.field_GodotObjectOrDerivedArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFromSystemArrayOfGodotObject(this.field_GodotObjectOrDerivedArray); + return true; + } + else if (name == PropertyName.field_StringNameArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.StringName[]>(this.field_StringNameArray); + return true; + } + else if (name == PropertyName.field_NodePathArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.NodePath[]>(this.field_NodePathArray); + return true; + } + else if (name == PropertyName.field_RidArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rid[]>(this.field_RidArray); + return true; + } + else if (name == PropertyName.field_empty_Int32Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int[]>(this.field_empty_Int32Array); + return true; + } + else if (name == PropertyName.field_array_from_list) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int[]>(this.field_array_from_list); + return true; + } + else if (name == PropertyName.field_Variant) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Variant>(this.field_Variant); + return true; + } + else if (name == PropertyName.field_GodotObjectOrDerived) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.GodotObject>(this.field_GodotObjectOrDerived); + return true; + } + else if (name == PropertyName.field_GodotResourceTexture) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Texture>(this.field_GodotResourceTexture); + return true; + } + else if (name == PropertyName.field_StringName) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.StringName>(this.field_StringName); + return true; + } + else if (name == PropertyName.field_NodePath) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.NodePath>(this.field_NodePath); + return true; + } + else if (name == PropertyName.field_Rid) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rid>(this.field_Rid); + return true; + } + else if (name == PropertyName.field_GodotDictionary) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Collections.Dictionary>(this.field_GodotDictionary); + return true; + } + else if (name == PropertyName.field_GodotArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Collections.Array>(this.field_GodotArray); + return true; + } + else if (name == PropertyName.field_GodotGenericDictionary) { + value = global::Godot.NativeInterop.VariantUtils.CreateFromDictionary(this.field_GodotGenericDictionary); + return true; + } + else if (name == PropertyName.field_GodotGenericArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFromArray(this.field_GodotGenericArray); + return true; + } + else if (name == PropertyName.field_empty_Int64Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<long[]>(this.field_empty_Int64Array); + return true; + } + return base.GetGodotClassPropertyValue(name, out value); + } + /// <summary> + /// Get the property information for all the properties declared in this class. + /// This method is used by Godot to register the available properties in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList() + { + var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>(); + properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.field_Boolean, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_Char, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_SByte, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_Int16, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_Int32, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_Int64, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_Byte, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_UInt16, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_UInt32, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_UInt64, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)3, name: PropertyName.field_Single, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)3, name: PropertyName.field_Double, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.field_String, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)5, name: PropertyName.field_Vector2, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)6, name: PropertyName.field_Vector2I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)7, name: PropertyName.field_Rect2, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)8, name: PropertyName.field_Rect2I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)11, name: PropertyName.field_Transform2D, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)9, name: PropertyName.field_Vector3, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)10, name: PropertyName.field_Vector3I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)17, name: PropertyName.field_Basis, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)15, name: PropertyName.field_Quaternion, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)18, name: PropertyName.field_Transform3D, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)12, name: PropertyName.field_Vector4, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)13, name: PropertyName.field_Vector4I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)19, name: PropertyName.field_Projection, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)16, name: PropertyName.field_Aabb, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)20, name: PropertyName.field_Color, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)14, name: PropertyName.field_Plane, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)25, name: PropertyName.field_Callable, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)26, name: PropertyName.field_Signal, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_Enum, hint: (global::Godot.PropertyHint)2, hintString: "A,B,C", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.field_FlagsEnum, hint: (global::Godot.PropertyHint)6, hintString: "A:0,B:1,C:2", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)29, name: PropertyName.field_ByteArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)30, name: PropertyName.field_Int32Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)31, name: PropertyName.field_Int64Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)32, name: PropertyName.field_SingleArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)33, name: PropertyName.field_DoubleArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)34, name: PropertyName.field_StringArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)34, name: PropertyName.field_StringArrayEnum, hint: (global::Godot.PropertyHint)23, hintString: "4/2:A,B,C", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)35, name: PropertyName.field_Vector2Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)36, name: PropertyName.field_Vector3Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)37, name: PropertyName.field_ColorArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_GodotObjectOrDerivedArray, hint: (global::Godot.PropertyHint)23, hintString: "24/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_StringNameArray, hint: (global::Godot.PropertyHint)23, hintString: "21/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_NodePathArray, hint: (global::Godot.PropertyHint)23, hintString: "22/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_RidArray, hint: (global::Godot.PropertyHint)23, hintString: "23/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)30, name: PropertyName.field_empty_Int32Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)30, name: PropertyName.field_array_from_list, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)0, name: PropertyName.field_Variant, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)135174, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)24, name: PropertyName.field_GodotObjectOrDerived, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)24, name: PropertyName.field_GodotResourceTexture, hint: (global::Godot.PropertyHint)17, hintString: "Texture", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)21, name: PropertyName.field_StringName, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)22, name: PropertyName.field_NodePath, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)23, name: PropertyName.field_Rid, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.field_GodotDictionary, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_GodotArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.field_GodotGenericDictionary, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_GodotGenericArray, hint: (global::Godot.PropertyHint)23, hintString: "2/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)31, name: PropertyName.field_empty_Int64Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + return properties; + } +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptPropertyDefVal.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptPropertyDefVal.generated.cs new file mode 100644 index 0000000000..185b8e4ac6 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedFields_ScriptPropertyDefVal.generated.cs @@ -0,0 +1,139 @@ +partial class ExportedFields +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword +#if TOOLS + /// <summary> + /// Get the default values for all properties declared in this class. + /// This method is used by Godot to determine the value that will be + /// used by the inspector when resetting properties. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant> GetGodotPropertyDefaultValues() + { + var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(60); + bool __field_Boolean_default_value = true; + values.Add(PropertyName.field_Boolean, global::Godot.Variant.From<bool>(__field_Boolean_default_value)); + char __field_Char_default_value = 'f'; + values.Add(PropertyName.field_Char, global::Godot.Variant.From<char>(__field_Char_default_value)); + sbyte __field_SByte_default_value = 10; + values.Add(PropertyName.field_SByte, global::Godot.Variant.From<sbyte>(__field_SByte_default_value)); + short __field_Int16_default_value = 10; + values.Add(PropertyName.field_Int16, global::Godot.Variant.From<short>(__field_Int16_default_value)); + int __field_Int32_default_value = 10; + values.Add(PropertyName.field_Int32, global::Godot.Variant.From<int>(__field_Int32_default_value)); + long __field_Int64_default_value = 10; + values.Add(PropertyName.field_Int64, global::Godot.Variant.From<long>(__field_Int64_default_value)); + byte __field_Byte_default_value = 10; + values.Add(PropertyName.field_Byte, global::Godot.Variant.From<byte>(__field_Byte_default_value)); + ushort __field_UInt16_default_value = 10; + values.Add(PropertyName.field_UInt16, global::Godot.Variant.From<ushort>(__field_UInt16_default_value)); + uint __field_UInt32_default_value = 10; + values.Add(PropertyName.field_UInt32, global::Godot.Variant.From<uint>(__field_UInt32_default_value)); + ulong __field_UInt64_default_value = 10; + values.Add(PropertyName.field_UInt64, global::Godot.Variant.From<ulong>(__field_UInt64_default_value)); + float __field_Single_default_value = 10; + values.Add(PropertyName.field_Single, global::Godot.Variant.From<float>(__field_Single_default_value)); + double __field_Double_default_value = 10; + values.Add(PropertyName.field_Double, global::Godot.Variant.From<double>(__field_Double_default_value)); + string __field_String_default_value = "foo"; + values.Add(PropertyName.field_String, global::Godot.Variant.From<string>(__field_String_default_value)); + global::Godot.Vector2 __field_Vector2_default_value = new(10f, 10f); + values.Add(PropertyName.field_Vector2, global::Godot.Variant.From<global::Godot.Vector2>(__field_Vector2_default_value)); + global::Godot.Vector2I __field_Vector2I_default_value = global::Godot.Vector2I.Up; + values.Add(PropertyName.field_Vector2I, global::Godot.Variant.From<global::Godot.Vector2I>(__field_Vector2I_default_value)); + global::Godot.Rect2 __field_Rect2_default_value = new(new global::Godot.Vector2(10f, 10f), new global::Godot.Vector2(10f, 10f)); + values.Add(PropertyName.field_Rect2, global::Godot.Variant.From<global::Godot.Rect2>(__field_Rect2_default_value)); + global::Godot.Rect2I __field_Rect2I_default_value = new(new global::Godot.Vector2I(10, 10), new global::Godot.Vector2I(10, 10)); + values.Add(PropertyName.field_Rect2I, global::Godot.Variant.From<global::Godot.Rect2I>(__field_Rect2I_default_value)); + global::Godot.Transform2D __field_Transform2D_default_value = global::Godot.Transform2D.Identity; + values.Add(PropertyName.field_Transform2D, global::Godot.Variant.From<global::Godot.Transform2D>(__field_Transform2D_default_value)); + global::Godot.Vector3 __field_Vector3_default_value = new(10f, 10f, 10f); + values.Add(PropertyName.field_Vector3, global::Godot.Variant.From<global::Godot.Vector3>(__field_Vector3_default_value)); + global::Godot.Vector3I __field_Vector3I_default_value = global::Godot.Vector3I.Back; + values.Add(PropertyName.field_Vector3I, global::Godot.Variant.From<global::Godot.Vector3I>(__field_Vector3I_default_value)); + global::Godot.Basis __field_Basis_default_value = new global::Godot.Basis(global::Godot.Quaternion.Identity); + values.Add(PropertyName.field_Basis, global::Godot.Variant.From<global::Godot.Basis>(__field_Basis_default_value)); + global::Godot.Quaternion __field_Quaternion_default_value = new global::Godot.Quaternion(global::Godot.Basis.Identity); + values.Add(PropertyName.field_Quaternion, global::Godot.Variant.From<global::Godot.Quaternion>(__field_Quaternion_default_value)); + global::Godot.Transform3D __field_Transform3D_default_value = global::Godot.Transform3D.Identity; + values.Add(PropertyName.field_Transform3D, global::Godot.Variant.From<global::Godot.Transform3D>(__field_Transform3D_default_value)); + global::Godot.Vector4 __field_Vector4_default_value = new(10f, 10f, 10f, 10f); + values.Add(PropertyName.field_Vector4, global::Godot.Variant.From<global::Godot.Vector4>(__field_Vector4_default_value)); + global::Godot.Vector4I __field_Vector4I_default_value = global::Godot.Vector4I.One; + values.Add(PropertyName.field_Vector4I, global::Godot.Variant.From<global::Godot.Vector4I>(__field_Vector4I_default_value)); + global::Godot.Projection __field_Projection_default_value = global::Godot.Projection.Identity; + values.Add(PropertyName.field_Projection, global::Godot.Variant.From<global::Godot.Projection>(__field_Projection_default_value)); + global::Godot.Aabb __field_Aabb_default_value = new global::Godot.Aabb(10f, 10f, 10f, new global::Godot.Vector3(1f, 1f, 1f)); + values.Add(PropertyName.field_Aabb, global::Godot.Variant.From<global::Godot.Aabb>(__field_Aabb_default_value)); + global::Godot.Color __field_Color_default_value = global::Godot.Colors.Aquamarine; + values.Add(PropertyName.field_Color, global::Godot.Variant.From<global::Godot.Color>(__field_Color_default_value)); + global::Godot.Plane __field_Plane_default_value = global::Godot.Plane.PlaneXZ; + values.Add(PropertyName.field_Plane, global::Godot.Variant.From<global::Godot.Plane>(__field_Plane_default_value)); + global::Godot.Callable __field_Callable_default_value = new global::Godot.Callable(global::Godot.Engine.GetMainLoop(), "_process"); + values.Add(PropertyName.field_Callable, global::Godot.Variant.From<global::Godot.Callable>(__field_Callable_default_value)); + global::Godot.Signal __field_Signal_default_value = new global::Godot.Signal(global::Godot.Engine.GetMainLoop(), "property_list_changed"); + values.Add(PropertyName.field_Signal, global::Godot.Variant.From<global::Godot.Signal>(__field_Signal_default_value)); + global::ExportedFields.MyEnum __field_Enum_default_value = global::ExportedFields.MyEnum.C; + values.Add(PropertyName.field_Enum, global::Godot.Variant.From<global::ExportedFields.MyEnum>(__field_Enum_default_value)); + global::ExportedFields.MyFlagsEnum __field_FlagsEnum_default_value = global::ExportedFields.MyFlagsEnum.C; + values.Add(PropertyName.field_FlagsEnum, global::Godot.Variant.From<global::ExportedFields.MyFlagsEnum>(__field_FlagsEnum_default_value)); + byte[] __field_ByteArray_default_value = { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.field_ByteArray, global::Godot.Variant.From<byte[]>(__field_ByteArray_default_value)); + int[] __field_Int32Array_default_value = { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.field_Int32Array, global::Godot.Variant.From<int[]>(__field_Int32Array_default_value)); + long[] __field_Int64Array_default_value = { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.field_Int64Array, global::Godot.Variant.From<long[]>(__field_Int64Array_default_value)); + float[] __field_SingleArray_default_value = { 0f, 1f, 2f, 3f, 4f, 5f, 6f }; + values.Add(PropertyName.field_SingleArray, global::Godot.Variant.From<float[]>(__field_SingleArray_default_value)); + double[] __field_DoubleArray_default_value = { 0d, 1d, 2d, 3d, 4d, 5d, 6d }; + values.Add(PropertyName.field_DoubleArray, global::Godot.Variant.From<double[]>(__field_DoubleArray_default_value)); + string[] __field_StringArray_default_value = { "foo", "bar" }; + values.Add(PropertyName.field_StringArray, global::Godot.Variant.From<string[]>(__field_StringArray_default_value)); + string[] __field_StringArrayEnum_default_value = { "foo", "bar" }; + values.Add(PropertyName.field_StringArrayEnum, global::Godot.Variant.From<string[]>(__field_StringArrayEnum_default_value)); + global::Godot.Vector2[] __field_Vector2Array_default_value = { global::Godot.Vector2.Up, global::Godot.Vector2.Down, global::Godot.Vector2.Left, global::Godot.Vector2.Right }; + values.Add(PropertyName.field_Vector2Array, global::Godot.Variant.From<global::Godot.Vector2[]>(__field_Vector2Array_default_value)); + global::Godot.Vector3[] __field_Vector3Array_default_value = { global::Godot.Vector3.Up, global::Godot.Vector3.Down, global::Godot.Vector3.Left, global::Godot.Vector3.Right }; + values.Add(PropertyName.field_Vector3Array, global::Godot.Variant.From<global::Godot.Vector3[]>(__field_Vector3Array_default_value)); + global::Godot.Color[] __field_ColorArray_default_value = { global::Godot.Colors.Aqua, global::Godot.Colors.Aquamarine, global::Godot.Colors.Azure, global::Godot.Colors.Beige }; + values.Add(PropertyName.field_ColorArray, global::Godot.Variant.From<global::Godot.Color[]>(__field_ColorArray_default_value)); + global::Godot.GodotObject[] __field_GodotObjectOrDerivedArray_default_value = { null }; + values.Add(PropertyName.field_GodotObjectOrDerivedArray, global::Godot.Variant.CreateFrom(__field_GodotObjectOrDerivedArray_default_value)); + global::Godot.StringName[] __field_StringNameArray_default_value = { "foo", "bar" }; + values.Add(PropertyName.field_StringNameArray, global::Godot.Variant.From<global::Godot.StringName[]>(__field_StringNameArray_default_value)); + global::Godot.NodePath[] __field_NodePathArray_default_value = { "foo", "bar" }; + values.Add(PropertyName.field_NodePathArray, global::Godot.Variant.From<global::Godot.NodePath[]>(__field_NodePathArray_default_value)); + global::Godot.Rid[] __field_RidArray_default_value = { default, default, default }; + values.Add(PropertyName.field_RidArray, global::Godot.Variant.From<global::Godot.Rid[]>(__field_RidArray_default_value)); + int[] __field_empty_Int32Array_default_value = global::System.Array.Empty<int>(); + values.Add(PropertyName.field_empty_Int32Array, global::Godot.Variant.From<int[]>(__field_empty_Int32Array_default_value)); + int[] __field_array_from_list_default_value = new global::System.Collections.Generic.List<int>(global::System.Array.Empty<int>()).ToArray(); + values.Add(PropertyName.field_array_from_list, global::Godot.Variant.From<int[]>(__field_array_from_list_default_value)); + global::Godot.Variant __field_Variant_default_value = "foo"; + values.Add(PropertyName.field_Variant, global::Godot.Variant.From<global::Godot.Variant>(__field_Variant_default_value)); + global::Godot.GodotObject __field_GodotObjectOrDerived_default_value = default; + values.Add(PropertyName.field_GodotObjectOrDerived, global::Godot.Variant.From<global::Godot.GodotObject>(__field_GodotObjectOrDerived_default_value)); + global::Godot.Texture __field_GodotResourceTexture_default_value = default; + values.Add(PropertyName.field_GodotResourceTexture, global::Godot.Variant.From<global::Godot.Texture>(__field_GodotResourceTexture_default_value)); + global::Godot.StringName __field_StringName_default_value = new global::Godot.StringName("foo"); + values.Add(PropertyName.field_StringName, global::Godot.Variant.From<global::Godot.StringName>(__field_StringName_default_value)); + global::Godot.NodePath __field_NodePath_default_value = new global::Godot.NodePath("foo"); + values.Add(PropertyName.field_NodePath, global::Godot.Variant.From<global::Godot.NodePath>(__field_NodePath_default_value)); + global::Godot.Rid __field_Rid_default_value = default; + values.Add(PropertyName.field_Rid, global::Godot.Variant.From<global::Godot.Rid>(__field_Rid_default_value)); + global::Godot.Collections.Dictionary __field_GodotDictionary_default_value = new() { { "foo", 10 }, { global::Godot.Vector2.Up, global::Godot.Colors.Chocolate } }; + values.Add(PropertyName.field_GodotDictionary, global::Godot.Variant.From<global::Godot.Collections.Dictionary>(__field_GodotDictionary_default_value)); + global::Godot.Collections.Array __field_GodotArray_default_value = new() { "foo", 10, global::Godot.Vector2.Up, global::Godot.Colors.Chocolate }; + values.Add(PropertyName.field_GodotArray, global::Godot.Variant.From<global::Godot.Collections.Array>(__field_GodotArray_default_value)); + global::Godot.Collections.Dictionary<string, bool> __field_GodotGenericDictionary_default_value = new() { { "foo", true }, { "bar", false } }; + values.Add(PropertyName.field_GodotGenericDictionary, global::Godot.Variant.CreateFrom(__field_GodotGenericDictionary_default_value)); + global::Godot.Collections.Array<int> __field_GodotGenericArray_default_value = new() { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.field_GodotGenericArray, global::Godot.Variant.CreateFrom(__field_GodotGenericArray_default_value)); + long[] __field_empty_Int64Array_default_value = global::System.Array.Empty<long>(); + values.Add(PropertyName.field_empty_Int64Array, global::Godot.Variant.From<long[]>(__field_empty_Int64Array_default_value)); + return values; + } +#endif // TOOLS +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs new file mode 100644 index 0000000000..b5ec9b5b49 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptProperties.generated.cs @@ -0,0 +1,933 @@ +using Godot; +using Godot.NativeInterop; + +partial class ExportedProperties +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the properties and fields contained in this class, for fast lookup. + /// </summary> + public new class PropertyName : global::Godot.GodotObject.PropertyName { + /// <summary> + /// Cached name for the 'NotGenerate_Complex_Lamda_Property' property. + /// </summary> + public new static readonly global::Godot.StringName NotGenerate_Complex_Lamda_Property = "NotGenerate_Complex_Lamda_Property"; + /// <summary> + /// Cached name for the 'NotGenerate_Lamda_NoField_Property' property. + /// </summary> + public new static readonly global::Godot.StringName NotGenerate_Lamda_NoField_Property = "NotGenerate_Lamda_NoField_Property"; + /// <summary> + /// Cached name for the 'NotGenerate_Complex_Return_Property' property. + /// </summary> + public new static readonly global::Godot.StringName NotGenerate_Complex_Return_Property = "NotGenerate_Complex_Return_Property"; + /// <summary> + /// Cached name for the 'NotGenerate_Returns_Property' property. + /// </summary> + public new static readonly global::Godot.StringName NotGenerate_Returns_Property = "NotGenerate_Returns_Property"; + /// <summary> + /// Cached name for the 'FullProperty_String' property. + /// </summary> + public new static readonly global::Godot.StringName FullProperty_String = "FullProperty_String"; + /// <summary> + /// Cached name for the 'FullProperty_String_Complex' property. + /// </summary> + public new static readonly global::Godot.StringName FullProperty_String_Complex = "FullProperty_String_Complex"; + /// <summary> + /// Cached name for the 'LamdaProperty_String' property. + /// </summary> + public new static readonly global::Godot.StringName LamdaProperty_String = "LamdaProperty_String"; + /// <summary> + /// Cached name for the 'property_Boolean' property. + /// </summary> + public new static readonly global::Godot.StringName property_Boolean = "property_Boolean"; + /// <summary> + /// Cached name for the 'property_Char' property. + /// </summary> + public new static readonly global::Godot.StringName property_Char = "property_Char"; + /// <summary> + /// Cached name for the 'property_SByte' property. + /// </summary> + public new static readonly global::Godot.StringName property_SByte = "property_SByte"; + /// <summary> + /// Cached name for the 'property_Int16' property. + /// </summary> + public new static readonly global::Godot.StringName property_Int16 = "property_Int16"; + /// <summary> + /// Cached name for the 'property_Int32' property. + /// </summary> + public new static readonly global::Godot.StringName property_Int32 = "property_Int32"; + /// <summary> + /// Cached name for the 'property_Int64' property. + /// </summary> + public new static readonly global::Godot.StringName property_Int64 = "property_Int64"; + /// <summary> + /// Cached name for the 'property_Byte' property. + /// </summary> + public new static readonly global::Godot.StringName property_Byte = "property_Byte"; + /// <summary> + /// Cached name for the 'property_UInt16' property. + /// </summary> + public new static readonly global::Godot.StringName property_UInt16 = "property_UInt16"; + /// <summary> + /// Cached name for the 'property_UInt32' property. + /// </summary> + public new static readonly global::Godot.StringName property_UInt32 = "property_UInt32"; + /// <summary> + /// Cached name for the 'property_UInt64' property. + /// </summary> + public new static readonly global::Godot.StringName property_UInt64 = "property_UInt64"; + /// <summary> + /// Cached name for the 'property_Single' property. + /// </summary> + public new static readonly global::Godot.StringName property_Single = "property_Single"; + /// <summary> + /// Cached name for the 'property_Double' property. + /// </summary> + public new static readonly global::Godot.StringName property_Double = "property_Double"; + /// <summary> + /// Cached name for the 'property_String' property. + /// </summary> + public new static readonly global::Godot.StringName property_String = "property_String"; + /// <summary> + /// Cached name for the 'property_Vector2' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector2 = "property_Vector2"; + /// <summary> + /// Cached name for the 'property_Vector2I' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector2I = "property_Vector2I"; + /// <summary> + /// Cached name for the 'property_Rect2' property. + /// </summary> + public new static readonly global::Godot.StringName property_Rect2 = "property_Rect2"; + /// <summary> + /// Cached name for the 'property_Rect2I' property. + /// </summary> + public new static readonly global::Godot.StringName property_Rect2I = "property_Rect2I"; + /// <summary> + /// Cached name for the 'property_Transform2D' property. + /// </summary> + public new static readonly global::Godot.StringName property_Transform2D = "property_Transform2D"; + /// <summary> + /// Cached name for the 'property_Vector3' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector3 = "property_Vector3"; + /// <summary> + /// Cached name for the 'property_Vector3I' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector3I = "property_Vector3I"; + /// <summary> + /// Cached name for the 'property_Basis' property. + /// </summary> + public new static readonly global::Godot.StringName property_Basis = "property_Basis"; + /// <summary> + /// Cached name for the 'property_Quaternion' property. + /// </summary> + public new static readonly global::Godot.StringName property_Quaternion = "property_Quaternion"; + /// <summary> + /// Cached name for the 'property_Transform3D' property. + /// </summary> + public new static readonly global::Godot.StringName property_Transform3D = "property_Transform3D"; + /// <summary> + /// Cached name for the 'property_Vector4' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector4 = "property_Vector4"; + /// <summary> + /// Cached name for the 'property_Vector4I' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector4I = "property_Vector4I"; + /// <summary> + /// Cached name for the 'property_Projection' property. + /// </summary> + public new static readonly global::Godot.StringName property_Projection = "property_Projection"; + /// <summary> + /// Cached name for the 'property_Aabb' property. + /// </summary> + public new static readonly global::Godot.StringName property_Aabb = "property_Aabb"; + /// <summary> + /// Cached name for the 'property_Color' property. + /// </summary> + public new static readonly global::Godot.StringName property_Color = "property_Color"; + /// <summary> + /// Cached name for the 'property_Plane' property. + /// </summary> + public new static readonly global::Godot.StringName property_Plane = "property_Plane"; + /// <summary> + /// Cached name for the 'property_Callable' property. + /// </summary> + public new static readonly global::Godot.StringName property_Callable = "property_Callable"; + /// <summary> + /// Cached name for the 'property_Signal' property. + /// </summary> + public new static readonly global::Godot.StringName property_Signal = "property_Signal"; + /// <summary> + /// Cached name for the 'property_Enum' property. + /// </summary> + public new static readonly global::Godot.StringName property_Enum = "property_Enum"; + /// <summary> + /// Cached name for the 'property_FlagsEnum' property. + /// </summary> + public new static readonly global::Godot.StringName property_FlagsEnum = "property_FlagsEnum"; + /// <summary> + /// Cached name for the 'property_ByteArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_ByteArray = "property_ByteArray"; + /// <summary> + /// Cached name for the 'property_Int32Array' property. + /// </summary> + public new static readonly global::Godot.StringName property_Int32Array = "property_Int32Array"; + /// <summary> + /// Cached name for the 'property_Int64Array' property. + /// </summary> + public new static readonly global::Godot.StringName property_Int64Array = "property_Int64Array"; + /// <summary> + /// Cached name for the 'property_SingleArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_SingleArray = "property_SingleArray"; + /// <summary> + /// Cached name for the 'property_DoubleArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_DoubleArray = "property_DoubleArray"; + /// <summary> + /// Cached name for the 'property_StringArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_StringArray = "property_StringArray"; + /// <summary> + /// Cached name for the 'property_StringArrayEnum' property. + /// </summary> + public new static readonly global::Godot.StringName property_StringArrayEnum = "property_StringArrayEnum"; + /// <summary> + /// Cached name for the 'property_Vector2Array' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector2Array = "property_Vector2Array"; + /// <summary> + /// Cached name for the 'property_Vector3Array' property. + /// </summary> + public new static readonly global::Godot.StringName property_Vector3Array = "property_Vector3Array"; + /// <summary> + /// Cached name for the 'property_ColorArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_ColorArray = "property_ColorArray"; + /// <summary> + /// Cached name for the 'property_GodotObjectOrDerivedArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_GodotObjectOrDerivedArray = "property_GodotObjectOrDerivedArray"; + /// <summary> + /// Cached name for the 'field_StringNameArray' property. + /// </summary> + public new static readonly global::Godot.StringName field_StringNameArray = "field_StringNameArray"; + /// <summary> + /// Cached name for the 'field_NodePathArray' property. + /// </summary> + public new static readonly global::Godot.StringName field_NodePathArray = "field_NodePathArray"; + /// <summary> + /// Cached name for the 'field_RidArray' property. + /// </summary> + public new static readonly global::Godot.StringName field_RidArray = "field_RidArray"; + /// <summary> + /// Cached name for the 'property_Variant' property. + /// </summary> + public new static readonly global::Godot.StringName property_Variant = "property_Variant"; + /// <summary> + /// Cached name for the 'property_GodotObjectOrDerived' property. + /// </summary> + public new static readonly global::Godot.StringName property_GodotObjectOrDerived = "property_GodotObjectOrDerived"; + /// <summary> + /// Cached name for the 'property_GodotResourceTexture' property. + /// </summary> + public new static readonly global::Godot.StringName property_GodotResourceTexture = "property_GodotResourceTexture"; + /// <summary> + /// Cached name for the 'property_StringName' property. + /// </summary> + public new static readonly global::Godot.StringName property_StringName = "property_StringName"; + /// <summary> + /// Cached name for the 'property_NodePath' property. + /// </summary> + public new static readonly global::Godot.StringName property_NodePath = "property_NodePath"; + /// <summary> + /// Cached name for the 'property_Rid' property. + /// </summary> + public new static readonly global::Godot.StringName property_Rid = "property_Rid"; + /// <summary> + /// Cached name for the 'property_GodotDictionary' property. + /// </summary> + public new static readonly global::Godot.StringName property_GodotDictionary = "property_GodotDictionary"; + /// <summary> + /// Cached name for the 'property_GodotArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_GodotArray = "property_GodotArray"; + /// <summary> + /// Cached name for the 'property_GodotGenericDictionary' property. + /// </summary> + public new static readonly global::Godot.StringName property_GodotGenericDictionary = "property_GodotGenericDictionary"; + /// <summary> + /// Cached name for the 'property_GodotGenericArray' property. + /// </summary> + public new static readonly global::Godot.StringName property_GodotGenericArray = "property_GodotGenericArray"; + /// <summary> + /// Cached name for the '_notGenerate_Property_String' field. + /// </summary> + public new static readonly global::Godot.StringName _notGenerate_Property_String = "_notGenerate_Property_String"; + /// <summary> + /// Cached name for the '_notGenerate_Property_Int' field. + /// </summary> + public new static readonly global::Godot.StringName _notGenerate_Property_Int = "_notGenerate_Property_Int"; + /// <summary> + /// Cached name for the '_fullProperty_String' field. + /// </summary> + public new static readonly global::Godot.StringName _fullProperty_String = "_fullProperty_String"; + /// <summary> + /// Cached name for the '_fullProperty_String_Complex' field. + /// </summary> + public new static readonly global::Godot.StringName _fullProperty_String_Complex = "_fullProperty_String_Complex"; + /// <summary> + /// Cached name for the '_lamdaProperty_String' field. + /// </summary> + public new static readonly global::Godot.StringName _lamdaProperty_String = "_lamdaProperty_String"; + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value) + { + if (name == PropertyName.NotGenerate_Complex_Lamda_Property) { + this.NotGenerate_Complex_Lamda_Property = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.NotGenerate_Lamda_NoField_Property) { + this.NotGenerate_Lamda_NoField_Property = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.NotGenerate_Complex_Return_Property) { + this.NotGenerate_Complex_Return_Property = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.NotGenerate_Returns_Property) { + this.NotGenerate_Returns_Property = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.FullProperty_String) { + this.FullProperty_String = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.FullProperty_String_Complex) { + this.FullProperty_String_Complex = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.LamdaProperty_String) { + this.LamdaProperty_String = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.property_Boolean) { + this.property_Boolean = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value); + return true; + } + else if (name == PropertyName.property_Char) { + this.property_Char = global::Godot.NativeInterop.VariantUtils.ConvertTo<char>(value); + return true; + } + else if (name == PropertyName.property_SByte) { + this.property_SByte = global::Godot.NativeInterop.VariantUtils.ConvertTo<sbyte>(value); + return true; + } + else if (name == PropertyName.property_Int16) { + this.property_Int16 = global::Godot.NativeInterop.VariantUtils.ConvertTo<short>(value); + return true; + } + else if (name == PropertyName.property_Int32) { + this.property_Int32 = global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(value); + return true; + } + else if (name == PropertyName.property_Int64) { + this.property_Int64 = global::Godot.NativeInterop.VariantUtils.ConvertTo<long>(value); + return true; + } + else if (name == PropertyName.property_Byte) { + this.property_Byte = global::Godot.NativeInterop.VariantUtils.ConvertTo<byte>(value); + return true; + } + else if (name == PropertyName.property_UInt16) { + this.property_UInt16 = global::Godot.NativeInterop.VariantUtils.ConvertTo<ushort>(value); + return true; + } + else if (name == PropertyName.property_UInt32) { + this.property_UInt32 = global::Godot.NativeInterop.VariantUtils.ConvertTo<uint>(value); + return true; + } + else if (name == PropertyName.property_UInt64) { + this.property_UInt64 = global::Godot.NativeInterop.VariantUtils.ConvertTo<ulong>(value); + return true; + } + else if (name == PropertyName.property_Single) { + this.property_Single = global::Godot.NativeInterop.VariantUtils.ConvertTo<float>(value); + return true; + } + else if (name == PropertyName.property_Double) { + this.property_Double = global::Godot.NativeInterop.VariantUtils.ConvertTo<double>(value); + return true; + } + else if (name == PropertyName.property_String) { + this.property_String = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName.property_Vector2) { + this.property_Vector2 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector2>(value); + return true; + } + else if (name == PropertyName.property_Vector2I) { + this.property_Vector2I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector2I>(value); + return true; + } + else if (name == PropertyName.property_Rect2) { + this.property_Rect2 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rect2>(value); + return true; + } + else if (name == PropertyName.property_Rect2I) { + this.property_Rect2I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rect2I>(value); + return true; + } + else if (name == PropertyName.property_Transform2D) { + this.property_Transform2D = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Transform2D>(value); + return true; + } + else if (name == PropertyName.property_Vector3) { + this.property_Vector3 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector3>(value); + return true; + } + else if (name == PropertyName.property_Vector3I) { + this.property_Vector3I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector3I>(value); + return true; + } + else if (name == PropertyName.property_Basis) { + this.property_Basis = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Basis>(value); + return true; + } + else if (name == PropertyName.property_Quaternion) { + this.property_Quaternion = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Quaternion>(value); + return true; + } + else if (name == PropertyName.property_Transform3D) { + this.property_Transform3D = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Transform3D>(value); + return true; + } + else if (name == PropertyName.property_Vector4) { + this.property_Vector4 = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector4>(value); + return true; + } + else if (name == PropertyName.property_Vector4I) { + this.property_Vector4I = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector4I>(value); + return true; + } + else if (name == PropertyName.property_Projection) { + this.property_Projection = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Projection>(value); + return true; + } + else if (name == PropertyName.property_Aabb) { + this.property_Aabb = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Aabb>(value); + return true; + } + else if (name == PropertyName.property_Color) { + this.property_Color = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Color>(value); + return true; + } + else if (name == PropertyName.property_Plane) { + this.property_Plane = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Plane>(value); + return true; + } + else if (name == PropertyName.property_Callable) { + this.property_Callable = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Callable>(value); + return true; + } + else if (name == PropertyName.property_Signal) { + this.property_Signal = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Signal>(value); + return true; + } + else if (name == PropertyName.property_Enum) { + this.property_Enum = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::ExportedProperties.MyEnum>(value); + return true; + } + else if (name == PropertyName.property_FlagsEnum) { + this.property_FlagsEnum = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::ExportedProperties.MyFlagsEnum>(value); + return true; + } + else if (name == PropertyName.property_ByteArray) { + this.property_ByteArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<byte[]>(value); + return true; + } + else if (name == PropertyName.property_Int32Array) { + this.property_Int32Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<int[]>(value); + return true; + } + else if (name == PropertyName.property_Int64Array) { + this.property_Int64Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<long[]>(value); + return true; + } + else if (name == PropertyName.property_SingleArray) { + this.property_SingleArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<float[]>(value); + return true; + } + else if (name == PropertyName.property_DoubleArray) { + this.property_DoubleArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<double[]>(value); + return true; + } + else if (name == PropertyName.property_StringArray) { + this.property_StringArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<string[]>(value); + return true; + } + else if (name == PropertyName.property_StringArrayEnum) { + this.property_StringArrayEnum = global::Godot.NativeInterop.VariantUtils.ConvertTo<string[]>(value); + return true; + } + else if (name == PropertyName.property_Vector2Array) { + this.property_Vector2Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector2[]>(value); + return true; + } + else if (name == PropertyName.property_Vector3Array) { + this.property_Vector3Array = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Vector3[]>(value); + return true; + } + else if (name == PropertyName.property_ColorArray) { + this.property_ColorArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Color[]>(value); + return true; + } + else if (name == PropertyName.property_GodotObjectOrDerivedArray) { + this.property_GodotObjectOrDerivedArray = global::Godot.NativeInterop.VariantUtils.ConvertToSystemArrayOfGodotObject<global::Godot.GodotObject>(value); + return true; + } + else if (name == PropertyName.field_StringNameArray) { + this.field_StringNameArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.StringName[]>(value); + return true; + } + else if (name == PropertyName.field_NodePathArray) { + this.field_NodePathArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.NodePath[]>(value); + return true; + } + else if (name == PropertyName.field_RidArray) { + this.field_RidArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rid[]>(value); + return true; + } + else if (name == PropertyName.property_Variant) { + this.property_Variant = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Variant>(value); + return true; + } + else if (name == PropertyName.property_GodotObjectOrDerived) { + this.property_GodotObjectOrDerived = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.GodotObject>(value); + return true; + } + else if (name == PropertyName.property_GodotResourceTexture) { + this.property_GodotResourceTexture = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Texture>(value); + return true; + } + else if (name == PropertyName.property_StringName) { + this.property_StringName = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.StringName>(value); + return true; + } + else if (name == PropertyName.property_NodePath) { + this.property_NodePath = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.NodePath>(value); + return true; + } + else if (name == PropertyName.property_Rid) { + this.property_Rid = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Rid>(value); + return true; + } + else if (name == PropertyName.property_GodotDictionary) { + this.property_GodotDictionary = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Collections.Dictionary>(value); + return true; + } + else if (name == PropertyName.property_GodotArray) { + this.property_GodotArray = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.Collections.Array>(value); + return true; + } + else if (name == PropertyName.property_GodotGenericDictionary) { + this.property_GodotGenericDictionary = global::Godot.NativeInterop.VariantUtils.ConvertToDictionary<string, bool>(value); + return true; + } + else if (name == PropertyName.property_GodotGenericArray) { + this.property_GodotGenericArray = global::Godot.NativeInterop.VariantUtils.ConvertToArray<int>(value); + return true; + } + else if (name == PropertyName._notGenerate_Property_String) { + this._notGenerate_Property_String = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName._notGenerate_Property_Int) { + this._notGenerate_Property_Int = global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(value); + return true; + } + else if (name == PropertyName._fullProperty_String) { + this._fullProperty_String = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName._fullProperty_String_Complex) { + this._fullProperty_String_Complex = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + else if (name == PropertyName._lamdaProperty_String) { + this._lamdaProperty_String = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value); + return true; + } + return base.SetGodotClassPropertyValue(name, value); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value) + { + if (name == PropertyName.NotGenerate_Complex_Lamda_Property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.NotGenerate_Complex_Lamda_Property); + return true; + } + else if (name == PropertyName.NotGenerate_Lamda_NoField_Property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.NotGenerate_Lamda_NoField_Property); + return true; + } + else if (name == PropertyName.NotGenerate_Complex_Return_Property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.NotGenerate_Complex_Return_Property); + return true; + } + else if (name == PropertyName.NotGenerate_Returns_Property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.NotGenerate_Returns_Property); + return true; + } + else if (name == PropertyName.FullProperty_String) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.FullProperty_String); + return true; + } + else if (name == PropertyName.FullProperty_String_Complex) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.FullProperty_String_Complex); + return true; + } + else if (name == PropertyName.LamdaProperty_String) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.LamdaProperty_String); + return true; + } + else if (name == PropertyName.property_Boolean) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<bool>(this.property_Boolean); + return true; + } + else if (name == PropertyName.property_Char) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<char>(this.property_Char); + return true; + } + else if (name == PropertyName.property_SByte) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<sbyte>(this.property_SByte); + return true; + } + else if (name == PropertyName.property_Int16) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<short>(this.property_Int16); + return true; + } + else if (name == PropertyName.property_Int32) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int>(this.property_Int32); + return true; + } + else if (name == PropertyName.property_Int64) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<long>(this.property_Int64); + return true; + } + else if (name == PropertyName.property_Byte) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<byte>(this.property_Byte); + return true; + } + else if (name == PropertyName.property_UInt16) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<ushort>(this.property_UInt16); + return true; + } + else if (name == PropertyName.property_UInt32) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<uint>(this.property_UInt32); + return true; + } + else if (name == PropertyName.property_UInt64) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<ulong>(this.property_UInt64); + return true; + } + else if (name == PropertyName.property_Single) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<float>(this.property_Single); + return true; + } + else if (name == PropertyName.property_Double) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<double>(this.property_Double); + return true; + } + else if (name == PropertyName.property_String) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.property_String); + return true; + } + else if (name == PropertyName.property_Vector2) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector2>(this.property_Vector2); + return true; + } + else if (name == PropertyName.property_Vector2I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector2I>(this.property_Vector2I); + return true; + } + else if (name == PropertyName.property_Rect2) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rect2>(this.property_Rect2); + return true; + } + else if (name == PropertyName.property_Rect2I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rect2I>(this.property_Rect2I); + return true; + } + else if (name == PropertyName.property_Transform2D) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Transform2D>(this.property_Transform2D); + return true; + } + else if (name == PropertyName.property_Vector3) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector3>(this.property_Vector3); + return true; + } + else if (name == PropertyName.property_Vector3I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector3I>(this.property_Vector3I); + return true; + } + else if (name == PropertyName.property_Basis) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Basis>(this.property_Basis); + return true; + } + else if (name == PropertyName.property_Quaternion) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Quaternion>(this.property_Quaternion); + return true; + } + else if (name == PropertyName.property_Transform3D) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Transform3D>(this.property_Transform3D); + return true; + } + else if (name == PropertyName.property_Vector4) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector4>(this.property_Vector4); + return true; + } + else if (name == PropertyName.property_Vector4I) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector4I>(this.property_Vector4I); + return true; + } + else if (name == PropertyName.property_Projection) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Projection>(this.property_Projection); + return true; + } + else if (name == PropertyName.property_Aabb) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Aabb>(this.property_Aabb); + return true; + } + else if (name == PropertyName.property_Color) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Color>(this.property_Color); + return true; + } + else if (name == PropertyName.property_Plane) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Plane>(this.property_Plane); + return true; + } + else if (name == PropertyName.property_Callable) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Callable>(this.property_Callable); + return true; + } + else if (name == PropertyName.property_Signal) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Signal>(this.property_Signal); + return true; + } + else if (name == PropertyName.property_Enum) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::ExportedProperties.MyEnum>(this.property_Enum); + return true; + } + else if (name == PropertyName.property_FlagsEnum) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::ExportedProperties.MyFlagsEnum>(this.property_FlagsEnum); + return true; + } + else if (name == PropertyName.property_ByteArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<byte[]>(this.property_ByteArray); + return true; + } + else if (name == PropertyName.property_Int32Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int[]>(this.property_Int32Array); + return true; + } + else if (name == PropertyName.property_Int64Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<long[]>(this.property_Int64Array); + return true; + } + else if (name == PropertyName.property_SingleArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<float[]>(this.property_SingleArray); + return true; + } + else if (name == PropertyName.property_DoubleArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<double[]>(this.property_DoubleArray); + return true; + } + else if (name == PropertyName.property_StringArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string[]>(this.property_StringArray); + return true; + } + else if (name == PropertyName.property_StringArrayEnum) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string[]>(this.property_StringArrayEnum); + return true; + } + else if (name == PropertyName.property_Vector2Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector2[]>(this.property_Vector2Array); + return true; + } + else if (name == PropertyName.property_Vector3Array) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Vector3[]>(this.property_Vector3Array); + return true; + } + else if (name == PropertyName.property_ColorArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Color[]>(this.property_ColorArray); + return true; + } + else if (name == PropertyName.property_GodotObjectOrDerivedArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFromSystemArrayOfGodotObject(this.property_GodotObjectOrDerivedArray); + return true; + } + else if (name == PropertyName.field_StringNameArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.StringName[]>(this.field_StringNameArray); + return true; + } + else if (name == PropertyName.field_NodePathArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.NodePath[]>(this.field_NodePathArray); + return true; + } + else if (name == PropertyName.field_RidArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rid[]>(this.field_RidArray); + return true; + } + else if (name == PropertyName.property_Variant) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Variant>(this.property_Variant); + return true; + } + else if (name == PropertyName.property_GodotObjectOrDerived) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.GodotObject>(this.property_GodotObjectOrDerived); + return true; + } + else if (name == PropertyName.property_GodotResourceTexture) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Texture>(this.property_GodotResourceTexture); + return true; + } + else if (name == PropertyName.property_StringName) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.StringName>(this.property_StringName); + return true; + } + else if (name == PropertyName.property_NodePath) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.NodePath>(this.property_NodePath); + return true; + } + else if (name == PropertyName.property_Rid) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Rid>(this.property_Rid); + return true; + } + else if (name == PropertyName.property_GodotDictionary) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Collections.Dictionary>(this.property_GodotDictionary); + return true; + } + else if (name == PropertyName.property_GodotArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Collections.Array>(this.property_GodotArray); + return true; + } + else if (name == PropertyName.property_GodotGenericDictionary) { + value = global::Godot.NativeInterop.VariantUtils.CreateFromDictionary(this.property_GodotGenericDictionary); + return true; + } + else if (name == PropertyName.property_GodotGenericArray) { + value = global::Godot.NativeInterop.VariantUtils.CreateFromArray(this.property_GodotGenericArray); + return true; + } + else if (name == PropertyName._notGenerate_Property_String) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this._notGenerate_Property_String); + return true; + } + else if (name == PropertyName._notGenerate_Property_Int) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int>(this._notGenerate_Property_Int); + return true; + } + else if (name == PropertyName._fullProperty_String) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this._fullProperty_String); + return true; + } + else if (name == PropertyName._fullProperty_String_Complex) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this._fullProperty_String_Complex); + return true; + } + else if (name == PropertyName._lamdaProperty_String) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this._lamdaProperty_String); + return true; + } + return base.GetGodotClassPropertyValue(name, out value); + } + /// <summary> + /// Get the property information for all the properties declared in this class. + /// This method is used by Godot to register the available properties in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList() + { + var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>(); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName._notGenerate_Property_String, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.NotGenerate_Complex_Lamda_Property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.NotGenerate_Lamda_NoField_Property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.NotGenerate_Complex_Return_Property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName._notGenerate_Property_Int, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.NotGenerate_Returns_Property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName._fullProperty_String, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.FullProperty_String, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName._fullProperty_String_Complex, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.FullProperty_String_Complex, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName._lamdaProperty_String, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.LamdaProperty_String, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.property_Boolean, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_Char, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_SByte, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_Int16, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_Int32, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_Int64, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_Byte, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_UInt16, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_UInt32, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_UInt64, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)3, name: PropertyName.property_Single, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)3, name: PropertyName.property_Double, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.property_String, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)5, name: PropertyName.property_Vector2, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)6, name: PropertyName.property_Vector2I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)7, name: PropertyName.property_Rect2, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)8, name: PropertyName.property_Rect2I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)11, name: PropertyName.property_Transform2D, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)9, name: PropertyName.property_Vector3, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)10, name: PropertyName.property_Vector3I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)17, name: PropertyName.property_Basis, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)15, name: PropertyName.property_Quaternion, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)18, name: PropertyName.property_Transform3D, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)12, name: PropertyName.property_Vector4, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)13, name: PropertyName.property_Vector4I, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)19, name: PropertyName.property_Projection, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)16, name: PropertyName.property_Aabb, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)20, name: PropertyName.property_Color, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)14, name: PropertyName.property_Plane, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)25, name: PropertyName.property_Callable, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)26, name: PropertyName.property_Signal, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_Enum, hint: (global::Godot.PropertyHint)2, hintString: "A,B,C", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.property_FlagsEnum, hint: (global::Godot.PropertyHint)6, hintString: "A:0,B:1,C:2", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)29, name: PropertyName.property_ByteArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)30, name: PropertyName.property_Int32Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)31, name: PropertyName.property_Int64Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)32, name: PropertyName.property_SingleArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)33, name: PropertyName.property_DoubleArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)34, name: PropertyName.property_StringArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)34, name: PropertyName.property_StringArrayEnum, hint: (global::Godot.PropertyHint)23, hintString: "4/2:A,B,C", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)35, name: PropertyName.property_Vector2Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)36, name: PropertyName.property_Vector3Array, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)37, name: PropertyName.property_ColorArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.property_GodotObjectOrDerivedArray, hint: (global::Godot.PropertyHint)23, hintString: "24/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_StringNameArray, hint: (global::Godot.PropertyHint)23, hintString: "21/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_NodePathArray, hint: (global::Godot.PropertyHint)23, hintString: "22/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.field_RidArray, hint: (global::Godot.PropertyHint)23, hintString: "23/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)0, name: PropertyName.property_Variant, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)135174, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)24, name: PropertyName.property_GodotObjectOrDerived, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)24, name: PropertyName.property_GodotResourceTexture, hint: (global::Godot.PropertyHint)17, hintString: "Texture", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)21, name: PropertyName.property_StringName, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)22, name: PropertyName.property_NodePath, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)23, name: PropertyName.property_Rid, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.property_GodotDictionary, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.property_GodotArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)27, name: PropertyName.property_GodotGenericDictionary, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.property_GodotGenericArray, hint: (global::Godot.PropertyHint)23, hintString: "2/0:", usage: (global::Godot.PropertyUsageFlags)4102, exported: true)); + return properties; + } +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptPropertyDefVal.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptPropertyDefVal.generated.cs new file mode 100644 index 0000000000..a4cd10d080 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportedProperties_ScriptPropertyDefVal.generated.cs @@ -0,0 +1,147 @@ +partial class ExportedProperties +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword +#if TOOLS + /// <summary> + /// Get the default values for all properties declared in this class. + /// This method is used by Godot to determine the value that will be + /// used by the inspector when resetting properties. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant> GetGodotPropertyDefaultValues() + { + var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(64); + string __NotGenerate_Complex_Lamda_Property_default_value = default; + values.Add(PropertyName.NotGenerate_Complex_Lamda_Property, global::Godot.Variant.From<string>(__NotGenerate_Complex_Lamda_Property_default_value)); + string __NotGenerate_Lamda_NoField_Property_default_value = default; + values.Add(PropertyName.NotGenerate_Lamda_NoField_Property, global::Godot.Variant.From<string>(__NotGenerate_Lamda_NoField_Property_default_value)); + string __NotGenerate_Complex_Return_Property_default_value = default; + values.Add(PropertyName.NotGenerate_Complex_Return_Property, global::Godot.Variant.From<string>(__NotGenerate_Complex_Return_Property_default_value)); + string __NotGenerate_Returns_Property_default_value = default; + values.Add(PropertyName.NotGenerate_Returns_Property, global::Godot.Variant.From<string>(__NotGenerate_Returns_Property_default_value)); + string __FullProperty_String_default_value = "FullProperty_String"; + values.Add(PropertyName.FullProperty_String, global::Godot.Variant.From<string>(__FullProperty_String_default_value)); + string __FullProperty_String_Complex_default_value = new string("FullProperty_String_Complex") + global::System.Convert.ToInt32("1"); + values.Add(PropertyName.FullProperty_String_Complex, global::Godot.Variant.From<string>(__FullProperty_String_Complex_default_value)); + string __LamdaProperty_String_default_value = "LamdaProperty_String"; + values.Add(PropertyName.LamdaProperty_String, global::Godot.Variant.From<string>(__LamdaProperty_String_default_value)); + bool __property_Boolean_default_value = true; + values.Add(PropertyName.property_Boolean, global::Godot.Variant.From<bool>(__property_Boolean_default_value)); + char __property_Char_default_value = 'f'; + values.Add(PropertyName.property_Char, global::Godot.Variant.From<char>(__property_Char_default_value)); + sbyte __property_SByte_default_value = 10; + values.Add(PropertyName.property_SByte, global::Godot.Variant.From<sbyte>(__property_SByte_default_value)); + short __property_Int16_default_value = 10; + values.Add(PropertyName.property_Int16, global::Godot.Variant.From<short>(__property_Int16_default_value)); + int __property_Int32_default_value = 10; + values.Add(PropertyName.property_Int32, global::Godot.Variant.From<int>(__property_Int32_default_value)); + long __property_Int64_default_value = 10; + values.Add(PropertyName.property_Int64, global::Godot.Variant.From<long>(__property_Int64_default_value)); + byte __property_Byte_default_value = 10; + values.Add(PropertyName.property_Byte, global::Godot.Variant.From<byte>(__property_Byte_default_value)); + ushort __property_UInt16_default_value = 10; + values.Add(PropertyName.property_UInt16, global::Godot.Variant.From<ushort>(__property_UInt16_default_value)); + uint __property_UInt32_default_value = 10; + values.Add(PropertyName.property_UInt32, global::Godot.Variant.From<uint>(__property_UInt32_default_value)); + ulong __property_UInt64_default_value = 10; + values.Add(PropertyName.property_UInt64, global::Godot.Variant.From<ulong>(__property_UInt64_default_value)); + float __property_Single_default_value = 10; + values.Add(PropertyName.property_Single, global::Godot.Variant.From<float>(__property_Single_default_value)); + double __property_Double_default_value = 10; + values.Add(PropertyName.property_Double, global::Godot.Variant.From<double>(__property_Double_default_value)); + string __property_String_default_value = "foo"; + values.Add(PropertyName.property_String, global::Godot.Variant.From<string>(__property_String_default_value)); + global::Godot.Vector2 __property_Vector2_default_value = new(10f, 10f); + values.Add(PropertyName.property_Vector2, global::Godot.Variant.From<global::Godot.Vector2>(__property_Vector2_default_value)); + global::Godot.Vector2I __property_Vector2I_default_value = global::Godot.Vector2I.Up; + values.Add(PropertyName.property_Vector2I, global::Godot.Variant.From<global::Godot.Vector2I>(__property_Vector2I_default_value)); + global::Godot.Rect2 __property_Rect2_default_value = new(new global::Godot.Vector2(10f, 10f), new global::Godot.Vector2(10f, 10f)); + values.Add(PropertyName.property_Rect2, global::Godot.Variant.From<global::Godot.Rect2>(__property_Rect2_default_value)); + global::Godot.Rect2I __property_Rect2I_default_value = new(new global::Godot.Vector2I(10, 10), new global::Godot.Vector2I(10, 10)); + values.Add(PropertyName.property_Rect2I, global::Godot.Variant.From<global::Godot.Rect2I>(__property_Rect2I_default_value)); + global::Godot.Transform2D __property_Transform2D_default_value = global::Godot.Transform2D.Identity; + values.Add(PropertyName.property_Transform2D, global::Godot.Variant.From<global::Godot.Transform2D>(__property_Transform2D_default_value)); + global::Godot.Vector3 __property_Vector3_default_value = new(10f, 10f, 10f); + values.Add(PropertyName.property_Vector3, global::Godot.Variant.From<global::Godot.Vector3>(__property_Vector3_default_value)); + global::Godot.Vector3I __property_Vector3I_default_value = global::Godot.Vector3I.Back; + values.Add(PropertyName.property_Vector3I, global::Godot.Variant.From<global::Godot.Vector3I>(__property_Vector3I_default_value)); + global::Godot.Basis __property_Basis_default_value = new global::Godot.Basis(global::Godot.Quaternion.Identity); + values.Add(PropertyName.property_Basis, global::Godot.Variant.From<global::Godot.Basis>(__property_Basis_default_value)); + global::Godot.Quaternion __property_Quaternion_default_value = new global::Godot.Quaternion(global::Godot.Basis.Identity); + values.Add(PropertyName.property_Quaternion, global::Godot.Variant.From<global::Godot.Quaternion>(__property_Quaternion_default_value)); + global::Godot.Transform3D __property_Transform3D_default_value = global::Godot.Transform3D.Identity; + values.Add(PropertyName.property_Transform3D, global::Godot.Variant.From<global::Godot.Transform3D>(__property_Transform3D_default_value)); + global::Godot.Vector4 __property_Vector4_default_value = new(10f, 10f, 10f, 10f); + values.Add(PropertyName.property_Vector4, global::Godot.Variant.From<global::Godot.Vector4>(__property_Vector4_default_value)); + global::Godot.Vector4I __property_Vector4I_default_value = global::Godot.Vector4I.One; + values.Add(PropertyName.property_Vector4I, global::Godot.Variant.From<global::Godot.Vector4I>(__property_Vector4I_default_value)); + global::Godot.Projection __property_Projection_default_value = global::Godot.Projection.Identity; + values.Add(PropertyName.property_Projection, global::Godot.Variant.From<global::Godot.Projection>(__property_Projection_default_value)); + global::Godot.Aabb __property_Aabb_default_value = new global::Godot.Aabb(10f, 10f, 10f, new global::Godot.Vector3(1f, 1f, 1f)); + values.Add(PropertyName.property_Aabb, global::Godot.Variant.From<global::Godot.Aabb>(__property_Aabb_default_value)); + global::Godot.Color __property_Color_default_value = global::Godot.Colors.Aquamarine; + values.Add(PropertyName.property_Color, global::Godot.Variant.From<global::Godot.Color>(__property_Color_default_value)); + global::Godot.Plane __property_Plane_default_value = global::Godot.Plane.PlaneXZ; + values.Add(PropertyName.property_Plane, global::Godot.Variant.From<global::Godot.Plane>(__property_Plane_default_value)); + global::Godot.Callable __property_Callable_default_value = new global::Godot.Callable(global::Godot.Engine.GetMainLoop(), "_process"); + values.Add(PropertyName.property_Callable, global::Godot.Variant.From<global::Godot.Callable>(__property_Callable_default_value)); + global::Godot.Signal __property_Signal_default_value = new global::Godot.Signal(global::Godot.Engine.GetMainLoop(), "property_list_changed"); + values.Add(PropertyName.property_Signal, global::Godot.Variant.From<global::Godot.Signal>(__property_Signal_default_value)); + global::ExportedProperties.MyEnum __property_Enum_default_value = global::ExportedProperties.MyEnum.C; + values.Add(PropertyName.property_Enum, global::Godot.Variant.From<global::ExportedProperties.MyEnum>(__property_Enum_default_value)); + global::ExportedProperties.MyFlagsEnum __property_FlagsEnum_default_value = global::ExportedProperties.MyFlagsEnum.C; + values.Add(PropertyName.property_FlagsEnum, global::Godot.Variant.From<global::ExportedProperties.MyFlagsEnum>(__property_FlagsEnum_default_value)); + byte[] __property_ByteArray_default_value = { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.property_ByteArray, global::Godot.Variant.From<byte[]>(__property_ByteArray_default_value)); + int[] __property_Int32Array_default_value = { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.property_Int32Array, global::Godot.Variant.From<int[]>(__property_Int32Array_default_value)); + long[] __property_Int64Array_default_value = { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.property_Int64Array, global::Godot.Variant.From<long[]>(__property_Int64Array_default_value)); + float[] __property_SingleArray_default_value = { 0f, 1f, 2f, 3f, 4f, 5f, 6f }; + values.Add(PropertyName.property_SingleArray, global::Godot.Variant.From<float[]>(__property_SingleArray_default_value)); + double[] __property_DoubleArray_default_value = { 0d, 1d, 2d, 3d, 4d, 5d, 6d }; + values.Add(PropertyName.property_DoubleArray, global::Godot.Variant.From<double[]>(__property_DoubleArray_default_value)); + string[] __property_StringArray_default_value = { "foo", "bar" }; + values.Add(PropertyName.property_StringArray, global::Godot.Variant.From<string[]>(__property_StringArray_default_value)); + string[] __property_StringArrayEnum_default_value = { "foo", "bar" }; + values.Add(PropertyName.property_StringArrayEnum, global::Godot.Variant.From<string[]>(__property_StringArrayEnum_default_value)); + global::Godot.Vector2[] __property_Vector2Array_default_value = { global::Godot.Vector2.Up, global::Godot.Vector2.Down, global::Godot.Vector2.Left, global::Godot.Vector2.Right }; + values.Add(PropertyName.property_Vector2Array, global::Godot.Variant.From<global::Godot.Vector2[]>(__property_Vector2Array_default_value)); + global::Godot.Vector3[] __property_Vector3Array_default_value = { global::Godot.Vector3.Up, global::Godot.Vector3.Down, global::Godot.Vector3.Left, global::Godot.Vector3.Right }; + values.Add(PropertyName.property_Vector3Array, global::Godot.Variant.From<global::Godot.Vector3[]>(__property_Vector3Array_default_value)); + global::Godot.Color[] __property_ColorArray_default_value = { global::Godot.Colors.Aqua, global::Godot.Colors.Aquamarine, global::Godot.Colors.Azure, global::Godot.Colors.Beige }; + values.Add(PropertyName.property_ColorArray, global::Godot.Variant.From<global::Godot.Color[]>(__property_ColorArray_default_value)); + global::Godot.GodotObject[] __property_GodotObjectOrDerivedArray_default_value = { null }; + values.Add(PropertyName.property_GodotObjectOrDerivedArray, global::Godot.Variant.CreateFrom(__property_GodotObjectOrDerivedArray_default_value)); + global::Godot.StringName[] __field_StringNameArray_default_value = { "foo", "bar" }; + values.Add(PropertyName.field_StringNameArray, global::Godot.Variant.From<global::Godot.StringName[]>(__field_StringNameArray_default_value)); + global::Godot.NodePath[] __field_NodePathArray_default_value = { "foo", "bar" }; + values.Add(PropertyName.field_NodePathArray, global::Godot.Variant.From<global::Godot.NodePath[]>(__field_NodePathArray_default_value)); + global::Godot.Rid[] __field_RidArray_default_value = { default, default, default }; + values.Add(PropertyName.field_RidArray, global::Godot.Variant.From<global::Godot.Rid[]>(__field_RidArray_default_value)); + global::Godot.Variant __property_Variant_default_value = "foo"; + values.Add(PropertyName.property_Variant, global::Godot.Variant.From<global::Godot.Variant>(__property_Variant_default_value)); + global::Godot.GodotObject __property_GodotObjectOrDerived_default_value = default; + values.Add(PropertyName.property_GodotObjectOrDerived, global::Godot.Variant.From<global::Godot.GodotObject>(__property_GodotObjectOrDerived_default_value)); + global::Godot.Texture __property_GodotResourceTexture_default_value = default; + values.Add(PropertyName.property_GodotResourceTexture, global::Godot.Variant.From<global::Godot.Texture>(__property_GodotResourceTexture_default_value)); + global::Godot.StringName __property_StringName_default_value = new global::Godot.StringName("foo"); + values.Add(PropertyName.property_StringName, global::Godot.Variant.From<global::Godot.StringName>(__property_StringName_default_value)); + global::Godot.NodePath __property_NodePath_default_value = new global::Godot.NodePath("foo"); + values.Add(PropertyName.property_NodePath, global::Godot.Variant.From<global::Godot.NodePath>(__property_NodePath_default_value)); + global::Godot.Rid __property_Rid_default_value = default; + values.Add(PropertyName.property_Rid, global::Godot.Variant.From<global::Godot.Rid>(__property_Rid_default_value)); + global::Godot.Collections.Dictionary __property_GodotDictionary_default_value = new() { { "foo", 10 }, { global::Godot.Vector2.Up, global::Godot.Colors.Chocolate } }; + values.Add(PropertyName.property_GodotDictionary, global::Godot.Variant.From<global::Godot.Collections.Dictionary>(__property_GodotDictionary_default_value)); + global::Godot.Collections.Array __property_GodotArray_default_value = new() { "foo", 10, global::Godot.Vector2.Up, global::Godot.Colors.Chocolate }; + values.Add(PropertyName.property_GodotArray, global::Godot.Variant.From<global::Godot.Collections.Array>(__property_GodotArray_default_value)); + global::Godot.Collections.Dictionary<string, bool> __property_GodotGenericDictionary_default_value = new() { { "foo", true }, { "bar", false } }; + values.Add(PropertyName.property_GodotGenericDictionary, global::Godot.Variant.CreateFrom(__property_GodotGenericDictionary_default_value)); + global::Godot.Collections.Array<int> __property_GodotGenericArray_default_value = new() { 0, 1, 2, 3, 4, 5, 6 }; + values.Add(PropertyName.property_GodotGenericArray, global::Godot.Variant.CreateFrom(__property_GodotGenericArray_default_value)); + return values; + } +#endif // TOOLS +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Foo_ScriptPath.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Foo_ScriptPath.generated.cs new file mode 100644 index 0000000000..9092ad9938 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Foo_ScriptPath.generated.cs @@ -0,0 +1,5 @@ +using Godot; +[ScriptPathAttribute("res://Foo.cs")] +partial class Foo +{ +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Generic_ScriptPath.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Generic_ScriptPath.generated.cs new file mode 100644 index 0000000000..72c48595a2 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Generic_ScriptPath.generated.cs @@ -0,0 +1,5 @@ +using Godot; +[ScriptPathAttribute("res://Generic.cs")] +partial class Generic +{ +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Methods_ScriptMethods.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Methods_ScriptMethods.generated.cs new file mode 100644 index 0000000000..f757497618 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/Methods_ScriptMethods.generated.cs @@ -0,0 +1,61 @@ +using Godot; +using Godot.NativeInterop; + +partial class Methods +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the methods contained in this class, for fast lookup. + /// </summary> + public new class MethodName : global::Godot.GodotObject.MethodName { + /// <summary> + /// Cached name for the 'MethodWithOverload' method. + /// </summary> + public new static readonly global::Godot.StringName MethodWithOverload = "MethodWithOverload"; + } + /// <summary> + /// Get the method information for all the methods declared in this class. + /// This method is used by Godot to register the available methods in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo> GetGodotMethodList() + { + var methods = new global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>(3); + methods.Add(new(name: MethodName.MethodWithOverload, returnVal: new(type: (global::Godot.Variant.Type)0, name: "", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), flags: (global::Godot.MethodFlags)1, arguments: null, defaultArguments: null)); + methods.Add(new(name: MethodName.MethodWithOverload, returnVal: new(type: (global::Godot.Variant.Type)0, name: "", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), flags: (global::Godot.MethodFlags)1, arguments: new() { new(type: (global::Godot.Variant.Type)2, name: "a", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), }, defaultArguments: null)); + methods.Add(new(name: MethodName.MethodWithOverload, returnVal: new(type: (global::Godot.Variant.Type)0, name: "", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), flags: (global::Godot.MethodFlags)1, arguments: new() { new(type: (global::Godot.Variant.Type)2, name: "a", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), new(type: (global::Godot.Variant.Type)2, name: "b", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), }, defaultArguments: null)); + return methods; + } +#pragma warning restore CS0109 + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool InvokeGodotClassMethod(in godot_string_name method, NativeVariantPtrArgs args, out godot_variant ret) + { + if (method == MethodName.MethodWithOverload && args.Count == 0) { + MethodWithOverload(); + ret = default; + return true; + } + if (method == MethodName.MethodWithOverload && args.Count == 1) { + MethodWithOverload(global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(args[0])); + ret = default; + return true; + } + if (method == MethodName.MethodWithOverload && args.Count == 2) { + MethodWithOverload(global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(args[0]), global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(args[1])); + ret = default; + return true; + } + return base.InvokeGodotClassMethod(method, args, out ret); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool HasGodotClassMethod(in godot_string_name method) + { + if (method == MethodName.MethodWithOverload) { + return true; + } + return base.HasGodotClassMethod(method); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/MixedReadOnlyWriteOnly_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/MixedReadOnlyWriteOnly_ScriptProperties.generated.cs new file mode 100644 index 0000000000..f812457aa5 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/MixedReadOnlyWriteOnly_ScriptProperties.generated.cs @@ -0,0 +1,94 @@ +using Godot; +using Godot.NativeInterop; + +partial class MixedReadOnlyWriteOnly +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the properties and fields contained in this class, for fast lookup. + /// </summary> + public new class PropertyName : global::Godot.GodotObject.PropertyName { + /// <summary> + /// Cached name for the 'readonly_auto_property' property. + /// </summary> + public new static readonly global::Godot.StringName readonly_auto_property = "readonly_auto_property"; + /// <summary> + /// Cached name for the 'readonly_property' property. + /// </summary> + public new static readonly global::Godot.StringName readonly_property = "readonly_property"; + /// <summary> + /// Cached name for the 'initonly_auto_property' property. + /// </summary> + public new static readonly global::Godot.StringName initonly_auto_property = "initonly_auto_property"; + /// <summary> + /// Cached name for the 'writeonly_property' property. + /// </summary> + public new static readonly global::Godot.StringName writeonly_property = "writeonly_property"; + /// <summary> + /// Cached name for the 'readonly_field' field. + /// </summary> + public new static readonly global::Godot.StringName readonly_field = "readonly_field"; + /// <summary> + /// Cached name for the 'writeonly_backing_field' field. + /// </summary> + public new static readonly global::Godot.StringName writeonly_backing_field = "writeonly_backing_field"; + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value) + { + if (name == PropertyName.writeonly_property) { + this.writeonly_property = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value); + return true; + } + else if (name == PropertyName.writeonly_backing_field) { + this.writeonly_backing_field = global::Godot.NativeInterop.VariantUtils.ConvertTo<bool>(value); + return true; + } + return base.SetGodotClassPropertyValue(name, value); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value) + { + if (name == PropertyName.readonly_auto_property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.readonly_auto_property); + return true; + } + else if (name == PropertyName.readonly_property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.readonly_property); + return true; + } + else if (name == PropertyName.initonly_auto_property) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.initonly_auto_property); + return true; + } + else if (name == PropertyName.readonly_field) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.readonly_field); + return true; + } + else if (name == PropertyName.writeonly_backing_field) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<bool>(this.writeonly_backing_field); + return true; + } + return base.GetGodotClassPropertyValue(name, out value); + } + /// <summary> + /// Get the property information for all the properties declared in this class. + /// This method is used by Godot to register the available properties in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList() + { + var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>(); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.readonly_field, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.readonly_auto_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.readonly_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.initonly_auto_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.writeonly_backing_field, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)1, name: PropertyName.writeonly_property, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + return properties; + } +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptMethods.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptMethods.generated.cs new file mode 100644 index 0000000000..328107a237 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptMethods.generated.cs @@ -0,0 +1,52 @@ +using Godot; +using Godot.NativeInterop; + +partial struct OuterClass +{ +partial class NestedClass +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the methods contained in this class, for fast lookup. + /// </summary> + public new class MethodName : global::Godot.RefCounted.MethodName { + /// <summary> + /// Cached name for the '_Get' method. + /// </summary> + public new static readonly global::Godot.StringName _Get = "_Get"; + } + /// <summary> + /// Get the method information for all the methods declared in this class. + /// This method is used by Godot to register the available methods in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo> GetGodotMethodList() + { + var methods = new global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>(1); + methods.Add(new(name: MethodName._Get, returnVal: new(type: (global::Godot.Variant.Type)0, name: "", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)131078, exported: false), flags: (global::Godot.MethodFlags)1, arguments: new() { new(type: (global::Godot.Variant.Type)21, name: "property", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), }, defaultArguments: null)); + return methods; + } +#pragma warning restore CS0109 + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool InvokeGodotClassMethod(in godot_string_name method, NativeVariantPtrArgs args, out godot_variant ret) + { + if (method == MethodName._Get && args.Count == 1) { + var callRet = _Get(global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.StringName>(args[0])); + ret = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.Variant>(callRet); + return true; + } + return base.InvokeGodotClassMethod(method, args, out ret); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool HasGodotClassMethod(in godot_string_name method) + { + if (method == MethodName._Get) { + return true; + } + return base.HasGodotClassMethod(method); + } +} +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptProperties.generated.cs new file mode 100644 index 0000000000..79f014a41e --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptProperties.generated.cs @@ -0,0 +1,15 @@ +using Godot; +using Godot.NativeInterop; + +partial struct OuterClass +{ +partial class NestedClass +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the properties and fields contained in this class, for fast lookup. + /// </summary> + public new class PropertyName : global::Godot.RefCounted.PropertyName { + } +} +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptSerialization.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptSerialization.generated.cs new file mode 100644 index 0000000000..4ecce50178 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/OuterClass.NestedClass_ScriptSerialization.generated.cs @@ -0,0 +1,21 @@ +using Godot; +using Godot.NativeInterop; + +partial struct OuterClass +{ +partial class NestedClass +{ + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override void SaveGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info) + { + base.SaveGodotObjectData(info); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override void RestoreGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info) + { + base.RestoreGodotObjectData(info); + } +} +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptMethods.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptMethods.generated.cs new file mode 100644 index 0000000000..8656f4617e --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptMethods.generated.cs @@ -0,0 +1,62 @@ +using Godot; +using Godot.NativeInterop; + +partial class ScriptBoilerplate +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the methods contained in this class, for fast lookup. + /// </summary> + public new class MethodName : global::Godot.Node.MethodName { + /// <summary> + /// Cached name for the '_Process' method. + /// </summary> + public new static readonly global::Godot.StringName _Process = "_Process"; + /// <summary> + /// Cached name for the 'Bazz' method. + /// </summary> + public new static readonly global::Godot.StringName Bazz = "Bazz"; + } + /// <summary> + /// Get the method information for all the methods declared in this class. + /// This method is used by Godot to register the available methods in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo> GetGodotMethodList() + { + var methods = new global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>(2); + methods.Add(new(name: MethodName._Process, returnVal: new(type: (global::Godot.Variant.Type)0, name: "", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), flags: (global::Godot.MethodFlags)1, arguments: new() { new(type: (global::Godot.Variant.Type)3, name: "delta", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), }, defaultArguments: null)); + methods.Add(new(name: MethodName.Bazz, returnVal: new(type: (global::Godot.Variant.Type)2, name: "", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), flags: (global::Godot.MethodFlags)1, arguments: new() { new(type: (global::Godot.Variant.Type)21, name: "name", hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)6, exported: false), }, defaultArguments: null)); + return methods; + } +#pragma warning restore CS0109 + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool InvokeGodotClassMethod(in godot_string_name method, NativeVariantPtrArgs args, out godot_variant ret) + { + if (method == MethodName._Process && args.Count == 1) { + _Process(global::Godot.NativeInterop.VariantUtils.ConvertTo<double>(args[0])); + ret = default; + return true; + } + if (method == MethodName.Bazz && args.Count == 1) { + var callRet = Bazz(global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.StringName>(args[0])); + ret = global::Godot.NativeInterop.VariantUtils.CreateFrom<int>(callRet); + return true; + } + return base.InvokeGodotClassMethod(method, args, out ret); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool HasGodotClassMethod(in godot_string_name method) + { + if (method == MethodName._Process) { + return true; + } + else if (method == MethodName.Bazz) { + return true; + } + return base.HasGodotClassMethod(method); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptPath.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptPath.generated.cs new file mode 100644 index 0000000000..ffcd29f7cd --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptPath.generated.cs @@ -0,0 +1,5 @@ +using Godot; +[ScriptPathAttribute("res://ScriptBoilerplate.cs")] +partial class ScriptBoilerplate +{ +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptProperties.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptProperties.generated.cs new file mode 100644 index 0000000000..09368b7ab6 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptProperties.generated.cs @@ -0,0 +1,62 @@ +using Godot; +using Godot.NativeInterop; + +partial class ScriptBoilerplate +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// <summary> + /// Cached StringNames for the properties and fields contained in this class, for fast lookup. + /// </summary> + public new class PropertyName : global::Godot.Node.PropertyName { + /// <summary> + /// Cached name for the '_nodePath' field. + /// </summary> + public new static readonly global::Godot.StringName _nodePath = "_nodePath"; + /// <summary> + /// Cached name for the '_velocity' field. + /// </summary> + public new static readonly global::Godot.StringName _velocity = "_velocity"; + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value) + { + if (name == PropertyName._nodePath) { + this._nodePath = global::Godot.NativeInterop.VariantUtils.ConvertTo<global::Godot.NodePath>(value); + return true; + } + else if (name == PropertyName._velocity) { + this._velocity = global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(value); + return true; + } + return base.SetGodotClassPropertyValue(name, value); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value) + { + if (name == PropertyName._nodePath) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<global::Godot.NodePath>(this._nodePath); + return true; + } + else if (name == PropertyName._velocity) { + value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int>(this._velocity); + return true; + } + return base.GetGodotClassPropertyValue(name, out value); + } + /// <summary> + /// Get the property information for all the properties declared in this class. + /// This method is used by Godot to register the available properties in the editor. + /// Do not call this method. + /// </summary> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList() + { + var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>(); + properties.Add(new(type: (global::Godot.Variant.Type)22, name: PropertyName._nodePath, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName._velocity, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false)); + return properties; + } +#pragma warning restore CS0109 +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptSerialization.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptSerialization.generated.cs new file mode 100644 index 0000000000..28bc863b0a --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ScriptBoilerplate_ScriptSerialization.generated.cs @@ -0,0 +1,24 @@ +using Godot; +using Godot.NativeInterop; + +partial class ScriptBoilerplate +{ + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override void SaveGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info) + { + base.SaveGodotObjectData(info); + info.AddProperty(PropertyName._nodePath, global::Godot.Variant.From<global::Godot.NodePath>(this._nodePath)); + info.AddProperty(PropertyName._velocity, global::Godot.Variant.From<int>(this._velocity)); + } + /// <inheritdoc/> + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + protected override void RestoreGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info) + { + base.RestoreGodotObjectData(info); + if (info.TryGetProperty(PropertyName._nodePath, out var _value__nodePath)) + this._nodePath = _value__nodePath.As<global::Godot.NodePath>(); + if (info.TryGetProperty(PropertyName._velocity, out var _value__velocity)) + this._velocity = _value__velocity.As<int>(); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/AllReadOnly.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/AllReadOnly.cs new file mode 100644 index 0000000000..94c2bda363 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/AllReadOnly.cs @@ -0,0 +1,9 @@ +using Godot; + +public partial class AllReadOnly : GodotObject +{ + public readonly string readonly_field = "foo"; + public string readonly_auto_property { get; } = "foo"; + public string readonly_property { get => "foo"; } + public string initonly_auto_property { get; init; } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/AllWriteOnly.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/AllWriteOnly.cs new file mode 100644 index 0000000000..156d6bb6a5 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/AllWriteOnly.cs @@ -0,0 +1,7 @@ +using Godot; + +public partial class AllWriteOnly : GodotObject +{ + bool writeonly_backing_field = false; + public bool writeonly_property { set => writeonly_backing_field = value; } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Bar.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Bar.cs new file mode 100644 index 0000000000..dfe2217c26 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Bar.cs @@ -0,0 +1,14 @@ +using Godot; + +partial class Bar : GodotObject +{ +} + +// Foo in another file +partial class Foo +{ +} + +partial class NotSameNameAsFile : GodotObject +{ +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/EventSignals.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/EventSignals.cs new file mode 100644 index 0000000000..160c5d193d --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/EventSignals.cs @@ -0,0 +1,7 @@ +using Godot; + +public partial class EventSignals : GodotObject +{ + [Signal] + public delegate void MySignalEventHandler(string str, int num); +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedFields.cs new file mode 100644 index 0000000000..09d654ffcb --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedFields.cs @@ -0,0 +1,102 @@ +using Godot; +using System; +using System.Collections.Generic; + +public partial class ExportedFields : GodotObject +{ + [Export] private Boolean field_Boolean = true; + [Export] private Char field_Char = 'f'; + [Export] private SByte field_SByte = 10; + [Export] private Int16 field_Int16 = 10; + [Export] private Int32 field_Int32 = 10; + [Export] private Int64 field_Int64 = 10; + [Export] private Byte field_Byte = 10; + [Export] private UInt16 field_UInt16 = 10; + [Export] private UInt32 field_UInt32 = 10; + [Export] private UInt64 field_UInt64 = 10; + [Export] private Single field_Single = 10; + [Export] private Double field_Double = 10; + [Export] private String field_String = "foo"; + + // Godot structs + [Export] private Vector2 field_Vector2 = new(10f, 10f); + [Export] private Vector2I field_Vector2I = Vector2I.Up; + [Export] private Rect2 field_Rect2 = new(new Vector2(10f, 10f), new Vector2(10f, 10f)); + [Export] private Rect2I field_Rect2I = new(new Vector2I(10, 10), new Vector2I(10, 10)); + [Export] private Transform2D field_Transform2D = Transform2D.Identity; + [Export] private Vector3 field_Vector3 = new(10f, 10f, 10f); + [Export] private Vector3I field_Vector3I = Vector3I.Back; + [Export] private Basis field_Basis = new Basis(Quaternion.Identity); + [Export] private Quaternion field_Quaternion = new Quaternion(Basis.Identity); + [Export] private Transform3D field_Transform3D = Transform3D.Identity; + [Export] private Vector4 field_Vector4 = new(10f, 10f, 10f, 10f); + [Export] private Vector4I field_Vector4I = Vector4I.One; + [Export] private Projection field_Projection = Projection.Identity; + [Export] private Aabb field_Aabb = new Aabb(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); + [Export] private Color field_Color = Colors.Aquamarine; + [Export] private Plane field_Plane = Plane.PlaneXZ; + [Export] private Callable field_Callable = new Callable(Engine.GetMainLoop(), "_process"); + [Export] private Signal field_Signal = new Signal(Engine.GetMainLoop(), "property_list_changed"); + + // Enums + enum MyEnum + { + A, + B, + C + } + + [Export] private MyEnum field_Enum = MyEnum.C; + + [Flags] + enum MyFlagsEnum + { + A, + B, + C + } + + [Export] private MyFlagsEnum field_FlagsEnum = MyFlagsEnum.C; + + // Arrays + [Export] private Byte[] field_ByteArray = { 0, 1, 2, 3, 4, 5, 6 }; + [Export] private Int32[] field_Int32Array = { 0, 1, 2, 3, 4, 5, 6 }; + [Export] private Int64[] field_Int64Array = { 0, 1, 2, 3, 4, 5, 6 }; + [Export] private Single[] field_SingleArray = { 0f, 1f, 2f, 3f, 4f, 5f, 6f }; + [Export] private Double[] field_DoubleArray = { 0d, 1d, 2d, 3d, 4d, 5d, 6d }; + [Export] private String[] field_StringArray = { "foo", "bar" }; + [Export(PropertyHint.Enum, "A,B,C")] private String[] field_StringArrayEnum = { "foo", "bar" }; + [Export] private Vector2[] field_Vector2Array = { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right }; + [Export] private Vector3[] field_Vector3Array = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; + [Export] private Color[] field_ColorArray = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige }; + [Export] private GodotObject[] field_GodotObjectOrDerivedArray = { null }; + [Export] private StringName[] field_StringNameArray = { "foo", "bar" }; + [Export] private NodePath[] field_NodePathArray = { "foo", "bar" }; + [Export] private Rid[] field_RidArray = { default, default, default }; + // Note we use Array and not System.Array. This tests the generated namespace qualification. + [Export] private Int32[] field_empty_Int32Array = Array.Empty<Int32>(); + // Note we use List and not System.Collections.Generic. + [Export] private int[] field_array_from_list = new List<int>(Array.Empty<int>()).ToArray(); + + // Variant + [Export] private Variant field_Variant = "foo"; + + // Classes + [Export] private GodotObject field_GodotObjectOrDerived; + [Export] private Godot.Texture field_GodotResourceTexture; + [Export] private StringName field_StringName = new StringName("foo"); + [Export] private NodePath field_NodePath = new NodePath("foo"); + [Export] private Rid field_Rid; + + [Export] + private Godot.Collections.Dictionary field_GodotDictionary = new() { { "foo", 10 }, { Vector2.Up, Colors.Chocolate } }; + + [Export] + private Godot.Collections.Array field_GodotArray = new() { "foo", 10, Vector2.Up, Colors.Chocolate }; + + [Export] + private Godot.Collections.Dictionary<string, bool> field_GodotGenericDictionary = new() { { "foo", true }, { "bar", false } }; + + [Export] + private Godot.Collections.Array<int> field_GodotGenericArray = new() { 0, 1, 2, 3, 4, 5, 6 }; +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs new file mode 100644 index 0000000000..3783838dae --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportedProperties.cs @@ -0,0 +1,186 @@ +using Godot; +using System; + +public partial class ExportedProperties : GodotObject +{ + // Do not generate default value + private String _notGenerate_Property_String = new string("not generate"); + [Export] + public String NotGenerate_Complex_Lamda_Property + { + get => _notGenerate_Property_String + Convert.ToInt32("1"); + set => _notGenerate_Property_String = value; + } + + [Export] + public String NotGenerate_Lamda_NoField_Property + { + get => new string("not generate"); + set => _notGenerate_Property_String = value; + } + + [Export] + public String NotGenerate_Complex_Return_Property + { + get + { + return _notGenerate_Property_String + Convert.ToInt32("1"); + } + set + { + _notGenerate_Property_String = value; + } + } + + private int _notGenerate_Property_Int = 1; + [Export] + public string NotGenerate_Returns_Property + { + get + { + if (_notGenerate_Property_Int == 1) + { + return "a"; + } + else + { + return "b"; + } + } + set + { + _notGenerate_Property_Int = value == "a" ? 1 : 2; + } + } + + // Full Property + private String _fullProperty_String = "FullProperty_String"; + [Export] + public String FullProperty_String + { + get + { + return _fullProperty_String; + } + set + { + _fullProperty_String = value; + } + } + + private String _fullProperty_String_Complex = new string("FullProperty_String_Complex") + Convert.ToInt32("1"); + [Export] + public String FullProperty_String_Complex + { + get + { + return _fullProperty_String_Complex; + } + set + { + _fullProperty_String_Complex = value; + } + } + + // Lambda Property + private String _lamdaProperty_String = "LamdaProperty_String"; + [Export] + public String LamdaProperty_String + { + get => _lamdaProperty_String; + set => _lamdaProperty_String = value; + } + + // Auto Property + [Export] private Boolean property_Boolean { get; set; } = true; + [Export] private Char property_Char { get; set; } = 'f'; + [Export] private SByte property_SByte { get; set; } = 10; + [Export] private Int16 property_Int16 { get; set; } = 10; + [Export] private Int32 property_Int32 { get; set; } = 10; + [Export] private Int64 property_Int64 { get; set; } = 10; + [Export] private Byte property_Byte { get; set; } = 10; + [Export] private UInt16 property_UInt16 { get; set; } = 10; + [Export] private UInt32 property_UInt32 { get; set; } = 10; + [Export] private UInt64 property_UInt64 { get; set; } = 10; + [Export] private Single property_Single { get; set; } = 10; + [Export] private Double property_Double { get; set; } = 10; + [Export] private String property_String { get; set; } = "foo"; + + // Godot structs + [Export] private Vector2 property_Vector2 { get; set; } = new(10f, 10f); + [Export] private Vector2I property_Vector2I { get; set; } = Vector2I.Up; + [Export] private Rect2 property_Rect2 { get; set; } = new(new Vector2(10f, 10f), new Vector2(10f, 10f)); + [Export] private Rect2I property_Rect2I { get; set; } = new(new Vector2I(10, 10), new Vector2I(10, 10)); + [Export] private Transform2D property_Transform2D { get; set; } = Transform2D.Identity; + [Export] private Vector3 property_Vector3 { get; set; } = new(10f, 10f, 10f); + [Export] private Vector3I property_Vector3I { get; set; } = Vector3I.Back; + [Export] private Basis property_Basis { get; set; } = new Basis(Quaternion.Identity); + [Export] private Quaternion property_Quaternion { get; set; } = new Quaternion(Basis.Identity); + [Export] private Transform3D property_Transform3D { get; set; } = Transform3D.Identity; + [Export] private Vector4 property_Vector4 { get; set; } = new(10f, 10f, 10f, 10f); + [Export] private Vector4I property_Vector4I { get; set; } = Vector4I.One; + [Export] private Projection property_Projection { get; set; } = Projection.Identity; + [Export] private Aabb property_Aabb { get; set; } = new Aabb(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); + [Export] private Color property_Color { get; set; } = Colors.Aquamarine; + [Export] private Plane property_Plane { get; set; } = Plane.PlaneXZ; + [Export] private Callable property_Callable { get; set; } = new Callable(Engine.GetMainLoop(), "_process"); + [Export] private Signal property_Signal { get; set; } = new Signal(Engine.GetMainLoop(), "property_list_changed"); + + // Enums + enum MyEnum + { + A, + B, + C + } + + [Export] private MyEnum property_Enum { get; set; } = MyEnum.C; + + [Flags] + enum MyFlagsEnum + { + A, + B, + C + } + + [Export] private MyFlagsEnum property_FlagsEnum { get; set; } = MyFlagsEnum.C; + + // Arrays + [Export] private Byte[] property_ByteArray { get; set; } = { 0, 1, 2, 3, 4, 5, 6 }; + [Export] private Int32[] property_Int32Array { get; set; } = { 0, 1, 2, 3, 4, 5, 6 }; + [Export] private Int64[] property_Int64Array { get; set; } = { 0, 1, 2, 3, 4, 5, 6 }; + [Export] private Single[] property_SingleArray { get; set; } = { 0f, 1f, 2f, 3f, 4f, 5f, 6f }; + [Export] private Double[] property_DoubleArray { get; set; } = { 0d, 1d, 2d, 3d, 4d, 5d, 6d }; + [Export] private String[] property_StringArray { get; set; } = { "foo", "bar" }; + [Export(PropertyHint.Enum, "A,B,C")] private String[] property_StringArrayEnum { get; set; } = { "foo", "bar" }; + [Export] private Vector2[] property_Vector2Array { get; set; } = { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right }; + [Export] private Vector3[] property_Vector3Array { get; set; } = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; + [Export] private Color[] property_ColorArray { get; set; } = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige }; + [Export] private GodotObject[] property_GodotObjectOrDerivedArray { get; set; } = { null }; + [Export] private StringName[] field_StringNameArray { get; set; } = { "foo", "bar" }; + [Export] private NodePath[] field_NodePathArray { get; set; } = { "foo", "bar" }; + [Export] private Rid[] field_RidArray { get; set; } = { default, default, default }; + + // Variant + [Export] private Variant property_Variant { get; set; } = "foo"; + + // Classes + [Export] private GodotObject property_GodotObjectOrDerived { get; set; } + [Export] private Godot.Texture property_GodotResourceTexture { get; set; } + [Export] private StringName property_StringName { get; set; } = new StringName("foo"); + [Export] private NodePath property_NodePath { get; set; } = new NodePath("foo"); + [Export] private Rid property_Rid { get; set; } + + [Export] + private Godot.Collections.Dictionary property_GodotDictionary { get; set; } = new() { { "foo", 10 }, { Vector2.Up, Colors.Chocolate } }; + + [Export] + private Godot.Collections.Array property_GodotArray { get; set; } = new() { "foo", 10, Vector2.Up, Colors.Chocolate }; + + [Export] + private Godot.Collections.Dictionary<string, bool> property_GodotGenericDictionary { get; set; } = new() { { "foo", true }, { "bar", false } }; + + [Export] + private Godot.Collections.Array<int> property_GodotGenericArray { get; set; } = new() { 0, 1, 2, 3, 4, 5, 6 }; +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Foo.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Foo.cs new file mode 100644 index 0000000000..26853553c7 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Foo.cs @@ -0,0 +1,10 @@ +using Godot; + +partial class Foo : GodotObject +{ +} + +// Foo again in the same file +partial class Foo +{ +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Generic.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Generic.cs new file mode 100644 index 0000000000..84d1ede065 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Generic.cs @@ -0,0 +1,18 @@ +using Godot; + +partial class Generic<T> : GodotObject +{ + private int _field; +} + +// Generic again but different generic parameters +partial class Generic<T, R> : GodotObject +{ + private int _field; +} + +// Generic again but without generic parameters +partial class Generic : GodotObject +{ + private int _field; +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Methods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Methods.cs new file mode 100644 index 0000000000..1da9db8204 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/Methods.cs @@ -0,0 +1,26 @@ +using Godot; + +public partial class Methods : GodotObject +{ + private void MethodWithOverload() + { + } + + private void MethodWithOverload(int a) + { + } + + private void MethodWithOverload(int a, int b) + { + } + + // Should be ignored. The previous one is picked. + private void MethodWithOverload(float a, float b) + { + } + + // Generic methods should be ignored. + private void GenericMethod<T>(T t) + { + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MixedReadOnlyWriteOnly.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MixedReadOnlyWriteOnly.cs new file mode 100644 index 0000000000..61a48cefc9 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MixedReadOnlyWriteOnly.cs @@ -0,0 +1,12 @@ +using Godot; + +public partial class MixedReadOnlyWriteOnly : GodotObject +{ + public readonly string readonly_field = "foo"; + public string readonly_auto_property { get; } = "foo"; + public string readonly_property { get => "foo"; } + public string initonly_auto_property { get; init; } + + bool writeonly_backing_field = false; + public bool writeonly_property { set => writeonly_backing_field = value; } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MoreExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MoreExportedFields.cs new file mode 100644 index 0000000000..47063a9cdf --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MoreExportedFields.cs @@ -0,0 +1,8 @@ +using Godot; +using System; + +public partial class ExportedFields : GodotObject +{ + // Note we use Array and not System.Array. This tests the generated namespace qualification. + [Export] private Int64[] field_empty_Int64Array = Array.Empty<Int64>(); +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs new file mode 100644 index 0000000000..5506465b92 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ScriptBoilerplate.cs @@ -0,0 +1,33 @@ +using Godot; + +public partial class ScriptBoilerplate : Node +{ + private NodePath _nodePath; + private int _velocity; + + public override void _Process(double delta) + { + _ = delta; + + base._Process(delta); + } + + public int Bazz(StringName name) + { + _ = name; + return 1; + } + + public void IgnoreThisMethodWithByRefParams(ref int a) + { + _ = a; + } +} + +partial struct OuterClass +{ + public partial class NestedClass : RefCounted + { + public override Variant _Get(StringName property) => default; + } +} diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 36fdda4625..25a5720bc4 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -69,6 +69,7 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) { #define OPEN_BLOCK_L1 INDENT1 OPEN_BLOCK #define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK +#define OPEN_BLOCK_L3 INDENT3 OPEN_BLOCK #define CLOSE_BLOCK_L1 INDENT1 CLOSE_BLOCK #define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK #define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK @@ -2591,7 +2592,11 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall, // Generate icall function r_output << MEMBER_BEGIN "internal static unsafe " << (ret_void ? "void" : return_type->c_type_out) << " " - << icall_method << "(" << c_func_sig.as_string() << ") " OPEN_BLOCK; + << icall_method << "(" << c_func_sig.as_string() << ")\n" OPEN_BLOCK_L1; + + if (!p_icall.is_static) { + r_output << INDENT2 "ExceptionUtils.ThrowIfNullPtr(" CS_PARAM_INSTANCE ");\n"; + } if (!ret_void && (!p_icall.is_vararg || return_type->cname != name_cache.type_Variant)) { String ptrcall_return_type; @@ -2619,11 +2624,6 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall, r_output << ptrcall_return_type << " " C_LOCAL_RET << initialization << ";\n"; } - if (!p_icall.is_static) { - r_output << INDENT2 "if (" CS_PARAM_INSTANCE " == IntPtr.Zero)\n" - << INDENT3 "throw new ArgumentNullException(nameof(" CS_PARAM_INSTANCE "));\n"; - } - String argc_str = itos(p_icall.get_arguments_count()); auto generate_call_and_return_stmts = [&](const char *base_indent) { @@ -2714,7 +2714,7 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall, r_output << c_in_statements.as_string(); - r_output << INDENT3 "for (int i = 0; i < vararg_length; i++) " OPEN_BLOCK + r_output << INDENT3 "for (int i = 0; i < vararg_length; i++)\n" OPEN_BLOCK_L3 << INDENT4 "varargs[i] = " << vararg_arg << "[i].NativeVar;\n" << INDENT4 C_LOCAL_PTRCALL_ARGS "[" << real_argc_str << " + i] = new IntPtr(&varargs[i]);\n" << CLOSE_BLOCK_L3; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs index cc99225a33..57b5b09ebb 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -689,7 +692,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the AABB and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Aabb other && Equals(other); } @@ -739,7 +742,7 @@ namespace Godot /// Converts this <see cref="Aabb"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this AABB.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"{_position.ToString(format)}, {_size.ToString(format)}"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs index 13c0cde1ef..c7420dcf7e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs @@ -6,6 +6,8 @@ using System.Linq; using System.Runtime.CompilerServices; using Godot.NativeInterop; +#nullable enable + namespace Godot.Collections { /// <summary> @@ -22,7 +24,7 @@ namespace Godot.Collections { internal godot_array.movable NativeValue; - private WeakReference<IDisposable> _weakReferenceToSelf; + private WeakReference<IDisposable>? _weakReferenceToSelf; /// <summary> /// Constructs a new empty <see cref="Array"/>. @@ -1140,7 +1142,8 @@ namespace Godot.Collections /// </summary> /// <param name="from">The typed array to convert.</param> /// <returns>A new Godot Array, or <see langword="null"/> if <see paramref="from"/> was null.</returns> - public static explicit operator Array(Array<T> from) + [return: NotNullIfNotNull("from")] + public static explicit operator Array?(Array<T>? from) { return from?._underlyingArray; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index b4f7b82f60..589d6596f0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -1,7 +1,10 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.ComponentModel; +#nullable enable + namespace Godot { /// <summary> @@ -1090,7 +1093,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the basis matrix and the object are exactly equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Basis other && Equals(other); } @@ -1140,7 +1143,7 @@ namespace Godot /// Converts this <see cref="Basis"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this basis.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"[X: {X.ToString(format)}, Y: {Y.ToString(format)}, Z: {Z.ToString(format)}]"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs index 80c26e5708..a087b20308 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs @@ -194,7 +194,7 @@ namespace Godot.Bridge var native = GodotObject.InternalGetClassNativeBase(scriptType); - var field = native?.GetField("NativeName", BindingFlags.DeclaredOnly | BindingFlags.Static | + var field = native.GetField("NativeName", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) @@ -253,11 +253,15 @@ namespace Godot.Bridge { var editorAssembly = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.GetName().Name == "GodotSharpEditor"); - wrapperType = editorAssembly?.GetType("Godot." + nativeTypeNameStr); - if (wrapperType == null) + if (editorAssembly != null) { - wrapperType = GetTypeByGodotClassAttr(editorAssembly, nativeTypeNameStr); + wrapperType = editorAssembly.GetType("Godot." + nativeTypeNameStr); + + if (wrapperType == null) + { + wrapperType = GetTypeByGodotClassAttr(editorAssembly, nativeTypeNameStr); + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 293e680067..772209064c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -1,7 +1,10 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using Godot.NativeInterop; +#nullable enable + namespace Godot { /// <summary> @@ -1274,7 +1277,7 @@ namespace Godot /// </summary> /// <param name="obj">The other object to compare.</param> /// <returns>Whether or not the color and the other object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Color other && Equals(other); } @@ -1324,7 +1327,7 @@ namespace Godot /// Converts this <see cref="Color"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this color.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({R.ToString(format)}, {G.ToString(format)}, {B.ToString(format)}, {A.ToString(format)})"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index 6c2fb7374c..ab2e0a78b9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -414,7 +414,7 @@ namespace Godot { ulong objectId = reader.ReadUInt64(); // ReSharper disable once RedundantNameQualifier - GodotObject godotObject = GodotObject.InstanceFromId(objectId); + GodotObject? godotObject = GodotObject.InstanceFromId(objectId); if (godotObject == null) return false; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs index 2a72ebc32b..d08fad90db 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs @@ -5,6 +5,8 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Godot.NativeInterop; +#nullable enable + namespace Godot.Collections { /// <summary> @@ -19,7 +21,7 @@ namespace Godot.Collections { internal godot_dictionary.movable NativeValue; - private WeakReference<IDisposable> _weakReferenceToSelf; + private WeakReference<IDisposable>? _weakReferenceToSelf; /// <summary> /// Constructs a new empty <see cref="Dictionary"/>. @@ -559,7 +561,8 @@ namespace Godot.Collections /// </summary> /// <param name="from">The typed dictionary to convert.</param> /// <returns>A new Godot Dictionary, or <see langword="null"/> if <see paramref="from"/> was null.</returns> - public static explicit operator Dictionary(Dictionary<TKey, TValue> from) + [return: NotNullIfNotNull("from")] + public static explicit operator Dictionary?(Dictionary<TKey, TValue>? from) { return from?._underlyingDict; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/GodotObjectExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/GodotObjectExtensions.cs index 6c90c17078..563a6abe9b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/GodotObjectExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/GodotObjectExtensions.cs @@ -1,6 +1,8 @@ using System; using Godot.NativeInterop; +#nullable enable + namespace Godot { public partial class GodotObject @@ -26,7 +28,7 @@ namespace Godot /// </example> /// <param name="instanceId">Instance ID of the Object to retrieve.</param> /// <returns>The <see cref="GodotObject"/> instance.</returns> - public static GodotObject InstanceFromId(ulong instanceId) + public static GodotObject? InstanceFromId(ulong instanceId) { return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId)); } @@ -49,7 +51,7 @@ namespace Godot /// </summary> /// <param name="instance">The instance to check.</param> /// <returns>If the instance is a valid object.</returns> - public static bool IsInstanceValid(GodotObject instance) + public static bool IsInstanceValid(GodotObject? instance) { return instance != null && instance.NativeInstance != IntPtr.Zero; } @@ -66,9 +68,9 @@ namespace Godot /// </summary> /// <param name="obj">The object.</param> /// <returns> - /// The <see cref="WeakRef"/> reference to the object or <see langword="null"/>. + /// The <see cref="Godot.WeakRef"/> reference to the object or <see langword="null"/>. /// </returns> - public static WeakRef WeakRef(GodotObject obj) + public static WeakRef? WeakRef(GodotObject? obj) { if (!IsInstanceValid(obj)) return null; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs index 43598ca84d..8f8e884b8c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs @@ -1,8 +1,11 @@ using System; +using System.Diagnostics; using System.Runtime.InteropServices; using Godot.Bridge; using Godot.NativeInterop; +#nullable enable + namespace Godot { public partial class GodotObject : IDisposable @@ -13,7 +16,7 @@ namespace Godot internal IntPtr NativePtr; private bool _memoryOwn; - private WeakReference<GodotObject> _weakReferenceToSelf; + private WeakReference<GodotObject>? _weakReferenceToSelf; /// <summary> /// Constructs a new <see cref="GodotObject"/>. @@ -59,7 +62,7 @@ namespace Godot /// </summary> public IntPtr NativeInstance => NativePtr; - internal static IntPtr GetPtr(GodotObject instance) + internal static IntPtr GetPtr(GodotObject? instance) { if (instance == null) return IntPtr.Zero; @@ -105,7 +108,7 @@ namespace Godot if (gcHandleToFree != IntPtr.Zero) { - object target = GCHandle.FromIntPtr(gcHandleToFree).Target; + object? target = GCHandle.FromIntPtr(gcHandleToFree).Target; // The GC handle may have been replaced in another thread. Release it only if // it's associated to this managed instance, or if the target is no longer alive. if (target != this && target != null) @@ -176,18 +179,14 @@ namespace Godot internal static Type InternalGetClassNativeBase(Type t) { - do - { - var assemblyName = t.Assembly.GetName(); + var name = t.Assembly.GetName().Name; - if (assemblyName.Name == "GodotSharp") - return t; + if (name == "GodotSharp" || name == "GodotSharpEditor") + return t; - if (assemblyName.Name == "GodotSharpEditor") - return t; - } while ((t = t.BaseType) != null); + Debug.Assert(t.BaseType is not null, "Script types must derive from a native Godot type."); - return null; + return InternalGetClassNativeBase(t.BaseType); } // ReSharper disable once VirtualMemberNeverOverridden.Global diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs index dc53e48bd0..04b6c2e743 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Runtime.CompilerServices; using System.Text; #nullable enable @@ -239,5 +240,13 @@ namespace Godot.NativeInterop return variant->Type.ToString(); } + + internal static void ThrowIfNullPtr(IntPtr ptr, [CallerArgumentExpression("ptr")] string? paramName = null) + { + if (ptr == IntPtr.Zero) + { + throw new ArgumentNullException(paramName); + } + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs index f216fb7ea3..0af640533d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using Godot.NativeInterop; +#nullable enable + namespace Godot { /// <summary> @@ -39,11 +42,11 @@ namespace Godot /// new NodePath("/root/MyAutoload"); // If you have an autoloaded node or scene. /// </code> /// </example> - public sealed class NodePath : IDisposable, IEquatable<NodePath> + public sealed class NodePath : IDisposable, IEquatable<NodePath?> { internal godot_node_path.movable NativeValue; - private WeakReference<IDisposable> _weakReferenceToSelf; + private WeakReference<IDisposable>? _weakReferenceToSelf; ~NodePath() { @@ -135,7 +138,8 @@ namespace Godot /// Converts this <see cref="NodePath"/> to a string. /// </summary> /// <param name="from">The <see cref="NodePath"/> to convert.</param> - public static implicit operator string(NodePath from) => from?.ToString(); + [return: NotNullIfNotNull("from")] + public static implicit operator string?(NodePath? from) => from?.ToString(); /// <summary> /// Converts this <see cref="NodePath"/> to a string. @@ -289,19 +293,19 @@ namespace Godot /// <returns>If the <see cref="NodePath"/> is empty.</returns> public bool IsEmpty => NativeValue.DangerousSelfRef.IsEmpty; - public static bool operator ==(NodePath left, NodePath right) + public static bool operator ==(NodePath? left, NodePath? right) { if (left is null) return right is null; return left.Equals(right); } - public static bool operator !=(NodePath left, NodePath right) + public static bool operator !=(NodePath? left, NodePath? right) { return !(left == right); } - public bool Equals(NodePath other) + public bool Equals([NotNullWhen(true)] NodePath? other) { if (other is null) return false; @@ -310,7 +314,7 @@ namespace Godot return NativeFuncs.godotsharp_node_path_equals(self, otherNative).ToBool(); } - public override bool Equals(object obj) + public override bool Equals([NotNullWhen(true)] object? obj) { return ReferenceEquals(this, obj) || (obj is NodePath other && Equals(other)); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs index 85b2b02c45..f5dc34d824 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -382,7 +385,7 @@ namespace Godot /// </summary> /// <param name="obj">The other object to compare.</param> /// <returns>Whether or not the plane and the other object are exactly equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Plane other && Equals(other); } @@ -430,7 +433,7 @@ namespace Godot /// Converts this <see cref="Plane"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this plane.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"{_normal.ToString(format)}, {_d.ToString(format)}"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs index 155e90ff24..4c9e21fb79 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -586,7 +589,7 @@ namespace Godot public readonly Vector2 GetFarPlaneHalfExtents() { var res = GetProjectionPlane(Planes.Far).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top)); - return new Vector2(res.Value.X, res.Value.Y); + return res is null ? default : new Vector2(res.Value.X, res.Value.Y); } /// <summary> @@ -597,7 +600,7 @@ namespace Godot public readonly Vector2 GetViewportHalfExtents() { var res = GetProjectionPlane(Planes.Near).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top)); - return new Vector2(res.Value.X, res.Value.Y); + return res is null ? default : new Vector2(res.Value.X, res.Value.Y); } /// <summary> @@ -981,7 +984,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the vector and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Projection other && Equals(other); } @@ -1018,7 +1021,7 @@ namespace Godot /// Converts this <see cref="Projection"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this projection.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"{X.X.ToString(format)}, {X.Y.ToString(format)}, {X.Z.ToString(format)}, {X.W.ToString(format)}\n" + $"{Y.X.ToString(format)}, {Y.Y.ToString(format)}, {Y.Z.ToString(format)}, {Y.W.ToString(format)}\n" + diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index 3d45913586..2344e8c510 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -769,7 +772,7 @@ namespace Godot /// </summary> /// <param name="obj">The other object to compare.</param> /// <returns>Whether or not the quaternion and the other object are exactly equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Quaternion other && Equals(other); } @@ -817,7 +820,7 @@ namespace Godot /// Converts this <see cref="Quaternion"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this quaternion.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}, {W.ToString(format)})"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs index babb26960b..71a35ab809 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -427,7 +430,7 @@ namespace Godot /// </summary> /// <param name="obj">The other object to compare.</param> /// <returns>Whether or not the rect and the other object are exactly equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Rect2 other && Equals(other); } @@ -475,7 +478,7 @@ namespace Godot /// Converts this <see cref="Rect2"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this rect.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"{_position.ToString(format)}, {_size.ToString(format)}"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2I.cs index 49fba02b54..ef7e9eacd8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2I.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2I.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -398,7 +401,7 @@ namespace Godot /// </summary> /// <param name="obj">The other object to compare.</param> /// <returns>Whether or not the rect and the other object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Rect2I other && Equals(other); } @@ -435,7 +438,7 @@ namespace Godot /// Converts this <see cref="Rect2I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this rect.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"{_position.ToString(format)}, {_size.ToString(format)}"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rid.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rid.cs index 350626389b..fccae94eac 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rid.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rid.cs @@ -1,8 +1,11 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Godot.NativeInterop; +#nullable enable + namespace Godot { /// <summary> @@ -71,7 +74,7 @@ namespace Godot /// </summary> /// <param name="obj">The other object to compare.</param> /// <returns>Whether or not the color and the other object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Rid other && Equals(other); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs index 97d28f9ee9..21d9ada127 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using Godot.NativeInterop; +#nullable enable + namespace Godot { /// <summary> @@ -10,11 +13,11 @@ namespace Godot /// Comparing them is much faster than with regular strings, because only the pointers are compared, /// not the whole strings. /// </summary> - public sealed class StringName : IDisposable, IEquatable<StringName> + public sealed class StringName : IDisposable, IEquatable<StringName?> { internal godot_string_name.movable NativeValue; - private WeakReference<IDisposable> _weakReferenceToSelf; + private WeakReference<IDisposable>? _weakReferenceToSelf; ~StringName() { @@ -81,7 +84,8 @@ namespace Godot /// Converts a <see cref="StringName"/> to a string. /// </summary> /// <param name="from">The <see cref="StringName"/> to convert.</param> - public static implicit operator string(StringName from) => from?.ToString(); + [return: NotNullIfNotNull("from")] + public static implicit operator string?(StringName? from) => from?.ToString(); /// <summary> /// Converts this <see cref="StringName"/> to a string. @@ -104,43 +108,43 @@ namespace Godot /// <returns>If the <see cref="StringName"/> is empty.</returns> public bool IsEmpty => NativeValue.DangerousSelfRef.IsEmpty; - public static bool operator ==(StringName left, StringName right) + public static bool operator ==(StringName? left, StringName? right) { if (left is null) return right is null; return left.Equals(right); } - public static bool operator !=(StringName left, StringName right) + public static bool operator !=(StringName? left, StringName? right) { return !(left == right); } - public bool Equals(StringName other) + public bool Equals([NotNullWhen(true)] StringName? other) { if (other is null) return false; return NativeValue.DangerousSelfRef == other.NativeValue.DangerousSelfRef; } - public static bool operator ==(StringName left, in godot_string_name right) + public static bool operator ==(StringName? left, in godot_string_name right) { if (left is null) return right.IsEmpty; return left.Equals(right); } - public static bool operator !=(StringName left, in godot_string_name right) + public static bool operator !=(StringName? left, in godot_string_name right) { return !(left == right); } - public static bool operator ==(in godot_string_name left, StringName right) + public static bool operator ==(in godot_string_name left, StringName? right) { return right == left; } - public static bool operator !=(in godot_string_name left, StringName right) + public static bool operator !=(in godot_string_name left, StringName? right) { return !(right == left); } @@ -150,7 +154,7 @@ namespace Godot return NativeValue.DangerousSelfRef == other; } - public override bool Equals(object obj) + public override bool Equals([NotNullWhen(true)] object? obj) { return ReferenceEquals(this, obj) || (obj is StringName other && Equals(other)); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index 386f587464..3443277fee 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -1,7 +1,10 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -606,7 +609,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the transform and the object are exactly equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Transform2D other && Equals(other); } @@ -656,7 +659,7 @@ namespace Godot /// Converts this <see cref="Transform2D"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this transform.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"[X: {X.ToString(format)}, Y: {Y.ToString(format)}, O: {Origin.ToString(format)}]"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 2d09259dcb..f80c0bd8dd 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -1,7 +1,10 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.ComponentModel; +#nullable enable + namespace Godot { /// <summary> @@ -630,7 +633,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the transform and the object are exactly equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Transform3D other && Equals(other); } @@ -680,7 +683,7 @@ namespace Godot /// Converts this <see cref="Transform3D"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this transform.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"[X: {Basis.X.ToString(format)}, Y: {Basis.Y.ToString(format)}, Z: {Basis.Z.ToString(format)}, O: {Origin.ToString(format)}]"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 4842dbc9af..a27a1ab1cf 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -954,7 +957,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the vector and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Vector2 other && Equals(other); } @@ -1016,7 +1019,7 @@ namespace Godot /// Converts this <see cref="Vector2"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({X.ToString(format)}, {Y.ToString(format)})"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs index 215bb4df8c..104e30981f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -535,7 +538,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the vector and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Vector2I other && Equals(other); } @@ -572,7 +575,7 @@ namespace Godot /// Converts this <see cref="Vector2I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({X.ToString(format)}, {Y.ToString(format)})"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index d26d4662a0..54d698345f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -1056,7 +1059,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the vector and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Vector3 other && Equals(other); } @@ -1118,7 +1121,7 @@ namespace Godot /// Converts this <see cref="Vector3"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)})"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs index fe74ec8884..4af9fd878b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -590,7 +593,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the vector and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Vector3I other && Equals(other); } @@ -627,7 +630,7 @@ namespace Godot /// Converts this <see cref="Vector3I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)})"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs index eeaef5e46e..87c01ad5ea 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -838,7 +841,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the vector and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Vector4 other && Equals(other); } @@ -900,7 +903,7 @@ namespace Godot /// Converts this <see cref="Vector4"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}, {W.ToString(format)})"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs index a0a4393523..7d4d3dd353 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs @@ -1,6 +1,9 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +#nullable enable + namespace Godot { /// <summary> @@ -611,7 +614,7 @@ namespace Godot /// </summary> /// <param name="obj">The object to compare with.</param> /// <returns>Whether or not the vector and the object are equal.</returns> - public override readonly bool Equals(object obj) + public override readonly bool Equals([NotNullWhen(true)] object? obj) { return obj is Vector4I other && Equals(other); } @@ -648,7 +651,7 @@ namespace Godot /// Converts this <see cref="Vector4I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> - public readonly string ToString(string format) + public readonly string ToString(string? format) { return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}), {W.ToString(format)})"; } diff --git a/modules/multiplayer/scene_multiplayer.cpp b/modules/multiplayer/scene_multiplayer.cpp index 04de3dfb7f..665b246bc5 100644 --- a/modules/multiplayer/scene_multiplayer.cpp +++ b/modules/multiplayer/scene_multiplayer.cpp @@ -483,9 +483,14 @@ Error SceneMultiplayer::complete_auth(int p_peer) { ERR_FAIL_COND_V(!pending_peers.has(p_peer), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(pending_peers[p_peer].local, ERR_FILE_CANT_WRITE, "The authentication session was already marked as completed."); pending_peers[p_peer].local = true; + // Notify the remote peer that the authentication has completed. uint8_t buf[2] = { NETWORK_COMMAND_SYS, SYS_COMMAND_AUTH }; + multiplayer_peer->set_target_peer(p_peer); + multiplayer_peer->set_transfer_channel(0); + multiplayer_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); Error err = _send(buf, 2); + // The remote peer already reported the authentication as completed, so admit the peer. // May generate new packets, so it must happen after sending confirmation. if (pending_peers[p_peer].remote) { diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index 5a28f8b8ef..5a27f315b9 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -391,6 +391,13 @@ COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform) { region->set_transform(p_transform); } +Transform3D GodotNavigationServer::region_get_transform(RID p_region) const { + NavRegion *region = region_owner.get_or_null(p_region); + ERR_FAIL_NULL_V(region, Transform3D()); + + return region->get_transform(); +} + COMMAND_2(region_set_enter_cost, RID, p_region, real_t, p_enter_cost) { NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_NULL(region); @@ -719,6 +726,13 @@ COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance) { agent->set_neighbor_distance(p_distance); } +real_t GodotNavigationServer::agent_get_neighbor_distance(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_neighbor_distance(); +} + COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) { NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL(agent); @@ -726,22 +740,43 @@ COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) { agent->set_max_neighbors(p_count); } +int GodotNavigationServer::agent_get_max_neighbors(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_max_neighbors(); +} + COMMAND_2(agent_set_time_horizon_agents, RID, p_agent, real_t, p_time_horizon) { - ERR_FAIL_COND_MSG(p_time_horizon < 0.0, "Time horizion must be positive."); + ERR_FAIL_COND_MSG(p_time_horizon < 0.0, "Time horizon must be positive."); NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL(agent); agent->set_time_horizon_agents(p_time_horizon); } +real_t GodotNavigationServer::agent_get_time_horizon_agents(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_time_horizon_agents(); +} + COMMAND_2(agent_set_time_horizon_obstacles, RID, p_agent, real_t, p_time_horizon) { - ERR_FAIL_COND_MSG(p_time_horizon < 0.0, "Time horizion must be positive."); + ERR_FAIL_COND_MSG(p_time_horizon < 0.0, "Time horizon must be positive."); NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL(agent); agent->set_time_horizon_obstacles(p_time_horizon); } +real_t GodotNavigationServer::agent_get_time_horizon_obstacles(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_time_horizon_obstacles(); +} + COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) { ERR_FAIL_COND_MSG(p_radius < 0.0, "Radius must be positive."); NavAgent *agent = agent_owner.get_or_null(p_agent); @@ -750,6 +785,13 @@ COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) { agent->set_radius(p_radius); } +real_t GodotNavigationServer::agent_get_radius(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_radius(); +} + COMMAND_2(agent_set_height, RID, p_agent, real_t, p_height) { ERR_FAIL_COND_MSG(p_height < 0.0, "Height must be positive."); NavAgent *agent = agent_owner.get_or_null(p_agent); @@ -758,6 +800,13 @@ COMMAND_2(agent_set_height, RID, p_agent, real_t, p_height) { agent->set_height(p_height); } +real_t GodotNavigationServer::agent_get_height(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_height(); +} + COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) { ERR_FAIL_COND_MSG(p_max_speed < 0.0, "Max speed must be positive."); NavAgent *agent = agent_owner.get_or_null(p_agent); @@ -766,6 +815,13 @@ COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) { agent->set_max_speed(p_max_speed); } +real_t GodotNavigationServer::agent_get_max_speed(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_max_speed(); +} + COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) { NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL(agent); @@ -773,6 +829,13 @@ COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) { agent->set_velocity(p_velocity); } +Vector3 GodotNavigationServer::agent_get_velocity(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, Vector3()); + + return agent->get_velocity(); +} + COMMAND_2(agent_set_velocity_forced, RID, p_agent, Vector3, p_velocity) { NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL(agent); @@ -787,6 +850,13 @@ COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) { agent->set_position(p_position); } +Vector3 GodotNavigationServer::agent_get_position(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, Vector3()); + + return agent->get_position(); +} + bool GodotNavigationServer::agent_is_map_changed(RID p_agent) const { NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL_V(agent, false); @@ -809,18 +879,39 @@ COMMAND_2(agent_set_avoidance_callback, RID, p_agent, Callable, p_callback) { } } +bool GodotNavigationServer::agent_has_avoidance_callback(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, false); + + return agent->has_avoidance_callback(); +} + COMMAND_2(agent_set_avoidance_layers, RID, p_agent, uint32_t, p_layers) { NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL(agent); agent->set_avoidance_layers(p_layers); } +uint32_t GodotNavigationServer::agent_get_avoidance_layers(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_avoidance_layers(); +} + COMMAND_2(agent_set_avoidance_mask, RID, p_agent, uint32_t, p_mask) { NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_NULL(agent); agent->set_avoidance_mask(p_mask); } +uint32_t GodotNavigationServer::agent_get_avoidance_mask(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_avoidance_mask(); +} + COMMAND_2(agent_set_avoidance_priority, RID, p_agent, real_t, p_priority) { ERR_FAIL_COND_MSG(p_priority < 0.0, "Avoidance priority must be between 0.0 and 1.0 inclusive."); ERR_FAIL_COND_MSG(p_priority > 1.0, "Avoidance priority must be between 0.0 and 1.0 inclusive."); @@ -829,6 +920,13 @@ COMMAND_2(agent_set_avoidance_priority, RID, p_agent, real_t, p_priority) { agent->set_avoidance_priority(p_priority); } +real_t GodotNavigationServer::agent_get_avoidance_priority(RID p_agent) const { + NavAgent *agent = agent_owner.get_or_null(p_agent); + ERR_FAIL_NULL_V(agent, 0); + + return agent->get_avoidance_priority(); +} + RID GodotNavigationServer::obstacle_create() { MutexLock lock(operations_mutex); @@ -913,12 +1011,26 @@ COMMAND_2(obstacle_set_radius, RID, p_obstacle, real_t, p_radius) { obstacle->set_radius(p_radius); } +real_t GodotNavigationServer::obstacle_get_radius(RID p_obstacle) const { + NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); + ERR_FAIL_NULL_V(obstacle, 0); + + return obstacle->get_radius(); +} + COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height) { NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); ERR_FAIL_NULL(obstacle); obstacle->set_height(p_height); } +real_t GodotNavigationServer::obstacle_get_height(RID p_obstacle) const { + NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); + ERR_FAIL_NULL_V(obstacle, 0); + + return obstacle->get_height(); +} + COMMAND_2(obstacle_set_velocity, RID, p_obstacle, Vector3, p_velocity) { NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); ERR_FAIL_NULL(obstacle); @@ -926,24 +1038,52 @@ COMMAND_2(obstacle_set_velocity, RID, p_obstacle, Vector3, p_velocity) { obstacle->set_velocity(p_velocity); } +Vector3 GodotNavigationServer::obstacle_get_velocity(RID p_obstacle) const { + NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); + ERR_FAIL_NULL_V(obstacle, Vector3()); + + return obstacle->get_velocity(); +} + COMMAND_2(obstacle_set_position, RID, p_obstacle, Vector3, p_position) { NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); ERR_FAIL_NULL(obstacle); obstacle->set_position(p_position); } +Vector3 GodotNavigationServer::obstacle_get_position(RID p_obstacle) const { + NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); + ERR_FAIL_NULL_V(obstacle, Vector3()); + + return obstacle->get_position(); +} + void GodotNavigationServer::obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) { NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); ERR_FAIL_NULL(obstacle); obstacle->set_vertices(p_vertices); } +Vector<Vector3> GodotNavigationServer::obstacle_get_vertices(RID p_obstacle) const { + NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); + ERR_FAIL_NULL_V(obstacle, Vector<Vector3>()); + + return obstacle->get_vertices(); +} + COMMAND_2(obstacle_set_avoidance_layers, RID, p_obstacle, uint32_t, p_layers) { NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); ERR_FAIL_NULL(obstacle); obstacle->set_avoidance_layers(p_layers); } +uint32_t GodotNavigationServer::obstacle_get_avoidance_layers(RID p_obstacle) const { + NavObstacle *obstacle = obstacle_owner.get_or_null(p_obstacle); + ERR_FAIL_NULL_V(obstacle, 0); + + return obstacle->get_avoidance_layers(); +} + void GodotNavigationServer::parse_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, Node *p_root_node, const Callable &p_callback) { #ifndef _3D_DISABLED ERR_FAIL_COND_MSG(!Thread::is_main_thread(), "The SceneTree can only be parsed on the main thread. Call this function from the main thread or use call_deferred()."); diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 3a76f83b09..f19450db27 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -165,6 +165,7 @@ public: COMMAND_2(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers); virtual uint32_t region_get_navigation_layers(RID p_region) const override; COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform); + virtual Transform3D region_get_transform(RID p_region) const override; COMMAND_2(region_set_navigation_mesh, RID, p_region, Ref<NavigationMesh>, p_navigation_mesh); #ifndef DISABLE_DEPRECATED virtual void region_bake_navigation_mesh(Ref<NavigationMesh> p_navigation_mesh, Node *p_root_node) override; @@ -204,20 +205,33 @@ public: COMMAND_2(agent_set_paused, RID, p_agent, bool, p_paused); virtual bool agent_get_paused(RID p_agent) const override; COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance); + virtual real_t agent_get_neighbor_distance(RID p_agent) const override; COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count); + virtual int agent_get_max_neighbors(RID p_agent) const override; COMMAND_2(agent_set_time_horizon_agents, RID, p_agent, real_t, p_time_horizon); + virtual real_t agent_get_time_horizon_agents(RID p_agent) const override; COMMAND_2(agent_set_time_horizon_obstacles, RID, p_agent, real_t, p_time_horizon); + virtual real_t agent_get_time_horizon_obstacles(RID p_agent) const override; COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius); + virtual real_t agent_get_radius(RID p_agent) const override; COMMAND_2(agent_set_height, RID, p_agent, real_t, p_height); + virtual real_t agent_get_height(RID p_agent) const override; COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed); + virtual real_t agent_get_max_speed(RID p_agent) const override; COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity); + virtual Vector3 agent_get_velocity(RID p_agent) const override; COMMAND_2(agent_set_velocity_forced, RID, p_agent, Vector3, p_velocity); COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position); + virtual Vector3 agent_get_position(RID p_agent) const override; virtual bool agent_is_map_changed(RID p_agent) const override; COMMAND_2(agent_set_avoidance_callback, RID, p_agent, Callable, p_callback); + virtual bool agent_has_avoidance_callback(RID p_agent) const override; COMMAND_2(agent_set_avoidance_layers, RID, p_agent, uint32_t, p_layers); + virtual uint32_t agent_get_avoidance_layers(RID p_agent) const override; COMMAND_2(agent_set_avoidance_mask, RID, p_agent, uint32_t, p_mask); + virtual uint32_t agent_get_avoidance_mask(RID p_agent) const override; COMMAND_2(agent_set_avoidance_priority, RID, p_agent, real_t, p_priority); + virtual real_t agent_get_avoidance_priority(RID p_agent) const override; virtual RID obstacle_create() override; COMMAND_2(obstacle_set_avoidance_enabled, RID, p_obstacle, bool, p_enabled); @@ -229,11 +243,17 @@ public: COMMAND_2(obstacle_set_paused, RID, p_obstacle, bool, p_paused); virtual bool obstacle_get_paused(RID p_obstacle) const override; COMMAND_2(obstacle_set_radius, RID, p_obstacle, real_t, p_radius); + virtual real_t obstacle_get_radius(RID p_obstacle) const override; COMMAND_2(obstacle_set_velocity, RID, p_obstacle, Vector3, p_velocity); + virtual Vector3 obstacle_get_velocity(RID p_obstacle) const override; COMMAND_2(obstacle_set_position, RID, p_obstacle, Vector3, p_position); + virtual Vector3 obstacle_get_position(RID p_obstacle) const override; COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height); + virtual real_t obstacle_get_height(RID p_obstacle) const override; virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) override; + virtual Vector<Vector3> obstacle_get_vertices(RID p_obstacle) const override; COMMAND_2(obstacle_set_avoidance_layers, RID, p_obstacle, uint32_t, p_layers); + virtual uint32_t obstacle_get_avoidance_layers(RID p_obstacle) const override; virtual void parse_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, Node *p_root_node, const Callable &p_callback = Callable()) override; virtual void bake_from_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data, const Callable &p_callback = Callable()) override; diff --git a/modules/navigation/godot_navigation_server_2d.cpp b/modules/navigation/godot_navigation_server_2d.cpp index 142d6181a1..76bfd3a101 100644 --- a/modules/navigation/godot_navigation_server_2d.cpp +++ b/modules/navigation/godot_navigation_server_2d.cpp @@ -141,6 +141,13 @@ static Transform3D trf2_to_trf3(const Transform2D &d) { return Transform3D(b, o); } +static Transform2D trf3_to_trf2(const Transform3D &d) { + Vector3 o = d.get_origin(); + Vector3 nx = d.xform(Vector3(1, 0, 0)) - o; + Vector3 nz = d.xform(Vector3(0, 0, 1)) - o; + return Transform2D(nx.x, nx.z, nz.x, nz.z, o.x, o.z); +} + static ObjectID id_to_id(const ObjectID &id) { return id; } @@ -283,6 +290,10 @@ void FORWARD_2(region_set_navigation_layers, RID, p_region, uint32_t, p_navigati uint32_t FORWARD_1_C(region_get_navigation_layers, RID, p_region, rid_to_rid); void FORWARD_2(region_set_transform, RID, p_region, Transform2D, p_transform, rid_to_rid, trf2_to_trf3); +Transform2D GodotNavigationServer2D::region_get_transform(RID p_region) const { + return trf3_to_trf2(NavigationServer3D::get_singleton()->region_get_transform(p_region)); +} + void GodotNavigationServer2D::region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_polygon) { NavigationServer3D::get_singleton()->region_set_navigation_mesh(p_region, poly_to_mesh(p_navigation_polygon)); } @@ -326,25 +337,60 @@ void FORWARD_2(agent_set_avoidance_enabled, RID, p_agent, bool, p_enabled, rid_t bool FORWARD_1_C(agent_get_avoidance_enabled, RID, p_agent, rid_to_rid); void FORWARD_2(agent_set_map, RID, p_agent, RID, p_map, rid_to_rid, rid_to_rid); void FORWARD_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_dist, rid_to_rid, real_to_real); +real_t GodotNavigationServer2D::agent_get_neighbor_distance(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_neighbor_distance(p_agent); +} void FORWARD_2(agent_set_max_neighbors, RID, p_agent, int, p_count, rid_to_rid, int_to_int); +int GodotNavigationServer2D::agent_get_max_neighbors(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_max_neighbors(p_agent); +} void FORWARD_2(agent_set_time_horizon_agents, RID, p_agent, real_t, p_time_horizon, rid_to_rid, real_to_real); +real_t GodotNavigationServer2D::agent_get_time_horizon_agents(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_time_horizon_agents(p_agent); +} void FORWARD_2(agent_set_time_horizon_obstacles, RID, p_agent, real_t, p_time_horizon, rid_to_rid, real_to_real); +real_t GodotNavigationServer2D::agent_get_time_horizon_obstacles(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_time_horizon_obstacles(p_agent); +} void FORWARD_2(agent_set_radius, RID, p_agent, real_t, p_radius, rid_to_rid, real_to_real); +real_t GodotNavigationServer2D::agent_get_radius(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_radius(p_agent); +} void FORWARD_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed, rid_to_rid, real_to_real); +real_t GodotNavigationServer2D::agent_get_max_speed(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_max_speed(p_agent); +} void FORWARD_2(agent_set_velocity_forced, RID, p_agent, Vector2, p_velocity, rid_to_rid, v2_to_v3); void FORWARD_2(agent_set_velocity, RID, p_agent, Vector2, p_velocity, rid_to_rid, v2_to_v3); +Vector2 GodotNavigationServer2D::agent_get_velocity(RID p_agent) const { + return v3_to_v2(NavigationServer3D::get_singleton()->agent_get_velocity(p_agent)); +} void FORWARD_2(agent_set_position, RID, p_agent, Vector2, p_position, rid_to_rid, v2_to_v3); - +Vector2 GodotNavigationServer2D::agent_get_position(RID p_agent) const { + return v3_to_v2(NavigationServer3D::get_singleton()->agent_get_position(p_agent)); +} bool FORWARD_1_C(agent_is_map_changed, RID, p_agent, rid_to_rid); void FORWARD_2(agent_set_paused, RID, p_agent, bool, p_paused, rid_to_rid, bool_to_bool); bool FORWARD_1_C(agent_get_paused, RID, p_agent, rid_to_rid); void FORWARD_1(free, RID, p_object, rid_to_rid); void FORWARD_2(agent_set_avoidance_callback, RID, p_agent, Callable, p_callback, rid_to_rid, callable_to_callable); +bool GodotNavigationServer2D::agent_has_avoidance_callback(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_has_avoidance_callback(p_agent); +} void FORWARD_2(agent_set_avoidance_layers, RID, p_agent, uint32_t, p_layers, rid_to_rid, uint32_to_uint32); +uint32_t GodotNavigationServer2D::agent_get_avoidance_layers(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_avoidance_layers(p_agent); +} void FORWARD_2(agent_set_avoidance_mask, RID, p_agent, uint32_t, p_mask, rid_to_rid, uint32_to_uint32); +uint32_t GodotNavigationServer2D::agent_get_avoidance_mask(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_avoidance_mask(p_agent); +} void FORWARD_2(agent_set_avoidance_priority, RID, p_agent, real_t, p_priority, rid_to_rid, real_to_real); +real_t GodotNavigationServer2D::agent_get_avoidance_priority(RID p_agent) const { + return NavigationServer3D::get_singleton()->agent_get_avoidance_priority(p_agent); +} RID GodotNavigationServer2D::obstacle_create() { RID obstacle = NavigationServer3D::get_singleton()->obstacle_create(); @@ -357,13 +403,28 @@ RID FORWARD_1_C(obstacle_get_map, RID, p_obstacle, rid_to_rid); void FORWARD_2(obstacle_set_paused, RID, p_obstacle, bool, p_paused, rid_to_rid, bool_to_bool); bool FORWARD_1_C(obstacle_get_paused, RID, p_obstacle, rid_to_rid); void FORWARD_2(obstacle_set_radius, RID, p_obstacle, real_t, p_radius, rid_to_rid, real_to_real); +real_t GodotNavigationServer2D::obstacle_get_radius(RID p_obstacle) const { + return NavigationServer3D::get_singleton()->obstacle_get_radius(p_obstacle); +} void FORWARD_2(obstacle_set_velocity, RID, p_obstacle, Vector2, p_velocity, rid_to_rid, v2_to_v3); +Vector2 GodotNavigationServer2D::obstacle_get_velocity(RID p_obstacle) const { + return v3_to_v2(NavigationServer3D::get_singleton()->obstacle_get_velocity(p_obstacle)); +} void FORWARD_2(obstacle_set_position, RID, p_obstacle, Vector2, p_position, rid_to_rid, v2_to_v3); +Vector2 GodotNavigationServer2D::obstacle_get_position(RID p_obstacle) const { + return v3_to_v2(NavigationServer3D::get_singleton()->obstacle_get_position(p_obstacle)); +} void FORWARD_2(obstacle_set_avoidance_layers, RID, p_obstacle, uint32_t, p_layers, rid_to_rid, uint32_to_uint32); +uint32_t GodotNavigationServer2D::obstacle_get_avoidance_layers(RID p_obstacle) const { + return NavigationServer3D::get_singleton()->obstacle_get_avoidance_layers(p_obstacle); +} void GodotNavigationServer2D::obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) { NavigationServer3D::get_singleton()->obstacle_set_vertices(p_obstacle, vector_v2_to_v3(p_vertices)); } +Vector<Vector2> GodotNavigationServer2D::obstacle_get_vertices(RID p_obstacle) const { + return vector_v3_to_v2(NavigationServer3D::get_singleton()->obstacle_get_vertices(p_obstacle)); +} void GodotNavigationServer2D::query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const { ERR_FAIL_COND(!p_query_parameters.is_valid()); diff --git a/modules/navigation/godot_navigation_server_2d.h b/modules/navigation/godot_navigation_server_2d.h index 88dee0ce69..2f473da1ab 100644 --- a/modules/navigation/godot_navigation_server_2d.h +++ b/modules/navigation/godot_navigation_server_2d.h @@ -95,6 +95,7 @@ public: virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers) override; virtual uint32_t region_get_navigation_layers(RID p_region) const override; virtual void region_set_transform(RID p_region, Transform2D p_transform) override; + virtual Transform2D region_get_transform(RID p_region) const override; virtual void region_set_navigation_polygon(RID p_region, Ref<NavigationPolygon> p_navigation_polygon) override; virtual int region_get_connections_count(RID p_region) const override; virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const override; @@ -159,6 +160,7 @@ public: /// low, the simulation will not be safe. /// Must be non-negative. virtual void agent_set_neighbor_distance(RID p_agent, real_t p_distance) override; + virtual real_t agent_get_neighbor_distance(RID p_agent) const override; /// The maximum number of other agents this /// agent takes into account in the navigation. @@ -167,6 +169,7 @@ public: /// number is too low, the simulation will not /// be safe. virtual void agent_set_max_neighbors(RID p_agent, int p_count) override; + virtual int agent_get_max_neighbors(RID p_agent) const override; /// The minimal amount of time for which this /// agent's velocities that are computed by the @@ -176,17 +179,20 @@ public: /// other agents, but the less freedom this /// agent has in choosing its velocities. /// Must be positive. - virtual void agent_set_time_horizon_agents(RID p_agent, real_t p_time_horizon) override; + virtual real_t agent_get_time_horizon_agents(RID p_agent) const override; virtual void agent_set_time_horizon_obstacles(RID p_agent, real_t p_time_horizon) override; + virtual real_t agent_get_time_horizon_obstacles(RID p_agent) const override; /// The radius of this agent. /// Must be non-negative. virtual void agent_set_radius(RID p_agent, real_t p_radius) override; + virtual real_t agent_get_radius(RID p_agent) const override; /// The maximum speed of this agent. /// Must be non-negative. virtual void agent_set_max_speed(RID p_agent, real_t p_max_speed) override; + virtual real_t agent_get_max_speed(RID p_agent) const override; /// forces and agent velocity change in the avoidance simulation, adds simulation instability if done recklessly virtual void agent_set_velocity_forced(RID p_agent, Vector2 p_velocity) override; @@ -194,19 +200,27 @@ public: /// The wanted velocity for the agent as a "suggestion" to the avoidance simulation. /// The simulation will try to fulfill this velocity wish if possible but may change the velocity depending on other agent's and obstacles'. virtual void agent_set_velocity(RID p_agent, Vector2 p_velocity) override; + virtual Vector2 agent_get_velocity(RID p_agent) const override; /// Position of the agent in world space. virtual void agent_set_position(RID p_agent, Vector2 p_position) override; + virtual Vector2 agent_get_position(RID p_agent) const override; /// Returns true if the map got changed the previous frame. virtual bool agent_is_map_changed(RID p_agent) const override; /// Callback called at the end of the RVO process virtual void agent_set_avoidance_callback(RID p_agent, Callable p_callback) override; + virtual bool agent_has_avoidance_callback(RID p_agent) const override; virtual void agent_set_avoidance_layers(RID p_agent, uint32_t p_layers) override; + virtual uint32_t agent_get_avoidance_layers(RID p_agent) const override; + virtual void agent_set_avoidance_mask(RID p_agent, uint32_t p_mask) override; + virtual uint32_t agent_get_avoidance_mask(RID p_agent) const override; + virtual void agent_set_avoidance_priority(RID p_agent, real_t p_priority) override; + virtual real_t agent_get_avoidance_priority(RID p_agent) const override; virtual RID obstacle_create() override; virtual void obstacle_set_avoidance_enabled(RID p_obstacle, bool p_enabled) override; @@ -216,10 +230,15 @@ public: virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) override; virtual bool obstacle_get_paused(RID p_obstacle) const override; virtual void obstacle_set_radius(RID p_obstacle, real_t p_radius) override; + virtual real_t obstacle_get_radius(RID p_obstacle) const override; virtual void obstacle_set_velocity(RID p_obstacle, Vector2 p_velocity) override; + virtual Vector2 obstacle_get_velocity(RID p_obstacle) const override; virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position) override; + virtual Vector2 obstacle_get_position(RID p_obstacle) const override; virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) override; + virtual Vector<Vector2> obstacle_get_vertices(RID p_obstacle) const override; virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) override; + virtual uint32_t obstacle_get_avoidance_layers(RID p_obstacle) const override; virtual void query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const override; diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 3b875b7fa7..6429513b53 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -372,7 +372,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p // Stores the further reachable end polygon, in case our goal is not reachable. if (is_reachable) { - real_t d = navigation_polys[least_cost_id].entry.distance_to(p_destination) * navigation_polys[least_cost_id].poly->owner->get_travel_cost(); + real_t d = navigation_polys[least_cost_id].entry.distance_to(p_destination); if (reachable_d > d) { reachable_d = d; reachable_end = navigation_polys[least_cost_id].poly; diff --git a/modules/navigation/nav_mesh_generator_2d.cpp b/modules/navigation/nav_mesh_generator_2d.cpp index f8c12935b4..6dfafa4e91 100644 --- a/modules/navigation/nav_mesh_generator_2d.cpp +++ b/modules/navigation/nav_mesh_generator_2d.cpp @@ -591,13 +591,19 @@ void NavMeshGenerator2D::generator_parse_tilemap_node(const Ref<NavigationPolygo continue; } + // Transform flags. + const int alternative_id = tilemap->get_cell_alternative_tile(tilemap_layer, cell, false); + bool flip_h = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_H); + bool flip_v = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_V); + bool transpose = (alternative_id & TileSetAtlasSource::TRANSFORM_TRANSPOSE); + Transform2D tile_transform; tile_transform.set_origin(tilemap->map_to_local(cell)); const Transform2D tile_transform_offset = tilemap_xform * tile_transform; if (navigation_layers_count > 0) { - Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(tilemap_layer); + Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(tilemap_layer, flip_h, flip_v, transpose); if (navigation_polygon.is_valid()) { for (int outline_index = 0; outline_index < navigation_polygon->get_outline_count(); outline_index++) { const Vector<Vector2> &navigation_polygon_outline = navigation_polygon->get_outline(outline_index); @@ -622,11 +628,15 @@ void NavMeshGenerator2D::generator_parse_tilemap_node(const Ref<NavigationPolygo if (physics_layers_count > 0 && (parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS || parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_BOTH) && (tile_set->get_physics_layer_collision_layer(tilemap_layer) & parsed_collision_mask)) { for (int collision_polygon_index = 0; collision_polygon_index < tile_data->get_collision_polygons_count(tilemap_layer); collision_polygon_index++) { - const Vector<Vector2> &collision_polygon_points = tile_data->get_collision_polygon_points(tilemap_layer, collision_polygon_index); + PackedVector2Array collision_polygon_points = tile_data->get_collision_polygon_points(tilemap_layer, collision_polygon_index); if (collision_polygon_points.size() == 0) { continue; } + if (flip_h || flip_v || transpose) { + collision_polygon_points = TileData::get_transformed_vertices(collision_polygon_points, flip_h, flip_v, transpose); + } + Vector<Vector2> obstruction_outline; obstruction_outline.resize(collision_polygon_points.size()); diff --git a/modules/ogg/ogg_packet_sequence.cpp b/modules/ogg/ogg_packet_sequence.cpp index 1100367f03..1e6a9bbb6a 100644 --- a/modules/ogg/ogg_packet_sequence.cpp +++ b/modules/ogg/ogg_packet_sequence.cpp @@ -159,9 +159,7 @@ bool OggPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { *p_packet = packet; - if (!packet->e_o_s) { // Added this so it doesn't try to go to the next packet if it's the last packet of the file. - packet_cursor++; - } + packet_cursor++; return true; } diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 3c606de670..da6fd2e9b2 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -87,7 +87,7 @@ String OpenXRAPI::get_default_action_map_resource_name() { return name; } -String OpenXRAPI::get_error_string(XrResult result) { +String OpenXRAPI::get_error_string(XrResult result) const { if (XR_SUCCEEDED(result)) { return String("Succeeded"); } @@ -1261,6 +1261,7 @@ bool OpenXRAPI::resolve_instance_openxr_symbols() { OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateFloat); OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateVector2f); OPENXR_API_INIT_XR_FUNC_V(xrGetCurrentInteractionProfile); + OPENXR_API_INIT_XR_FUNC_V(xrGetReferenceSpaceBoundsRect); OPENXR_API_INIT_XR_FUNC_V(xrGetSystem); OPENXR_API_INIT_XR_FUNC_V(xrGetSystemProperties); OPENXR_API_INIT_XR_FUNC_V(xrLocateViews); @@ -2072,6 +2073,25 @@ void OpenXRAPI::set_foveation_dynamic(bool p_foveation_dynamic) { } } +Size2 OpenXRAPI::get_play_space_bounds() const { + Size2 ret; + + ERR_FAIL_COND_V(session == XR_NULL_HANDLE, Size2()); + + XrExtent2Df extents; + + XrResult result = xrGetReferenceSpaceBoundsRect(session, reference_space, &extents); + if (XR_FAILED(result)) { + print_line("OpenXR: failed to get play space bounds! [", get_error_string(result), "]"); + return ret; + } + + ret.width = extents.width; + ret.height = extents.height; + + return ret; +} + OpenXRAPI::OpenXRAPI() { // OpenXRAPI is only constructed if OpenXR is enabled. singleton = this; diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index 64769b244c..efa32b7544 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -199,6 +199,7 @@ private: EXT_PROTO_XRRESULT_FUNC3(xrGetActionStateVector2f, (XrSession), session, (const XrActionStateGetInfo *), getInfo, (XrActionStateVector2f *), state) EXT_PROTO_XRRESULT_FUNC3(xrGetCurrentInteractionProfile, (XrSession), session, (XrPath), topLevelUserPath, (XrInteractionProfileState *), interactionProfile) EXT_PROTO_XRRESULT_FUNC2(xrGetInstanceProperties, (XrInstance), instance, (XrInstanceProperties *), instanceProperties) + EXT_PROTO_XRRESULT_FUNC3(xrGetReferenceSpaceBoundsRect, (XrSession), session, (XrReferenceSpaceType), referenceSpaceType, (XrExtent2Df *), bounds) EXT_PROTO_XRRESULT_FUNC3(xrGetSystem, (XrInstance), instance, (const XrSystemGetInfo *), getInfo, (XrSystemId *), systemId) EXT_PROTO_XRRESULT_FUNC3(xrGetSystemProperties, (XrInstance), instance, (XrSystemId), systemId, (XrSystemProperties *), properties) EXT_PROTO_XRRESULT_FUNC4(xrLocateSpace, (XrSpace), space, (XrSpace), baseSpace, (XrTime), time, (XrSpaceLocation *), location) @@ -317,7 +318,7 @@ public: XrResult try_get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr); XrResult get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr); - String get_error_string(XrResult result); + String get_error_string(XrResult result) const; String get_swapchain_format_name(int64_t p_swapchain_format) const; void set_xr_interface(OpenXRInterface *p_xr_interface); @@ -380,6 +381,9 @@ public: bool get_foveation_dynamic() const; void set_foveation_dynamic(bool p_foveation_dynamic); + // Play space. + Size2 get_play_space_bounds() const; + // action map String get_default_action_map_resource_name(); diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 8ce76a5fad..66f8192c9e 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -690,6 +690,42 @@ bool OpenXRInterface::set_play_area_mode(XRInterface::PlayAreaMode p_mode) { return false; } +PackedVector3Array OpenXRInterface::get_play_area() const { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, PackedVector3Array()); + PackedVector3Array arr; + + Vector3 sides[4] = { + Vector3(-0.5f, 0.0f, -0.5f), + Vector3(0.5f, 0.0f, -0.5f), + Vector3(0.5f, 0.0f, 0.5f), + Vector3(-0.5f, 0.0f, 0.5f), + }; + + if (openxr_api != nullptr && openxr_api->is_initialized()) { + Size2 extents = openxr_api->get_play_space_bounds(); + if (extents.width != 0.0 && extents.height != 0.0) { + Transform3D reference_frame = xr_server->get_reference_frame(); + + for (int i = 0; i < 4; i++) { + Vector3 coord = sides[i]; + + // Scale it up. + coord.x *= extents.width; + coord.z *= extents.height; + + // Now apply our reference. + Vector3 out = reference_frame.xform(coord); + arr.push_back(out); + } + } else { + WARN_PRINT_ONCE("OpenXR: No extents available."); + } + } + + return arr; +} + float OpenXRInterface::get_display_refresh_rate() const { if (openxr_api == nullptr) { return 0.0; diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h index 51ef4ea228..489d0845ba 100644 --- a/modules/openxr/openxr_interface.h +++ b/modules/openxr/openxr_interface.h @@ -125,6 +125,7 @@ public: virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode) override; virtual XRInterface::PlayAreaMode get_play_area_mode() const override; virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode) override; + virtual PackedVector3Array get_play_area() const override; float get_display_refresh_rate() const; void set_display_refresh_rate(float p_refresh_rate); diff --git a/modules/squish/image_decompress_squish.cpp b/modules/squish/image_decompress_squish.cpp index 5b35a2643a..fba76621d6 100644 --- a/modules/squish/image_decompress_squish.cpp +++ b/modules/squish/image_decompress_squish.cpp @@ -36,7 +36,9 @@ void image_decompress_squish(Image *p_image) { int w = p_image->get_width(); int h = p_image->get_height(); + Image::Format source_format = p_image->get_format(); Image::Format target_format = Image::FORMAT_RGBA8; + Vector<uint8_t> data; int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps()); int mm_count = p_image->get_mipmap_count(); @@ -45,33 +47,49 @@ void image_decompress_squish(Image *p_image) { const uint8_t *rb = p_image->get_data().ptr(); uint8_t *wb = data.ptrw(); - int squish_flags = Image::FORMAT_MAX; - if (p_image->get_format() == Image::FORMAT_DXT1) { - squish_flags = squish::kDxt1; - } else if (p_image->get_format() == Image::FORMAT_DXT3) { - squish_flags = squish::kDxt3; - } else if (p_image->get_format() == Image::FORMAT_DXT5 || p_image->get_format() == Image::FORMAT_DXT5_RA_AS_RG) { - squish_flags = squish::kDxt5; - } else if (p_image->get_format() == Image::FORMAT_RGTC_R) { - squish_flags = squish::kBc4; - } else if (p_image->get_format() == Image::FORMAT_RGTC_RG) { - squish_flags = squish::kBc5; - } else { - ERR_FAIL_MSG("Squish: Can't decompress unknown format: " + itos(p_image->get_format()) + "."); + int squish_flags = 0; + + switch (source_format) { + case Image::FORMAT_DXT1: + squish_flags = squish::kDxt1; + break; + + case Image::FORMAT_DXT3: + squish_flags = squish::kDxt3; + break; + + case Image::FORMAT_DXT5: + case Image::FORMAT_DXT5_RA_AS_RG: + squish_flags = squish::kDxt5; + break; + + case Image::FORMAT_RGTC_R: + squish_flags = squish::kBc4; + break; + + case Image::FORMAT_RGTC_RG: + squish_flags = squish::kBc5; + break; + + default: + ERR_FAIL_MSG("Squish: Can't decompress unknown format: " + itos(p_image->get_format()) + "."); + break; } for (int i = 0; i <= mm_count; i++) { int src_ofs = 0, mipmap_size = 0, mipmap_w = 0, mipmap_h = 0; p_image->get_mipmap_offset_size_and_dimensions(i, src_ofs, mipmap_size, mipmap_w, mipmap_h); + int dst_ofs = Image::get_image_mipmap_offset(p_image->get_width(), p_image->get_height(), target_format, i); squish::DecompressImage(&wb[dst_ofs], w, h, &rb[src_ofs], squish_flags); + w >>= 1; h >>= 1; } p_image->set_data(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); - if (p_image->get_format() == Image::FORMAT_DXT5_RA_AS_RG) { + if (source_format == Image::FORMAT_DXT5_RA_AS_RG) { p_image->convert_ra_rgba8_to_rg(); } } diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index d93aa1fcd8..bcc7bff909 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -3504,6 +3504,9 @@ void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2 } void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { + if (p_index == 0) { + return; // Non visual character, skip. + } FontAdvanced *fd = _get_font_data(p_font_rid); ERR_FAIL_NULL(fd); @@ -3541,6 +3544,9 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca const FontGlyph &gl = fd->cache[size]->glyph_map[index]; if (gl.found) { + if (gl.uv_rect.size.x <= 2 || gl.uv_rect.size.y <= 2) { + return; // Nothing to draw. + } ERR_FAIL_COND(gl.texture_idx < -1 || gl.texture_idx >= fd->cache[size]->textures.size()); if (gl.texture_idx != -1) { @@ -3608,6 +3614,9 @@ void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca } void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { + if (p_index == 0) { + return; // Non visual character, skip. + } FontAdvanced *fd = _get_font_data(p_font_rid); ERR_FAIL_NULL(fd); @@ -3645,6 +3654,9 @@ void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, const R const FontGlyph &gl = fd->cache[size]->glyph_map[index]; if (gl.found) { + if (gl.uv_rect.size.x <= 2 || gl.uv_rect.size.y <= 2) { + return; // Nothing to draw. + } ERR_FAIL_COND(gl.texture_idx < -1 || gl.texture_idx >= fd->cache[size]->textures.size()); if (gl.texture_idx != -1) { diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 9f21642a17..8fc7694aa4 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -2439,6 +2439,9 @@ void TextServerFallback::_font_render_glyph(const RID &p_font_rid, const Vector2 } void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { + if (p_index == 0) { + return; // Non visual character, skip. + } FontFallback *fd = _get_font_data(p_font_rid); ERR_FAIL_NULL(fd); @@ -2476,6 +2479,9 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca const FontGlyph &gl = fd->cache[size]->glyph_map[index]; if (gl.found) { + if (gl.uv_rect.size.x <= 2 || gl.uv_rect.size.y <= 2) { + return; // Nothing to draw. + } ERR_FAIL_COND(gl.texture_idx < -1 || gl.texture_idx >= fd->cache[size]->textures.size()); if (gl.texture_idx != -1) { @@ -2543,6 +2549,9 @@ void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_ca } void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { + if (p_index == 0) { + return; // Non visual character, skip. + } FontFallback *fd = _get_font_data(p_font_rid); ERR_FAIL_NULL(fd); @@ -2580,6 +2589,9 @@ void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, const R const FontGlyph &gl = fd->cache[size]->glyph_map[index]; if (gl.found) { + if (gl.uv_rect.size.x <= 2 || gl.uv_rect.size.y <= 2) { + return; // Nothing to draw. + } ERR_FAIL_COND(gl.texture_idx < -1 || gl.texture_idx >= fd->cache[size]->textures.size()); if (gl.texture_idx != -1) { diff --git a/modules/vorbis/register_types.cpp b/modules/vorbis/register_types.cpp index 26af912999..def34220ea 100644 --- a/modules/vorbis/register_types.cpp +++ b/modules/vorbis/register_types.cpp @@ -48,8 +48,13 @@ void initialize_vorbis_module(ModuleInitializationLevel p_level) { ResourceFormatImporter::get_singleton()->add_importer(ogg_vorbis_importer); } + ClassDB::APIType prev_api = ClassDB::get_current_api(); + ClassDB::set_current_api(ClassDB::API_EDITOR); + // Required to document import options in the class reference. GDREGISTER_CLASS(ResourceImporterOggVorbis); + + ClassDB::set_current_api(prev_api); #endif GDREGISTER_CLASS(AudioStreamOggVorbis); diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml index 454f8f2ed4..8698c5755a 100644 --- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml +++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml @@ -76,7 +76,7 @@ <method name="get_signaling_state" qualifiers="const"> <return type="int" enum="WebRTCPeerConnection.SignalingState" /> <description> - Returns the [enum SignalingState] on the local end of the connection while connecting or reconnecting to another peer. + Returns the signaling state on the local end of the connection while connecting or reconnecting to another peer. </description> </method> <method name="initialize"> |