summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/SCsub9
-rw-r--r--modules/arkit/SCsub6
-rw-r--r--modules/arkit/arkit_interface.h20
-rw-r--r--modules/arkit/arkit_interface.mm62
-rw-r--r--modules/arkit/arkit_session_delegate.mm2
-rw-r--r--modules/arkit/config.py3
-rw-r--r--modules/arkit/register_types.cpp2
-rw-r--r--modules/assimp/SCsub176
-rw-r--r--modules/assimp/config.py3
-rw-r--r--modules/assimp/editor_scene_importer_assimp.cpp241
-rw-r--r--modules/assimp/editor_scene_importer_assimp.h20
-rw-r--r--modules/assimp/import_state.h34
-rw-r--r--modules/assimp/import_utils.h42
-rw-r--r--modules/assimp/register_types.h5
-rw-r--r--modules/basis_universal/SCsub48
-rw-r--r--modules/basis_universal/config.py (renamed from modules/recast/config.py)3
-rw-r--r--modules/basis_universal/register_types.cpp288
-rw-r--r--modules/basis_universal/register_types.h (renamed from modules/recast/register_types.h)9
-rw-r--r--modules/basis_universal/texture_basisu.cpp233
-rw-r--r--modules/basis_universal/texture_basisu.h77
-rw-r--r--modules/bmp/SCsub4
-rw-r--r--modules/bmp/config.py1
-rw-r--r--modules/bmp/image_loader_bmp.cpp42
-rw-r--r--modules/bmp/register_types.cpp2
-rw-r--r--modules/bmp/register_types.h5
-rw-r--r--modules/bullet/SCsub357
-rw-r--r--modules/bullet/area_bullet.cpp56
-rw-r--r--modules/bullet/area_bullet.h19
-rw-r--r--modules/bullet/btRayShape.cpp1
-rw-r--r--modules/bullet/bullet_physics_server.cpp806
-rw-r--r--modules/bullet/bullet_physics_server.h50
-rw-r--r--modules/bullet/bullet_utilities.h2
-rw-r--r--modules/bullet/collision_object_bullet.cpp16
-rw-r--r--modules/bullet/collision_object_bullet.h8
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp34
-rw-r--r--modules/bullet/cone_twist_joint_bullet.h6
-rw-r--r--modules/bullet/config.py10
-rw-r--r--modules/bullet/constraint_bullet.cpp4
-rw-r--r--modules/bullet/constraint_bullet.h2
-rw-r--r--modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml13
-rw-r--r--modules/bullet/doc_classes/BulletPhysicsServer.xml13
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp116
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.h12
-rw-r--r--modules/bullet/godot_collision_configuration.cpp4
-rw-r--r--modules/bullet/godot_result_callbacks.cpp8
-rw-r--r--modules/bullet/godot_result_callbacks.h14
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp63
-rw-r--r--modules/bullet/hinge_joint_bullet.h10
-rw-r--r--modules/bullet/joint_bullet.h4
-rw-r--r--modules/bullet/pin_joint_bullet.cpp21
-rw-r--r--modules/bullet/pin_joint_bullet.h6
-rw-r--r--modules/bullet/register_types.cpp8
-rw-r--r--modules/bullet/rid_bullet.h10
-rw-r--r--modules/bullet/rigid_body_bullet.cpp222
-rw-r--r--modules/bullet/rigid_body_bullet.h44
-rw-r--r--modules/bullet/shape_bullet.cpp80
-rw-r--r--modules/bullet/shape_bullet.h34
-rw-r--r--modules/bullet/slider_joint_bullet.cpp94
-rw-r--r--modules/bullet/slider_joint_bullet.h6
-rw-r--r--modules/bullet/soft_body_bullet.cpp35
-rw-r--r--modules/bullet/soft_body_bullet.h8
-rw-r--r--modules/bullet/space_bullet.cpp181
-rw-r--r--modules/bullet/space_bullet.h32
-rw-r--r--modules/camera/SCsub7
-rw-r--r--modules/camera/camera_ios.h2
-rw-r--r--modules/camera/camera_ios.mm6
-rw-r--r--modules/camera/camera_osx.mm10
-rw-r--r--modules/camera/config.py3
-rw-r--r--modules/csg/SCsub4
-rw-r--r--modules/csg/config.py21
-rw-r--r--modules/csg/csg.cpp2129
-rw-r--r--modules/csg/csg.h162
-rw-r--r--modules/csg/csg_gizmos.cpp150
-rw-r--r--modules/csg/csg_gizmos.h20
-rw-r--r--modules/csg/csg_shape.cpp807
-rw-r--r--modules/csg/csg_shape.h92
-rw-r--r--modules/csg/doc_classes/CSGBox3D.xml (renamed from modules/csg/doc_classes/CSGBox.xml)2
-rw-r--r--modules/csg/doc_classes/CSGCombiner.xml15
-rw-r--r--modules/csg/doc_classes/CSGCombiner3D.xml15
-rw-r--r--modules/csg/doc_classes/CSGCylinder3D.xml (renamed from modules/csg/doc_classes/CSGCylinder.xml)2
-rw-r--r--modules/csg/doc_classes/CSGMesh3D.xml (renamed from modules/csg/doc_classes/CSGMesh.xml)2
-rw-r--r--modules/csg/doc_classes/CSGPolygon3D.xml (renamed from modules/csg/doc_classes/CSGPolygon.xml)18
-rw-r--r--modules/csg/doc_classes/CSGPrimitive3D.xml (renamed from modules/csg/doc_classes/CSGPrimitive.xml)2
-rw-r--r--modules/csg/doc_classes/CSGShape3D.xml (renamed from modules/csg/doc_classes/CSGShape.xml)4
-rw-r--r--modules/csg/doc_classes/CSGSphere3D.xml (renamed from modules/csg/doc_classes/CSGSphere.xml)2
-rw-r--r--modules/csg/doc_classes/CSGTorus3D.xml (renamed from modules/csg/doc_classes/CSGTorus.xml)2
-rw-r--r--modules/csg/icons/CSGBox3D.svg (renamed from modules/csg/icons/icon_c_s_g_box.svg)0
-rw-r--r--modules/csg/icons/CSGCapsule3D.svg (renamed from modules/csg/icons/icon_c_s_g_capsule.svg)0
-rw-r--r--modules/csg/icons/CSGCombiner3D.svg (renamed from modules/csg/icons/icon_c_s_g_combiner.svg)0
-rw-r--r--modules/csg/icons/CSGCylinder3D.svg (renamed from modules/csg/icons/icon_c_s_g_cylinder.svg)0
-rw-r--r--modules/csg/icons/CSGMesh3D.svg (renamed from modules/csg/icons/icon_c_s_g_mesh.svg)0
-rw-r--r--modules/csg/icons/CSGPolygon3D.svg (renamed from modules/csg/icons/icon_c_s_g_polygon.svg)0
-rw-r--r--modules/csg/icons/CSGSphere3D.svg (renamed from modules/csg/icons/icon_c_s_g_sphere.svg)0
-rw-r--r--modules/csg/icons/CSGTorus3D.svg (renamed from modules/csg/icons/icon_c_s_g_torus.svg)0
-rw-r--r--modules/csg/register_types.cpp18
-rw-r--r--modules/csg/register_types.h5
-rw-r--r--modules/cvtt/SCsub6
-rw-r--r--modules/cvtt/config.py3
-rw-r--r--modules/cvtt/image_compress_cvtt.cpp29
-rw-r--r--modules/cvtt/image_compress_cvtt.h2
-rw-r--r--modules/cvtt/register_types.h9
-rw-r--r--modules/dds/SCsub4
-rw-r--r--modules/dds/config.py1
-rw-r--r--modules/dds/register_types.h5
-rw-r--r--modules/dds/texture_loader_dds.cpp18
-rw-r--r--modules/dds/texture_loader_dds.h2
-rw-r--r--modules/enet/SCsub6
-rw-r--r--modules/enet/config.py3
-rw-r--r--modules/enet/doc_classes/NetworkedMultiplayerENet.xml25
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp160
-rw-r--r--modules/enet/networked_multiplayer_enet.h12
-rw-r--r--modules/enet/register_types.h5
-rw-r--r--modules/etc/SCsub34
-rw-r--r--modules/etc/config.py3
-rw-r--r--modules/etc/image_etc.cpp82
-rw-r--r--modules/etc/register_types.h5
-rw-r--r--modules/etc/texture_loader_pkm.cpp11
-rw-r--r--modules/etc/texture_loader_pkm.h2
-rw-r--r--modules/freetype/SCsub30
-rw-r--r--modules/freetype/config.py1
-rw-r--r--modules/freetype/register_types.h5
-rw-r--r--modules/gdnative/SCsub17
-rw-r--r--modules/gdnative/android/android_gdn.cpp8
-rw-r--r--modules/gdnative/arvr/SCsub6
-rw-r--r--modules/gdnative/arvr/arvr_interface_gdnative.cpp428
-rw-r--r--modules/gdnative/config.py5
-rw-r--r--modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml15
-rw-r--r--modules/gdnative/doc_classes/GDNative.xml4
-rw-r--r--modules/gdnative/doc_classes/GDNativeLibrary.xml4
-rw-r--r--modules/gdnative/doc_classes/NativeScript.xml6
-rw-r--r--modules/gdnative/doc_classes/XRInterfaceGDNative.xml15
-rw-r--r--modules/gdnative/gdnative.cpp22
-rw-r--r--modules/gdnative/gdnative.h4
-rw-r--r--modules/gdnative/gdnative/array.cpp29
-rw-r--r--modules/gdnative/gdnative/color.cpp5
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp16
-rw-r--r--modules/gdnative/gdnative/pool_arrays.cpp822
-rw-r--r--modules/gdnative/gdnative/string.cpp37
-rw-r--r--modules/gdnative/gdnative/variant.cpp88
-rw-r--r--modules/gdnative/gdnative_api.json1086
-rw-r--r--modules/gdnative/gdnative_builders.py270
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp60
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.h2
-rw-r--r--modules/gdnative/gdnative_library_singleton_editor.cpp6
-rw-r--r--modules/gdnative/icons/GDNativeLibrary.svg (renamed from modules/gdnative/icons/icon_g_d_native_library.svg)0
-rw-r--r--modules/gdnative/icons/NativeScript.svg (renamed from modules/gdnative/icons/icon_native_script.svg)0
-rw-r--r--modules/gdnative/include/gdnative/array.h14
-rw-r--r--modules/gdnative/include/gdnative/color.h2
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h6
-rw-r--r--modules/gdnative/include/gdnative/pool_arrays.h432
-rw-r--r--modules/gdnative/include/gdnative/string.h6
-rw-r--r--modules/gdnative/include/gdnative/variant.h54
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h6
-rw-r--r--modules/gdnative/include/pluginscript/godot_pluginscript.h29
-rw-r--r--modules/gdnative/include/videodecoder/godot_videodecoder.h2
-rw-r--r--modules/gdnative/include/xr/godot_xr.h (renamed from modules/gdnative/include/arvr/godot_arvr.h)37
-rw-r--r--modules/gdnative/nativescript/SCsub8
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp20
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp42
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp508
-rw-r--r--modules/gdnative/nativescript/nativescript.h71
-rw-r--r--modules/gdnative/nativescript/register_types.h5
-rw-r--r--modules/gdnative/net/SCsub9
-rw-r--r--modules/gdnative/net/multiplayer_peer_gdnative.cpp30
-rw-r--r--modules/gdnative/net/packet_peer_gdnative.cpp10
-rw-r--r--modules/gdnative/net/register_types.h5
-rw-r--r--modules/gdnative/net/stream_peer_gdnative.cpp12
-rw-r--r--modules/gdnative/pluginscript/SCsub6
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp42
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.h13
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp50
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.h8
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.cpp4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.h2
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp170
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.h23
-rw-r--r--modules/gdnative/pluginscript/register_types.h5
-rw-r--r--modules/gdnative/register_types.cpp10
-rw-r--r--modules/gdnative/register_types.h5
-rw-r--r--modules/gdnative/videodecoder/SCsub8
-rw-r--r--modules/gdnative/videodecoder/register_types.h5
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.cpp62
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.h12
-rw-r--r--modules/gdnative/xr/SCsub6
-rw-r--r--modules/gdnative/xr/config.py (renamed from modules/gdnative/arvr/config.py)5
-rw-r--r--modules/gdnative/xr/register_types.cpp (renamed from modules/gdnative/arvr/register_types.cpp)9
-rw-r--r--modules/gdnative/xr/register_types.h (renamed from modules/gdnative/arvr/register_types.h)9
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.cpp428
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.h (renamed from modules/gdnative/arvr/arvr_interface_gdnative.h)36
-rw-r--r--modules/gdnavigation/SCsub50
-rw-r--r--modules/gdnavigation/config.py6
-rw-r--r--modules/gdnavigation/gd_navigation_server.cpp502
-rw-r--r--modules/gdnavigation/gd_navigation_server.h142
-rw-r--r--modules/gdnavigation/nav_map.cpp807
-rw-r--r--modules/gdnavigation/nav_map.h141
-rw-r--r--modules/gdnavigation/nav_region.cpp136
-rw-r--r--modules/gdnavigation/nav_region.h89
-rw-r--r--modules/gdnavigation/nav_rid.h (renamed from modules/vorbis/stub/register_types.cpp)21
-rw-r--r--modules/gdnavigation/nav_utils.h169
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.cpp (renamed from modules/recast/navigation_mesh_editor_plugin.cpp)46
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.h (renamed from modules/recast/navigation_mesh_editor_plugin.h)17
-rw-r--r--modules/gdnavigation/navigation_mesh_generator.cpp (renamed from modules/recast/navigation_mesh_generator.cpp)243
-rw-r--r--modules/gdnavigation/navigation_mesh_generator.h (renamed from modules/recast/navigation_mesh_generator.h)40
-rw-r--r--modules/gdnavigation/register_types.cpp (renamed from modules/recast/register_types.cpp)45
-rw-r--r--modules/gdnavigation/register_types.h (renamed from modules/opus/stub/register_types.h)13
-rw-r--r--modules/gdnavigation/rvo_agent.cpp84
-rw-r--r--modules/gdnavigation/rvo_agent.h77
-rw-r--r--modules/gdscript/SCsub10
-rw-r--r--modules/gdscript/config.py4
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml41
-rw-r--r--modules/gdscript/doc_classes/GDScript.xml2
-rw-r--r--modules/gdscript/doc_classes/GDScriptNativeClass.xml19
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp10
-rw-r--r--modules/gdscript/gdscript.cpp538
-rw-r--r--modules/gdscript/gdscript.h72
-rw-r--r--modules/gdscript/gdscript_compiler.cpp38
-rw-r--r--modules/gdscript/gdscript_compiler.h4
-rw-r--r--modules/gdscript/gdscript_editor.cpp175
-rw-r--r--modules/gdscript/gdscript_function.cpp267
-rw-r--r--modules/gdscript/gdscript_function.h20
-rw-r--r--modules/gdscript/gdscript_functions.cpp403
-rw-r--r--modules/gdscript/gdscript_functions.h3
-rw-r--r--modules/gdscript/gdscript_parser.cpp493
-rw-r--r--modules/gdscript/gdscript_parser.h24
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp57
-rw-r--r--modules/gdscript/gdscript_tokenizer.h13
-rw-r--r--modules/gdscript/icons/GDScript.svg (renamed from modules/gdscript/icons/icon_g_d_script.svg)0
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp16
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.cpp207
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.h40
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.cpp8
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp12
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp73
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.h5
-rw-r--r--modules/gdscript/language_server/lsp.hpp8
-rw-r--r--modules/gdscript/register_types.cpp2
-rw-r--r--modules/gdscript/register_types.h5
-rw-r--r--modules/glslang/SCsub72
-rw-r--r--modules/glslang/config.py6
-rw-r--r--modules/glslang/register_types.cpp246
-rw-r--r--modules/glslang/register_types.h (renamed from modules/vorbis/stub/register_types.h)12
-rw-r--r--modules/gridmap/SCsub4
-rw-r--r--modules/gridmap/config.py3
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml2
-rw-r--r--modules/gridmap/doc_classes/README.md2
-rw-r--r--modules/gridmap/grid_map.cpp205
-rw-r--r--modules/gridmap/grid_map.h16
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp271
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h19
-rw-r--r--modules/gridmap/icons/GridMap.svg (renamed from modules/gridmap/icons/icon_grid_map.svg)0
-rw-r--r--modules/gridmap/register_types.h5
-rw-r--r--modules/hdr/SCsub4
-rw-r--r--modules/hdr/config.py1
-rw-r--r--modules/hdr/image_loader_hdr.cpp6
-rw-r--r--modules/hdr/register_types.cpp2
-rw-r--r--modules/hdr/register_types.h5
-rw-r--r--modules/jpg/SCsub4
-rw-r--r--modules/jpg/config.py1
-rw-r--r--modules/jpg/image_loader_jpegd.cpp13
-rw-r--r--modules/jpg/register_types.cpp2
-rw-r--r--modules/jpg/register_types.h5
-rw-r--r--modules/jsonrpc/SCsub4
-rw-r--r--modules/jsonrpc/config.py5
-rw-r--r--modules/jsonrpc/jsonrpc.cpp2
-rw-r--r--modules/jsonrpc/register_types.h5
-rwxr-xr-xmodules/mbedtls/SCsub8
-rwxr-xr-xmodules/mbedtls/config.py1
-rw-r--r--modules/mbedtls/crypto_mbedtls.cpp58
-rw-r--r--modules/mbedtls/crypto_mbedtls.h6
-rw-r--r--modules/mbedtls/dtls_server_mbedtls.cpp78
-rw-r--r--modules/mbedtls/dtls_server_mbedtls.h (renamed from modules/mono/utils/mutex_utils.h)51
-rwxr-xr-xmodules/mbedtls/packet_peer_mbed_dtls.cpp297
-rwxr-xr-xmodules/mbedtls/packet_peer_mbed_dtls.h88
-rwxr-xr-xmodules/mbedtls/register_types.cpp6
-rwxr-xr-xmodules/mbedtls/register_types.h5
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.cpp73
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.h30
-rwxr-xr-xmodules/mbedtls/stream_peer_mbedtls.cpp27
-rw-r--r--modules/mobile_vr/SCsub6
-rw-r--r--modules/mobile_vr/config.py3
-rw-r--r--modules/mobile_vr/doc_classes/MobileVRInterface.xml8
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp75
-rw-r--r--modules/mobile_vr/mobile_vr_interface.h14
-rw-r--r--modules/mobile_vr/register_types.cpp2
-rw-r--r--modules/mobile_vr/register_types.h5
-rw-r--r--modules/modules_builders.py6
-rw-r--r--modules/mono/SCsub49
-rw-r--r--modules/mono/build_scripts/api_solution_build.py35
-rw-r--r--modules/mono/build_scripts/gen_cs_glue_version.py20
-rw-r--r--modules/mono/build_scripts/godot_tools_build.py23
-rw-r--r--modules/mono/build_scripts/make_android_mono_config.py26
-rw-r--r--modules/mono/build_scripts/mono_configure.py509
-rw-r--r--modules/mono/build_scripts/mono_reg_utils.py59
-rw-r--r--modules/mono/build_scripts/solution_builder.py132
-rw-r--r--modules/mono/build_scripts/tls_configure.py36
-rw-r--r--modules/mono/class_db_api_json.cpp10
-rw-r--r--modules/mono/config.py62
-rw-r--r--modules/mono/csharp_script.cpp1082
-rw-r--r--modules/mono/csharp_script.h169
-rw-r--r--modules/mono/doc_classes/@C#.xml2
-rw-r--r--modules/mono/doc_classes/CSharpScript.xml4
-rw-r--r--modules/mono/doc_classes/GodotSharp.xml2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs27
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs42
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs78
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs64
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs220
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs28
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs7
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildManager.cs25
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildTab.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs12
-rwxr-xr-xmodules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs618
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs450
-rwxr-xr-xmodules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs93
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs124
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs109
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs33
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs44
-rw-r--r--modules/mono/editor/bindings_generator.cpp437
-rw-r--r--modules/mono/editor/bindings_generator.h67
-rw-r--r--modules/mono/editor/csharp_project.cpp4
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp42
-rw-r--r--modules/mono/editor/godotsharp_export.cpp29
-rw-r--r--modules/mono/editor/godotsharp_export.h4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp.sln2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs28
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs64
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs31
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs28
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs395
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs31
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs39
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs178
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs59
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs29
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs27
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs262
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs17
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs11
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs82
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs70
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs46
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs39
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs380
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs33
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs402
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj7
-rw-r--r--modules/mono/glue/base_object_glue.cpp58
-rw-r--r--modules/mono/glue/base_object_glue.h8
-rw-r--r--modules/mono/glue/collections_glue.cpp26
-rw-r--r--modules/mono/glue/gd_glue.cpp44
-rw-r--r--modules/mono/glue/gd_glue.h2
-rw-r--r--modules/mono/glue/glue_header.h4
-rw-r--r--modules/mono/glue/string_name_glue.cpp61
-rw-r--r--modules/mono/glue/string_name_glue.h54
-rw-r--r--modules/mono/godotsharp_dirs.cpp12
-rw-r--r--modules/mono/icons/CSharpScript.svg (renamed from modules/mono/icons/icon_c_sharp_script.svg)0
-rw-r--r--modules/mono/managed_callable.cpp145
-rw-r--r--modules/mono/managed_callable.h (renamed from modules/mono/utils/thread_local.cpp)100
-rw-r--r--modules/mono/mono_gc_handle.cpp57
-rw-r--r--modules/mono/mono_gc_handle.h87
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp218
-rw-r--r--modules/mono/mono_gd/gd_mono.h14
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp297
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h35
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp216
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h52
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp94
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp240
-rw-r--r--modules/mono/mono_gd/gd_mono_field.h15
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp22
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp10
-rw-r--r--modules/mono/mono_gd/gd_mono_log.h9
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp866
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h153
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp93
-rw-r--r--modules/mono/mono_gd/gd_mono_method.h26
-rw-r--r--modules/mono/mono_gd/gd_mono_method_thunk.h52
-rw-r--r--modules/mono/mono_gd/gd_mono_property.cpp32
-rw-r--r--modules/mono/mono_gd/gd_mono_property.h20
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp228
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h40
-rw-r--r--modules/mono/mono_gd/managed_type.h2
-rwxr-xr-x[-rw-r--r--]modules/mono/mono_gd/support/android_support.cpp (renamed from modules/mono/mono_gd/gd_mono_android.cpp)98
-rwxr-xr-x[-rw-r--r--]modules/mono/mono_gd/support/android_support.h (renamed from modules/mono/mono_gd/gd_mono_android.h)19
-rwxr-xr-x[-rw-r--r--]modules/mono/mono_gd/support/ios_support.h (renamed from modules/opus/stub/register_types.cpp)24
-rwxr-xr-xmodules/mono/mono_gd/support/ios_support.mm151
-rw-r--r--modules/mono/register_types.cpp4
-rw-r--r--modules/mono/signal_awaiter_utils.cpp216
-rw-r--r--modules/mono/signal_awaiter_utils.h68
-rw-r--r--modules/mono/utils/macros.h53
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp6
-rw-r--r--modules/mono/utils/osx_utils.cpp6
-rw-r--r--modules/mono/utils/path_utils.cpp10
-rw-r--r--modules/mono/utils/string_utils.cpp10
-rw-r--r--modules/mono/utils/thread_local.h177
-rw-r--r--modules/ogg/SCsub9
-rw-r--r--modules/ogg/config.py1
-rw-r--r--modules/ogg/register_types.h5
-rw-r--r--modules/opensimplex/SCsub4
-rw-r--r--modules/opensimplex/config.py9
-rw-r--r--modules/opensimplex/doc_classes/NoiseTexture.xml5
-rw-r--r--modules/opensimplex/icons/NoiseTexture.svg (renamed from modules/opensimplex/icons/icon_noise_texture.svg)0
-rw-r--r--modules/opensimplex/noise_texture.cpp48
-rw-r--r--modules/opensimplex/noise_texture.h11
-rw-r--r--modules/opensimplex/open_simplex_noise.cpp14
-rw-r--r--modules/opensimplex/register_types.h5
-rw-r--r--modules/opus/SCsub43
-rw-r--r--modules/opus/audio_stream_opus.cpp379
-rw-r--r--modules/opus/audio_stream_opus.h142
-rw-r--r--modules/opus/config.py9
-rw-r--r--modules/opus/register_types.cpp21
-rw-r--r--modules/opus/register_types.h5
-rw-r--r--modules/pvr/SCsub4
-rw-r--r--modules/pvr/config.py1
-rw-r--r--modules/pvr/register_types.h5
-rw-r--r--modules/pvr/texture_loader_pvr.cpp40
-rw-r--r--modules/pvr/texture_loader_pvr.h2
-rw-r--r--modules/recast/SCsub33
-rw-r--r--modules/regex/SCsub16
-rw-r--r--modules/regex/config.py3
-rw-r--r--modules/regex/doc_classes/RegEx.xml4
-rw-r--r--modules/regex/regex.cpp26
-rw-r--r--modules/regex/register_types.h5
-rw-r--r--modules/register_module_types.h1
-rw-r--r--modules/squish/SCsub6
-rw-r--r--modules/squish/config.py1
-rw-r--r--modules/squish/image_compress_squish.cpp77
-rw-r--r--modules/squish/image_compress_squish.h2
-rw-r--r--modules/squish/register_types.h5
-rw-r--r--modules/stb_vorbis/SCsub4
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp54
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.h4
-rw-r--r--modules/stb_vorbis/config.py3
-rw-r--r--modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml2
-rw-r--r--modules/stb_vorbis/register_types.h5
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.cpp8
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.h2
-rw-r--r--modules/svg/SCsub6
-rw-r--r--modules/svg/config.py1
-rw-r--r--modules/svg/image_loader_svg.cpp31
-rw-r--r--modules/svg/image_loader_svg.h4
-rw-r--r--modules/svg/register_types.cpp2
-rw-r--r--modules/svg/register_types.h5
-rw-r--r--modules/tga/SCsub4
-rw-r--r--modules/tga/config.py1
-rw-r--r--modules/tga/image_loader_tga.cpp44
-rw-r--r--modules/tga/register_types.cpp2
-rw-r--r--modules/tga/register_types.h5
-rw-r--r--modules/theora/SCsub60
-rw-r--r--modules/theora/config.py3
-rw-r--r--modules/theora/register_types.h5
-rw-r--r--modules/theora/video_stream_theora.cpp28
-rw-r--r--modules/theora/video_stream_theora.h6
-rw-r--r--modules/tinyexr/SCsub4
-rw-r--r--modules/tinyexr/config.py3
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp24
-rw-r--r--modules/tinyexr/image_saver_tinyexr.cpp39
-rw-r--r--modules/tinyexr/register_types.cpp4
-rw-r--r--modules/tinyexr/register_types.h5
-rw-r--r--modules/upnp/SCsub6
-rw-r--r--modules/upnp/config.py5
-rw-r--r--modules/upnp/doc_classes/UPNP.xml2
-rw-r--r--modules/upnp/register_types.h5
-rw-r--r--modules/upnp/upnp.cpp29
-rw-r--r--modules/upnp/upnp.h2
-rw-r--r--modules/upnp/upnp_device.cpp30
-rw-r--r--modules/vhacd/SCsub6
-rw-r--r--modules/vhacd/config.py2
-rw-r--r--modules/vhacd/register_types.cpp6
-rw-r--r--modules/vhacd/register_types.h5
-rw-r--r--modules/visual_script/SCsub4
-rw-r--r--modules/visual_script/config.py3
-rw-r--r--modules/visual_script/doc_classes/VisualScript.xml90
-rw-r--r--modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml6
-rw-r--r--modules/visual_script/doc_classes/VisualScriptClassConstant.xml4
-rw-r--r--modules/visual_script/doc_classes/VisualScriptEmitSignal.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptFunctionCall.xml6
-rw-r--r--modules/visual_script/doc_classes/VisualScriptInputAction.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptLocalVar.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptPropertyGet.xml6
-rw-r--r--modules/visual_script/doc_classes/VisualScriptPropertySet.xml6
-rw-r--r--modules/visual_script/doc_classes/VisualScriptTypeCast.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptVariableGet.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptVariableSet.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptYieldSignal.xml4
-rw-r--r--modules/visual_script/icons/VisualScript.svg (renamed from modules/visual_script/icons/icon_visual_script.svg)0
-rw-r--r--modules/visual_script/register_types.cpp4
-rw-r--r--modules/visual_script/register_types.h5
-rw-r--r--modules/visual_script/visual_script.cpp347
-rw-r--r--modules/visual_script/visual_script.h61
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp190
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h4
-rw-r--r--modules/visual_script/visual_script_editor.cpp526
-rw-r--r--modules/visual_script/visual_script_editor.h16
-rw-r--r--modules/visual_script/visual_script_expression.cpp96
-rw-r--r--modules/visual_script/visual_script_expression.h2
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp26
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp106
-rw-r--r--modules/visual_script/visual_script_nodes.cpp148
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp139
-rw-r--r--modules/visual_script/visual_script_property_selector.h11
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp32
-rw-r--r--modules/vorbis/SCsub29
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp406
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.h137
-rw-r--r--modules/vorbis/config.py1
-rw-r--r--modules/vorbis/register_types.cpp17
-rw-r--r--modules/vorbis/register_types.h5
-rw-r--r--modules/webm/SCsub12
-rw-r--r--modules/webm/config.py5
-rw-r--r--modules/webm/libvpx/SCsub175
-rw-r--r--modules/webm/register_types.h5
-rw-r--r--modules/webm/video_stream_webm.cpp55
-rw-r--r--modules/webm/video_stream_webm.h6
-rw-r--r--modules/webp/SCsub6
-rw-r--r--modules/webp/config.py1
-rw-r--r--modules/webp/image_loader_webp.cpp51
-rw-r--r--modules/webp/register_types.cpp2
-rw-r--r--modules/webp/register_types.h5
-rw-r--r--modules/webrtc/SCsub8
-rw-r--r--modules/webrtc/config.py5
-rw-r--r--modules/webrtc/register_types.h5
-rw-r--r--modules/webrtc/webrtc_data_channel_gdnative.cpp36
-rw-r--r--modules/webrtc/webrtc_data_channel_js.cpp4
-rw-r--r--modules/webrtc/webrtc_multiplayer.cpp27
-rw-r--r--modules/webrtc/webrtc_multiplayer.h4
-rw-r--r--modules/webrtc/webrtc_peer_connection.cpp4
-rw-r--r--modules/webrtc/webrtc_peer_connection_gdnative.cpp24
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.cpp2
-rw-r--r--modules/websocket/SCsub6
-rw-r--r--modules/websocket/config.py5
-rw-r--r--modules/websocket/doc_classes/WebSocketClient.xml4
-rw-r--r--modules/websocket/doc_classes/WebSocketServer.xml2
-rw-r--r--modules/websocket/emws_client.cpp24
-rw-r--r--modules/websocket/emws_peer.cpp20
-rw-r--r--modules/websocket/emws_peer.h2
-rw-r--r--modules/websocket/emws_server.cpp6
-rw-r--r--modules/websocket/emws_server.h2
-rw-r--r--modules/websocket/packet_buffer.h4
-rw-r--r--modules/websocket/register_types.h5
-rw-r--r--modules/websocket/websocket_macros.h4
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp34
-rw-r--r--modules/websocket/websocket_multiplayer_peer.h4
-rw-r--r--modules/websocket/wsl_client.cpp6
-rw-r--r--modules/websocket/wsl_peer.cpp30
-rw-r--r--modules/websocket/wsl_peer.h8
-rw-r--r--modules/websocket/wsl_server.cpp14
-rw-r--r--modules/websocket/wsl_server.h2
-rw-r--r--modules/xatlas_unwrap/SCsub6
-rw-r--r--modules/xatlas_unwrap/config.py3
-rw-r--r--modules/xatlas_unwrap/register_types.cpp4
-rw-r--r--modules/xatlas_unwrap/register_types.h5
571 files changed, 21169 insertions, 14533 deletions
diff --git a/modules/SCsub b/modules/SCsub
index 5b39b18334..fb46c5f877 100644
--- a/modules/SCsub
+++ b/modules/SCsub
@@ -1,16 +1,17 @@
#!/usr/bin/env python
-Import('env')
+Import("env")
import modules_builders
env_modules = env.Clone()
-Export('env_modules')
+Export("env_modules")
# Header with MODULE_*_ENABLED defines.
env.CommandNoCache("modules_enabled.gen.h", Value(env.module_list), modules_builders.generate_modules_enabled)
+vs_sources = []
# libmodule_<name>.a for each active module.
for module in env.module_list:
env.modules_sources = []
@@ -23,6 +24,8 @@ for module in env.module_list:
lib = env_modules.add_library("module_%s" % module, env.modules_sources)
env.Prepend(LIBS=[lib])
+ if env["vsproj"]:
+ vs_sources += env.modules_sources
# libmodules.a with only register_module_types.
# Must be last so that all libmodule_<name>.a libraries are on the right side
@@ -31,3 +34,5 @@ env.modules_sources = []
env_modules.add_source_files(env.modules_sources, "register_module_types.gen.cpp")
lib = env_modules.add_library("modules", env.modules_sources)
env.Prepend(LIBS=[lib])
+if env["vsproj"]:
+ env.modules_sources += vs_sources
diff --git a/modules/arkit/SCsub b/modules/arkit/SCsub
index e605703a72..61c0a8248c 100644
--- a/modules/arkit/SCsub
+++ b/modules/arkit/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_arkit = env_modules.Clone()
@@ -9,4 +9,4 @@ env_arkit = env_modules.Clone()
modules_sources = []
env_arkit.add_source_files(modules_sources, "*.cpp")
env_arkit.add_source_files(modules_sources, "*.mm")
-mod_lib = env_modules.add_library('#bin/libgodot_arkit_module' + env['LIBSUFFIX'], modules_sources) \ No newline at end of file
+mod_lib = env_modules.add_library("#bin/libgodot_arkit_module" + env["LIBSUFFIX"], modules_sources)
diff --git a/modules/arkit/arkit_interface.h b/modules/arkit/arkit_interface.h
index cb18350409..1044f3cf6f 100644
--- a/modules/arkit/arkit_interface.h
+++ b/modules/arkit/arkit_interface.h
@@ -31,9 +31,9 @@
#ifndef ARKIT_INTERFACE_H
#define ARKIT_INTERFACE_H
-#include "servers/arvr/arvr_interface.h"
-#include "servers/arvr/arvr_positional_tracker.h"
#include "servers/camera/camera_feed.h"
+#include "servers/xr/xr_interface.h"
+#include "servers/xr/xr_positional_tracker.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
@@ -44,8 +44,8 @@
// forward declaration for some needed objects
class ARKitShader;
-class ARKitInterface : public ARVRInterface {
- GDCLASS(ARKitInterface, ARVRInterface);
+class ARKitInterface : public XRInterface {
+ GDCLASS(ARKitInterface, XRInterface);
private:
bool initialized;
@@ -62,10 +62,10 @@ private:
Ref<CameraFeed> feed;
int image_width[2];
int image_height[2];
- PoolVector<uint8_t> img_data[2];
+ Vector<uint8_t> img_data[2];
struct anchor_map {
- ARVRPositionalTracker *tracker;
+ XRPositionalTracker *tracker;
unsigned char uuid[16];
};
@@ -73,7 +73,7 @@ private:
unsigned int num_anchors;
unsigned int max_anchors;
anchor_map *anchors;
- ARVRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid);
+ XRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid);
void remove_anchor_for_uuid(const unsigned char *p_uuid);
void remove_all_anchors();
@@ -108,9 +108,9 @@ public:
virtual Size2 get_render_targetsize();
virtual bool is_stereo();
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+ virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform);
+ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
virtual void process();
diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm
index 1896a34e46..79f09e2a7e 100644
--- a/modules/arkit/arkit_interface.mm
+++ b/modules/arkit/arkit_interface.mm
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/os/input.h"
+#include "core/input/input_filter.h"
#include "core/os/os.h"
#include "scene/resources/surface_tool.h"
-#include "servers/visual/visual_server_globals.h"
+#include "servers/rendering/rendering_server_globals.h"
#import <ARKit/ARKit.h>
#import <UIKit/UIKit.h>
@@ -158,7 +158,7 @@ StringName ARKitInterface::get_name() const {
}
int ARKitInterface::get_capabilities() const {
- return ARKitInterface::ARVR_MONO + ARKitInterface::ARVR_AR;
+ return ARKitInterface::XR_MONO + ARKitInterface::XR_AR;
}
Array ARKitInterface::raycast(Vector2 p_screen_coord) {
@@ -218,8 +218,8 @@ bool ARKitInterface::is_initialized() const {
}
bool ARKitInterface::initialize() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, false);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, false);
if (!initialized) {
print_line("initializing ARKit");
@@ -244,7 +244,7 @@ bool ARKitInterface::initialize() {
transform = Transform();
// make this our primary interface
- arvr_server->set_primary_interface(this);
+ xr_server->set_primary_interface(this);
// make sure we have our feed setup
if (feed.is_null()) {
@@ -270,10 +270,10 @@ bool ARKitInterface::initialize() {
void ARKitInterface::uninitialize() {
if (initialized) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != NULL) {
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != NULL) {
// no longer our primary interface
- arvr_server->clear_primary_interface_if(this);
+ xr_server->clear_primary_interface_if(this);
}
if (feed.is_valid()) {
@@ -303,22 +303,22 @@ Size2 ARKitInterface::get_render_targetsize() {
return target_size;
}
-Transform ARKitInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+Transform ARKitInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
_THREAD_SAFE_METHOD_
Transform transform_for_eye;
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, transform_for_eye);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, transform_for_eye);
if (initialized) {
- float world_scale = arvr_server->get_world_scale();
+ float world_scale = xr_server->get_world_scale();
// just scale our origin point of our transform, note that we really shouldn't be using world_scale in ARKit but....
transform_for_eye = transform;
transform_for_eye.origin *= world_scale;
- transform_for_eye = p_cam_transform * arvr_server->get_reference_frame() * transform_for_eye;
+ transform_for_eye = p_cam_transform * xr_server->get_reference_frame() * transform_for_eye;
} else {
// huh? well just return what we got....
transform_for_eye = p_cam_transform;
@@ -327,7 +327,7 @@ Transform ARKitInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const
return transform_for_eye;
}
-CameraMatrix ARKitInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+CameraMatrix ARKitInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
// Remember our near and far, it will be used in process when we obtain our projection from our ARKit session.
z_near = p_z_near;
z_far = p_z_far;
@@ -335,7 +335,7 @@ CameraMatrix ARKitInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, r
return projection;
}
-void ARKitInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+void ARKitInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
_THREAD_SAFE_METHOD_
// We must have a valid render target
@@ -356,7 +356,7 @@ void ARKitInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_targ
VSG::rasterizer->blit_render_target_to_screen(p_render_target, screen_rect, 0);
}
-ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) {
+XRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) {
if (anchors == NULL) {
num_anchors = 0;
max_anchors = 10;
@@ -377,8 +377,8 @@ ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *
ERR_FAIL_NULL_V(anchors, NULL);
}
- ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker);
- new_tracker->set_type(ARVRServer::TRACKER_ANCHOR);
+ XRPositionalTracker *new_tracker = memnew(XRPositionalTracker);
+ new_tracker->set_type(XRServer::TRACKER_ANCHOR);
char tracker_name[256];
sprintf(tracker_name, "Anchor %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p_uuid[0], p_uuid[1], p_uuid[2], p_uuid[3], p_uuid[4], p_uuid[5], p_uuid[6], p_uuid[7], p_uuid[8], p_uuid[9], p_uuid[10], p_uuid[11], p_uuid[12], p_uuid[13], p_uuid[14], p_uuid[15]);
@@ -388,7 +388,7 @@ ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *
new_tracker->set_name(name);
// add our tracker
- ARVRServer::get_singleton()->add_tracker(new_tracker);
+ XRServer::get_singleton()->add_tracker(new_tracker);
anchors[num_anchors].tracker = new_tracker;
memcpy(anchors[num_anchors].uuid, p_uuid, 16);
num_anchors++;
@@ -401,7 +401,7 @@ void ARKitInterface::remove_anchor_for_uuid(const unsigned char *p_uuid) {
for (unsigned int i = 0; i < num_anchors; i++) {
if (memcmp(anchors[i].uuid, p_uuid, 16) == 0) {
// remove our tracker
- ARVRServer::get_singleton()->remove_tracker(anchors[i].tracker);
+ XRServer::get_singleton()->remove_tracker(anchors[i].tracker);
memdelete(anchors[i].tracker);
// bring remaining forward
@@ -421,7 +421,7 @@ void ARKitInterface::remove_all_anchors() {
if (anchors != NULL) {
for (unsigned int i = 0; i < num_anchors; i++) {
// remove our tracker
- ARVRServer::get_singleton()->remove_tracker(anchors[i].tracker);
+ XRServer::get_singleton()->remove_tracker(anchors[i].tracker);
memdelete(anchors[i].tracker);
};
@@ -488,7 +488,7 @@ void ARKitInterface::process() {
img_data[0].resize(new_width * new_height);
}
- PoolVector<uint8_t>::Write w = img_data[0].write();
+ uint8_t *w = img_data[0].write();
if (new_width == bytes_per_row) {
memcpy(w.ptr(), dataY, new_width * new_height);
} else {
@@ -519,7 +519,7 @@ void ARKitInterface::process() {
img_data[1].resize(2 * new_width * new_height);
}
- PoolVector<uint8_t>::Write w = img_data[1].write();
+ uint8_t *w = img_data[1].write();
if ((2 * new_width) == bytes_per_row) {
memcpy(w.ptr(), dataCbCr, 2 * new_width * new_height);
} else {
@@ -582,16 +582,16 @@ void ARKitInterface::process() {
// strangely enough we have to states, rolling them up into one
if (camera.trackingState == ARTrackingStateNotAvailable) {
// no tracking, would be good if we black out the screen or something...
- tracking_state = ARVRInterface::ARVR_NOT_TRACKING;
+ tracking_state = XRInterface::XR_NOT_TRACKING;
} else {
if (camera.trackingState == ARTrackingStateNormal) {
- tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
+ tracking_state = XRInterface::XR_NORMAL_TRACKING;
} else if (camera.trackingStateReason == ARTrackingStateReasonExcessiveMotion) {
- tracking_state = ARVRInterface::ARVR_EXCESSIVE_MOTION;
+ tracking_state = XRInterface::XR_EXCESSIVE_MOTION;
} else if (camera.trackingStateReason == ARTrackingStateReasonInsufficientFeatures) {
- tracking_state = ARVRInterface::ARVR_INSUFFICIENT_FEATURES;
+ tracking_state = XRInterface::XR_INSUFFICIENT_FEATURES;
} else {
- tracking_state = ARVRInterface::ARVR_UNKNOWN_TRACKING;
+ tracking_state = XRInterface::XR_UNKNOWN_TRACKING;
}
// copy our current frame transform
@@ -665,7 +665,7 @@ void ARKitInterface::_add_or_update_anchor(void *p_anchor) {
unsigned char uuid[16];
[anchor.identifier getUUIDBytes:uuid];
- ARVRPositionalTracker *tracker = get_anchor_for_uuid(uuid);
+ XRPositionalTracker *tracker = get_anchor_for_uuid(uuid);
if (tracker != NULL) {
// lets update our mesh! (using Arjens code as is for now)
// we should also probably limit how often we do this...
@@ -695,7 +695,7 @@ void ARKitInterface::_add_or_update_anchor(void *p_anchor) {
}
// Note, this also contains a scale factor which gives us an idea of the size of the anchor
- // We may extract that in our ARVRAnchor class
+ // We may extract that in our XRAnchor class
Basis b;
matrix_float4x4 m44 = anchor.transform;
b.elements[0].x = m44.columns[0][0];
diff --git a/modules/arkit/arkit_session_delegate.mm b/modules/arkit/arkit_session_delegate.mm
index d3c12ad582..f44f46b7b7 100644
--- a/modules/arkit/arkit_session_delegate.mm
+++ b/modules/arkit/arkit_session_delegate.mm
@@ -53,4 +53,4 @@
}
}
-@end \ No newline at end of file
+@end
diff --git a/modules/arkit/config.py b/modules/arkit/config.py
index 96e41826c5..e68603fc93 100644
--- a/modules/arkit/config.py
+++ b/modules/arkit/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return platform == 'iphone'
+ return platform == "iphone"
+
def configure(env):
pass
diff --git a/modules/arkit/register_types.cpp b/modules/arkit/register_types.cpp
index c78b35529b..91069ab364 100644
--- a/modules/arkit/register_types.cpp
+++ b/modules/arkit/register_types.cpp
@@ -37,7 +37,7 @@ void register_arkit_types() {
Ref<ARKitInterface> arkit_interface;
arkit_interface.instance();
- ARVRServer::get_singleton()->add_interface(arkit_interface);
+ XRServer::get_singleton()->add_interface(arkit_interface);
}
void unregister_arkit_types() {
diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub
index 5e66b50de3..f1d0c742b4 100644
--- a/modules/assimp/SCsub
+++ b/modules/assimp/SCsub
@@ -1,100 +1,94 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_assimp = env_modules.Clone()
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/include'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/IFC'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/misc'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/common'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/irrXML/'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/unzip/'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/STEPParser'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/zlib/'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/openddlparser/include'])
-env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/rapidjson/include'])
-env_assimp.Prepend(CPPPATH=['.'])
-#env_assimp.Append(CPPDEFINES=['ASSIMP_DOUBLE_PRECISION']) # TODO default to what godot is compiled with for future double support
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_BOOST_WORKAROUND'])
-env_assimp.Append(CPPDEFINES=['OPENDDLPARSER_BUILD'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OWN_ZLIB'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_EXPORT'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_AMF_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3DS_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD3_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD5_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MDL_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD2_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_PLY_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_ASE_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OBJ_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_HMP_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_SMD_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MDC_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD5_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_STL_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_LWO_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_DXF_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_NFF_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_RAW_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_SIB_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OFF_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_AC_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_BVH_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IRRMESH_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IRR_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_Q3D_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_B3D_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_COLLADA_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_TERRAGEN_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_CSM_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3D_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_LWS_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OGRE_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OPENGEX_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MS3D_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_COB_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_BLEND_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_Q3BSP_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_NDO_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_STEP_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IFC_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_XGL_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_ASSBIN_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_C4D_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3MF_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X3D_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF2_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_SINGLETHREADED'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_M3D_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MMD_IMPORTER'])
+# Force bundled version for now, there's no released version of Assimp with
+# support for ArmaturePopulate which we use from their master branch.
+if True: # env['builtin_assimp']:
+ thirdparty_dir = "#thirdparty/assimp"
-if(env['platform'] == 'windows'):
- env_assimp.Append(CPPDEFINES=['PLATFORM_WINDOWS'])
- env_assimp.Append(CPPDEFINES=[('PLATFORM', 'WINDOWS')])
-elif(env['platform'] == 'x11'):
- env_assimp.Append(CPPDEFINES=['PLATFORM_LINUX'])
- env_assimp.Append(CPPDEFINES=[('PLATFORM', 'LINUX')])
-elif(env['platform'] == 'osx'):
- env_assimp.Append(CPPDEFINES=['PLATFORM_DARWIN'])
- env_assimp.Append(CPPDEFINES=[('PLATFORM', 'DARWIN')])
-
-env_thirdparty = env_assimp.Clone()
-env_thirdparty.disable_warnings()
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Common/*.cpp'))
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/PostProcessing/*.cpp'))
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Material/*.cpp'))
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/FBX/*.cpp'))
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/MMD/*.cpp'))
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF/*.cpp'))
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF2/*.cpp'))
+ env_assimp.Prepend(CPPPATH=["#thirdparty/assimp"])
+ env_assimp.Prepend(CPPPATH=["#thirdparty/assimp/code"])
+ env_assimp.Prepend(CPPPATH=["#thirdparty/assimp/include"])
+
+ # env_assimp.Append(CPPDEFINES=['ASSIMP_DOUBLE_PRECISION']) # TODO default to what godot is compiled with for future double support
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_SINGLETHREADED"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_BOOST_WORKAROUND"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OWN_ZLIB"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_EXPORT"])
+
+ # Importers we don't need
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_3D_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_3DS_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_3MF_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_AC_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_AMF_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_ASE_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_ASSBIN_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_B3D_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_BLEND_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_BVH_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_C4D_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_COB_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_COLLADA_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_CSM_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_DXF_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_GLTF2_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_GLTF_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_HMP_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_IFC_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_IRR_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_IRRMESH_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_LWO_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_LWS_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_M3D_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD2_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD3_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD5_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MD5_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MDC_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MDL_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MMD_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_MS3D_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_NDO_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_NFF_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OBJ_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OFF_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OGRE_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_OPENGEX_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_PLY_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_Q3BSP_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_Q3D_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_RAW_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_SIB_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_SMD_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_STEP_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_STL_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_TERRAGEN_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_X3D_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_XGL_IMPORTER"])
+ env_assimp.Append(CPPDEFINES=["ASSIMP_BUILD_NO_X_IMPORTER"])
+
+ if env["platform"] == "windows":
+ env_assimp.Append(CPPDEFINES=["PLATFORM_WINDOWS"])
+ env_assimp.Append(CPPDEFINES=[("PLATFORM", "WINDOWS")])
+ elif env["platform"] == "linuxbsd":
+ env_assimp.Append(CPPDEFINES=["PLATFORM_LINUX"])
+ env_assimp.Append(CPPDEFINES=[("PLATFORM", "LINUX")])
+ elif env["platform"] == "osx":
+ env_assimp.Append(CPPDEFINES=["PLATFORM_DARWIN"])
+ env_assimp.Append(CPPDEFINES=[("PLATFORM", "DARWIN")])
+
+ env_thirdparty = env_assimp.Clone()
+ env_thirdparty.disable_warnings()
+ env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/CApi/*.cpp"))
+ env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/Common/*.cpp"))
+ env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/PostProcessing/*.cpp"))
+ env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/Material/*.cpp"))
+ env_thirdparty.add_source_files(env.modules_sources, Glob("#thirdparty/assimp/code/FBX/*.cpp"))
# Godot's own source files
env_assimp.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/assimp/config.py b/modules/assimp/config.py
index 098f1eafa9..53b8f2f2e3 100644
--- a/modules/assimp/config.py
+++ b/modules/assimp/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return env['tools']
+ return env["tools"]
+
def configure(env):
pass
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp
index 69ab068648..cc74674eff 100644
--- a/modules/assimp/editor_scene_importer_assimp.cpp
+++ b/modules/assimp/editor_scene_importer_assimp.cpp
@@ -32,9 +32,9 @@
#include "core/io/image_loader.h"
#include "editor/import/resource_importer_scene.h"
#include "import_utils.h"
-#include "scene/3d/camera.h"
-#include "scene/3d/light.h"
-#include "scene/3d/mesh_instance.h"
+#include "scene/3d/camera_3d.h"
+#include "scene/3d/light_3d.h"
+#include "scene/3d/mesh_instance_3d.h"
#include "scene/main/node.h"
#include "scene/resources/material.h"
#include "scene/resources/surface_tool.h"
@@ -62,7 +62,7 @@ aiBone *get_bone_by_name(const aiScene *scene, aiString bone_name) {
}
}
- return NULL;
+ return nullptr;
}
void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const {
@@ -149,7 +149,7 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f
0;
aiScene *scene = (aiScene *)importer.ReadFile(s_path.c_str(), post_process_Steps);
- ERR_FAIL_COND_V_MSG(scene == NULL, NULL, String("Open Asset Import failed to open: ") + String(importer.GetErrorString()));
+ ERR_FAIL_COND_V_MSG(scene == nullptr, nullptr, String("Open Asset Import failed to open: ") + String(importer.GetErrorString()));
return _generate_scene(p_path, scene, p_flags, p_bake_fps, max_bone_weights);
}
@@ -167,8 +167,7 @@ struct EditorSceneImporterAssetImportInterpolate {
float t2 = t * t;
float t3 = t2 * t;
- return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 +
- (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
+ return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
}
T bezier(T start, T control_1, T control_2, T end, float t) {
@@ -285,7 +284,7 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
aiBone *EditorSceneImporterAssimp::get_bone_from_stack(ImportState &state, aiString name) {
List<aiBone *>::Element *iter;
- aiBone *bone = NULL;
+ aiBone *bone = nullptr;
for (iter = state.bone_stack.front(); iter; iter = iter->next()) {
bone = (aiBone *)iter->get();
@@ -295,32 +294,32 @@ aiBone *EditorSceneImporterAssimp::get_bone_from_stack(ImportState &state, aiStr
}
}
- return NULL;
+ return nullptr;
}
-Spatial *
+Node3D *
EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps,
const int32_t p_max_bone_weights) {
- ERR_FAIL_COND_V(scene == NULL, NULL);
+ ERR_FAIL_COND_V(scene == nullptr, nullptr);
ImportState state;
state.path = p_path;
state.assimp_scene = scene;
state.max_bone_weights = p_max_bone_weights;
- state.animation_player = NULL;
+ state.animation_player = nullptr;
// populate light map
for (unsigned int l = 0; l < scene->mNumLights; l++) {
aiLight *ai_light = scene->mLights[l];
- ERR_CONTINUE(ai_light == NULL);
+ ERR_CONTINUE(ai_light == nullptr);
state.light_cache[AssimpUtils::get_assimp_string(ai_light->mName)] = l;
}
// fill camera cache
for (unsigned int c = 0; c < scene->mNumCameras; c++) {
aiCamera *ai_camera = scene->mCameras[c];
- ERR_CONTINUE(ai_camera == NULL);
+ ERR_CONTINUE(ai_camera == nullptr);
state.camera_cache[AssimpUtils::get_assimp_string(ai_camera->mName)] = c;
}
@@ -334,7 +333,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
RegenerateBoneStack(state);
- Node *last_valid_parent = NULL;
+ Node *last_valid_parent = nullptr;
List<const aiNode *>::Element *iter;
for (iter = state.nodes.front(); iter; iter = iter->next()) {
@@ -344,7 +343,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
String node_name = AssimpUtils::get_assimp_string(element_assimp_node->mName);
//print_verbose("node: " + node_name);
- Spatial *spatial = NULL;
+ Node3D *spatial = nullptr;
Transform transform = AssimpUtils::assimp_matrix_transform(element_assimp_node->mTransformation);
// retrieve this node bone
@@ -357,18 +356,18 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
} else if (state.armature_nodes.find(element_assimp_node)) {
// create skeleton
print_verbose("Making skeleton: " + node_name);
- Skeleton *skeleton = memnew(Skeleton);
+ Skeleton3D *skeleton = memnew(Skeleton3D);
spatial = skeleton;
if (!state.armature_skeletons.has(element_assimp_node)) {
state.armature_skeletons.insert(element_assimp_node, skeleton);
}
- } else if (bone != NULL) {
+ } else if (bone != nullptr) {
continue;
} else {
- spatial = memnew(Spatial);
+ spatial = memnew(Node3D);
}
- ERR_CONTINUE_MSG(spatial == NULL, "FBX Import - are we out of ram?");
+ ERR_CONTINUE_MSG(spatial == nullptr, "FBX Import - are we out of ram?");
// we on purpose set the transform and name after creating the node.
spatial->set_name(node_name);
@@ -382,13 +381,13 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
// flat node map parent lookup tool
state.flat_node_map.insert(element_assimp_node, spatial);
- Map<const aiNode *, Spatial *>::Element *parent_lookup = state.flat_node_map.find(parent_assimp_node);
+ Map<const aiNode *, Node3D *>::Element *parent_lookup = state.flat_node_map.find(parent_assimp_node);
// note: this always fails on the root node :) keep that in mind this is by design
if (parent_lookup) {
- Spatial *parent_node = parent_lookup->value();
+ Node3D *parent_node = parent_lookup->value();
- ERR_FAIL_COND_V_MSG(parent_node == NULL, state.root,
+ ERR_FAIL_COND_V_MSG(parent_node == nullptr, state.root,
"Parent node invalid even though lookup successful, out of ram?");
if (spatial != state.root) {
@@ -435,8 +434,8 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
aiNode *parent_node = bone_node->mParent;
String bone_name = AssimpUtils::get_anim_string_from_assimp(bone->mName);
- ERR_CONTINUE_MSG(armature_for_bone == NULL, "Armature for bone invalid: " + bone_name);
- Skeleton *skeleton = state.armature_skeletons[armature_for_bone];
+ ERR_CONTINUE_MSG(armature_for_bone == nullptr, "Armature for bone invalid: " + bone_name);
+ Skeleton3D *skeleton = state.armature_skeletons[armature_for_bone];
state.skeleton_bone_map[bone] = skeleton;
@@ -455,7 +454,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
skeleton->set_bone_rest(boneIdx, pform);
skeleton->set_bone_pose(boneIdx, pform);
- if (parent_node != NULL) {
+ if (parent_node != nullptr) {
int parent_bone_id = skeleton->find_bone(AssimpUtils::get_anim_string_from_assimp(parent_node->mName));
int current_bone_id = boneIdx;
skeleton->set_bone_parent(current_bone_id, parent_bone_id);
@@ -465,14 +464,14 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
print_verbose("generating mesh phase from skeletal mesh");
- List<Spatial *> cleanup_template_nodes;
+ List<Node3D *> cleanup_template_nodes;
- for (Map<const aiNode *, Spatial *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ for (Map<const aiNode *, Node3D *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
const aiNode *assimp_node = key_value_pair->key();
- Spatial *mesh_template = key_value_pair->value();
+ Node3D *mesh_template = key_value_pair->value();
- ERR_CONTINUE(assimp_node == NULL);
- ERR_CONTINUE(mesh_template == NULL);
+ ERR_CONTINUE(assimp_node == nullptr);
+ ERR_CONTINUE(mesh_template == nullptr);
Node *parent_node = mesh_template->get_parent();
@@ -480,7 +479,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
continue;
}
- if (parent_node == NULL) {
+ if (parent_node == nullptr) {
print_error("Found invalid parent node!");
continue; // root node
}
@@ -489,7 +488,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation);
if (assimp_node->mNumMeshes > 0) {
- MeshInstance *mesh = create_mesh(state, assimp_node, node_name, parent_node, node_transform);
+ MeshInstance3D *mesh = create_mesh(state, assimp_node, node_name, parent_node, node_transform);
if (mesh) {
parent_node->remove_child(mesh_template);
@@ -523,7 +522,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
}
}
- for (List<Spatial *>::Element *element = cleanup_template_nodes.front(); element; element = element->next()) {
+ for (List<Node3D *>::Element *element = cleanup_template_nodes.front(); element; element = element->next()) {
if (element->get()) {
memdelete(element->get());
}
@@ -560,7 +559,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id,
int anim_fps, Ref<Animation> animation, float ticks_per_second,
- Skeleton *skeleton, const NodePath &node_path,
+ Skeleton3D *skeleton, const NodePath &node_path,
const String &node_name, aiBone *track_bone) {
const aiNodeAnim *assimp_track = assimp_anim->mChannels[track_id];
//make transform track
@@ -653,16 +652,16 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons
// I really do not like this but need to figure out a better way of removing it later.
Node *EditorSceneImporterAssimp::get_node_by_name(ImportState &state, String name) {
- for (Map<const aiNode *, Spatial *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ for (Map<const aiNode *, Node3D *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
const aiNode *assimp_node = key_value_pair->key();
- Spatial *node = key_value_pair->value();
+ Node3D *node = key_value_pair->value();
String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
if (name == node_name && node) {
return node;
}
}
- return NULL;
+ return nullptr;
}
/* Bone stack is a fifo handler for multiple armatures since armatures aren't a thing in assimp (yet) */
@@ -692,7 +691,7 @@ void EditorSceneImporterAssimp::RegenerateBoneStack(ImportState &state, aiMesh *
// iterate over all the bones on the mesh for this node only!
for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; boneIndex++) {
aiBone *bone = mesh->mBones[boneIndex];
- if (state.bone_stack.find(bone) == NULL) {
+ if (state.bone_stack.find(bone) == nullptr) {
state.bone_stack.push_back(bone);
}
}
@@ -712,7 +711,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
print_verbose("import animation: " + name);
float ticks_per_second = anim->mTicksPerSecond;
- if (state.assimp_scene->mMetaData != NULL && Math::is_equal_approx(ticks_per_second, 0.0f)) {
+ if (state.assimp_scene->mMetaData != nullptr && Math::is_equal_approx(ticks_per_second, 0.0f)) {
int32_t time_mode = 0;
state.assimp_scene->mMetaData->Get("TimeMode", time_mode);
ticks_per_second = AssimpUtils::get_fbx_fps(time_mode, state.assimp_scene);
@@ -748,9 +747,9 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
continue; //do not bother
}
- Skeleton *skeleton = NULL;
+ Skeleton3D *skeleton = nullptr;
NodePath node_path;
- aiBone *bone = NULL;
+ aiBone *bone = nullptr;
// Import skeleton bone animation for this track
// Any bone will do, no point in processing more than just what is in the skeleton
@@ -806,8 +805,8 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
Node *item = get_node_by_name(state, mesh_name);
ERR_CONTINUE_MSG(!item, "failed to look up node by name");
- const MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(item);
- ERR_CONTINUE(mesh_instance == NULL);
+ const MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(item);
+ ERR_CONTINUE(mesh_instance == nullptr);
String base_path = state.root->get_path_to(mesh_instance);
@@ -843,7 +842,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
Ref<Mesh>
EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices,
const aiNode *assimp_node, Ref<Skin> &skin,
- Skeleton *&skeleton_assigned) {
+ Skeleton3D *&skeleton_assigned) {
Ref<ArrayMesh> mesh;
mesh.instance();
@@ -873,7 +872,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
const unsigned int mesh_idx = p_surface_indices[i];
const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx];
- Map<uint32_t, Vector<BoneInfo> > vertex_weights;
+ Map<uint32_t, Vector<BoneInfo>> vertex_weights;
if (ai_mesh->mNumBones > 0) {
for (size_t b = 0; b < ai_mesh->mNumBones; b++) {
@@ -941,7 +940,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
}
// Work out normal calculations? - this needs work it doesn't work properly on huestos
- if (ai_mesh->mNormals != NULL) {
+ if (ai_mesh->mNormals != nullptr) {
const aiVector3D normals = ai_mesh->mNormals[j];
const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z);
st->add_normal(godot_normal);
@@ -995,15 +994,15 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
}
aiMaterial *ai_material = state.assimp_scene->mMaterials[ai_mesh->mMaterialIndex];
- Ref<SpatialMaterial> mat;
+ Ref<StandardMaterial3D> mat;
mat.instance();
int32_t mat_two_sided = 0;
if (AI_SUCCESS == ai_material->Get(AI_MATKEY_TWOSIDED, mat_two_sided)) {
if (mat_two_sided > 0) {
- mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED);
} else {
- mat->set_cull_mode(SpatialMaterial::CULL_BACK);
+ mat->set_cull_mode(StandardMaterial3D::CULL_BACK);
}
}
@@ -1015,7 +1014,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Culling handling for meshes
// cull all back faces
- mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED);
// Now process materials
aiTextureType base_color = aiTextureType_BASE_COLOR;
@@ -1028,13 +1027,11 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// anything transparent must be culled
if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- mat->set_cull_mode(
- SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
+ mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode
}
- mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
+ mat->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, image_data.texture);
}
}
@@ -1048,22 +1045,18 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// anything transparent must be culled
if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- mat->set_cull_mode(
- SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
+ mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode
}
- mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
+ mat->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, image_data.texture);
}
aiColor4D clr_diffuse;
if (AI_SUCCESS == ai_material->Get(AI_MATKEY_COLOR_DIFFUSE, clr_diffuse)) {
if (Math::is_equal_approx(clr_diffuse.a, 1.0f) == false) {
- mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- mat->set_cull_mode(
- SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS);
+ mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode
}
mat->set_albedo(Color(clr_diffuse.r, clr_diffuse.g, clr_diffuse.b, clr_diffuse.a));
}
@@ -1078,14 +1071,14 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
- mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture);
} else {
aiString texture_path;
if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_NORMAL_TEXTURE, AI_PROPERTIES, texture_path)) {
if (AssimpUtils::CreateAssimpTexture(state, texture_path, filename, path, image_data)) {
- mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
- mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture);
}
}
}
@@ -1100,8 +1093,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal_camera, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
- mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture);
}
}
@@ -1114,8 +1107,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emission_color, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
- mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture);
}
}
@@ -1128,7 +1121,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_metalness, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture);
+ mat->set_texture(StandardMaterial3D::TEXTURE_METALLIC, image_data.texture);
}
}
@@ -1141,7 +1134,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture);
+ mat->set_texture(StandardMaterial3D::TEXTURE_ROUGHNESS, image_data.texture);
}
}
@@ -1154,16 +1147,16 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emissive, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
- mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture);
+ mat->set_feature(StandardMaterial3D::FEATURE_EMISSION, true);
+ mat->set_texture(StandardMaterial3D::TEXTURE_EMISSION, image_data.texture);
} else {
// Process emission textures
aiString texture_emissive_path;
if (AI_SUCCESS ==
ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE, AI_PROPERTIES, texture_emissive_path)) {
if (AssimpUtils::CreateAssimpTexture(state, texture_emissive_path, filename, path, image_data)) {
- mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
- mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture);
+ mat->set_feature(StandardMaterial3D::FEATURE_EMISSION, true);
+ mat->set_texture(StandardMaterial3D::TEXTURE_EMISSION, image_data.texture);
}
} else {
float pbr_emission = 0.0f;
@@ -1183,7 +1176,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_specular, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture);
+ mat->set_texture(StandardMaterial3D::TEXTURE_METALLIC, image_data.texture);
}
}
@@ -1196,8 +1189,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_ao_map, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION, true);
- mat->set_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION, image_data.texture);
+ mat->set_feature(StandardMaterial3D::FEATURE_AMBIENT_OCCLUSION, true);
+ mat->set_texture(StandardMaterial3D::TEXTURE_AMBIENT_OCCLUSION, image_data.texture);
}
}
@@ -1215,82 +1208,82 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
}
Array array_copy;
- array_copy.resize(VisualServer::ARRAY_MAX);
+ array_copy.resize(RenderingServer::ARRAY_MAX);
- for (int l = 0; l < VisualServer::ARRAY_MAX; l++) {
+ for (int l = 0; l < RenderingServer::ARRAY_MAX; l++) {
array_copy[l] = array_mesh[l].duplicate(true);
}
const size_t num_vertices = ai_mesh->mAnimMeshes[j]->mNumVertices;
array_copy[Mesh::ARRAY_INDEX] = Variant();
if (ai_mesh->mAnimMeshes[j]->HasPositions()) {
- PoolVector3Array vertices;
+ PackedVector3Array vertices;
vertices.resize(num_vertices);
for (size_t l = 0; l < num_vertices; l++) {
const aiVector3D ai_pos = ai_mesh->mAnimMeshes[j]->mVertices[l];
Vector3 position = Vector3(ai_pos.x, ai_pos.y, ai_pos.z);
- vertices.write()[l] = position;
+ vertices.ptrw()[l] = position;
}
- PoolVector3Array new_vertices = array_copy[VisualServer::ARRAY_VERTEX].duplicate(true);
+ PackedVector3Array new_vertices = array_copy[RenderingServer::ARRAY_VERTEX].duplicate(true);
ERR_CONTINUE(vertices.size() != new_vertices.size());
for (int32_t l = 0; l < new_vertices.size(); l++) {
- PoolVector3Array::Write w = new_vertices.write();
+ Vector3 *w = new_vertices.ptrw();
w[l] = vertices[l];
}
- array_copy[VisualServer::ARRAY_VERTEX] = new_vertices;
+ array_copy[RenderingServer::ARRAY_VERTEX] = new_vertices;
}
int32_t color_set = 0;
if (ai_mesh->mAnimMeshes[j]->HasVertexColors(color_set)) {
- PoolColorArray colors;
+ PackedColorArray colors;
colors.resize(num_vertices);
for (size_t l = 0; l < num_vertices; l++) {
const aiColor4D ai_color = ai_mesh->mAnimMeshes[j]->mColors[color_set][l];
Color color = Color(ai_color.r, ai_color.g, ai_color.b, ai_color.a);
- colors.write()[l] = color;
+ colors.ptrw()[l] = color;
}
- PoolColorArray new_colors = array_copy[VisualServer::ARRAY_COLOR].duplicate(true);
+ PackedColorArray new_colors = array_copy[RenderingServer::ARRAY_COLOR].duplicate(true);
ERR_CONTINUE(colors.size() != new_colors.size());
for (int32_t l = 0; l < colors.size(); l++) {
- PoolColorArray::Write w = new_colors.write();
+ Color *w = new_colors.ptrw();
w[l] = colors[l];
}
- array_copy[VisualServer::ARRAY_COLOR] = new_colors;
+ array_copy[RenderingServer::ARRAY_COLOR] = new_colors;
}
if (ai_mesh->mAnimMeshes[j]->HasNormals()) {
- PoolVector3Array normals;
+ PackedVector3Array normals;
normals.resize(num_vertices);
for (size_t l = 0; l < num_vertices; l++) {
const aiVector3D ai_normal = ai_mesh->mAnimMeshes[j]->mNormals[l];
Vector3 normal = Vector3(ai_normal.x, ai_normal.y, ai_normal.z);
- normals.write()[l] = normal;
+ normals.ptrw()[l] = normal;
}
- PoolVector3Array new_normals = array_copy[VisualServer::ARRAY_NORMAL].duplicate(true);
+ PackedVector3Array new_normals = array_copy[RenderingServer::ARRAY_NORMAL].duplicate(true);
ERR_CONTINUE(normals.size() != new_normals.size());
for (int l = 0; l < normals.size(); l++) {
- PoolVector3Array::Write w = new_normals.write();
+ Vector3 *w = new_normals.ptrw();
w[l] = normals[l];
}
- array_copy[VisualServer::ARRAY_NORMAL] = new_normals;
+ array_copy[RenderingServer::ARRAY_NORMAL] = new_normals;
}
if (ai_mesh->mAnimMeshes[j]->HasTangentsAndBitangents()) {
- PoolColorArray tangents;
+ PackedColorArray tangents;
tangents.resize(num_vertices);
- PoolColorArray::Write w = tangents.write();
+ Color *w = tangents.ptrw();
for (size_t l = 0; l < num_vertices; l++) {
AssimpUtils::calc_tangent_from_mesh(ai_mesh, j, l, l, w);
}
- PoolRealArray new_tangents = array_copy[VisualServer::ARRAY_TANGENT].duplicate(true);
+ PackedFloat32Array new_tangents = array_copy[RenderingServer::ARRAY_TANGENT].duplicate(true);
ERR_CONTINUE(new_tangents.size() != tangents.size() * 4);
for (int32_t l = 0; l < tangents.size(); l++) {
- new_tangents.write()[l + 0] = tangents[l].r;
- new_tangents.write()[l + 1] = tangents[l].g;
- new_tangents.write()[l + 2] = tangents[l].b;
- new_tangents.write()[l + 3] = tangents[l].a;
+ new_tangents.ptrw()[l + 0] = tangents[l].r;
+ new_tangents.ptrw()[l + 1] = tangents[l].g;
+ new_tangents.ptrw()[l + 2] = tangents[l].b;
+ new_tangents.ptrw()[l + 3] = tangents[l].a;
}
- array_copy[VisualServer::ARRAY_TANGENT] = new_tangents;
+ array_copy[RenderingServer::ARRAY_TANGENT] = new_tangents;
}
morphs[j] = array_copy;
@@ -1306,7 +1299,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
/**
* Create a new mesh for the node supplied
*/
-MeshInstance *
+MeshInstance3D *
EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform) {
/* MESH NODE */
Ref<Mesh> mesh;
@@ -1332,15 +1325,15 @@ EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_
mesh_key += itos(surface_indices[i]);
}
- Skeleton *skeleton = NULL;
- aiNode *armature = NULL;
+ Skeleton3D *skeleton = nullptr;
+ aiNode *armature = nullptr;
if (!state.mesh_cache.has(mesh_key)) {
mesh = _generate_mesh_from_surface_indices(state, surface_indices, assimp_node, skin, skeleton);
state.mesh_cache[mesh_key] = mesh;
}
- MeshInstance *mesh_node = memnew(MeshInstance);
+ MeshInstance3D *mesh_node = memnew(MeshInstance3D);
mesh = state.mesh_cache[mesh_key];
mesh_node->set_mesh(mesh);
@@ -1414,22 +1407,22 @@ EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_
* Create a light for the scene
* Automatically caches lights for lookup later
*/
-Spatial *EditorSceneImporterAssimp::create_light(
+Node3D *EditorSceneImporterAssimp::create_light(
ImportState &state,
const String &node_name,
Transform &look_at_transform) {
- Light *light = NULL;
+ Light3D *light = nullptr;
aiLight *assimp_light = state.assimp_scene->mLights[state.light_cache[node_name]];
- ERR_FAIL_COND_V(!assimp_light, NULL);
+ ERR_FAIL_COND_V(!assimp_light, nullptr);
if (assimp_light->mType == aiLightSource_DIRECTIONAL) {
- light = memnew(DirectionalLight);
+ light = memnew(DirectionalLight3D);
} else if (assimp_light->mType == aiLightSource_POINT) {
- light = memnew(OmniLight);
+ light = memnew(OmniLight3D);
} else if (assimp_light->mType == aiLightSource_SPOT) {
- light = memnew(SpotLight);
+ light = memnew(SpotLight3D);
}
- ERR_FAIL_COND_V(light == NULL, NULL);
+ ERR_FAIL_COND_V(light == nullptr, nullptr);
if (assimp_light->mType != aiLightSource_POINT) {
Vector3 pos = Vector3(
@@ -1460,15 +1453,15 @@ Spatial *EditorSceneImporterAssimp::create_light(
/**
* Create camera for the scene
*/
-Spatial *EditorSceneImporterAssimp::create_camera(
+Node3D *EditorSceneImporterAssimp::create_camera(
ImportState &state,
const String &node_name,
Transform &look_at_transform) {
aiCamera *camera = state.assimp_scene->mCameras[state.camera_cache[node_name]];
- ERR_FAIL_COND_V(!camera, NULL);
+ ERR_FAIL_COND_V(!camera, nullptr);
- Camera *camera_node = memnew(Camera);
- ERR_FAIL_COND_V(!camera_node, NULL);
+ Camera3D *camera_node = memnew(Camera3D);
+ ERR_FAIL_COND_V(!camera_node, nullptr);
float near = camera->mClipPlaneNear;
if (Math::is_equal_approx(near, 0.0f)) {
near = 0.1f;
@@ -1490,7 +1483,7 @@ void EditorSceneImporterAssimp::_generate_node(
ImportState &state,
const aiNode *assimp_node) {
- ERR_FAIL_COND(assimp_node == NULL);
+ ERR_FAIL_COND(assimp_node == nullptr);
state.nodes.push_back(assimp_node);
String parent_name = AssimpUtils::get_assimp_string(assimp_node->mParent->mName);
@@ -1505,7 +1498,7 @@ void EditorSceneImporterAssimp::_generate_node(
// is this an armature
// parent null
// and this is the first bone :)
- if (parent_bone == NULL && current_bone) {
+ if (parent_bone == nullptr && current_bone) {
state.armature_nodes.push_back(assimp_node->mParent);
print_verbose("found valid armature: " + parent_name);
}
diff --git a/modules/assimp/editor_scene_importer_assimp.h b/modules/assimp/editor_scene_importer_assimp.h
index 4cd50e7681..ab00a6c3aa 100644
--- a/modules/assimp/editor_scene_importer_assimp.h
+++ b/modules/assimp/editor_scene_importer_assimp.h
@@ -37,9 +37,9 @@
#include "core/vector.h"
#include "editor/import/resource_importer_scene.h"
#include "editor/project_settings_editor.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/node_3d.h"
+#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
#include "scene/resources/surface_tool.h"
@@ -90,29 +90,29 @@ private:
Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices,
const aiNode *assimp_node, Ref<Skin> &skin,
- Skeleton *&skeleton_assigned);
+ Skeleton3D *&skeleton_assigned);
// simple object creation functions
- Spatial *create_light(ImportState &state,
+ Node3D *create_light(ImportState &state,
const String &node_name,
Transform &look_at_transform);
- Spatial *create_camera(
+ Node3D *create_camera(
ImportState &state,
const String &node_name,
Transform &look_at_transform);
// non recursive - linear so must not use recursive arguments
- MeshInstance *create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform);
+ MeshInstance3D *create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform);
// recursive node generator
void _generate_node(ImportState &state, const aiNode *assimp_node);
void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id,
int anim_fps, Ref<Animation> animation, float ticks_per_second,
- Skeleton *skeleton, const NodePath &node_path,
+ Skeleton3D *skeleton, const NodePath &node_path,
const String &node_name, aiBone *track_bone);
void _import_animation(ImportState &state, int p_animation_index, int p_bake_fps);
Node *get_node_by_name(ImportState &state, String name);
aiBone *get_bone_from_stack(ImportState &state, aiString name);
- Spatial *_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
+ Node3D *_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
template <class T>
T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);
@@ -138,7 +138,7 @@ public:
virtual void get_extensions(List<String> *r_extensions) const;
virtual uint32_t get_import_flags() const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path);
static void RegenerateBoneStack(ImportState &state);
diff --git a/modules/assimp/import_state.h b/modules/assimp/import_state.h
index 26aad423cd..cda1a854f0 100644
--- a/modules/assimp/import_state.h
+++ b/modules/assimp/import_state.h
@@ -36,9 +36,9 @@
#include "core/vector.h"
#include "editor/import/resource_importer_scene.h"
#include "editor/project_settings_editor.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/node_3d.h"
+#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
#include "scene/resources/surface_tool.h"
@@ -57,32 +57,32 @@ namespace AssimpImporter {
struct ImportState {
String path;
- Spatial *root;
+ Node3D *root;
const aiScene *assimp_scene;
uint32_t max_bone_weights;
- Map<String, Ref<Mesh> > mesh_cache;
- Map<int, Ref<Material> > material_cache;
+ Map<String, Ref<Mesh>> mesh_cache;
+ Map<int, Ref<Material>> material_cache;
Map<String, int> light_cache;
Map<String, int> camera_cache;
// very useful for when you need to ask assimp for the bone mesh
Map<const aiNode *, Node *> assimp_node_map;
- Map<String, Ref<Image> > path_to_image_cache;
+ Map<String, Ref<Image>> path_to_image_cache;
// Generation 3 - determinisitic iteration
// to lower potential recursion errors
List<const aiNode *> nodes;
- Map<const aiNode *, Spatial *> flat_node_map;
+ Map<const aiNode *, Node3D *> flat_node_map;
AnimationPlayer *animation_player;
// Generation 3 - deterministic armatures
// list of armature nodes - flat and simple to parse
// assimp node, node in godot
List<aiNode *> armature_nodes;
- Map<const aiNode *, Skeleton *> armature_skeletons;
- Map<aiBone *, Skeleton *> skeleton_bone_map;
+ Map<const aiNode *, Skeleton3D *> armature_skeletons;
+ Map<aiBone *, Skeleton3D *> skeleton_bone_map;
// Generation 3 - deterministic bone handling
// bones from the stack are popped when found
// this means we can detect
@@ -103,8 +103,8 @@ struct RecursiveState {
RecursiveState() {} // do not construct :)
RecursiveState(
Transform &_node_transform,
- Skeleton *_skeleton,
- Spatial *_new_node,
+ Skeleton3D *_skeleton,
+ Node3D *_new_node,
String &_node_name,
aiNode *_assimp_node,
Node *_parent_node,
@@ -118,12 +118,12 @@ struct RecursiveState {
bone(_bone) {}
Transform node_transform;
- Skeleton *skeleton = NULL;
- Spatial *new_node = NULL;
+ Skeleton3D *skeleton = nullptr;
+ Node3D *new_node = nullptr;
String node_name;
- aiNode *assimp_node = NULL;
- Node *parent_node = NULL;
- aiBone *bone = NULL;
+ aiNode *assimp_node = nullptr;
+ Node *parent_node = nullptr;
+ aiBone *bone = nullptr;
};
} // namespace AssimpImporter
diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h
index c522b01727..f78931add3 100644
--- a/modules/assimp/import_utils.h
+++ b/modules/assimp/import_utils.h
@@ -98,7 +98,7 @@ public:
/**
* calculate tangents for mesh data from assimp data
*/
- static void calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w) {
+ static void calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, Color *w) {
const aiVector3D normals = ai_mesh->mAnimMeshes[i]->mNormals[tri_index];
const Vector3 godot_normal = Vector3(normals.x, normals.y, normals.z);
const aiVector3D tangent = ai_mesh->mAnimMeshes[i]->mTangents[tri_index];
@@ -189,7 +189,7 @@ public:
}
/**
- * Converts aiMatrix4x4 to godot Transform
+ * Converts aiMatrix4x4 to godot Transform
*/
static const Transform assimp_matrix_transform(const aiMatrix4x4 p_matrix) {
aiMatrix4x4 matrix = p_matrix;
@@ -233,7 +233,7 @@ public:
static Transform _get_global_assimp_node_transform(const aiNode *p_current_node) {
aiNode const *current_node = p_current_node;
Transform xform;
- while (current_node != NULL) {
+ while (current_node != nullptr) {
xform = assimp_matrix_transform(current_node->mTransformation) * xform;
current_node = current_node->mParent;
}
@@ -319,18 +319,21 @@ public:
*/
static void set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<ImageTexture> texture) {
ERR_FAIL_COND(texture.is_null());
- ERR_FAIL_COND(map_mode == NULL);
+ ERR_FAIL_COND(map_mode == nullptr);
+ // FIXME: Commented out during Vulkan port.
+ /*
aiTextureMapMode tex_mode = map_mode[0];
- int32_t flags = Texture::FLAGS_DEFAULT;
+ int32_t flags = Texture2D::FLAGS_DEFAULT;
if (tex_mode == aiTextureMapMode_Wrap) {
//Default
} else if (tex_mode == aiTextureMapMode_Clamp) {
- flags = flags & ~Texture::FLAG_REPEAT;
+ flags = flags & ~Texture2D::FLAG_REPEAT;
} else if (tex_mode == aiTextureMapMode_Mirror) {
- flags = flags | Texture::FLAG_MIRRORED_REPEAT;
+ flags = flags | Texture2D::FLAG_MIRRORED_REPEAT;
}
texture->set_flags(flags);
+ */
}
/**
@@ -338,7 +341,7 @@ public:
*/
static Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path) {
- Map<String, Ref<Image> >::Element *match = state.path_to_image_cache.find(p_path);
+ Map<String, Ref<Image>>::Element *match = state.path_to_image_cache.find(p_path);
// if our cache contains this image then don't bother
if (match) {
@@ -355,13 +358,13 @@ public:
print_verbose("Open Asset Import: Loading embedded texture " + filename);
if (tex->mHeight == 0) {
if (tex->CheckFormat("png")) {
- ERR_FAIL_COND_V(Image::_png_mem_loader_func == NULL, Ref<Image>());
+ ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, Ref<Image>());
Ref<Image> img = Image::_png_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
ERR_FAIL_COND_V(img.is_null(), Ref<Image>());
state.path_to_image_cache.insert(p_path, img);
return img;
} else if (tex->CheckFormat("jpg")) {
- ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == NULL, Ref<Image>());
+ ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, Ref<Image>());
Ref<Image> img = Image::_jpg_mem_loader_func((uint8_t *)tex->pcData, tex->mWidth);
ERR_FAIL_COND_V(img.is_null(), Ref<Image>());
state.path_to_image_cache.insert(p_path, img);
@@ -372,17 +375,17 @@ public:
} else {
Ref<Image> img;
img.instance();
- PoolByteArray arr;
+ PackedByteArray arr;
uint32_t size = tex->mWidth * tex->mHeight;
arr.resize(size);
- memcpy(arr.write().ptr(), tex->pcData, size);
+ memcpy(arr.ptrw(), tex->pcData, size);
ERR_FAIL_COND_V(arr.size() % 4 != 0, Ref<Image>());
//ARGB8888 to RGBA8888
for (int32_t i = 0; i < arr.size() / 4; i++) {
- arr.write().ptr()[(4 * i) + 3] = arr[(4 * i) + 0];
- arr.write().ptr()[(4 * i) + 0] = arr[(4 * i) + 1];
- arr.write().ptr()[(4 * i) + 1] = arr[(4 * i) + 2];
- arr.write().ptr()[(4 * i) + 2] = arr[(4 * i) + 3];
+ arr.ptrw()[(4 * i) + 3] = arr[(4 * i) + 0];
+ arr.ptrw()[(4 * i) + 0] = arr[(4 * i) + 1];
+ arr.ptrw()[(4 * i) + 1] = arr[(4 * i) + 2];
+ arr.ptrw()[(4 * i) + 2] = arr[(4 * i) + 3];
}
img->create(tex->mWidth, tex->mHeight, true, Image::FORMAT_RGBA8, arr);
ERR_FAIL_COND_V(img.is_null(), Ref<Image>());
@@ -391,7 +394,7 @@ public:
}
return Ref<Image>();
} else {
- Ref<Texture> texture = ResourceLoader::load(p_path);
+ Ref<Texture2D> texture = ResourceLoader::load(p_path);
ERR_FAIL_COND_V(texture.is_null(), Ref<Image>());
Ref<Image> image = texture->get_data();
ERR_FAIL_COND_V(image.is_null(), Ref<Image>());
@@ -418,7 +421,8 @@ public:
if (image_state.raw_image.is_valid()) {
image_state.texture.instance();
image_state.texture->create_from_image(image_state.raw_image);
- image_state.texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
+ // FIXME: Commented out during Vulkan port.
+ //image_state.texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY);
return true;
}
}
@@ -436,7 +440,7 @@ public:
String &path,
AssimpImageData &image_state) {
aiString ai_filename = aiString();
- if (AI_SUCCESS == ai_material->GetTexture(texture_type, 0, &ai_filename, NULL, NULL, NULL, NULL, image_state.map_mode)) {
+ if (AI_SUCCESS == ai_material->GetTexture(texture_type, 0, &ai_filename, nullptr, nullptr, nullptr, nullptr, image_state.map_mode)) {
return CreateAssimpTexture(state, ai_filename, filename, path, image_state);
}
diff --git a/modules/assimp/register_types.h b/modules/assimp/register_types.h
index f363744c0a..f399a7acc6 100644
--- a/modules/assimp/register_types.h
+++ b/modules/assimp/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef ASSIMP_REGISTER_TYPES_H
+#define ASSIMP_REGISTER_TYPES_H
+
void register_assimp_types();
void unregister_assimp_types();
+
+#endif // ASSIMP_REGISTER_TYPES_H
diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub
new file mode 100644
index 0000000000..dc7b176d24
--- /dev/null
+++ b/modules/basis_universal/SCsub
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_modules")
+
+env_basisu = env_modules.Clone()
+
+# Thirdparty source files
+# Not unbundled so far since not widespread as shared library
+thirdparty_dir = "#thirdparty/basis_universal/"
+tool_sources = [
+ "basisu_astc_decomp.cpp",
+ "basisu_backend.cpp",
+ "basisu_basis_file.cpp",
+ "basisu_comp.cpp",
+ "basisu_enc.cpp",
+ "basisu_etc.cpp",
+ "basisu_frontend.cpp",
+ "basisu_global_selector_palette_helpers.cpp",
+ "basisu_gpu_texture.cpp",
+ "basisu_pvrtc1_4.cpp",
+ "basisu_resample_filters.cpp",
+ "basisu_resampler.cpp",
+ "basisu_ssim.cpp",
+ "lodepng.cpp",
+]
+tool_sources = [thirdparty_dir + file for file in tool_sources]
+transcoder_sources = [thirdparty_dir + "transcoder/basisu_transcoder.cpp"]
+
+# Treat Basis headers as system headers to avoid raising warnings. Not supported on MSVC.
+if not env.msvc:
+ env_basisu.Append(
+ CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir(thirdparty_dir + "transcoder").path]
+ )
+else:
+ env_basisu.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "transcoder"])
+
+if env["target"] == "debug":
+ env_basisu.Append(CPPFLAGS=["-DBASISU_DEVEL_MESSAGES=1", "-DBASISD_ENABLE_DEBUG_FLAGS=1"])
+
+env_thirdparty = env_basisu.Clone()
+env_thirdparty.disable_warnings()
+if env["tools"]:
+ env_thirdparty.add_source_files(env.modules_sources, tool_sources)
+env_thirdparty.add_source_files(env.modules_sources, transcoder_sources)
+
+# Godot source files
+env_basisu.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/recast/config.py b/modules/basis_universal/config.py
index 098f1eafa9..d22f9454ed 100644
--- a/modules/recast/config.py
+++ b/modules/basis_universal/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return env['tools']
+ return True
+
def configure(env):
pass
diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp
new file mode 100644
index 0000000000..f31c889a6d
--- /dev/null
+++ b/modules/basis_universal/register_types.cpp
@@ -0,0 +1,288 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "register_types.h"
+
+#include "core/os/os.h"
+#include "servers/rendering_server.h"
+#include "texture_basisu.h"
+
+#ifdef TOOLS_ENABLED
+#include <basisu_comp.h>
+#endif
+
+#include <transcoder/basisu_transcoder.h>
+
+enum BasisDecompressFormat {
+ BASIS_DECOMPRESS_RG,
+ BASIS_DECOMPRESS_RGB,
+ BASIS_DECOMPRESS_RGBA,
+ BASIS_DECOMPRESS_RG_AS_RA
+};
+
+//workaround for lack of ETC2 RG
+#define USE_RG_AS_RGBA
+
+basist::etc1_global_selector_codebook *sel_codebook = nullptr;
+
+#ifdef TOOLS_ENABLED
+static Vector<uint8_t> basis_universal_packer(const Ref<Image> &p_image, Image::UsedChannels p_channels) {
+
+ Vector<uint8_t> budata;
+
+ {
+ Ref<Image> image = p_image->duplicate();
+
+ // unfortunately, basis universal does not support compressing supplied mipmaps,
+ // so for the time being, only compressing individual images will have to do.
+
+ if (image->has_mipmaps()) {
+ image->clear_mipmaps();
+ }
+ if (image->get_format() != Image::FORMAT_RGBA8) {
+ image->convert(Image::FORMAT_RGBA8);
+ }
+
+ basisu::image buimg(image->get_width(), image->get_height());
+
+ {
+ Vector<uint8_t> vec = image->get_data();
+ const uint8_t *r = vec.ptr();
+
+ memcpy(buimg.get_ptr(), r, vec.size());
+ }
+
+ //image->save_png("pepeche.png");
+
+ basisu::basis_compressor_params params;
+ params.m_max_endpoint_clusters = 512;
+ params.m_max_selector_clusters = 512;
+ params.m_multithreading = true;
+ //params.m_no_hybrid_sel_cb = true; //fixme, default on this causes crashes //seems fixed?
+ params.m_pSel_codebook = sel_codebook;
+ //params.m_quality_level = 0;
+ //params.m_disable_hierarchical_endpoint_codebooks = true;
+ //params.m_no_selector_rdo = true;
+ params.m_auto_global_sel_pal = false;
+
+ basisu::job_pool jpool(OS::get_singleton()->get_processor_count());
+ params.m_pJob_pool = &jpool;
+
+ params.m_mip_gen = false; //sorry, please some day support provided mipmaps.
+ params.m_source_images.push_back(buimg);
+
+ BasisDecompressFormat decompress_format = BASIS_DECOMPRESS_RG;
+ params.m_check_for_alpha = false;
+
+ switch (p_channels) {
+ case Image::USED_CHANNELS_L: {
+ decompress_format = BASIS_DECOMPRESS_RGB;
+ } break;
+ case Image::USED_CHANNELS_LA: {
+ params.m_force_alpha = true;
+ decompress_format = BASIS_DECOMPRESS_RGBA;
+ } break;
+ case Image::USED_CHANNELS_R: {
+ decompress_format = BASIS_DECOMPRESS_RGB;
+ } break;
+ case Image::USED_CHANNELS_RG: {
+#ifdef USE_RG_AS_RGBA
+ image->convert_rg_to_ra_rgba8();
+ decompress_format = BASIS_DECOMPRESS_RG_AS_RA;
+#else
+ params.m_seperate_rg_to_color_alpha = true;
+ decompress_format = BASIS_DECOMPRESS_RG;
+#endif
+ } break;
+ case Image::USED_CHANNELS_RGB: {
+ decompress_format = BASIS_DECOMPRESS_RGB;
+ } break;
+ case Image::USED_CHANNELS_RGBA: {
+ params.m_force_alpha = true;
+ decompress_format = BASIS_DECOMPRESS_RGBA;
+ } break;
+ }
+
+ basisu::basis_compressor c;
+ c.init(params);
+
+ int buerr = c.process();
+ ERR_FAIL_COND_V(buerr != basisu::basis_compressor::cECSuccess, budata);
+
+ const basisu::uint8_vec &buvec = c.get_output_basis_file();
+ budata.resize(buvec.size() + 4);
+
+ {
+ uint8_t *w = budata.ptrw();
+ uint32_t *decf = (uint32_t *)w;
+ *decf = decompress_format;
+ memcpy(w + 4, &buvec[0], buvec.size());
+ }
+ }
+
+ return budata;
+}
+#endif // TOOLS_ENABLED
+
+static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) {
+ Ref<Image> image;
+
+ const uint8_t *r = p_buffer.ptr();
+ const uint8_t *ptr = r;
+ int size = p_buffer.size();
+
+ basist::transcoder_texture_format format = basist::transcoder_texture_format::cTFTotalTextureFormats;
+ Image::Format imgfmt = Image::FORMAT_MAX;
+
+ switch (*(uint32_t *)(ptr)) {
+ case BASIS_DECOMPRESS_RG: {
+
+ if (RS::get_singleton()->has_os_feature("rgtc")) {
+ format = basist::transcoder_texture_format::cTFBC5; // get this from renderer
+ imgfmt = Image::FORMAT_RGTC_RG;
+ } else if (RS::get_singleton()->has_os_feature("etc2")) {
+ //unfortunately, basis universal does not support
+ //
+ ERR_FAIL_V(image); //unimplemented here
+ //format = basist::transcoder_texture_format::cTFETC1; // get this from renderer
+ //imgfmt = Image::FORMAT_RGTC_RG;
+ } else {
+ // FIXME: There wasn't anything here, but then imgformat is used uninitialized.
+ ERR_FAIL_V(image);
+ }
+ } break;
+ case BASIS_DECOMPRESS_RGB: {
+ if (RS::get_singleton()->has_os_feature("bptc")) {
+ format = basist::transcoder_texture_format::cTFBC7_M6_OPAQUE_ONLY; // get this from renderer
+ imgfmt = Image::FORMAT_BPTC_RGBA;
+ } else if (RS::get_singleton()->has_os_feature("s3tc")) {
+ format = basist::transcoder_texture_format::cTFBC1; // get this from renderer
+ imgfmt = Image::FORMAT_DXT1;
+ } else if (RS::get_singleton()->has_os_feature("etc")) {
+
+ format = basist::transcoder_texture_format::cTFETC1; // get this from renderer
+ imgfmt = Image::FORMAT_ETC;
+ } else {
+ format = basist::transcoder_texture_format::cTFBGR565; // get this from renderer
+ imgfmt = Image::FORMAT_RGB565;
+ }
+
+ } break;
+ case BASIS_DECOMPRESS_RGBA: {
+ if (RS::get_singleton()->has_os_feature("bptc")) {
+ format = basist::transcoder_texture_format::cTFBC7_M5; // get this from renderer
+ imgfmt = Image::FORMAT_BPTC_RGBA;
+ } else if (RS::get_singleton()->has_os_feature("s3tc")) {
+ format = basist::transcoder_texture_format::cTFBC3; // get this from renderer
+ imgfmt = Image::FORMAT_DXT5;
+ } else if (RS::get_singleton()->has_os_feature("etc2")) {
+ format = basist::transcoder_texture_format::cTFETC2; // get this from renderer
+ imgfmt = Image::FORMAT_ETC2_RGBA8;
+ } else {
+ //gles2 most likely
+ format = basist::transcoder_texture_format::cTFRGBA4444; // get this from renderer
+ imgfmt = Image::FORMAT_RGBA4444;
+ }
+ } break;
+ case BASIS_DECOMPRESS_RG_AS_RA: {
+ if (RS::get_singleton()->has_os_feature("s3tc")) {
+ format = basist::transcoder_texture_format::cTFBC3; // get this from renderer
+ imgfmt = Image::FORMAT_DXT5_RA_AS_RG;
+ } else if (RS::get_singleton()->has_os_feature("etc2")) {
+ format = basist::transcoder_texture_format::cTFETC2; // get this from renderer
+ imgfmt = Image::FORMAT_ETC2_RGBA8;
+ } else {
+ //gles2 most likely, bad for normalmaps, nothing to do about this.
+ format = basist::transcoder_texture_format::cTFRGBA32;
+ imgfmt = Image::FORMAT_RGBA8;
+ }
+ } break;
+ }
+
+ ptr += 4;
+ size -= 4;
+
+ basist::basisu_transcoder tr(nullptr);
+
+ ERR_FAIL_COND_V(!tr.validate_header(ptr, size), image);
+
+ basist::basisu_image_info info;
+ tr.get_image_info(ptr, size, info, 0);
+
+ int block_size = basist::basis_get_bytes_per_block(format);
+ Vector<uint8_t> gpudata;
+ gpudata.resize(info.m_total_blocks * block_size);
+
+ {
+ uint8_t *w = gpudata.ptrw();
+ uint8_t *dst = w;
+ for (int i = 0; i < gpudata.size(); i++)
+ dst[i] = 0x00;
+
+ int ofs = 0;
+ tr.start_transcoding(ptr, size);
+ for (uint32_t i = 0; i < info.m_total_levels; i++) {
+
+ basist::basisu_image_level_info level;
+ tr.get_image_level_info(ptr, size, level, 0, i);
+
+ bool ret = tr.transcode_image_level(ptr, size, 0, i, dst + ofs, level.m_total_blocks - i, format);
+ if (!ret) {
+ printf("failed! on level %i\n", i);
+ break;
+ };
+
+ ofs += level.m_total_blocks * block_size;
+ };
+ };
+
+ image.instance();
+ image->create(info.m_width, info.m_height, info.m_total_levels > 1, imgfmt, gpudata);
+
+ return image;
+}
+
+void register_basis_universal_types() {
+#ifdef TOOLS_ENABLED
+ sel_codebook = new basist::etc1_global_selector_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb);
+ Image::basis_universal_packer = basis_universal_packer;
+#endif
+ Image::basis_universal_unpacker = basis_universal_unpacker;
+ //ClassDB::register_class<TextureBasisU>();
+}
+
+void unregister_basis_universal_types() {
+
+#ifdef TOOLS_ENABLED
+ delete sel_codebook;
+ Image::basis_universal_packer = nullptr;
+#endif
+ Image::basis_universal_unpacker = nullptr;
+}
diff --git a/modules/recast/register_types.h b/modules/basis_universal/register_types.h
index d16ba37f5e..5053dc27ce 100644
--- a/modules/recast/register_types.h
+++ b/modules/basis_universal/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_recast_types();
-void unregister_recast_types();
+#ifndef BASIS_UNIVERSAL_REGISTER_TYPES_H
+#define BASIS_UNIVERSAL_REGISTER_TYPES_H
+
+void register_basis_universal_types();
+void unregister_basis_universal_types();
+
+#endif // BASIS_UNIVERSAL_REGISTER_TYPES_H
diff --git a/modules/basis_universal/texture_basisu.cpp b/modules/basis_universal/texture_basisu.cpp
new file mode 100644
index 0000000000..2ed0340927
--- /dev/null
+++ b/modules/basis_universal/texture_basisu.cpp
@@ -0,0 +1,233 @@
+/*************************************************************************/
+/* texture_basisu.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "texture_basisu.h"
+#if 0
+#include "core/os/os.h"
+
+#ifdef TOOLS_ENABLED
+#include <basisu_comp.h>
+#endif
+
+#include <transcoder/basisu_transcoder.h>
+
+void TextureBasisU::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_basisu_data", "data"), &TextureBasisU::set_basisu_data);
+ ClassDB::bind_method(D_METHOD("get_basisu_data"), &TextureBasisU::get_data);
+ ClassDB::bind_method(D_METHOD("import"), &TextureBasisU::import);
+
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "basisu_data"), "set_basisu_data", "get_basisu_data");
+
+};
+
+int TextureBasisU::get_width() const {
+
+ return tex_size.x;
+};
+
+int TextureBasisU::get_height() const {
+
+ return tex_size.y;
+};
+
+RID TextureBasisU::get_rid() const {
+
+ return texture;
+};
+
+
+bool TextureBasisU::has_alpha() const {
+
+ return false;
+};
+
+void TextureBasisU::set_flags(uint32_t p_flags) {
+
+ flags = p_flags;
+ RenderingServer::get_singleton()->texture_set_flags(texture, p_flags);
+};
+
+uint32_t TextureBasisU::get_flags() const {
+
+ return flags;
+};
+
+
+void TextureBasisU::set_basisu_data(const Vector<uint8_t>& p_data) {
+
+#ifdef TOOLS_ENABLED
+ data = p_data;
+#endif
+
+ const uint8_t* r = p_data.ptr();
+ const void* ptr = r.ptr();
+ int size = p_data.size();
+
+ basist::transcoder_texture_format format;
+ Image::Format imgfmt;
+
+ if (OS::get_singleton()->has_feature("s3tc")) {
+
+ format = basist::cTFBC3; // get this from renderer
+ imgfmt = Image::FORMAT_DXT5;
+
+ } else if (OS::get_singleton()->has_feature("etc2")) {
+
+ format = basist::cTFETC2;
+ imgfmt = Image::FORMAT_ETC2_RGBA8;
+ };
+
+ basist::basisu_transcoder tr(nullptr);
+
+ ERR_FAIL_COND(!tr.validate_header(ptr, size));
+
+ basist::basisu_image_info info;
+ tr.get_image_info(ptr, size, info, 0);
+ tex_size = Size2(info.m_width, info.m_height);
+
+ int block_size = basist::basis_get_bytes_per_block(format);
+ Vector<uint8_t> gpudata;
+ gpudata.resize(info.m_total_blocks * block_size);
+
+ {
+ uint8_t* w = gpudata.ptrw();
+ uint8_t* dst = w.ptr();
+ for (int i=0; i<gpudata.size(); i++)
+ dst[i] = 0x00;
+
+ int ofs = 0;
+ tr.start_transcoding(ptr, size);
+ for (int i=0; i<info.m_total_levels; i++) {
+
+ basist::basisu_image_level_info level;
+ tr.get_image_level_info(ptr, size, level, 0, i);
+
+ bool ret = tr.transcode_image_level(ptr, size, 0, i, dst + ofs, level.m_total_blocks - i, format);
+ if (!ret) {
+ printf("failed! on level %i\n", i);
+ break;
+ };
+
+ ofs += level.m_total_blocks * block_size;
+ };
+ };
+
+ Ref<Image> img;
+ img.instance();
+ img->create(info.m_width, info.m_height, info.m_total_levels > 1, imgfmt, gpudata);
+
+ RenderingServer::get_singleton()->texture_allocate(texture, tex_size.x, tex_size.y, 0, img->get_format(), RS::TEXTURE_TYPE_2D, flags);
+ RenderingServer::get_singleton()->texture_set_data(texture, img);
+};
+
+Error TextureBasisU::import(const Ref<Image>& p_img) {
+
+#ifdef TOOLS_ENABLED
+
+ Vector<uint8_t> budata;
+
+ {
+ Image::Format format = p_img->get_format();
+ if (format != Image::FORMAT_RGB8 && format != Image::FORMAT_RGBA8) {
+ ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ return ERR_INVALID_PARAMETER;
+ };
+
+ Ref<Image> copy = p_img->duplicate();
+ if (format == Image::FORMAT_RGB8)
+ copy->convert(Image::FORMAT_RGBA8);
+
+ basisu::image buimg(p_img->get_width(), p_img->get_height());
+ int size = p_img->get_width() * p_img->get_height() * 4;
+
+ Vector<uint8_t> vec = copy->get_data();
+ {
+ const uint8_t* r = vec.ptr();
+ memcpy(buimg.get_ptr(), r.ptr(), size);
+ };
+
+ basisu::basis_compressor_params params;
+ params.m_max_endpoint_clusters = 512;
+ params.m_max_selector_clusters = 512;
+ params.m_multithreading = true;
+
+ basisu::job_pool jpool(1);
+ params.m_pJob_pool = &jpool;
+
+ params.m_mip_gen = p_img->get_mipmap_count() > 0;
+ params.m_source_images.push_back(buimg);
+
+ basisu::basis_compressor c;
+ c.init(params);
+
+ int buerr = c.process();
+ if (buerr != basisu::basis_compressor::cECSuccess) {
+ ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ return ERR_INVALID_PARAMETER;
+ };
+
+ const basisu::uint8_vec& buvec = c.get_output_basis_file();
+ budata.resize(buvec.size());
+
+ {
+ uint8_t* w = budata.ptrw();
+ memcpy(w.ptr(), &buvec[0], budata.size());
+ };
+ };
+
+ set_basisu_data(budata);
+
+ return OK;
+#else
+
+ return ERR_UNAVAILABLE;
+#endif
+};
+
+
+Vector<uint8_t> TextureBasisU::get_basisu_data() const {
+
+ return data;
+};
+
+TextureBasisU::TextureBasisU() {
+
+ flags = FLAGS_DEFAULT;
+ texture = RenderingServer::get_singleton()->texture_create();
+};
+
+
+TextureBasisU::~TextureBasisU() {
+
+ RenderingServer::get_singleton()->free(texture);
+};
+
+#endif
diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h
new file mode 100644
index 0000000000..8de151ede0
--- /dev/null
+++ b/modules/basis_universal/texture_basisu.h
@@ -0,0 +1,77 @@
+/*************************************************************************/
+/* texture_basisu.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "scene/resources/texture.h"
+
+#ifdef TOOLS_ENABLED
+#include <basisu_comp.h>
+#endif
+
+#include <transcoder/basisu_transcoder.h>
+
+#if 0
+class TextureBasisU : public Texture {
+
+ GDCLASS(TextureBasisU, Texture);
+ RES_BASE_EXTENSION("butex");
+
+ RID texture;
+ Size2 tex_size;
+
+ uint32_t flags;
+
+ Vector<uint8_t> data;
+
+ static void _bind_methods();
+
+public:
+
+ virtual int get_width() const;
+ virtual int get_height() const;
+ virtual RID get_rid() const;
+ virtual bool has_alpha() const;
+
+ virtual void set_flags(uint32_t p_flags);
+ virtual uint32_t get_flags() const;
+
+
+ Error import(const Ref<Image> &p_img);
+
+ void set_basisu_data(const Vector<uint8_t>& p_data);
+
+ Vector<uint8_t> get_basisu_data() const;
+ String get_img_path() const;
+
+ TextureBasisU();
+ ~TextureBasisU();
+
+};
+
+#endif
diff --git a/modules/bmp/SCsub b/modules/bmp/SCsub
index e7da7cf108..4f3405ff28 100644
--- a/modules/bmp/SCsub
+++ b/modules/bmp/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_bmp = env_modules.Clone()
diff --git a/modules/bmp/config.py b/modules/bmp/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/bmp/config.py
+++ b/modules/bmp/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index 5ce6d59daa..ea2b2b548f 100644
--- a/modules/bmp/image_loader_bmp.cpp
+++ b/modules/bmp/image_loader_bmp.cpp
@@ -38,7 +38,7 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
Error err = OK;
- if (p_buffer == NULL)
+ if (p_buffer == nullptr)
err = FAILED;
if (err == OK) {
@@ -65,7 +65,7 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
}
// Image data (might be indexed)
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
int data_len = 0;
if (bits_per_pixel <= 8) { // indexed
@@ -76,8 +76,8 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
ERR_FAIL_COND_V(data_len == 0, ERR_BUG);
err = data.resize(data_len);
- PoolVector<uint8_t>::Write data_w = data.write();
- uint8_t *write_buffer = data_w.ptr();
+ uint8_t *data_w = data.ptrw();
+ uint8_t *write_buffer = data_w;
const uint32_t width_bytes = width * bits_per_pixel / 8;
const uint32_t line_width = (width_bytes + 3) & ~3;
@@ -151,18 +151,18 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
line -= line_width;
}
- if (p_color_buffer == NULL || color_table_size == 0) { // regular pixels
+ if (p_color_buffer == nullptr || color_table_size == 0) { // regular pixels
p_image->create(width, height, 0, Image::FORMAT_RGBA8, data);
} else { // data is in indexed format, extend it
// Palette data
- PoolVector<uint8_t> palette_data;
+ Vector<uint8_t> palette_data;
palette_data.resize(color_table_size * 4);
- PoolVector<uint8_t>::Write palette_data_w = palette_data.write();
- uint8_t *pal = palette_data_w.ptr();
+ uint8_t *palette_data_w = palette_data.ptrw();
+ uint8_t *pal = palette_data_w;
const uint8_t *cb = p_color_buffer;
@@ -177,11 +177,11 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
cb += 4;
}
// Extend palette to image
- PoolVector<uint8_t> extended_data;
+ Vector<uint8_t> extended_data;
extended_data.resize(data.size() * 4);
- PoolVector<uint8_t>::Write ex_w = extended_data.write();
- uint8_t *dest = ex_w.ptr();
+ uint8_t *ex_w = extended_data.ptrw();
+ uint8_t *dest = ex_w;
const int num_pixels = width * height;
@@ -260,27 +260,27 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f,
ERR_FAIL_COND_V(color_table_size == 0, ERR_BUG);
}
- PoolVector<uint8_t> bmp_color_table;
+ Vector<uint8_t> bmp_color_table;
// Color table is usually 4 bytes per color -> [B][G][R][0]
bmp_color_table.resize(color_table_size * 4);
- PoolVector<uint8_t>::Write bmp_color_table_w = bmp_color_table.write();
- f->get_buffer(bmp_color_table_w.ptr(), color_table_size * 4);
+ uint8_t *bmp_color_table_w = bmp_color_table.ptrw();
+ f->get_buffer(bmp_color_table_w, color_table_size * 4);
f->seek(bmp_header.bmp_file_header.bmp_file_offset);
uint32_t bmp_buffer_size = (bmp_header.bmp_file_header.bmp_file_size -
bmp_header.bmp_file_header.bmp_file_offset);
- PoolVector<uint8_t> bmp_buffer;
+ Vector<uint8_t> bmp_buffer;
err = bmp_buffer.resize(bmp_buffer_size);
if (err == OK) {
- PoolVector<uint8_t>::Write bmp_buffer_w = bmp_buffer.write();
- f->get_buffer(bmp_buffer_w.ptr(), bmp_buffer_size);
+ uint8_t *bmp_buffer_w = bmp_buffer.ptrw();
+ f->get_buffer(bmp_buffer_w, bmp_buffer_size);
- PoolVector<uint8_t>::Read bmp_buffer_r = bmp_buffer.read();
- PoolVector<uint8_t>::Read bmp_color_table_r = bmp_color_table.read();
- err = convert_to_image(p_image, bmp_buffer_r.ptr(),
- bmp_color_table_r.ptr(), color_table_size, bmp_header);
+ const uint8_t *bmp_buffer_r = bmp_buffer.ptr();
+ const uint8_t *bmp_color_table_r = bmp_color_table.ptr();
+ err = convert_to_image(p_image, bmp_buffer_r,
+ bmp_color_table_r, color_table_size, bmp_header);
}
f->close();
}
diff --git a/modules/bmp/register_types.cpp b/modules/bmp/register_types.cpp
index d5cc6c5eb3..6220e956d6 100644
--- a/modules/bmp/register_types.cpp
+++ b/modules/bmp/register_types.cpp
@@ -32,7 +32,7 @@
#include "image_loader_bmp.h"
-static ImageLoaderBMP *image_loader_bmp = NULL;
+static ImageLoaderBMP *image_loader_bmp = nullptr;
void register_bmp_types() {
image_loader_bmp = memnew(ImageLoaderBMP);
diff --git a/modules/bmp/register_types.h b/modules/bmp/register_types.h
index 398716eaa1..e7561dc32d 100644
--- a/modules/bmp/register_types.h
+++ b/modules/bmp/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef BMP_REGISTER_TYPES_H
+#define BMP_REGISTER_TYPES_H
+
void register_bmp_types();
void unregister_bmp_types();
+
+#endif // BMP_REGISTER_TYPES_H
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub
index 02d0a31a69..692c749886 100644
--- a/modules/bullet/SCsub
+++ b/modules/bullet/SCsub
@@ -1,208 +1,203 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_bullet = env_modules.Clone()
# Thirdparty source files
-if env['builtin_bullet']:
+if env["builtin_bullet"]:
# Build only version 2 for now (as of 2.89)
# Sync file list with relevant upstream CMakeLists.txt for each folder.
thirdparty_dir = "#thirdparty/bullet/"
bullet2_src = [
# BulletCollision
- "BulletCollision/BroadphaseCollision/btAxisSweep3.cpp"
- , "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp"
- , "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp"
- , "BulletCollision/BroadphaseCollision/btDbvt.cpp"
- , "BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp"
- , "BulletCollision/BroadphaseCollision/btDispatcher.cpp"
- , "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp"
- , "BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp"
- , "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp"
- , "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp"
- , "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp"
- , "BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp"
- , "BulletCollision/CollisionDispatch/btCollisionObject.cpp"
- , "BulletCollision/CollisionDispatch/btCollisionWorld.cpp"
- , "BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp"
- , "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp"
- , "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btGhostObject.cpp"
- , "BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp"
- , "BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp"
- , "BulletCollision/CollisionDispatch/btManifoldResult.cpp"
- , "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp"
- , "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp"
- , "BulletCollision/CollisionDispatch/btUnionFind.cpp"
- , "BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp"
- , "BulletCollision/CollisionShapes/btBoxShape.cpp"
- , "BulletCollision/CollisionShapes/btBox2dShape.cpp"
- , "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp"
- , "BulletCollision/CollisionShapes/btCapsuleShape.cpp"
- , "BulletCollision/CollisionShapes/btCollisionShape.cpp"
- , "BulletCollision/CollisionShapes/btCompoundShape.cpp"
- , "BulletCollision/CollisionShapes/btConcaveShape.cpp"
- , "BulletCollision/CollisionShapes/btConeShape.cpp"
- , "BulletCollision/CollisionShapes/btConvexHullShape.cpp"
- , "BulletCollision/CollisionShapes/btConvexInternalShape.cpp"
- , "BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp"
- , "BulletCollision/CollisionShapes/btConvexPolyhedron.cpp"
- , "BulletCollision/CollisionShapes/btConvexShape.cpp"
- , "BulletCollision/CollisionShapes/btConvex2dShape.cpp"
- , "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp"
- , "BulletCollision/CollisionShapes/btCylinderShape.cpp"
- , "BulletCollision/CollisionShapes/btEmptyShape.cpp"
- , "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp"
- , "BulletCollision/CollisionShapes/btMiniSDF.cpp"
- , "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp"
- , "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp"
- , "BulletCollision/CollisionShapes/btMultiSphereShape.cpp"
- , "BulletCollision/CollisionShapes/btOptimizedBvh.cpp"
- , "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp"
- , "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp"
- , "BulletCollision/CollisionShapes/btSdfCollisionShape.cpp"
- , "BulletCollision/CollisionShapes/btShapeHull.cpp"
- , "BulletCollision/CollisionShapes/btSphereShape.cpp"
- , "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp"
- , "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp"
- , "BulletCollision/CollisionShapes/btTetrahedronShape.cpp"
- , "BulletCollision/CollisionShapes/btTriangleBuffer.cpp"
- , "BulletCollision/CollisionShapes/btTriangleCallback.cpp"
- , "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp"
- , "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp"
- , "BulletCollision/CollisionShapes/btTriangleMesh.cpp"
- , "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp"
- , "BulletCollision/CollisionShapes/btUniformScalingShape.cpp"
- , "BulletCollision/Gimpact/btContactProcessing.cpp"
- , "BulletCollision/Gimpact/btGenericPoolAllocator.cpp"
- , "BulletCollision/Gimpact/btGImpactBvh.cpp"
- , "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp"
- , "BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp"
- , "BulletCollision/Gimpact/btGImpactShape.cpp"
- , "BulletCollision/Gimpact/btTriangleShapeEx.cpp"
- , "BulletCollision/Gimpact/gim_box_set.cpp"
- , "BulletCollision/Gimpact/gim_contact.cpp"
- , "BulletCollision/Gimpact/gim_memory.cpp"
- , "BulletCollision/Gimpact/gim_tri_collision.cpp"
- , "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp"
- , "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp"
- , "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp"
- , "BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp"
- , "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp"
- , "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp"
- , "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp"
- , "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp"
- , "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp"
- , "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp"
- , "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp"
- , "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp"
-
+ "BulletCollision/BroadphaseCollision/btAxisSweep3.cpp",
+ "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp",
+ "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp",
+ "BulletCollision/BroadphaseCollision/btDbvt.cpp",
+ "BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp",
+ "BulletCollision/BroadphaseCollision/btDispatcher.cpp",
+ "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp",
+ "BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp",
+ "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp",
+ "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp",
+ "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp",
+ "BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp",
+ "BulletCollision/CollisionDispatch/btCollisionObject.cpp",
+ "BulletCollision/CollisionDispatch/btCollisionWorld.cpp",
+ "BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp",
+ "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp",
+ "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btGhostObject.cpp",
+ "BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp",
+ "BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp",
+ "BulletCollision/CollisionDispatch/btManifoldResult.cpp",
+ "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp",
+ "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp",
+ "BulletCollision/CollisionDispatch/btUnionFind.cpp",
+ "BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp",
+ "BulletCollision/CollisionShapes/btBoxShape.cpp",
+ "BulletCollision/CollisionShapes/btBox2dShape.cpp",
+ "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp",
+ "BulletCollision/CollisionShapes/btCapsuleShape.cpp",
+ "BulletCollision/CollisionShapes/btCollisionShape.cpp",
+ "BulletCollision/CollisionShapes/btCompoundShape.cpp",
+ "BulletCollision/CollisionShapes/btConcaveShape.cpp",
+ "BulletCollision/CollisionShapes/btConeShape.cpp",
+ "BulletCollision/CollisionShapes/btConvexHullShape.cpp",
+ "BulletCollision/CollisionShapes/btConvexInternalShape.cpp",
+ "BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp",
+ "BulletCollision/CollisionShapes/btConvexPolyhedron.cpp",
+ "BulletCollision/CollisionShapes/btConvexShape.cpp",
+ "BulletCollision/CollisionShapes/btConvex2dShape.cpp",
+ "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp",
+ "BulletCollision/CollisionShapes/btCylinderShape.cpp",
+ "BulletCollision/CollisionShapes/btEmptyShape.cpp",
+ "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp",
+ "BulletCollision/CollisionShapes/btMiniSDF.cpp",
+ "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp",
+ "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp",
+ "BulletCollision/CollisionShapes/btMultiSphereShape.cpp",
+ "BulletCollision/CollisionShapes/btOptimizedBvh.cpp",
+ "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp",
+ "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp",
+ "BulletCollision/CollisionShapes/btSdfCollisionShape.cpp",
+ "BulletCollision/CollisionShapes/btShapeHull.cpp",
+ "BulletCollision/CollisionShapes/btSphereShape.cpp",
+ "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp",
+ "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp",
+ "BulletCollision/CollisionShapes/btTetrahedronShape.cpp",
+ "BulletCollision/CollisionShapes/btTriangleBuffer.cpp",
+ "BulletCollision/CollisionShapes/btTriangleCallback.cpp",
+ "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp",
+ "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp",
+ "BulletCollision/CollisionShapes/btTriangleMesh.cpp",
+ "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp",
+ "BulletCollision/CollisionShapes/btUniformScalingShape.cpp",
+ "BulletCollision/Gimpact/btContactProcessing.cpp",
+ "BulletCollision/Gimpact/btGenericPoolAllocator.cpp",
+ "BulletCollision/Gimpact/btGImpactBvh.cpp",
+ "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp",
+ "BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp",
+ "BulletCollision/Gimpact/btGImpactShape.cpp",
+ "BulletCollision/Gimpact/btTriangleShapeEx.cpp",
+ "BulletCollision/Gimpact/gim_box_set.cpp",
+ "BulletCollision/Gimpact/gim_contact.cpp",
+ "BulletCollision/Gimpact/gim_memory.cpp",
+ "BulletCollision/Gimpact/gim_tri_collision.cpp",
+ "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp",
+ "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp",
+ "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp",
+ "BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp",
+ "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp",
+ "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp",
+ "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp",
+ "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp",
+ "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp",
+ "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp",
+ "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp",
+ "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp",
# BulletDynamics
- , "BulletDynamics/Character/btKinematicCharacterController.cpp"
- , "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btContactConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btFixedConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btGearConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp"
- , "BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp"
- , "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp"
- , "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp"
- , "BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp"
- , "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp"
- , "BulletDynamics/ConstraintSolver/btSliderConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp"
- , "BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp"
- , "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp"
- , "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp"
- , "BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp"
- , "BulletDynamics/Dynamics/btRigidBody.cpp"
- , "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp"
- #, "BulletDynamics/Dynamics/Bullet-C-API.cpp"
- , "BulletDynamics/Vehicle/btRaycastVehicle.cpp"
- , "BulletDynamics/Vehicle/btWheelInfo.cpp"
- , "BulletDynamics/Featherstone/btMultiBody.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyConstraint.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp"
- , "BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp"
- , "BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp"
- , "BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp"
- , "BulletDynamics/MLCPSolvers/btDantzigLCP.cpp"
- , "BulletDynamics/MLCPSolvers/btMLCPSolver.cpp"
- , "BulletDynamics/MLCPSolvers/btLemkeAlgorithm.cpp"
-
+ "BulletDynamics/Character/btKinematicCharacterController.cpp",
+ "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btContactConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btFixedConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btGearConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp",
+ "BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp",
+ "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp",
+ "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp",
+ "BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp",
+ "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp",
+ "BulletDynamics/ConstraintSolver/btSliderConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp",
+ "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp",
+ "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp",
+ "BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp",
+ "BulletDynamics/Dynamics/btRigidBody.cpp",
+ "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp",
+ # "BulletDynamics/Dynamics/Bullet-C-API.cpp",
+ "BulletDynamics/Vehicle/btRaycastVehicle.cpp",
+ "BulletDynamics/Vehicle/btWheelInfo.cpp",
+ "BulletDynamics/Featherstone/btMultiBody.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyConstraint.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp",
+ "BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp",
+ "BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp",
+ "BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp",
+ "BulletDynamics/MLCPSolvers/btDantzigLCP.cpp",
+ "BulletDynamics/MLCPSolvers/btMLCPSolver.cpp",
+ "BulletDynamics/MLCPSolvers/btLemkeAlgorithm.cpp",
# BulletInverseDynamics
- , "BulletInverseDynamics/IDMath.cpp"
- , "BulletInverseDynamics/MultiBodyTree.cpp"
- , "BulletInverseDynamics/details/MultiBodyTreeInitCache.cpp"
- , "BulletInverseDynamics/details/MultiBodyTreeImpl.cpp"
-
+ "BulletInverseDynamics/IDMath.cpp",
+ "BulletInverseDynamics/MultiBodyTree.cpp",
+ "BulletInverseDynamics/details/MultiBodyTreeInitCache.cpp",
+ "BulletInverseDynamics/details/MultiBodyTreeImpl.cpp",
# BulletSoftBody
- , "BulletSoftBody/btSoftBody.cpp"
- , "BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp"
- , "BulletSoftBody/btSoftBodyHelpers.cpp"
- , "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp"
- , "BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp"
- , "BulletSoftBody/btSoftRigidDynamicsWorld.cpp"
- , "BulletSoftBody/btSoftMultiBodyDynamicsWorld.cpp"
- , "BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp"
- , "BulletSoftBody/btDefaultSoftBodySolver.cpp"
- , "BulletSoftBody/btDeformableBackwardEulerObjective.cpp"
- , "BulletSoftBody/btDeformableBodySolver.cpp"
- , "BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp"
- , "BulletSoftBody/btDeformableContactProjection.cpp"
- , "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp"
- , "BulletSoftBody/btDeformableContactConstraint.cpp"
-
+ "BulletSoftBody/btSoftBody.cpp",
+ "BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp",
+ "BulletSoftBody/btSoftBodyHelpers.cpp",
+ "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp",
+ "BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp",
+ "BulletSoftBody/btSoftRigidDynamicsWorld.cpp",
+ "BulletSoftBody/btSoftMultiBodyDynamicsWorld.cpp",
+ "BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp",
+ "BulletSoftBody/btDefaultSoftBodySolver.cpp",
+ "BulletSoftBody/btDeformableBackwardEulerObjective.cpp",
+ "BulletSoftBody/btDeformableBodySolver.cpp",
+ "BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp",
+ "BulletSoftBody/btDeformableContactProjection.cpp",
+ "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp",
+ "BulletSoftBody/btDeformableContactConstraint.cpp",
# clew
- , "clew/clew.c"
-
+ "clew/clew.c",
# LinearMath
- , "LinearMath/btAlignedAllocator.cpp"
- , "LinearMath/btConvexHull.cpp"
- , "LinearMath/btConvexHullComputer.cpp"
- , "LinearMath/btGeometryUtil.cpp"
- , "LinearMath/btPolarDecomposition.cpp"
- , "LinearMath/btQuickprof.cpp"
- , "LinearMath/btSerializer.cpp"
- , "LinearMath/btSerializer64.cpp"
- , "LinearMath/btThreads.cpp"
- , "LinearMath/btVector3.cpp"
- , "LinearMath/TaskScheduler/btTaskScheduler.cpp"
- , "LinearMath/TaskScheduler/btThreadSupportPosix.cpp"
- , "LinearMath/TaskScheduler/btThreadSupportWin32.cpp"
+ "LinearMath/btAlignedAllocator.cpp",
+ "LinearMath/btConvexHull.cpp",
+ "LinearMath/btConvexHullComputer.cpp",
+ "LinearMath/btGeometryUtil.cpp",
+ "LinearMath/btPolarDecomposition.cpp",
+ "LinearMath/btQuickprof.cpp",
+ "LinearMath/btSerializer.cpp",
+ "LinearMath/btSerializer64.cpp",
+ "LinearMath/btThreads.cpp",
+ "LinearMath/btVector3.cpp",
+ "LinearMath/TaskScheduler/btTaskScheduler.cpp",
+ "LinearMath/TaskScheduler/btThreadSupportPosix.cpp",
+ "LinearMath/TaskScheduler/btThreadSupportWin32.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in bullet2_src]
# Treat Bullet headers as system headers to avoid raising warnings. Not supported on MSVC.
if not env.msvc:
- env_bullet.Append(CPPFLAGS=['-isystem', Dir(thirdparty_dir).path])
+ env_bullet.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path])
else:
env_bullet.Prepend(CPPPATH=[thirdparty_dir])
# if env['target'] == "debug" or env['target'] == "release_debug":
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index 8d03a99556..4d727529ef 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -46,7 +46,7 @@
AreaBullet::AreaBullet() :
RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_AREA),
monitorable(true),
- spOv_mode(PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED),
+ spOv_mode(PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED),
spOv_gravityPoint(false),
spOv_gravityPointDistanceScale(0),
spOv_gravityPointAttenuation(1),
@@ -86,11 +86,11 @@ void AreaBullet::dispatch_callbacks() {
switch (otherObj.state) {
case OVERLAP_STATE_ENTER:
otherObj.state = OVERLAP_STATE_INSIDE;
- call_event(otherObj.object, PhysicsServer::AREA_BODY_ADDED);
+ call_event(otherObj.object, PhysicsServer3D::AREA_BODY_ADDED);
otherObj.object->on_enter_area(this);
break;
case OVERLAP_STATE_EXIT:
- call_event(otherObj.object, PhysicsServer::AREA_BODY_REMOVED);
+ call_event(otherObj.object, PhysicsServer3D::AREA_BODY_REMOVED);
otherObj.object->on_exit_area(this);
overlappingObjects.remove(i); // Remove after callback
break;
@@ -101,13 +101,13 @@ void AreaBullet::dispatch_callbacks() {
}
}
-void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer::AreaBodyStatus p_status) {
+void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status) {
InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_otherObject->getType())];
Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id);
if (!areaGodoObject) {
- event.event_callback_id = 0;
+ event.event_callback_id = ObjectID();
return;
}
@@ -117,7 +117,7 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer:
call_event_res[3] = 0; // other_body_shape ID
call_event_res[4] = 0; // self_shape ID
- Variant::CallError outResp;
+ Callable::CallError outResp;
areaGodoObject->call(event.event_callback_method, (const Variant **)call_event_res_ptr, 5, outResp);
}
@@ -130,7 +130,7 @@ void AreaBullet::scratch() {
void AreaBullet::clear_overlaps(bool p_notify) {
for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
if (p_notify)
- call_event(overlappingObjects[i].object, PhysicsServer::AREA_BODY_REMOVED);
+ call_event(overlappingObjects[i].object, PhysicsServer3D::AREA_BODY_REMOVED);
overlappingObjects[i].object->on_exit_area(this);
}
overlappingObjects.clear();
@@ -140,7 +140,7 @@ void AreaBullet::remove_overlap(CollisionObjectBullet *p_object, bool p_notify)
for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
if (overlappingObjects[i].object == p_object) {
if (p_notify)
- call_event(overlappingObjects[i].object, PhysicsServer::AREA_BODY_REMOVED);
+ call_event(overlappingObjects[i].object, PhysicsServer3D::AREA_BODY_REMOVED);
overlappingObjects[i].object->on_exit_area(this);
overlappingObjects.remove(i);
break;
@@ -218,30 +218,30 @@ void AreaBullet::put_overlap_as_inside(int p_index) {
}
}
-void AreaBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value) {
+void AreaBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) {
switch (p_param) {
- case PhysicsServer::AREA_PARAM_GRAVITY:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY:
set_spOv_gravityMag(p_value);
break;
- case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR:
set_spOv_gravityVec(p_value);
break;
- case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
set_spOv_linearDump(p_value);
break;
- case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
set_spOv_angularDump(p_value);
break;
- case PhysicsServer::AREA_PARAM_PRIORITY:
+ case PhysicsServer3D::AREA_PARAM_PRIORITY:
set_spOv_priority(p_value);
break;
- case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT:
set_spOv_gravityPoint(p_value);
break;
- case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
set_spOv_gravityPointDistanceScale(p_value);
break;
- case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
set_spOv_gravityPointAttenuation(p_value);
break;
default:
@@ -249,23 +249,23 @@ void AreaBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant &
}
}
-Variant AreaBullet::get_param(PhysicsServer::AreaParameter p_param) const {
+Variant AreaBullet::get_param(PhysicsServer3D::AreaParameter p_param) const {
switch (p_param) {
- case PhysicsServer::AREA_PARAM_GRAVITY:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY:
return spOv_gravityMag;
- case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR:
return spOv_gravityVec;
- case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
return spOv_linearDump;
- case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
return spOv_angularDump;
- case PhysicsServer::AREA_PARAM_PRIORITY:
+ case PhysicsServer3D::AREA_PARAM_PRIORITY:
return spOv_priority;
- case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT:
return spOv_gravityPoint;
- case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
return spOv_gravityPointDistanceScale;
- case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
return spOv_gravityPointAttenuation;
default:
WARN_PRINT("Area doesn't support this parameter in the Bullet backend: " + itos(p_param));
@@ -279,7 +279,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co
ev.event_callback_method = p_method;
/// Set if monitoring
- if (eventsCallbacks[0].event_callback_id || eventsCallbacks[1].event_callback_id) {
+ if (eventsCallbacks[0].event_callback_id.is_valid() || eventsCallbacks[1].event_callback_id.is_valid()) {
set_godot_object_flags(get_godot_object_flags() | GOF_IS_MONITORING_AREA);
} else {
set_godot_object_flags(get_godot_object_flags() & (~GOF_IS_MONITORING_AREA));
@@ -287,7 +287,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co
}
bool AreaBullet::has_event_callback(Type p_callbackObjectType) {
- return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id;
+ return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id.is_valid();
}
void AreaBullet::on_enter_area(AreaBullet *p_area) {
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index f770c63bcc..0272350510 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -33,7 +33,7 @@
#include "collision_object_bullet.h"
#include "core/vector.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
#include "space_bullet.h"
/**
@@ -50,8 +50,7 @@ public:
ObjectID event_callback_id;
StringName event_callback_method;
- InOutEventCallback() :
- event_callback_id(0) {}
+ InOutEventCallback() {}
};
enum OverlapState {
@@ -66,7 +65,7 @@ public:
OverlapState state;
OverlappingObjectData() :
- object(NULL),
+ object(nullptr),
state(OVERLAP_STATE_ENTER) {}
OverlappingObjectData(CollisionObjectBullet *p_object, OverlapState p_state) :
object(p_object),
@@ -89,7 +88,7 @@ private:
Vector<OverlappingObjectData> overlappingObjects;
bool monitorable;
- PhysicsServer::AreaSpaceOverrideMode spOv_mode;
+ PhysicsServer3D::AreaSpaceOverrideMode spOv_mode;
bool spOv_gravityPoint;
real_t spOv_gravityPointDistanceScale;
real_t spOv_gravityPointAttenuation;
@@ -115,8 +114,8 @@ public:
bool is_monitoring() const;
- _FORCE_INLINE_ void set_spOv_mode(PhysicsServer::AreaSpaceOverrideMode p_mode) { spOv_mode = p_mode; }
- _FORCE_INLINE_ PhysicsServer::AreaSpaceOverrideMode get_spOv_mode() { return spOv_mode; }
+ _FORCE_INLINE_ void set_spOv_mode(PhysicsServer3D::AreaSpaceOverrideMode p_mode) { spOv_mode = p_mode; }
+ _FORCE_INLINE_ PhysicsServer3D::AreaSpaceOverrideMode get_spOv_mode() { return spOv_mode; }
_FORCE_INLINE_ void set_spOv_gravityPoint(bool p_isGP) { spOv_gravityPoint = p_isGP; }
_FORCE_INLINE_ bool is_spOv_gravityPoint() { return spOv_gravityPoint; }
@@ -147,7 +146,7 @@ public:
virtual void set_space(SpaceBullet *p_space);
virtual void dispatch_callbacks();
- void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer::AreaBodyStatus p_status);
+ void call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status);
void set_on_state_change(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
void scratch();
@@ -163,8 +162,8 @@ public:
void put_overlap_as_exit(int p_index);
void put_overlap_as_inside(int p_index);
- void set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value);
- Variant get_param(PhysicsServer::AreaParameter p_param) const;
+ void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value);
+ Variant get_param(PhysicsServer3D::AreaParameter p_param) const;
void set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method);
bool has_event_callback(Type p_callbackObjectType);
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp
index 4071723a3e..0f54f848dc 100644
--- a/modules/bullet/btRayShape.cpp
+++ b/modules/bullet/btRayShape.cpp
@@ -43,6 +43,7 @@ btRayShape::btRayShape(btScalar length) :
m_shapeAxis(0, 0, 1) {
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE;
setLength(length);
+ slipsOnSlope = false;
}
btRayShape::~btRayShape() {
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index e507987297..2705c749a2 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -74,19 +74,19 @@
body->get_space()->add_constraint(joint, joint->is_disabled_collisions_between_bodies());
// <--------------- Joint creation asserts
-void BulletPhysicsServer::_bind_methods() {
- //ClassDB::bind_method(D_METHOD("DoTest"), &BulletPhysicsServer::DoTest);
+void BulletPhysicsServer3D::_bind_methods() {
+ //ClassDB::bind_method(D_METHOD("DoTest"), &BulletPhysicsServer3D::DoTest);
}
-BulletPhysicsServer::BulletPhysicsServer() :
- PhysicsServer(),
+BulletPhysicsServer3D::BulletPhysicsServer3D() :
+ PhysicsServer3D(),
active(true),
active_spaces_count(0) {}
-BulletPhysicsServer::~BulletPhysicsServer() {}
+BulletPhysicsServer3D::~BulletPhysicsServer3D() {}
-RID BulletPhysicsServer::shape_create(ShapeType p_shape) {
- ShapeBullet *shape = NULL;
+RID BulletPhysicsServer3D::shape_create(ShapeType p_shape) {
+ ShapeBullet *shape = nullptr;
switch (p_shape) {
case SHAPE_PLANE: {
@@ -133,53 +133,53 @@ RID BulletPhysicsServer::shape_create(ShapeType p_shape) {
CreateThenReturnRID(shape_owner, shape)
}
-void BulletPhysicsServer::shape_set_data(RID p_shape, const Variant &p_data) {
- ShapeBullet *shape = shape_owner.get(p_shape);
+void BulletPhysicsServer3D::shape_set_data(RID p_shape, const Variant &p_data) {
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
shape->set_data(p_data);
}
-void BulletPhysicsServer::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {
+void BulletPhysicsServer3D::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {
//WARN_PRINT("Bias not supported by Bullet physics engine");
}
-PhysicsServer::ShapeType BulletPhysicsServer::shape_get_type(RID p_shape) const {
- ShapeBullet *shape = shape_owner.get(p_shape);
- ERR_FAIL_COND_V(!shape, PhysicsServer::SHAPE_CUSTOM);
+PhysicsServer3D::ShapeType BulletPhysicsServer3D::shape_get_type(RID p_shape) const {
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
+ ERR_FAIL_COND_V(!shape, PhysicsServer3D::SHAPE_CUSTOM);
return shape->get_type();
}
-Variant BulletPhysicsServer::shape_get_data(RID p_shape) const {
- ShapeBullet *shape = shape_owner.get(p_shape);
+Variant BulletPhysicsServer3D::shape_get_data(RID p_shape) const {
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, Variant());
return shape->get_data();
}
-void BulletPhysicsServer::shape_set_margin(RID p_shape, real_t p_margin) {
- ShapeBullet *shape = shape_owner.get(p_shape);
+void BulletPhysicsServer3D::shape_set_margin(RID p_shape, real_t p_margin) {
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
shape->set_margin(p_margin);
}
-real_t BulletPhysicsServer::shape_get_margin(RID p_shape) const {
- ShapeBullet *shape = shape_owner.get(p_shape);
+real_t BulletPhysicsServer3D::shape_get_margin(RID p_shape) const {
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0.0);
return shape->get_margin();
}
-real_t BulletPhysicsServer::shape_get_custom_solver_bias(RID p_shape) const {
+real_t BulletPhysicsServer3D::shape_get_custom_solver_bias(RID p_shape) const {
//WARN_PRINT("Bias not supported by Bullet physics engine");
return 0.;
}
-RID BulletPhysicsServer::space_create() {
+RID BulletPhysicsServer3D::space_create() {
SpaceBullet *space = bulletnew(SpaceBullet);
CreateThenReturnRID(space_owner, space);
}
-void BulletPhysicsServer::space_set_active(RID p_space, bool p_active) {
+void BulletPhysicsServer3D::space_set_active(RID p_space, bool p_active) {
- SpaceBullet *space = space_owner.get(p_space);
+ SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
if (space_is_active(p_space) == p_active) {
@@ -195,262 +195,262 @@ void BulletPhysicsServer::space_set_active(RID p_space, bool p_active) {
}
}
-bool BulletPhysicsServer::space_is_active(RID p_space) const {
- SpaceBullet *space = space_owner.get(p_space);
+bool BulletPhysicsServer3D::space_is_active(RID p_space) const {
+ SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, false);
return -1 != active_spaces.find(space);
}
-void BulletPhysicsServer::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) {
- SpaceBullet *space = space_owner.get(p_space);
+void BulletPhysicsServer3D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) {
+ SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
space->set_param(p_param, p_value);
}
-real_t BulletPhysicsServer::space_get_param(RID p_space, SpaceParameter p_param) const {
- SpaceBullet *space = space_owner.get(p_space);
+real_t BulletPhysicsServer3D::space_get_param(RID p_space, SpaceParameter p_param) const {
+ SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, 0);
return space->get_param(p_param);
}
-PhysicsDirectSpaceState *BulletPhysicsServer::space_get_direct_state(RID p_space) {
- SpaceBullet *space = space_owner.get(p_space);
- ERR_FAIL_COND_V(!space, NULL);
+PhysicsDirectSpaceState3D *BulletPhysicsServer3D::space_get_direct_state(RID p_space) {
+ SpaceBullet *space = space_owner.getornull(p_space);
+ ERR_FAIL_COND_V(!space, nullptr);
return space->get_direct_state();
}
-void BulletPhysicsServer::space_set_debug_contacts(RID p_space, int p_max_contacts) {
- SpaceBullet *space = space_owner.get(p_space);
+void BulletPhysicsServer3D::space_set_debug_contacts(RID p_space, int p_max_contacts) {
+ SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
space->set_debug_contacts(p_max_contacts);
}
-Vector<Vector3> BulletPhysicsServer::space_get_contacts(RID p_space) const {
- SpaceBullet *space = space_owner.get(p_space);
+Vector<Vector3> BulletPhysicsServer3D::space_get_contacts(RID p_space) const {
+ SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, Vector<Vector3>());
return space->get_debug_contacts();
}
-int BulletPhysicsServer::space_get_contact_count(RID p_space) const {
- SpaceBullet *space = space_owner.get(p_space);
+int BulletPhysicsServer3D::space_get_contact_count(RID p_space) const {
+ SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, 0);
return space->get_debug_contact_count();
}
-RID BulletPhysicsServer::area_create() {
+RID BulletPhysicsServer3D::area_create() {
AreaBullet *area = bulletnew(AreaBullet);
area->set_collision_layer(1);
area->set_collision_mask(1);
CreateThenReturnRID(area_owner, area)
}
-void BulletPhysicsServer::area_set_space(RID p_area, RID p_space) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_space(RID p_area, RID p_space) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- SpaceBullet *space = NULL;
+ SpaceBullet *space = nullptr;
if (p_space.is_valid()) {
- space = space_owner.get(p_space);
+ space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
}
area->set_space(space);
}
-RID BulletPhysicsServer::area_get_space(RID p_area) const {
- AreaBullet *area = area_owner.get(p_area);
+RID BulletPhysicsServer3D::area_get_space(RID p_area) const {
+ AreaBullet *area = area_owner.getornull(p_area);
return area->get_space()->get_self();
}
-void BulletPhysicsServer::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_spOv_mode(p_mode);
}
-PhysicsServer::AreaSpaceOverrideMode BulletPhysicsServer::area_get_space_override_mode(RID p_area) const {
- AreaBullet *area = area_owner.get(p_area);
- ERR_FAIL_COND_V(!area, PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED);
+PhysicsServer3D::AreaSpaceOverrideMode BulletPhysicsServer3D::area_get_space_override_mode(RID p_area) const {
+ AreaBullet *area = area_owner.getornull(p_area);
+ ERR_FAIL_COND_V(!area, PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED);
return area->get_spOv_mode();
}
-void BulletPhysicsServer::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- ShapeBullet *shape = shape_owner.get(p_shape);
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
area->add_shape(shape, p_transform, p_disabled);
}
-void BulletPhysicsServer::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- ShapeBullet *shape = shape_owner.get(p_shape);
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
area->set_shape(p_shape_idx, shape);
}
-void BulletPhysicsServer::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_shape_transform(p_shape_idx, p_transform);
}
-int BulletPhysicsServer::area_get_shape_count(RID p_area) const {
- AreaBullet *area = area_owner.get(p_area);
+int BulletPhysicsServer3D::area_get_shape_count(RID p_area) const {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, 0);
return area->get_shape_count();
}
-RID BulletPhysicsServer::area_get_shape(RID p_area, int p_shape_idx) const {
- AreaBullet *area = area_owner.get(p_area);
+RID BulletPhysicsServer3D::area_get_shape(RID p_area, int p_shape_idx) const {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, RID());
return area->get_shape(p_shape_idx)->get_self();
}
-Transform BulletPhysicsServer::area_get_shape_transform(RID p_area, int p_shape_idx) const {
- AreaBullet *area = area_owner.get(p_area);
+Transform BulletPhysicsServer3D::area_get_shape_transform(RID p_area, int p_shape_idx) const {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, Transform());
return area->get_shape_transform(p_shape_idx);
}
-void BulletPhysicsServer::area_remove_shape(RID p_area, int p_shape_idx) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_remove_shape(RID p_area, int p_shape_idx) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
return area->remove_shape_full(p_shape_idx);
}
-void BulletPhysicsServer::area_clear_shapes(RID p_area) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_clear_shapes(RID p_area) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
for (int i = area->get_shape_count(); 0 < i; --i)
area->remove_shape_full(0);
}
-void BulletPhysicsServer::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_shape_disabled(p_shape_idx, p_disabled);
}
-void BulletPhysicsServer::area_attach_object_instance_id(RID p_area, ObjectID p_id) {
+void BulletPhysicsServer3D::area_attach_object_instance_id(RID p_area, ObjectID p_id) {
if (space_owner.owns(p_area)) {
return;
}
- AreaBullet *area = area_owner.get(p_area);
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_instance_id(p_id);
}
-ObjectID BulletPhysicsServer::area_get_object_instance_id(RID p_area) const {
+ObjectID BulletPhysicsServer3D::area_get_object_instance_id(RID p_area) const {
if (space_owner.owns(p_area)) {
- return 0;
+ return ObjectID();
}
- AreaBullet *area = area_owner.get(p_area);
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, ObjectID());
return area->get_instance_id();
}
-void BulletPhysicsServer::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {
+void BulletPhysicsServer3D::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {
if (space_owner.owns(p_area)) {
- SpaceBullet *space = space_owner.get(p_area);
+ SpaceBullet *space = space_owner.getornull(p_area);
if (space) {
space->set_param(p_param, p_value);
}
} else {
- AreaBullet *area = area_owner.get(p_area);
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_param(p_param, p_value);
}
}
-Variant BulletPhysicsServer::area_get_param(RID p_area, AreaParameter p_param) const {
+Variant BulletPhysicsServer3D::area_get_param(RID p_area, AreaParameter p_param) const {
if (space_owner.owns(p_area)) {
- SpaceBullet *space = space_owner.get(p_area);
+ SpaceBullet *space = space_owner.getornull(p_area);
return space->get_param(p_param);
} else {
- AreaBullet *area = area_owner.get(p_area);
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, Variant());
return area->get_param(p_param);
}
}
-void BulletPhysicsServer::area_set_transform(RID p_area, const Transform &p_transform) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_transform(RID p_area, const Transform &p_transform) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_transform(p_transform);
}
-Transform BulletPhysicsServer::area_get_transform(RID p_area) const {
- AreaBullet *area = area_owner.get(p_area);
+Transform BulletPhysicsServer3D::area_get_transform(RID p_area) const {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, Transform());
return area->get_transform();
}
-void BulletPhysicsServer::area_set_collision_mask(RID p_area, uint32_t p_mask) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_collision_mask(p_mask);
}
-void BulletPhysicsServer::area_set_collision_layer(RID p_area, uint32_t p_layer) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_collision_layer(RID p_area, uint32_t p_layer) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_collision_layer(p_layer);
}
-void BulletPhysicsServer::area_set_monitorable(RID p_area, bool p_monitorable) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_monitorable(p_monitorable);
}
-void BulletPhysicsServer::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
-void BulletPhysicsServer::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
-void BulletPhysicsServer::area_set_ray_pickable(RID p_area, bool p_enable) {
- AreaBullet *area = area_owner.get(p_area);
+void BulletPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_ray_pickable(p_enable);
}
-bool BulletPhysicsServer::area_is_ray_pickable(RID p_area) const {
- AreaBullet *area = area_owner.get(p_area);
+bool BulletPhysicsServer3D::area_is_ray_pickable(RID p_area) const {
+ AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, false);
return area->is_ray_pickable();
}
-RID BulletPhysicsServer::body_create(BodyMode p_mode, bool p_init_sleeping) {
+RID BulletPhysicsServer3D::body_create(BodyMode p_mode, bool p_init_sleeping) {
RigidBodyBullet *body = bulletnew(RigidBodyBullet);
body->set_mode(p_mode);
body->set_collision_layer(1);
@@ -460,13 +460,13 @@ RID BulletPhysicsServer::body_create(BodyMode p_mode, bool p_init_sleeping) {
CreateThenReturnRID(rigid_body_owner, body);
}
-void BulletPhysicsServer::body_set_space(RID p_body, RID p_space) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_space(RID p_body, RID p_space) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- SpaceBullet *space = NULL;
+ SpaceBullet *space = nullptr;
if (p_space.is_valid()) {
- space = space_owner.get(p_space);
+ space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
}
@@ -476,8 +476,8 @@ void BulletPhysicsServer::body_set_space(RID p_body, RID p_space) {
body->set_space(space);
}
-RID BulletPhysicsServer::body_get_space(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+RID BulletPhysicsServer3D::body_get_space(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, RID());
SpaceBullet *space = body->get_space();
@@ -486,54 +486,54 @@ RID BulletPhysicsServer::body_get_space(RID p_body) const {
return space->get_self();
}
-void BulletPhysicsServer::body_set_mode(RID p_body, PhysicsServer::BodyMode p_mode) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_mode(RID p_body, PhysicsServer3D::BodyMode p_mode) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_mode(p_mode);
}
-PhysicsServer::BodyMode BulletPhysicsServer::body_get_mode(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+PhysicsServer3D::BodyMode BulletPhysicsServer3D::body_get_mode(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, BODY_MODE_STATIC);
return body->get_mode();
}
-void BulletPhysicsServer::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) {
+void BulletPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- ShapeBullet *shape = shape_owner.get(p_shape);
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
body->add_shape(shape, p_transform, p_disabled);
}
-void BulletPhysicsServer::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- ShapeBullet *shape = shape_owner.get(p_shape);
+ ShapeBullet *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
body->set_shape(p_shape_idx, shape);
}
-void BulletPhysicsServer::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_shape_transform(p_shape_idx, p_transform);
}
-int BulletPhysicsServer::body_get_shape_count(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+int BulletPhysicsServer3D::body_get_shape_count(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_shape_count();
}
-RID BulletPhysicsServer::body_get_shape(RID p_body, int p_shape_idx) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+RID BulletPhysicsServer3D::body_get_shape(RID p_body, int p_shape_idx) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, RID());
ShapeBullet *shape = body->get_shape(p_shape_idx);
@@ -542,114 +542,114 @@ RID BulletPhysicsServer::body_get_shape(RID p_body, int p_shape_idx) const {
return shape->get_self();
}
-Transform BulletPhysicsServer::body_get_shape_transform(RID p_body, int p_shape_idx) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+Transform BulletPhysicsServer3D::body_get_shape_transform(RID p_body, int p_shape_idx) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Transform());
return body->get_shape_transform(p_shape_idx);
}
-void BulletPhysicsServer::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_shape_disabled(p_shape_idx, p_disabled);
}
-void BulletPhysicsServer::body_remove_shape(RID p_body, int p_shape_idx) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_remove_shape(RID p_body, int p_shape_idx) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->remove_shape_full(p_shape_idx);
}
-void BulletPhysicsServer::body_clear_shapes(RID p_body) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_clear_shapes(RID p_body) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->remove_all_shapes();
}
-void BulletPhysicsServer::body_attach_object_instance_id(RID p_body, uint32_t p_id) {
+void BulletPhysicsServer3D::body_attach_object_instance_id(RID p_body, ObjectID p_id) {
CollisionObjectBullet *body = get_collisin_object(p_body);
ERR_FAIL_COND(!body);
body->set_instance_id(p_id);
}
-uint32_t BulletPhysicsServer::body_get_object_instance_id(RID p_body) const {
+ObjectID BulletPhysicsServer3D::body_get_object_instance_id(RID p_body) const {
CollisionObjectBullet *body = get_collisin_object(p_body);
- ERR_FAIL_COND_V(!body, 0);
+ ERR_FAIL_COND_V(!body, ObjectID());
return body->get_instance_id();
}
-void BulletPhysicsServer::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_continuous_collision_detection(p_enable);
}
-bool BulletPhysicsServer::body_is_continuous_collision_detection_enabled(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+bool BulletPhysicsServer3D::body_is_continuous_collision_detection_enabled(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
return body->is_continuous_collision_detection_enabled();
}
-void BulletPhysicsServer::body_set_collision_layer(RID p_body, uint32_t p_layer) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_collision_layer(RID p_body, uint32_t p_layer) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_collision_layer(p_layer);
}
-uint32_t BulletPhysicsServer::body_get_collision_layer(RID p_body) const {
- const RigidBodyBullet *body = rigid_body_owner.get(p_body);
+uint32_t BulletPhysicsServer3D::body_get_collision_layer(RID p_body) const {
+ const RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_collision_layer();
}
-void BulletPhysicsServer::body_set_collision_mask(RID p_body, uint32_t p_mask) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_collision_mask(RID p_body, uint32_t p_mask) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_collision_mask(p_mask);
}
-uint32_t BulletPhysicsServer::body_get_collision_mask(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+uint32_t BulletPhysicsServer3D::body_get_collision_mask(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_collision_mask();
}
-void BulletPhysicsServer::body_set_user_flags(RID p_body, uint32_t p_flags) {
+void BulletPhysicsServer3D::body_set_user_flags(RID p_body, uint32_t p_flags) {
// This function si not currently supported
}
-uint32_t BulletPhysicsServer::body_get_user_flags(RID p_body) const {
+uint32_t BulletPhysicsServer3D::body_get_user_flags(RID p_body) const {
// This function si not currently supported
return 0;
}
-void BulletPhysicsServer::body_set_param(RID p_body, BodyParameter p_param, float p_value) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, float p_value) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_param(p_param, p_value);
}
-float BulletPhysicsServer::body_get_param(RID p_body, BodyParameter p_param) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+float BulletPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_param(p_param);
}
-void BulletPhysicsServer::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
if (body->get_kinematic_utilities()) {
@@ -658,8 +658,8 @@ void BulletPhysicsServer::body_set_kinematic_safe_margin(RID p_body, real_t p_ma
}
}
-real_t BulletPhysicsServer::body_get_kinematic_safe_margin(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::body_get_kinematic_safe_margin(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
if (body->get_kinematic_utilities()) {
@@ -670,91 +670,91 @@ real_t BulletPhysicsServer::body_get_kinematic_safe_margin(RID p_body) const {
return 0;
}
-void BulletPhysicsServer::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_state(p_state, p_variant);
}
-Variant BulletPhysicsServer::body_get_state(RID p_body, BodyState p_state) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+Variant BulletPhysicsServer3D::body_get_state(RID p_body, BodyState p_state) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Variant());
return body->get_state(p_state);
}
-void BulletPhysicsServer::body_set_applied_force(RID p_body, const Vector3 &p_force) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_applied_force(RID p_body, const Vector3 &p_force) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_applied_force(p_force);
}
-Vector3 BulletPhysicsServer::body_get_applied_force(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+Vector3 BulletPhysicsServer3D::body_get_applied_force(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Vector3());
return body->get_applied_force();
}
-void BulletPhysicsServer::body_set_applied_torque(RID p_body, const Vector3 &p_torque) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_applied_torque(RID p_body, const Vector3 &p_torque) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_applied_torque(p_torque);
}
-Vector3 BulletPhysicsServer::body_get_applied_torque(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+Vector3 BulletPhysicsServer3D::body_get_applied_torque(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Vector3());
return body->get_applied_torque();
}
-void BulletPhysicsServer::body_add_central_force(RID p_body, const Vector3 &p_force) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_add_central_force(RID p_body, const Vector3 &p_force) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->apply_central_force(p_force);
}
-void BulletPhysicsServer::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->apply_force(p_force, p_pos);
}
-void BulletPhysicsServer::body_add_torque(RID p_body, const Vector3 &p_torque) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_add_torque(RID p_body, const Vector3 &p_torque) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->apply_torque(p_torque);
}
-void BulletPhysicsServer::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->apply_central_impulse(p_impulse);
}
-void BulletPhysicsServer::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->apply_impulse(p_pos, p_impulse);
}
-void BulletPhysicsServer::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->apply_torque_impulse(p_impulse);
}
-void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
Vector3 v = body->get_linear_velocity();
@@ -764,124 +764,124 @@ void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_ax
body->set_linear_velocity(v);
}
-void BulletPhysicsServer::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_axis_lock(p_axis, p_lock);
}
-bool BulletPhysicsServer::body_is_axis_locked(RID p_body, BodyAxis p_axis) const {
- const RigidBodyBullet *body = rigid_body_owner.get(p_body);
+bool BulletPhysicsServer3D::body_is_axis_locked(RID p_body, BodyAxis p_axis) const {
+ const RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->is_axis_locked(p_axis);
}
-void BulletPhysicsServer::body_add_collision_exception(RID p_body, RID p_body_b) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_add_collision_exception(RID p_body, RID p_body_b) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- RigidBodyBullet *other_body = rigid_body_owner.get(p_body_b);
+ RigidBodyBullet *other_body = rigid_body_owner.getornull(p_body_b);
ERR_FAIL_COND(!other_body);
body->add_collision_exception(other_body);
}
-void BulletPhysicsServer::body_remove_collision_exception(RID p_body, RID p_body_b) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_remove_collision_exception(RID p_body, RID p_body_b) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- RigidBodyBullet *other_body = rigid_body_owner.get(p_body_b);
+ RigidBodyBullet *other_body = rigid_body_owner.getornull(p_body_b);
ERR_FAIL_COND(!other_body);
body->remove_collision_exception(other_body);
}
-void BulletPhysicsServer::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
for (int i = 0; i < body->get_exceptions().size(); i++) {
p_exceptions->push_back(body->get_exceptions()[i]);
}
}
-void BulletPhysicsServer::body_set_max_contacts_reported(RID p_body, int p_contacts) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_max_contacts_reported(RID p_body, int p_contacts) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_max_collisions_detection(p_contacts);
}
-int BulletPhysicsServer::body_get_max_contacts_reported(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+int BulletPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_max_collisions_detection();
}
-void BulletPhysicsServer::body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) {
+void BulletPhysicsServer3D::body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) {
// Not supported by bullet and even Godot
}
-float BulletPhysicsServer::body_get_contacts_reported_depth_threshold(RID p_body) const {
+float BulletPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_body) const {
// Not supported by bullet and even Godot
return 0.;
}
-void BulletPhysicsServer::body_set_omit_force_integration(RID p_body, bool p_omit) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_omit_force_integration(RID p_body, bool p_omit) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_omit_forces_integration(p_omit);
}
-bool BulletPhysicsServer::body_is_omitting_force_integration(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+bool BulletPhysicsServer3D::body_is_omitting_force_integration(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
return body->get_omit_forces_integration();
}
-void BulletPhysicsServer::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata);
+ body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata);
}
-void BulletPhysicsServer::body_set_ray_pickable(RID p_body, bool p_enable) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+void BulletPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_ray_pickable(p_enable);
}
-bool BulletPhysicsServer::body_is_ray_pickable(RID p_body) const {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+bool BulletPhysicsServer3D::body_is_ray_pickable(RID p_body) const {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
return body->is_ray_pickable();
}
-PhysicsDirectBodyState *BulletPhysicsServer::body_get_direct_state(RID p_body) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, NULL);
- return BulletPhysicsDirectBodyState::get_singleton(body);
+PhysicsDirectBodyState3D *BulletPhysicsServer3D::body_get_direct_state(RID p_body) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
+ ERR_FAIL_COND_V(!body, nullptr);
+ return BulletPhysicsDirectBodyState3D::get_singleton(body);
}
-bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, r_result, p_exclude_raycast_shapes);
}
-int BulletPhysicsServer::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
- RigidBodyBullet *body = rigid_body_owner.get(p_body);
+int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
ERR_FAIL_COND_V(!body->get_space(), 0);
return body->get_space()->test_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
}
-RID BulletPhysicsServer::soft_body_create(bool p_init_sleeping) {
+RID BulletPhysicsServer3D::soft_body_create(bool p_init_sleeping) {
SoftBodyBullet *body = bulletnew(SoftBodyBullet);
body->set_collision_layer(1);
body->set_collision_mask(1);
@@ -890,20 +890,20 @@ RID BulletPhysicsServer::soft_body_create(bool p_init_sleeping) {
CreateThenReturnRID(soft_body_owner, body);
}
-void BulletPhysicsServer::soft_body_update_visual_server(RID p_body, class SoftBodyVisualServerHandler *p_visual_server_handler) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- body->update_visual_server(p_visual_server_handler);
+ body->update_rendering_server(p_rendering_server_handler);
}
-void BulletPhysicsServer::soft_body_set_space(RID p_body, RID p_space) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- SpaceBullet *space = NULL;
+ SpaceBullet *space = nullptr;
if (p_space.is_valid()) {
- space = space_owner.get(p_space);
+ space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
}
@@ -913,8 +913,8 @@ void BulletPhysicsServer::soft_body_set_space(RID p_body, RID p_space) {
body->set_space(space);
}
-RID BulletPhysicsServer::soft_body_get_space(RID p_body) const {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+RID BulletPhysicsServer3D::soft_body_get_space(RID p_body) const {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, RID());
SpaceBullet *space = body->get_space();
@@ -923,95 +923,95 @@ RID BulletPhysicsServer::soft_body_get_space(RID p_body) const {
return space->get_self();
}
-void BulletPhysicsServer::soft_body_set_mesh(RID p_body, const REF &p_mesh) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_mesh(RID p_body, const REF &p_mesh) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_soft_mesh(p_mesh);
}
-void BulletPhysicsServer::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_collision_layer(p_layer);
}
-uint32_t BulletPhysicsServer::soft_body_get_collision_layer(RID p_body) const {
- const SoftBodyBullet *body = soft_body_owner.get(p_body);
+uint32_t BulletPhysicsServer3D::soft_body_get_collision_layer(RID p_body) const {
+ const SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_collision_layer();
}
-void BulletPhysicsServer::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_collision_mask(p_mask);
}
-uint32_t BulletPhysicsServer::soft_body_get_collision_mask(RID p_body) const {
- const SoftBodyBullet *body = soft_body_owner.get(p_body);
+uint32_t BulletPhysicsServer3D::soft_body_get_collision_mask(RID p_body) const {
+ const SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_collision_mask();
}
-void BulletPhysicsServer::soft_body_add_collision_exception(RID p_body, RID p_body_b) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_add_collision_exception(RID p_body, RID p_body_b) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- CollisionObjectBullet *other_body = rigid_body_owner.get(p_body_b);
+ CollisionObjectBullet *other_body = rigid_body_owner.getornull(p_body_b);
if (!other_body) {
- other_body = soft_body_owner.get(p_body_b);
+ other_body = soft_body_owner.getornull(p_body_b);
}
ERR_FAIL_COND(!other_body);
body->add_collision_exception(other_body);
}
-void BulletPhysicsServer::soft_body_remove_collision_exception(RID p_body, RID p_body_b) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_remove_collision_exception(RID p_body, RID p_body_b) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- CollisionObjectBullet *other_body = rigid_body_owner.get(p_body_b);
+ CollisionObjectBullet *other_body = rigid_body_owner.getornull(p_body_b);
if (!other_body) {
- other_body = soft_body_owner.get(p_body_b);
+ other_body = soft_body_owner.getornull(p_body_b);
}
ERR_FAIL_COND(!other_body);
body->remove_collision_exception(other_body);
}
-void BulletPhysicsServer::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
for (int i = 0; i < body->get_exceptions().size(); i++) {
p_exceptions->push_back(body->get_exceptions()[i]);
}
}
-void BulletPhysicsServer::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
+void BulletPhysicsServer3D::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
// FIXME: Must be implemented.
WARN_PRINT("soft_body_state is not implemented yet in Bullet backend.");
}
-Variant BulletPhysicsServer::soft_body_get_state(RID p_body, BodyState p_state) const {
+Variant BulletPhysicsServer3D::soft_body_get_state(RID p_body, BodyState p_state) const {
// FIXME: Must be implemented.
WARN_PRINT("soft_body_state is not implemented yet in Bullet backend.");
return Variant();
}
-void BulletPhysicsServer::soft_body_set_transform(RID p_body, const Transform &p_transform) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform &p_transform) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_soft_transform(p_transform);
}
-Vector3 BulletPhysicsServer::soft_body_get_vertex_position(RID p_body, int vertex_index) const {
- const SoftBodyBullet *body = soft_body_owner.get(p_body);
+Vector3 BulletPhysicsServer3D::soft_body_get_vertex_position(RID p_body, int vertex_index) const {
+ const SoftBodyBullet *body = soft_body_owner.getornull(p_body);
Vector3 pos;
ERR_FAIL_COND_V(!body, pos);
@@ -1019,204 +1019,204 @@ Vector3 BulletPhysicsServer::soft_body_get_vertex_position(RID p_body, int verte
return pos;
}
-void BulletPhysicsServer::soft_body_set_ray_pickable(RID p_body, bool p_enable) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_ray_pickable(RID p_body, bool p_enable) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_ray_pickable(p_enable);
}
-bool BulletPhysicsServer::soft_body_is_ray_pickable(RID p_body) const {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+bool BulletPhysicsServer3D::soft_body_is_ray_pickable(RID p_body) const {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
return body->is_ray_pickable();
}
-void BulletPhysicsServer::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_simulation_precision(p_simulation_precision);
}
-int BulletPhysicsServer::soft_body_get_simulation_precision(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+int BulletPhysicsServer3D::soft_body_get_simulation_precision(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_simulation_precision();
}
-void BulletPhysicsServer::soft_body_set_total_mass(RID p_body, real_t p_total_mass) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_total_mass(RID p_body, real_t p_total_mass) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_total_mass(p_total_mass);
}
-real_t BulletPhysicsServer::soft_body_get_total_mass(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_total_mass(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_total_mass();
}
-void BulletPhysicsServer::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_linear_stiffness(p_stiffness);
}
-real_t BulletPhysicsServer::soft_body_get_linear_stiffness(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_linear_stiffness();
}
-void BulletPhysicsServer::soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_areaAngular_stiffness(p_stiffness);
}
-real_t BulletPhysicsServer::soft_body_get_areaAngular_stiffness(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_areaAngular_stiffness(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_areaAngular_stiffness();
}
-void BulletPhysicsServer::soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_volume_stiffness(p_stiffness);
}
-real_t BulletPhysicsServer::soft_body_get_volume_stiffness(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_volume_stiffness(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_volume_stiffness();
}
-void BulletPhysicsServer::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_pressure_coefficient(p_pressure_coefficient);
}
-real_t BulletPhysicsServer::soft_body_get_pressure_coefficient(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_pressure_coefficient(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_pressure_coefficient();
}
-void BulletPhysicsServer::soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
return body->set_pose_matching_coefficient(p_pose_matching_coefficient);
}
-real_t BulletPhysicsServer::soft_body_get_pose_matching_coefficient(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_pose_matching_coefficient(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_pose_matching_coefficient();
}
-void BulletPhysicsServer::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_damping_coefficient(p_damping_coefficient);
}
-real_t BulletPhysicsServer::soft_body_get_damping_coefficient(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_damping_coefficient(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_damping_coefficient();
}
-void BulletPhysicsServer::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_drag_coefficient(p_drag_coefficient);
}
-real_t BulletPhysicsServer::soft_body_get_drag_coefficient(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+real_t BulletPhysicsServer3D::soft_body_get_drag_coefficient(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_drag_coefficient();
}
-void BulletPhysicsServer::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_node_position(p_point_index, p_global_position);
}
-Vector3 BulletPhysicsServer::soft_body_get_point_global_position(RID p_body, int p_point_index) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+Vector3 BulletPhysicsServer3D::soft_body_get_point_global_position(RID p_body, int p_point_index) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Vector3(0., 0., 0.));
Vector3 pos;
body->get_node_position(p_point_index, pos);
return pos;
}
-Vector3 BulletPhysicsServer::soft_body_get_point_offset(RID p_body, int p_point_index) const {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+Vector3 BulletPhysicsServer3D::soft_body_get_point_offset(RID p_body, int p_point_index) const {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Vector3());
Vector3 res;
body->get_node_offset(p_point_index, res);
return res;
}
-void BulletPhysicsServer::soft_body_remove_all_pinned_points(RID p_body) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_remove_all_pinned_points(RID p_body) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->reset_all_node_mass();
}
-void BulletPhysicsServer::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+void BulletPhysicsServer3D::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_node_mass(p_point_index, p_pin ? 0 : 1);
}
-bool BulletPhysicsServer::soft_body_is_point_pinned(RID p_body, int p_point_index) {
- SoftBodyBullet *body = soft_body_owner.get(p_body);
+bool BulletPhysicsServer3D::soft_body_is_point_pinned(RID p_body, int p_point_index) {
+ SoftBodyBullet *body = soft_body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0.f);
return body->get_node_mass(p_point_index);
}
-PhysicsServer::JointType BulletPhysicsServer::joint_get_type(RID p_joint) const {
- JointBullet *joint = joint_owner.get(p_joint);
+PhysicsServer3D::JointType BulletPhysicsServer3D::joint_get_type(RID p_joint) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, JOINT_PIN);
return joint->get_type();
}
-void BulletPhysicsServer::joint_set_solver_priority(RID p_joint, int p_priority) {
+void BulletPhysicsServer3D::joint_set_solver_priority(RID p_joint, int p_priority) {
// Joint priority not supported by bullet
}
-int BulletPhysicsServer::joint_get_solver_priority(RID p_joint) const {
+int BulletPhysicsServer3D::joint_get_solver_priority(RID p_joint) const {
// Joint priority not supported by bullet
return 0;
}
-void BulletPhysicsServer::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
joint->disable_collisions_between_bodies(p_disable);
}
-bool BulletPhysicsServer::joint_is_disabled_collisions_between_bodies(RID p_joint) const {
- JointBullet *joint(joint_owner.get(p_joint));
+bool BulletPhysicsServer3D::joint_is_disabled_collisions_between_bodies(RID p_joint) const {
+ JointBullet *joint(joint_owner.getornull(p_joint));
ERR_FAIL_COND_V(!joint, false);
return joint->is_disabled_collisions_between_bodies();
}
-RID BulletPhysicsServer::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
- RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+RID BulletPhysicsServer3D::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
JointAssertSpace(body_A, "A", RID());
- RigidBodyBullet *body_B = NULL;
+ RigidBodyBullet *body_B = nullptr;
if (p_body_B.is_valid()) {
- body_B = rigid_body_owner.get(p_body_B);
+ body_B = rigid_body_owner.getornull(p_body_B);
JointAssertSpace(body_B, "B", RID());
JointAssertSameSpace(body_A, body_B, RID());
}
@@ -1229,62 +1229,62 @@ RID BulletPhysicsServer::joint_create_pin(RID p_body_A, const Vector3 &p_local_A
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer::pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint);
pin_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
- JointBullet *joint = joint_owner.get(p_joint);
+float BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0);
PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint);
return pin_joint->get_param(p_param);
}
-void BulletPhysicsServer::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint);
pin_joint->setPivotInA(p_A);
}
-Vector3 BulletPhysicsServer::pin_joint_get_local_a(RID p_joint) const {
- JointBullet *joint = joint_owner.get(p_joint);
+Vector3 BulletPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint);
return pin_joint->getPivotInA();
}
-void BulletPhysicsServer::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint);
pin_joint->setPivotInB(p_B);
}
-Vector3 BulletPhysicsServer::pin_joint_get_local_b(RID p_joint) const {
- JointBullet *joint = joint_owner.get(p_joint);
+Vector3 BulletPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint);
return pin_joint->getPivotInB();
}
-RID BulletPhysicsServer::joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) {
- RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+RID BulletPhysicsServer3D::joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
JointAssertSpace(body_A, "A", RID());
- RigidBodyBullet *body_B = NULL;
+ RigidBodyBullet *body_B = nullptr;
if (p_body_B.is_valid()) {
- body_B = rigid_body_owner.get(p_body_B);
+ body_B = rigid_body_owner.getornull(p_body_B);
JointAssertSpace(body_B, "B", RID());
JointAssertSameSpace(body_A, body_B, RID());
}
@@ -1297,14 +1297,14 @@ RID BulletPhysicsServer::joint_create_hinge(RID p_body_A, const Transform &p_hin
CreateThenReturnRID(joint_owner, joint);
}
-RID BulletPhysicsServer::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) {
- RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+RID BulletPhysicsServer3D::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
JointAssertSpace(body_A, "A", RID());
- RigidBodyBullet *body_B = NULL;
+ RigidBodyBullet *body_B = nullptr;
if (p_body_B.is_valid()) {
- body_B = rigid_body_owner.get(p_body_B);
+ body_B = rigid_body_owner.getornull(p_body_B);
JointAssertSpace(body_B, "B", RID());
JointAssertSameSpace(body_A, body_B, RID());
}
@@ -1317,46 +1317,46 @@ RID BulletPhysicsServer::joint_create_hinge_simple(RID p_body_A, const Vector3 &
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_HINGE);
HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint);
hinge_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
- JointBullet *joint = joint_owner.get(p_joint);
+float BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0);
HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint);
return hinge_joint->get_param(p_param);
}
-void BulletPhysicsServer::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_HINGE);
HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint);
hinge_joint->set_flag(p_flag, p_value);
}
-bool BulletPhysicsServer::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {
- JointBullet *joint = joint_owner.get(p_joint);
+bool BulletPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, false);
ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false);
HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint);
return hinge_joint->get_flag(p_flag);
}
-RID BulletPhysicsServer::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
- RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
JointAssertSpace(body_A, "A", RID());
- RigidBodyBullet *body_B = NULL;
+ RigidBodyBullet *body_B = nullptr;
if (p_body_B.is_valid()) {
- body_B = rigid_body_owner.get(p_body_B);
+ body_B = rigid_body_owner.getornull(p_body_B);
JointAssertSpace(body_B, "B", RID());
JointAssertSameSpace(body_A, body_B, RID());
}
@@ -1369,30 +1369,30 @@ RID BulletPhysicsServer::joint_create_slider(RID p_body_A, const Transform &p_lo
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer::slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER);
SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint);
slider_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
- JointBullet *joint = joint_owner.get(p_joint);
+float BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_SLIDER, 0);
SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint);
return slider_joint->get_param(p_param);
}
-RID BulletPhysicsServer::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
- RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
JointAssertSpace(body_A, "A", RID());
- RigidBodyBullet *body_B = NULL;
+ RigidBodyBullet *body_B = nullptr;
if (p_body_B.is_valid()) {
- body_B = rigid_body_owner.get(p_body_B);
+ body_B = rigid_body_owner.getornull(p_body_B);
JointAssertSpace(body_B, "B", RID());
JointAssertSameSpace(body_A, body_B, RID());
}
@@ -1403,30 +1403,30 @@ RID BulletPhysicsServer::joint_create_cone_twist(RID p_body_A, const Transform &
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST);
ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint);
coneTwist_joint->set_param(p_param, p_value);
}
-float BulletPhysicsServer::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
- JointBullet *joint = joint_owner.get(p_joint);
+float BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0.);
ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0.);
ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint);
return coneTwist_joint->get_param(p_param);
}
-RID BulletPhysicsServer::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
- RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A);
+RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
+ RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
JointAssertSpace(body_A, "A", RID());
- RigidBodyBullet *body_B = NULL;
+ RigidBodyBullet *body_B = nullptr;
if (p_body_B.is_valid()) {
- body_B = rigid_body_owner.get(p_body_B);
+ body_B = rigid_body_owner.getornull(p_body_B);
JointAssertSpace(body_B, "B", RID());
JointAssertSameSpace(body_A, body_B, RID());
}
@@ -1439,58 +1439,58 @@ RID BulletPhysicsServer::joint_create_generic_6dof(RID p_body_A, const Transform
CreateThenReturnRID(joint_owner, joint);
}
-void BulletPhysicsServer::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint);
generic_6dof_joint->set_param(p_axis, p_param, p_value);
}
-float BulletPhysicsServer::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
- JointBullet *joint = joint_owner.get(p_joint);
+float BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0);
Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint);
return generic_6dof_joint->get_param(p_axis, p_param);
}
-void BulletPhysicsServer::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint);
generic_6dof_joint->set_flag(p_axis, p_flag, p_enable);
}
-bool BulletPhysicsServer::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) {
- JointBullet *joint = joint_owner.get(p_joint);
+bool BulletPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, false);
ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false);
Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint);
return generic_6dof_joint->get_flag(p_axis, p_flag);
}
-void BulletPhysicsServer::generic_6dof_joint_set_precision(RID p_joint, int p_precision) {
- JointBullet *joint = joint_owner.get(p_joint);
+void BulletPhysicsServer3D::generic_6dof_joint_set_precision(RID p_joint, int p_precision) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint);
generic_6dof_joint->set_precision(p_precision);
}
-int BulletPhysicsServer::generic_6dof_joint_get_precision(RID p_joint) {
- JointBullet *joint = joint_owner.get(p_joint);
+int BulletPhysicsServer3D::generic_6dof_joint_get_precision(RID p_joint) {
+ JointBullet *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0);
Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint);
return generic_6dof_joint->get_precision();
}
-void BulletPhysicsServer::free(RID p_rid) {
+void BulletPhysicsServer3D::free(RID p_rid) {
if (shape_owner.owns(p_rid)) {
- ShapeBullet *shape = shape_owner.get(p_rid);
+ ShapeBullet *shape = shape_owner.getornull(p_rid);
// Notify the shape is configured
for (Map<ShapeOwnerBullet *, int>::Element *element = shape->get_owners().front(); element; element = element->next()) {
@@ -1501,9 +1501,9 @@ void BulletPhysicsServer::free(RID p_rid) {
bulletdelete(shape);
} else if (rigid_body_owner.owns(p_rid)) {
- RigidBodyBullet *body = rigid_body_owner.get(p_rid);
+ RigidBodyBullet *body = rigid_body_owner.getornull(p_rid);
- body->set_space(NULL);
+ body->set_space(nullptr);
body->remove_all_shapes(true, true);
@@ -1512,18 +1512,18 @@ void BulletPhysicsServer::free(RID p_rid) {
} else if (soft_body_owner.owns(p_rid)) {
- SoftBodyBullet *body = soft_body_owner.get(p_rid);
+ SoftBodyBullet *body = soft_body_owner.getornull(p_rid);
- body->set_space(NULL);
+ body->set_space(nullptr);
soft_body_owner.free(p_rid);
bulletdelete(body);
} else if (area_owner.owns(p_rid)) {
- AreaBullet *area = area_owner.get(p_rid);
+ AreaBullet *area = area_owner.getornull(p_rid);
- area->set_space(NULL);
+ area->set_space(nullptr);
area->remove_all_shapes(true, true);
@@ -1532,14 +1532,14 @@ void BulletPhysicsServer::free(RID p_rid) {
} else if (joint_owner.owns(p_rid)) {
- JointBullet *joint = joint_owner.get(p_rid);
+ JointBullet *joint = joint_owner.getornull(p_rid);
joint->destroy_internal_constraint();
joint_owner.free(p_rid);
bulletdelete(joint);
} else if (space_owner.owns(p_rid)) {
- SpaceBullet *space = space_owner.get(p_rid);
+ SpaceBullet *space = space_owner.getornull(p_rid);
space->remove_all_collision_objects();
@@ -1552,15 +1552,15 @@ void BulletPhysicsServer::free(RID p_rid) {
}
}
-void BulletPhysicsServer::init() {
- BulletPhysicsDirectBodyState::initSingleton();
+void BulletPhysicsServer3D::init() {
+ BulletPhysicsDirectBodyState3D::initSingleton();
}
-void BulletPhysicsServer::step(float p_deltaTime) {
+void BulletPhysicsServer3D::step(float p_deltaTime) {
if (!active)
return;
- BulletPhysicsDirectBodyState::singleton_setDeltaTime(p_deltaTime);
+ BulletPhysicsDirectBodyState3D::singleton_setDeltaTime(p_deltaTime);
for (int i = 0; i < active_spaces_count; ++i) {
@@ -1568,21 +1568,21 @@ void BulletPhysicsServer::step(float p_deltaTime) {
}
}
-void BulletPhysicsServer::sync() {
+void BulletPhysicsServer3D::sync() {
}
-void BulletPhysicsServer::flush_queries() {
+void BulletPhysicsServer3D::flush_queries() {
}
-void BulletPhysicsServer::finish() {
- BulletPhysicsDirectBodyState::destroySingleton();
+void BulletPhysicsServer3D::finish() {
+ BulletPhysicsDirectBodyState3D::destroySingleton();
}
-int BulletPhysicsServer::get_process_info(ProcessInfo p_info) {
+int BulletPhysicsServer3D::get_process_info(ProcessInfo p_info) {
return 0;
}
-CollisionObjectBullet *BulletPhysicsServer::get_collisin_object(RID p_object) const {
+CollisionObjectBullet *BulletPhysicsServer3D::get_collisin_object(RID p_object) const {
if (rigid_body_owner.owns(p_object)) {
return rigid_body_owner.getornull(p_object);
}
@@ -1592,15 +1592,15 @@ CollisionObjectBullet *BulletPhysicsServer::get_collisin_object(RID p_object) co
if (soft_body_owner.owns(p_object)) {
return soft_body_owner.getornull(p_object);
}
- return NULL;
+ return nullptr;
}
-RigidCollisionObjectBullet *BulletPhysicsServer::get_rigid_collisin_object(RID p_object) const {
+RigidCollisionObjectBullet *BulletPhysicsServer3D::get_rigid_collisin_object(RID p_object) const {
if (rigid_body_owner.owns(p_object)) {
return rigid_body_owner.getornull(p_object);
}
if (area_owner.owns(p_object)) {
return area_owner.getornull(p_object);
}
- return NULL;
+ return nullptr;
}
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index 4a3b4a2edc..ea9c5e589e 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -33,19 +33,19 @@
#include "area_bullet.h"
#include "core/rid.h"
+#include "core/rid_owner.h"
#include "joint_bullet.h"
#include "rigid_body_bullet.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
#include "shape_bullet.h"
#include "soft_body_bullet.h"
#include "space_bullet.h"
-
/**
@author AndreaCatania
*/
-class BulletPhysicsServer : public PhysicsServer {
- GDCLASS(BulletPhysicsServer, PhysicsServer);
+class BulletPhysicsServer3D : public PhysicsServer3D {
+ GDCLASS(BulletPhysicsServer3D, PhysicsServer3D);
friend class BulletPhysicsDirectSpaceState;
@@ -53,36 +53,36 @@ class BulletPhysicsServer : public PhysicsServer {
char active_spaces_count;
Vector<SpaceBullet *> active_spaces;
- mutable RID_Owner<SpaceBullet> space_owner;
- mutable RID_Owner<ShapeBullet> shape_owner;
- mutable RID_Owner<AreaBullet> area_owner;
- mutable RID_Owner<RigidBodyBullet> rigid_body_owner;
- mutable RID_Owner<SoftBodyBullet> soft_body_owner;
- mutable RID_Owner<JointBullet> joint_owner;
+ mutable RID_PtrOwner<SpaceBullet> space_owner;
+ mutable RID_PtrOwner<ShapeBullet> shape_owner;
+ mutable RID_PtrOwner<AreaBullet> area_owner;
+ mutable RID_PtrOwner<RigidBodyBullet> rigid_body_owner;
+ mutable RID_PtrOwner<SoftBodyBullet> soft_body_owner;
+ mutable RID_PtrOwner<JointBullet> joint_owner;
protected:
static void _bind_methods();
public:
- BulletPhysicsServer();
- ~BulletPhysicsServer();
+ BulletPhysicsServer3D();
+ ~BulletPhysicsServer3D();
- _FORCE_INLINE_ RID_Owner<SpaceBullet> *get_space_owner() {
+ _FORCE_INLINE_ RID_PtrOwner<SpaceBullet> *get_space_owner() {
return &space_owner;
}
- _FORCE_INLINE_ RID_Owner<ShapeBullet> *get_shape_owner() {
+ _FORCE_INLINE_ RID_PtrOwner<ShapeBullet> *get_shape_owner() {
return &shape_owner;
}
- _FORCE_INLINE_ RID_Owner<AreaBullet> *get_area_owner() {
+ _FORCE_INLINE_ RID_PtrOwner<AreaBullet> *get_area_owner() {
return &area_owner;
}
- _FORCE_INLINE_ RID_Owner<RigidBodyBullet> *get_rigid_body_owner() {
+ _FORCE_INLINE_ RID_PtrOwner<RigidBodyBullet> *get_rigid_body_owner() {
return &rigid_body_owner;
}
- _FORCE_INLINE_ RID_Owner<SoftBodyBullet> *get_soft_body_owner() {
+ _FORCE_INLINE_ RID_PtrOwner<SoftBodyBullet> *get_soft_body_owner() {
return &soft_body_owner;
}
- _FORCE_INLINE_ RID_Owner<JointBullet> *get_joint_owner() {
+ _FORCE_INLINE_ RID_PtrOwner<JointBullet> *get_joint_owner() {
return &joint_owner;
}
@@ -111,7 +111,7 @@ public:
/// Not supported
virtual real_t space_get_param(RID p_space, SpaceParameter p_param) const;
- virtual PhysicsDirectSpaceState *space_get_direct_state(RID p_space);
+ virtual PhysicsDirectSpaceState3D *space_get_direct_state(RID p_space);
virtual void space_set_debug_contacts(RID p_space, int p_max_contacts);
virtual Vector<Vector3> space_get_contacts(RID p_space) const;
@@ -189,8 +189,8 @@ public:
virtual void body_clear_shapes(RID p_body);
// Used for Rigid and Soft Bodies
- virtual void body_attach_object_instance_id(RID p_body, uint32_t p_id);
- virtual uint32_t body_get_object_instance_id(RID p_body) const;
+ virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id);
+ virtual ObjectID body_get_object_instance_id(RID p_body) const;
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable);
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const;
@@ -252,16 +252,16 @@ public:
virtual bool body_is_ray_pickable(RID p_body) const;
// this function only works on physics process, errors and returns null otherwise
- virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body);
+ virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body);
- virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true);
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true);
virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001);
/* SOFT BODY API */
virtual RID soft_body_create(bool p_init_sleeping = false);
- virtual void soft_body_update_visual_server(RID p_body, class SoftBodyVisualServerHandler *p_visual_server_handler);
+ virtual void soft_body_update_rendering_server(RID p_body, class SoftBodyRenderingServerHandler *p_rendering_server_handler);
virtual void soft_body_set_space(RID p_body, RID p_space);
virtual RID soft_body_get_space(RID p_body) const;
@@ -387,7 +387,7 @@ public:
}
static bool singleton_isActive() {
- return static_cast<BulletPhysicsServer *>(get_singleton())->active;
+ return static_cast<BulletPhysicsServer3D *>(get_singleton())->active;
}
bool isActive() {
diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h
index 968cb38ba2..a5e33d9829 100644
--- a/modules/bullet/bullet_utilities.h
+++ b/modules/bullet/bullet_utilities.h
@@ -41,6 +41,6 @@
#define bulletdelete(cl) \
{ \
delete cl; \
- cl = NULL; \
+ cl = nullptr; \
}
#endif
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index c916c65d2b..1b72c2f577 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -60,7 +60,7 @@ void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_tra
}
btTransform CollisionObjectBullet::ShapeWrapper::get_adjusted_transform() const {
- if (shape->get_type() == PhysicsServer::SHAPE_HEIGHTMAP) {
+ if (shape->get_type() == PhysicsServer3D::SHAPE_HEIGHTMAP) {
const HeightMapShapeBullet *hm_shape = (const HeightMapShapeBullet *)shape; // should be safe to cast now
btTransform adjusted_transform;
@@ -90,16 +90,16 @@ void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_s
CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
RIDBullet(),
type(p_type),
- instance_id(0),
+ instance_id(ObjectID()),
collisionLayer(0),
collisionMask(0),
collisionsEnabled(true),
m_isStatic(false),
ray_pickable(false),
- bt_collision_object(NULL),
+ bt_collision_object(nullptr),
body_scale(1., 1., 1.),
force_shape_reset(false),
- space(NULL),
+ space(nullptr),
isTransformChanged(false) {}
CollisionObjectBullet::~CollisionObjectBullet() {
@@ -227,7 +227,7 @@ void CollisionObjectBullet::notify_transform_changed() {
RigidCollisionObjectBullet::RigidCollisionObjectBullet(Type p_type) :
CollisionObjectBullet(p_type),
- mainShape(NULL) {
+ mainShape(nullptr) {
}
RigidCollisionObjectBullet::~RigidCollisionObjectBullet() {
@@ -332,7 +332,7 @@ bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) {
void RigidCollisionObjectBullet::shape_changed(int p_shape_index) {
ShapeWrapper &shp = shapes.write[p_shape_index];
if (shp.bt_shape == mainShape) {
- mainShape = NULL;
+ mainShape = nullptr;
}
bulletdelete(shp.bt_shape);
reload_shapes();
@@ -345,7 +345,7 @@ void RigidCollisionObjectBullet::reload_shapes() {
bulletdelete(mainShape);
}
- mainShape = NULL;
+ mainShape = nullptr;
ShapeWrapper *shpWrapper;
const int shape_count = shapes.size();
@@ -398,7 +398,7 @@ void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_perm
ShapeWrapper &shp = shapes.write[p_index];
shp.shape->remove_owner(this, p_permanentlyFromThisBody);
if (shp.bt_shape == mainShape) {
- mainShape = NULL;
+ mainShape = nullptr;
}
bulletdelete(shp.bt_shape);
}
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index 42ba4aa907..25176458a7 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -76,20 +76,20 @@ public:
bool active;
ShapeWrapper() :
- shape(NULL),
- bt_shape(NULL),
+ shape(nullptr),
+ bt_shape(nullptr),
active(true) {}
ShapeWrapper(ShapeBullet *p_shape, const btTransform &p_transform, bool p_active) :
shape(p_shape),
- bt_shape(NULL),
+ bt_shape(nullptr),
active(p_active) {
set_transform(p_transform);
}
ShapeWrapper(ShapeBullet *p_shape, const Transform &p_transform, bool p_active) :
shape(p_shape),
- bt_shape(NULL),
+ bt_shape(nullptr),
active(p_active) {
set_transform(p_transform);
}
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index afeafcc356..aac51034b8 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -64,44 +64,46 @@ ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet
setup(coneConstraint);
}
-void ConeTwistJointBullet::set_param(PhysicsServer::ConeTwistJointParam p_param, real_t p_value) {
+void ConeTwistJointBullet::set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer::CONE_TWIST_JOINT_SWING_SPAN:
+ case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN:
coneConstraint->setLimit(5, p_value);
coneConstraint->setLimit(4, p_value);
break;
- case PhysicsServer::CONE_TWIST_JOINT_TWIST_SPAN:
+ case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN:
coneConstraint->setLimit(3, p_value);
break;
- case PhysicsServer::CONE_TWIST_JOINT_BIAS:
+ case PhysicsServer3D::CONE_TWIST_JOINT_BIAS:
coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), p_value, coneConstraint->getRelaxationFactor());
break;
- case PhysicsServer::CONE_TWIST_JOINT_SOFTNESS:
+ case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS:
coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), p_value, coneConstraint->getBiasFactor(), coneConstraint->getRelaxationFactor());
break;
- case PhysicsServer::CONE_TWIST_JOINT_RELAXATION:
+ case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION:
coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), coneConstraint->getBiasFactor(), p_value);
break;
- default:
- WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
+ case PhysicsServer3D::CONE_TWIST_MAX:
+ // Internal size value, nothing to do.
break;
}
}
-real_t ConeTwistJointBullet::get_param(PhysicsServer::ConeTwistJointParam p_param) const {
+real_t ConeTwistJointBullet::get_param(PhysicsServer3D::ConeTwistJointParam p_param) const {
switch (p_param) {
- case PhysicsServer::CONE_TWIST_JOINT_SWING_SPAN:
+ case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN:
return coneConstraint->getSwingSpan1();
- case PhysicsServer::CONE_TWIST_JOINT_TWIST_SPAN:
+ case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN:
return coneConstraint->getTwistSpan();
- case PhysicsServer::CONE_TWIST_JOINT_BIAS:
+ case PhysicsServer3D::CONE_TWIST_JOINT_BIAS:
return coneConstraint->getBiasFactor();
- case PhysicsServer::CONE_TWIST_JOINT_SOFTNESS:
+ case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS:
return coneConstraint->getLimitSoftness();
- case PhysicsServer::CONE_TWIST_JOINT_RELAXATION:
+ case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION:
return coneConstraint->getRelaxationFactor();
- default:
- WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
+ case PhysicsServer3D::CONE_TWIST_MAX:
+ // Internal size value, nothing to do.
return 0;
}
+ // Compiler doesn't seem to notice that all code paths are fulfilled...
+ return 0;
}
diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h
index 134706f8bb..ed4baa9d1b 100644
--- a/modules/bullet/cone_twist_joint_bullet.h
+++ b/modules/bullet/cone_twist_joint_bullet.h
@@ -45,9 +45,9 @@ class ConeTwistJointBullet : public JointBullet {
public:
ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &rbAFrame, const Transform &rbBFrame);
- virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_CONE_TWIST; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_CONE_TWIST; }
- void set_param(PhysicsServer::ConeTwistJointParam p_param, real_t p_value);
- real_t get_param(PhysicsServer::ConeTwistJointParam p_param) const;
+ void set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer3D::ConeTwistJointParam p_param) const;
};
#endif
diff --git a/modules/bullet/config.py b/modules/bullet/config.py
index 92dbcf5cb0..d22f9454ed 100644
--- a/modules/bullet/config.py
+++ b/modules/bullet/config.py
@@ -1,14 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
-
-def get_doc_classes():
- return [
- "BulletPhysicsDirectBodyState",
- "BulletPhysicsServer",
- ]
-
-def get_doc_path():
- return "doc_classes"
diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp
index 7e90e2b488..469b58521e 100644
--- a/modules/bullet/constraint_bullet.cpp
+++ b/modules/bullet/constraint_bullet.cpp
@@ -38,8 +38,8 @@
*/
ConstraintBullet::ConstraintBullet() :
- space(NULL),
- constraint(NULL),
+ space(nullptr),
+ constraint(nullptr),
disabled_collisions_between_bodies(true) {}
void ConstraintBullet::setup(btTypedConstraint *p_constraint) {
diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h
index 89ad150257..1946807bad 100644
--- a/modules/bullet/constraint_bullet.h
+++ b/modules/bullet/constraint_bullet.h
@@ -64,7 +64,7 @@ public:
public:
virtual ~ConstraintBullet() {
bulletdelete(constraint);
- constraint = NULL;
+ constraint = nullptr;
}
_FORCE_INLINE_ btTypedConstraint *get_bt_constraint() { return constraint; }
diff --git a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml
deleted file mode 100644
index 5ea1b810a1..0000000000
--- a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="BulletPhysicsDirectBodyState" inherits="PhysicsDirectBodyState" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/bullet/doc_classes/BulletPhysicsServer.xml b/modules/bullet/doc_classes/BulletPhysicsServer.xml
deleted file mode 100644
index af8fb3c02c..0000000000
--- a/modules/bullet/doc_classes/BulletPhysicsServer.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="BulletPhysicsServer" inherits="PhysicsServer" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index 86bedd6c45..638944df76 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -43,6 +43,12 @@
Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB) :
JointBullet() {
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < PhysicsServer3D::G6DOF_JOINT_FLAG_MAX; j++) {
+ flags[i][j] = false;
+ }
+ }
+
Transform scaled_AFrame(frameInA.scaled(rbA->get_body_scale()));
scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis);
@@ -118,147 +124,153 @@ void Generic6DOFJointBullet::set_angular_upper_limit(const Vector3 &angularUpper
sixDOFConstraint->setAngularUpperLimit(btVec);
}
-void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisParam p_param, real_t p_value) {
+void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value) {
ERR_FAIL_INDEX(p_axis, 3);
switch (p_param) {
- case PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT:
limits_lower[0][p_axis] = p_value;
- set_flag(p_axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, flags[p_axis][PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT]); // Reload bullet parameter
+ set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT]); // Reload bullet parameter
break;
- case PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT:
limits_upper[0][p_axis] = p_value;
- set_flag(p_axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, flags[p_axis][PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT]); // Reload bullet parameter
+ set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT]); // Reload bullet parameter
break;
- case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY:
sixDOFConstraint->getTranslationalLimitMotor()->m_targetVelocity.m_floats[p_axis] = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT:
sixDOFConstraint->getTranslationalLimitMotor()->m_maxMotorForce.m_floats[p_axis] = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING:
sixDOFConstraint->getTranslationalLimitMotor()->m_springDamping.m_floats[p_axis] = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS:
sixDOFConstraint->getTranslationalLimitMotor()->m_springStiffness.m_floats[p_axis] = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT:
sixDOFConstraint->getTranslationalLimitMotor()->m_equilibriumPoint.m_floats[p_axis] = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT:
limits_lower[1][p_axis] = p_value;
- set_flag(p_axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, flags[p_axis][PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT]); // Reload bullet parameter
+ set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT]); // Reload bullet parameter
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT:
limits_upper[1][p_axis] = p_value;
- set_flag(p_axis, PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, flags[p_axis][PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT]); // Reload bullet parameter
+ set_flag(p_axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, flags[p_axis][PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT]); // Reload bullet parameter
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION:
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_bounce = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_ERP:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP:
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_stopERP = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY:
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_targetVelocity = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT:
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxMotorForce = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS:
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springStiffness = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING:
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springDamping = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT:
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint = p_value;
break;
+ case PhysicsServer3D::G6DOF_JOINT_MAX:
+ // Internal size value, nothing to do.
+ break;
default:
WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
break;
}
}
-real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisParam p_param) const {
+real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const {
ERR_FAIL_INDEX_V(p_axis, 3, 0.);
switch (p_param) {
- case PhysicsServer::G6DOF_JOINT_LINEAR_LOWER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT:
return limits_lower[0][p_axis];
- case PhysicsServer::G6DOF_JOINT_LINEAR_UPPER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT:
return limits_upper[0][p_axis];
- case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY:
return sixDOFConstraint->getTranslationalLimitMotor()->m_targetVelocity.m_floats[p_axis];
- case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT:
return sixDOFConstraint->getTranslationalLimitMotor()->m_maxMotorForce.m_floats[p_axis];
- case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING:
return sixDOFConstraint->getTranslationalLimitMotor()->m_springDamping.m_floats[p_axis];
- case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS:
return sixDOFConstraint->getTranslationalLimitMotor()->m_springStiffness.m_floats[p_axis];
- case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT:
+ case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT:
return sixDOFConstraint->getTranslationalLimitMotor()->m_equilibriumPoint.m_floats[p_axis];
- case PhysicsServer::G6DOF_JOINT_ANGULAR_LOWER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT:
return limits_lower[1][p_axis];
- case PhysicsServer::G6DOF_JOINT_ANGULAR_UPPER_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT:
return limits_upper[1][p_axis];
- case PhysicsServer::G6DOF_JOINT_ANGULAR_RESTITUTION:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_bounce;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_ERP:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_stopERP;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_targetVelocity;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxMotorForce;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springStiffness;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springDamping;
- case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT:
+ case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint;
+ case PhysicsServer3D::G6DOF_JOINT_MAX:
+ // Internal size value, nothing to do.
+ return 0;
default:
WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
return 0;
}
}
-void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag, bool p_value) {
+void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value) {
ERR_FAIL_INDEX(p_axis, 3);
flags[p_axis][p_flag] = p_value;
switch (p_flag) {
- case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT:
if (flags[p_axis][p_flag]) {
sixDOFConstraint->setLimit(p_axis, limits_lower[0][p_axis], limits_upper[0][p_axis]);
} else {
sixDOFConstraint->setLimit(p_axis, 0, -1); // Free
}
break;
- case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT:
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT:
if (flags[p_axis][p_flag]) {
sixDOFConstraint->setLimit(p_axis + 3, limits_lower[1][p_axis], limits_upper[1][p_axis]);
} else {
sixDOFConstraint->setLimit(p_axis + 3, 0, -1); // Free
}
break;
- case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR:
- sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableMotor = flags[p_axis][p_flag];
- break;
- case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR:
- sixDOFConstraint->getTranslationalLimitMotor()->m_enableMotor[p_axis] = flags[p_axis][p_flag];
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableSpring = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING:
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING:
sixDOFConstraint->getTranslationalLimitMotor()->m_enableSpring[p_axis] = p_value;
break;
- case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING:
- sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableSpring = p_value;
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_MOTOR:
+ sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableMotor = flags[p_axis][p_flag];
break;
- default:
- WARN_DEPRECATED_MSG("The flag " + itos(p_flag) + " is deprecated.");
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR:
+ sixDOFConstraint->getTranslationalLimitMotor()->m_enableMotor[p_axis] = flags[p_axis][p_flag];
+ break;
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX:
+ // Internal size value, nothing to do.
break;
}
}
-bool Generic6DOFJointBullet::get_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag) const {
+bool Generic6DOFJointBullet::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const {
ERR_FAIL_INDEX_V(p_axis, 3, false);
return flags[p_axis][p_flag];
}
diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h
index 75c8005811..316708bb11 100644
--- a/modules/bullet/generic_6dof_joint_bullet.h
+++ b/modules/bullet/generic_6dof_joint_bullet.h
@@ -45,12 +45,12 @@ class Generic6DOFJointBullet : public JointBullet {
// First is linear second is angular
Vector3 limits_lower[2];
Vector3 limits_upper[2];
- bool flags[3][PhysicsServer::G6DOF_JOINT_FLAG_MAX];
+ bool flags[3][PhysicsServer3D::G6DOF_JOINT_FLAG_MAX];
public:
Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB);
- virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_6DOF; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_6DOF; }
Transform getFrameOffsetA() const;
Transform getFrameOffsetB() const;
@@ -63,11 +63,11 @@ public:
void set_angular_lower_limit(const Vector3 &angularLower);
void set_angular_upper_limit(const Vector3 &angularUpper);
- void set_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisParam p_param, real_t p_value);
- real_t get_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisParam p_param) const;
+ void set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value);
+ real_t get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const;
- void set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag, bool p_value);
- bool get_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag) const;
+ void set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value);
+ bool get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const;
void set_precision(int p_precision);
int get_precision() const;
diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp
index f3e3a01a52..8e29845a36 100644
--- a/modules/bullet/godot_collision_configuration.cpp
+++ b/modules/bullet/godot_collision_configuration.cpp
@@ -42,7 +42,7 @@
GodotCollisionConfiguration::GodotCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) :
btDefaultCollisionConfiguration(constructionInfo) {
- void *mem = NULL;
+ void *mem = nullptr;
mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::CreateFunc), 16);
m_rayWorldCF = new (mem) GodotRayWorldAlgorithm::CreateFunc(world);
@@ -98,7 +98,7 @@ btCollisionAlgorithmCreateFunc *GodotCollisionConfiguration::getClosestPointsAlg
GodotSoftCollisionConfiguration::GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) :
btSoftBodyRigidBodyCollisionConfiguration(constructionInfo) {
- void *mem = NULL;
+ void *mem = nullptr;
mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::CreateFunc), 16);
m_rayWorldCF = new (mem) GodotRayWorldAlgorithm::CreateFunc(world);
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 6e54d10abf..ad20a7e451 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -107,12 +107,12 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(convexResult.m_hitCollisionObject->getUserPointer());
- PhysicsDirectSpaceState::ShapeResult &result = m_results[count];
+ PhysicsDirectSpaceState3D::ShapeResult &result = m_results[count];
result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
result.rid = gObj->get_self();
result.collider_id = gObj->get_instance_id();
- result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
+ result.collider = result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(result.collider_id);
++count;
return 1; // not used by bullet
@@ -207,7 +207,7 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con
if (cp.getDistance() <= 0) {
- PhysicsDirectSpaceState::ShapeResult &result = m_results[m_count];
+ PhysicsDirectSpaceState3D::ShapeResult &result = m_results[m_count];
// Penetrated
CollisionObjectBullet *colObj;
@@ -220,7 +220,7 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con
}
result.collider_id = colObj->get_instance_id();
- result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
+ result.collider = result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(result.collider_id);
result.rid = colObj->get_self();
++m_count;
}
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 4f634ed6f0..7e74a2b22e 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -31,7 +31,7 @@
#ifndef GODOT_RESULT_CALLBACKS_H
#define GODOT_RESULT_CALLBACKS_H
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
#include <btBulletDynamicsCommon.h>
@@ -85,12 +85,12 @@ public:
// store all colliding object
struct GodotAllConvexResultCallback : public btCollisionWorld::ConvexResultCallback {
public:
- PhysicsDirectSpaceState::ShapeResult *m_results;
+ PhysicsDirectSpaceState3D::ShapeResult *m_results;
int m_resultMax;
const Set<RID> *m_exclude;
int count;
- GodotAllConvexResultCallback(PhysicsDirectSpaceState::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude) :
+ GodotAllConvexResultCallback(PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude) :
m_results(p_results),
m_resultMax(p_resultMax),
m_exclude(p_exclude),
@@ -137,7 +137,7 @@ public:
struct GodotAllContactResultCallback : public btCollisionWorld::ContactResultCallback {
public:
const btCollisionObject *m_self_object;
- PhysicsDirectSpaceState::ShapeResult *m_results;
+ PhysicsDirectSpaceState3D::ShapeResult *m_results;
int m_resultMax;
const Set<RID> *m_exclude;
int m_count;
@@ -145,7 +145,7 @@ public:
bool collide_with_bodies;
bool collide_with_areas;
- GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
+ GodotAllContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
m_self_object(p_self_object),
m_results(p_results),
m_resultMax(p_resultMax),
@@ -188,7 +188,7 @@ public:
struct GodotRestInfoContactResultCallback : public btCollisionWorld::ContactResultCallback {
public:
const btCollisionObject *m_self_object;
- PhysicsDirectSpaceState::ShapeRestInfo *m_result;
+ PhysicsDirectSpaceState3D::ShapeRestInfo *m_result;
const Set<RID> *m_exclude;
bool m_collided;
real_t m_min_distance;
@@ -197,7 +197,7 @@ public:
bool collide_with_bodies;
bool collide_with_areas;
- GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState::ShapeRestInfo *p_result, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
+ GodotRestInfoContactResultCallback(btCollisionObject *p_self_object, PhysicsDirectSpaceState3D::ShapeRestInfo *p_result, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
m_self_object(p_self_object),
m_result(p_result),
m_exclude(p_exclude),
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index 49e67bfbc1..4bea9f87c0 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -93,79 +93,84 @@ real_t HingeJointBullet::get_hinge_angle() {
return hingeConstraint->getHingeAngle();
}
-void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t p_value) {
+void HingeJointBullet::set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer::HINGE_JOINT_LIMIT_UPPER:
+ case PhysicsServer3D::HINGE_JOINT_BIAS:
+ WARN_DEPRECATED_MSG("The HingeJoint3D parameter \"bias\" is deprecated.");
+ break;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER:
hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), p_value, hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
break;
- case PhysicsServer::HINGE_JOINT_LIMIT_LOWER:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER:
hingeConstraint->setLimit(p_value, hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
break;
- case PhysicsServer::HINGE_JOINT_LIMIT_BIAS:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS:
hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), p_value, hingeConstraint->getLimitRelaxationFactor());
break;
- case PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS:
hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), p_value, hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
break;
- case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION:
hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), hingeConstraint->getUpperLimit(), hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), p_value);
break;
- case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
hingeConstraint->setMotorTargetVelocity(p_value);
break;
- case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE:
hingeConstraint->setMaxMotorImpulse(p_value);
break;
- default:
- WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
+ case PhysicsServer3D::HINGE_JOINT_MAX:
+ // Internal size value, nothing to do.
break;
}
}
-real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const {
+real_t HingeJointBullet::get_param(PhysicsServer3D::HingeJointParam p_param) const {
switch (p_param) {
- case PhysicsServer::HINGE_JOINT_BIAS:
+ case PhysicsServer3D::HINGE_JOINT_BIAS:
+ WARN_DEPRECATED_MSG("The HingeJoint3D parameter \"bias\" is deprecated.");
return 0;
- break;
- case PhysicsServer::HINGE_JOINT_LIMIT_UPPER:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER:
return hingeConstraint->getUpperLimit();
- case PhysicsServer::HINGE_JOINT_LIMIT_LOWER:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER:
return hingeConstraint->getLowerLimit();
- case PhysicsServer::HINGE_JOINT_LIMIT_BIAS:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS:
return hingeConstraint->getLimitBiasFactor();
- case PhysicsServer::HINGE_JOINT_LIMIT_SOFTNESS:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS:
return hingeConstraint->getLimitSoftness();
- case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION:
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION:
return hingeConstraint->getLimitRelaxationFactor();
- case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
return hingeConstraint->getMotorTargetVelocity();
- case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE:
return hingeConstraint->getMaxMotorImpulse();
- default:
- WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated.");
+ case PhysicsServer3D::HINGE_JOINT_MAX:
+ // Internal size value, nothing to do.
return 0;
}
+ // Compiler doesn't seem to notice that all code paths are fulfilled...
+ return 0;
}
-void HingeJointBullet::set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_value) {
+void HingeJointBullet::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value) {
switch (p_flag) {
- case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT:
+ case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT:
if (!p_value) {
hingeConstraint->setLimit(-Math_PI, Math_PI);
}
break;
- case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR:
+ case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR:
hingeConstraint->enableMotor(p_value);
break;
- case PhysicsServer::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
}
}
-bool HingeJointBullet::get_flag(PhysicsServer::HingeJointFlag p_flag) const {
+bool HingeJointBullet::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const {
switch (p_flag) {
- case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT:
+ case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT:
return true;
- case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR:
+ case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR:
return hingeConstraint->getEnableAngularMotor();
default:
return false;
diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h
index d1061fe52f..120c40e5c0 100644
--- a/modules/bullet/hinge_joint_bullet.h
+++ b/modules/bullet/hinge_joint_bullet.h
@@ -44,14 +44,14 @@ public:
HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameA, const Transform &frameB);
HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB);
- virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_HINGE; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_HINGE; }
real_t get_hinge_angle();
- void set_param(PhysicsServer::HingeJointParam p_param, real_t p_value);
- real_t get_param(PhysicsServer::HingeJointParam p_param) const;
+ void set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer3D::HingeJointParam p_param) const;
- void set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_value);
- bool get_flag(PhysicsServer::HingeJointFlag p_flag) const;
+ void set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value);
+ bool get_flag(PhysicsServer3D::HingeJointFlag p_flag) const;
};
#endif
diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h
index c840eb8f14..9cb8aab276 100644
--- a/modules/bullet/joint_bullet.h
+++ b/modules/bullet/joint_bullet.h
@@ -32,7 +32,7 @@
#define JOINT_BULLET_H
#include "constraint_bullet.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
/**
@author AndreaCatania
@@ -47,6 +47,6 @@ public:
JointBullet();
virtual ~JointBullet();
- virtual PhysicsServer::JointType get_type() const = 0;
+ virtual PhysicsServer3D::JointType get_type() const = 0;
};
#endif
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index 1c2e5e65cc..68b40d7405 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -62,32 +62,31 @@ PinJointBullet::PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a
PinJointBullet::~PinJointBullet() {}
-void PinJointBullet::set_param(PhysicsServer::PinJointParam p_param, real_t p_value) {
+void PinJointBullet::set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer::PIN_JOINT_BIAS:
+ case PhysicsServer3D::PIN_JOINT_BIAS:
p2pConstraint->m_setting.m_tau = p_value;
break;
- case PhysicsServer::PIN_JOINT_DAMPING:
+ case PhysicsServer3D::PIN_JOINT_DAMPING:
p2pConstraint->m_setting.m_damping = p_value;
break;
- case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP:
+ case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP:
p2pConstraint->m_setting.m_impulseClamp = p_value;
break;
}
}
-real_t PinJointBullet::get_param(PhysicsServer::PinJointParam p_param) const {
+real_t PinJointBullet::get_param(PhysicsServer3D::PinJointParam p_param) const {
switch (p_param) {
- case PhysicsServer::PIN_JOINT_BIAS:
+ case PhysicsServer3D::PIN_JOINT_BIAS:
return p2pConstraint->m_setting.m_tau;
- case PhysicsServer::PIN_JOINT_DAMPING:
+ case PhysicsServer3D::PIN_JOINT_DAMPING:
return p2pConstraint->m_setting.m_damping;
- case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP:
+ case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP:
return p2pConstraint->m_setting.m_impulseClamp;
- default:
- WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated.");
- return 0;
}
+ // Compiler doesn't seem to notice that all code paths are fulfilled...
+ return 0;
}
void PinJointBullet::setPivotInA(const Vector3 &p_pos) {
diff --git a/modules/bullet/pin_joint_bullet.h b/modules/bullet/pin_joint_bullet.h
index d6e7a945b5..e7d05f34d4 100644
--- a/modules/bullet/pin_joint_bullet.h
+++ b/modules/bullet/pin_joint_bullet.h
@@ -46,10 +46,10 @@ public:
PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a, RigidBodyBullet *p_body_b, const Vector3 &p_pos_b);
~PinJointBullet();
- virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_PIN; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_PIN; }
- void set_param(PhysicsServer::PinJointParam p_param, real_t p_value);
- real_t get_param(PhysicsServer::PinJointParam p_param) const;
+ void set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer3D::PinJointParam p_param) const;
void setPivotInA(const Vector3 &p_pos);
void setPivotInB(const Vector3 &p_pos);
diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp
index 7819b67cad..009d0dff63 100644
--- a/modules/bullet/register_types.cpp
+++ b/modules/bullet/register_types.cpp
@@ -39,15 +39,15 @@
*/
#ifndef _3D_DISABLED
-PhysicsServer *_createBulletPhysicsCallback() {
- return memnew(BulletPhysicsServer);
+PhysicsServer3D *_createBulletPhysicsCallback() {
+ return memnew(BulletPhysicsServer3D);
}
#endif
void register_bullet_types() {
#ifndef _3D_DISABLED
- PhysicsServerManager::register_server("Bullet", &_createBulletPhysicsCallback);
- PhysicsServerManager::set_default_server("Bullet", 1);
+ PhysicsServer3DManager::register_server("Bullet", &_createBulletPhysicsCallback);
+ PhysicsServer3DManager::set_default_server("Bullet", 1);
GLOBAL_DEF("physics/3d/active_soft_world", true);
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/active_soft_world", PropertyInfo(Variant::BOOL, "physics/3d/active_soft_world"));
diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h
index 28bcedb01a..3551ca05f9 100644
--- a/modules/bullet/rid_bullet.h
+++ b/modules/bullet/rid_bullet.h
@@ -37,17 +37,17 @@
@author AndreaCatania
*/
-class BulletPhysicsServer;
+class BulletPhysicsServer3D;
-class RIDBullet : public RID_Data {
+class RIDBullet {
RID self;
- BulletPhysicsServer *physicsServer;
+ BulletPhysicsServer3D *physicsServer;
public:
_FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; }
_FORCE_INLINE_ RID get_self() const { return self; }
- _FORCE_INLINE_ void _set_physics_server(BulletPhysicsServer *p_physicsServer) { physicsServer = p_physicsServer; }
- _FORCE_INLINE_ BulletPhysicsServer *get_physics_server() const { return physicsServer; }
+ _FORCE_INLINE_ void _set_physics_server(BulletPhysicsServer3D *p_physicsServer) { physicsServer = p_physicsServer; }
+ _FORCE_INLINE_ BulletPhysicsServer3D *get_physics_server() const { return physicsServer; }
};
#endif
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index dfc9647813..a4f9affa95 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -48,141 +48,141 @@
@author AndreaCatania
*/
-BulletPhysicsDirectBodyState *BulletPhysicsDirectBodyState::singleton = NULL;
+BulletPhysicsDirectBodyState3D *BulletPhysicsDirectBodyState3D::singleton = nullptr;
-Vector3 BulletPhysicsDirectBodyState::get_total_gravity() const {
+Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const {
Vector3 gVec;
B_TO_G(body->btBody->getGravity(), gVec);
return gVec;
}
-float BulletPhysicsDirectBodyState::get_total_angular_damp() const {
+float BulletPhysicsDirectBodyState3D::get_total_angular_damp() const {
return body->btBody->getAngularDamping();
}
-float BulletPhysicsDirectBodyState::get_total_linear_damp() const {
+float BulletPhysicsDirectBodyState3D::get_total_linear_damp() const {
return body->btBody->getLinearDamping();
}
-Vector3 BulletPhysicsDirectBodyState::get_center_of_mass() const {
+Vector3 BulletPhysicsDirectBodyState3D::get_center_of_mass() const {
Vector3 gVec;
B_TO_G(body->btBody->getCenterOfMassPosition(), gVec);
return gVec;
}
-Basis BulletPhysicsDirectBodyState::get_principal_inertia_axes() const {
+Basis BulletPhysicsDirectBodyState3D::get_principal_inertia_axes() const {
return Basis();
}
-float BulletPhysicsDirectBodyState::get_inverse_mass() const {
+float BulletPhysicsDirectBodyState3D::get_inverse_mass() const {
return body->btBody->getInvMass();
}
-Vector3 BulletPhysicsDirectBodyState::get_inverse_inertia() const {
+Vector3 BulletPhysicsDirectBodyState3D::get_inverse_inertia() const {
Vector3 gVec;
B_TO_G(body->btBody->getInvInertiaDiagLocal(), gVec);
return gVec;
}
-Basis BulletPhysicsDirectBodyState::get_inverse_inertia_tensor() const {
+Basis BulletPhysicsDirectBodyState3D::get_inverse_inertia_tensor() const {
Basis gInertia;
B_TO_G(body->btBody->getInvInertiaTensorWorld(), gInertia);
return gInertia;
}
-void BulletPhysicsDirectBodyState::set_linear_velocity(const Vector3 &p_velocity) {
+void BulletPhysicsDirectBodyState3D::set_linear_velocity(const Vector3 &p_velocity) {
body->set_linear_velocity(p_velocity);
}
-Vector3 BulletPhysicsDirectBodyState::get_linear_velocity() const {
+Vector3 BulletPhysicsDirectBodyState3D::get_linear_velocity() const {
return body->get_linear_velocity();
}
-void BulletPhysicsDirectBodyState::set_angular_velocity(const Vector3 &p_velocity) {
+void BulletPhysicsDirectBodyState3D::set_angular_velocity(const Vector3 &p_velocity) {
body->set_angular_velocity(p_velocity);
}
-Vector3 BulletPhysicsDirectBodyState::get_angular_velocity() const {
+Vector3 BulletPhysicsDirectBodyState3D::get_angular_velocity() const {
return body->get_angular_velocity();
}
-void BulletPhysicsDirectBodyState::set_transform(const Transform &p_transform) {
+void BulletPhysicsDirectBodyState3D::set_transform(const Transform &p_transform) {
body->set_transform(p_transform);
}
-Transform BulletPhysicsDirectBodyState::get_transform() const {
+Transform BulletPhysicsDirectBodyState3D::get_transform() const {
return body->get_transform();
}
-void BulletPhysicsDirectBodyState::add_central_force(const Vector3 &p_force) {
+void BulletPhysicsDirectBodyState3D::add_central_force(const Vector3 &p_force) {
body->apply_central_force(p_force);
}
-void BulletPhysicsDirectBodyState::add_force(const Vector3 &p_force, const Vector3 &p_pos) {
+void BulletPhysicsDirectBodyState3D::add_force(const Vector3 &p_force, const Vector3 &p_pos) {
body->apply_force(p_force, p_pos);
}
-void BulletPhysicsDirectBodyState::add_torque(const Vector3 &p_torque) {
+void BulletPhysicsDirectBodyState3D::add_torque(const Vector3 &p_torque) {
body->apply_torque(p_torque);
}
-void BulletPhysicsDirectBodyState::apply_central_impulse(const Vector3 &p_impulse) {
+void BulletPhysicsDirectBodyState3D::apply_central_impulse(const Vector3 &p_impulse) {
body->apply_central_impulse(p_impulse);
}
-void BulletPhysicsDirectBodyState::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
+void BulletPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
body->apply_impulse(p_pos, p_impulse);
}
-void BulletPhysicsDirectBodyState::apply_torque_impulse(const Vector3 &p_impulse) {
+void BulletPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impulse) {
body->apply_torque_impulse(p_impulse);
}
-void BulletPhysicsDirectBodyState::set_sleep_state(bool p_enable) {
- body->set_activation_state(p_enable);
+void BulletPhysicsDirectBodyState3D::set_sleep_state(bool p_sleep) {
+ body->set_activation_state(!p_sleep);
}
-bool BulletPhysicsDirectBodyState::is_sleeping() const {
+bool BulletPhysicsDirectBodyState3D::is_sleeping() const {
return !body->is_active();
}
-int BulletPhysicsDirectBodyState::get_contact_count() const {
+int BulletPhysicsDirectBodyState3D::get_contact_count() const {
return body->collisionsCount;
}
-Vector3 BulletPhysicsDirectBodyState::get_contact_local_position(int p_contact_idx) const {
+Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_position(int p_contact_idx) const {
return body->collisions[p_contact_idx].hitLocalLocation;
}
-Vector3 BulletPhysicsDirectBodyState::get_contact_local_normal(int p_contact_idx) const {
+Vector3 BulletPhysicsDirectBodyState3D::get_contact_local_normal(int p_contact_idx) const {
return body->collisions[p_contact_idx].hitNormal;
}
-float BulletPhysicsDirectBodyState::get_contact_impulse(int p_contact_idx) const {
+float BulletPhysicsDirectBodyState3D::get_contact_impulse(int p_contact_idx) const {
return body->collisions[p_contact_idx].appliedImpulse;
}
-int BulletPhysicsDirectBodyState::get_contact_local_shape(int p_contact_idx) const {
+int BulletPhysicsDirectBodyState3D::get_contact_local_shape(int p_contact_idx) const {
return body->collisions[p_contact_idx].local_shape;
}
-RID BulletPhysicsDirectBodyState::get_contact_collider(int p_contact_idx) const {
+RID BulletPhysicsDirectBodyState3D::get_contact_collider(int p_contact_idx) const {
return body->collisions[p_contact_idx].otherObject->get_self();
}
-Vector3 BulletPhysicsDirectBodyState::get_contact_collider_position(int p_contact_idx) const {
+Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_position(int p_contact_idx) const {
return body->collisions[p_contact_idx].hitWorldLocation;
}
-ObjectID BulletPhysicsDirectBodyState::get_contact_collider_id(int p_contact_idx) const {
+ObjectID BulletPhysicsDirectBodyState3D::get_contact_collider_id(int p_contact_idx) const {
return body->collisions[p_contact_idx].otherObject->get_instance_id();
}
-int BulletPhysicsDirectBodyState::get_contact_collider_shape(int p_contact_idx) const {
+int BulletPhysicsDirectBodyState3D::get_contact_collider_shape(int p_contact_idx) const {
return body->collisions[p_contact_idx].other_object_shape;
}
-Vector3 BulletPhysicsDirectBodyState::get_contact_collider_velocity_at_position(int p_contact_idx) const {
+Vector3 BulletPhysicsDirectBodyState3D::get_contact_collider_velocity_at_position(int p_contact_idx) const {
RigidBodyBullet::CollisionData &colDat = body->collisions.write[p_contact_idx];
btVector3 hitLocation;
@@ -194,7 +194,7 @@ Vector3 BulletPhysicsDirectBodyState::get_contact_collider_velocity_at_position(
return velocityAtPoint;
}
-PhysicsDirectSpaceState *BulletPhysicsDirectBodyState::get_space_state() {
+PhysicsDirectSpaceState3D *BulletPhysicsDirectBodyState3D::get_space_state() {
return body->get_space()->get_direct_state();
}
@@ -231,17 +231,17 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
shapes.write[i].transform = shape_wrapper->transform;
shapes.write[i].transform.getOrigin() *= owner_scale;
switch (shape_wrapper->shape->get_type()) {
- case PhysicsServer::SHAPE_SPHERE:
- case PhysicsServer::SHAPE_BOX:
- case PhysicsServer::SHAPE_CAPSULE:
- case PhysicsServer::SHAPE_CYLINDER:
- case PhysicsServer::SHAPE_CONVEX_POLYGON:
- case PhysicsServer::SHAPE_RAY: {
+ case PhysicsServer3D::SHAPE_SPHERE:
+ case PhysicsServer3D::SHAPE_BOX:
+ case PhysicsServer3D::SHAPE_CAPSULE:
+ case PhysicsServer3D::SHAPE_CYLINDER:
+ case PhysicsServer3D::SHAPE_CONVEX_POLYGON:
+ case PhysicsServer3D::SHAPE_RAY: {
shapes.write[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin));
} break;
default:
- WARN_PRINT("This shape is not supported to be kinematic!");
- shapes.write[i].shape = NULL;
+ WARN_PRINT("This shape is not supported for kinematic collision.");
+ shapes.write[i].shape = nullptr;
}
}
}
@@ -257,7 +257,7 @@ void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) {
RigidBodyBullet::RigidBodyBullet() :
RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY),
- kinematic_utilities(NULL),
+ kinematic_utilities(nullptr),
locked_axis(0),
mass(1),
gravity_scale(1),
@@ -274,24 +274,24 @@ RigidBodyBullet::RigidBodyBullet() :
countGravityPointSpaces(0),
isScratchedSpaceOverrideModificator(false),
previousActiveState(true),
- force_integration_callback(NULL) {
+ force_integration_callback(nullptr) {
godotMotionState = bulletnew(GodotMotionState(this));
// Initial properties
const btVector3 localInertia(0, 0, 0);
- btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, NULL, localInertia);
+ btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, nullptr, localInertia);
btBody = bulletnew(btRigidBody(cInfo));
reload_shapes();
setupBulletCollisionObject(btBody);
- set_mode(PhysicsServer::BODY_MODE_RIGID);
+ set_mode(PhysicsServer3D::BODY_MODE_RIGID);
reload_axis_lock();
areasWhereIam.resize(maxAreasWhereIam);
for (int i = areasWhereIam.size() - 1; 0 <= i; --i) {
- areasWhereIam.write[i] = NULL;
+ areasWhereIam.write[i] = nullptr;
}
btBody->setSleepingThresholds(0.2, 0.2);
@@ -315,7 +315,7 @@ void RigidBodyBullet::init_kinematic_utilities() {
void RigidBodyBullet::destroy_kinematic_utilities() {
if (kinematic_utilities) {
memdelete(kinematic_utilities);
- kinematic_utilities = NULL;
+ kinematic_utilities = nullptr;
}
}
@@ -359,18 +359,18 @@ void RigidBodyBullet::dispatch_callbacks() {
if (omit_forces_integration)
btBody->clearForces();
- BulletPhysicsDirectBodyState *bodyDirect = BulletPhysicsDirectBodyState::get_singleton(this);
+ BulletPhysicsDirectBodyState3D *bodyDirect = BulletPhysicsDirectBodyState3D::get_singleton(this);
Variant variantBodyDirect = bodyDirect;
Object *obj = ObjectDB::get_instance(force_integration_callback->id);
if (!obj) {
// Remove integration callback
- set_force_integration_callback(0, StringName());
+ set_force_integration_callback(ObjectID(), StringName());
} else {
const Variant *vp[2] = { &variantBodyDirect, &force_integration_callback->udata };
- Variant::CallError responseCallError;
+ Callable::CallError responseCallError;
int argc = (force_integration_callback->udata.get_type() == Variant::NIL) ? 1 : 2;
obj->call(force_integration_callback->method, vp, argc, responseCallError);
}
@@ -392,10 +392,10 @@ void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const String
if (force_integration_callback) {
memdelete(force_integration_callback);
- force_integration_callback = NULL;
+ force_integration_callback = nullptr;
}
- if (p_id != 0) {
+ if (p_id.is_valid()) {
force_integration_callback = memnew(ForceIntegrationCallback);
force_integration_callback->id = p_id;
force_integration_callback->method = p_method;
@@ -487,29 +487,29 @@ void RigidBodyBullet::set_omit_forces_integration(bool p_omit) {
omit_forces_integration = p_omit;
}
-void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_value) {
+void RigidBodyBullet::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer::BODY_PARAM_BOUNCE:
+ case PhysicsServer3D::BODY_PARAM_BOUNCE:
btBody->setRestitution(p_value);
break;
- case PhysicsServer::BODY_PARAM_FRICTION:
+ case PhysicsServer3D::BODY_PARAM_FRICTION:
btBody->setFriction(p_value);
break;
- case PhysicsServer::BODY_PARAM_MASS: {
+ case PhysicsServer3D::BODY_PARAM_MASS: {
ERR_FAIL_COND(p_value < 0);
mass = p_value;
_internal_set_mass(p_value);
break;
}
- case PhysicsServer::BODY_PARAM_LINEAR_DAMP:
+ case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP:
linearDamp = p_value;
btBody->setDamping(linearDamp, angularDamp);
break;
- case PhysicsServer::BODY_PARAM_ANGULAR_DAMP:
+ case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP:
angularDamp = p_value;
btBody->setDamping(linearDamp, angularDamp);
break;
- case PhysicsServer::BODY_PARAM_GRAVITY_SCALE:
+ case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE:
gravity_scale = p_value;
/// The Bullet gravity will be is set by reload_space_override_modificator
scratch_space_override_modificator();
@@ -519,21 +519,21 @@ void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_v
}
}
-real_t RigidBodyBullet::get_param(PhysicsServer::BodyParameter p_param) const {
+real_t RigidBodyBullet::get_param(PhysicsServer3D::BodyParameter p_param) const {
switch (p_param) {
- case PhysicsServer::BODY_PARAM_BOUNCE:
+ case PhysicsServer3D::BODY_PARAM_BOUNCE:
return btBody->getRestitution();
- case PhysicsServer::BODY_PARAM_FRICTION:
+ case PhysicsServer3D::BODY_PARAM_FRICTION:
return btBody->getFriction();
- case PhysicsServer::BODY_PARAM_MASS: {
+ case PhysicsServer3D::BODY_PARAM_MASS: {
const btScalar invMass = btBody->getInvMass();
return 0 == invMass ? 0 : 1 / invMass;
}
- case PhysicsServer::BODY_PARAM_LINEAR_DAMP:
+ case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP:
return linearDamp;
- case PhysicsServer::BODY_PARAM_ANGULAR_DAMP:
+ case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP:
return angularDamp;
- case PhysicsServer::BODY_PARAM_GRAVITY_SCALE:
+ case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE:
return gravity_scale;
default:
WARN_PRINT("Parameter " + itos(p_param) + " not supported by bullet");
@@ -541,31 +541,31 @@ real_t RigidBodyBullet::get_param(PhysicsServer::BodyParameter p_param) const {
}
}
-void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) {
+void RigidBodyBullet::set_mode(PhysicsServer3D::BodyMode p_mode) {
// This is necessary to block force_integration untile next move
can_integrate_forces = false;
destroy_kinematic_utilities();
// The mode change is relevant to its mass
switch (p_mode) {
- case PhysicsServer::BODY_MODE_KINEMATIC:
- mode = PhysicsServer::BODY_MODE_KINEMATIC;
+ case PhysicsServer3D::BODY_MODE_KINEMATIC:
+ mode = PhysicsServer3D::BODY_MODE_KINEMATIC;
reload_axis_lock();
_internal_set_mass(0);
init_kinematic_utilities();
break;
- case PhysicsServer::BODY_MODE_STATIC:
- mode = PhysicsServer::BODY_MODE_STATIC;
+ case PhysicsServer3D::BODY_MODE_STATIC:
+ mode = PhysicsServer3D::BODY_MODE_STATIC;
reload_axis_lock();
_internal_set_mass(0);
break;
- case PhysicsServer::BODY_MODE_RIGID:
- mode = PhysicsServer::BODY_MODE_RIGID;
+ case PhysicsServer3D::BODY_MODE_RIGID:
+ mode = PhysicsServer3D::BODY_MODE_RIGID;
reload_axis_lock();
_internal_set_mass(0 == mass ? 1 : mass);
scratch_space_override_modificator();
break;
- case PhysicsServer::BODY_MODE_CHARACTER:
- mode = PhysicsServer::BODY_MODE_CHARACTER;
+ case PhysicsServer3D::BODY_MODE_CHARACTER:
+ mode = PhysicsServer3D::BODY_MODE_CHARACTER;
reload_axis_lock();
_internal_set_mass(0 == mass ? 1 : mass);
scratch_space_override_modificator();
@@ -575,26 +575,26 @@ void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) {
btBody->setAngularVelocity(btVector3(0, 0, 0));
btBody->setLinearVelocity(btVector3(0, 0, 0));
}
-PhysicsServer::BodyMode RigidBodyBullet::get_mode() const {
+PhysicsServer3D::BodyMode RigidBodyBullet::get_mode() const {
return mode;
}
-void RigidBodyBullet::set_state(PhysicsServer::BodyState p_state, const Variant &p_variant) {
+void RigidBodyBullet::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) {
switch (p_state) {
- case PhysicsServer::BODY_STATE_TRANSFORM:
+ case PhysicsServer3D::BODY_STATE_TRANSFORM:
set_transform(p_variant);
break;
- case PhysicsServer::BODY_STATE_LINEAR_VELOCITY:
+ case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY:
set_linear_velocity(p_variant);
break;
- case PhysicsServer::BODY_STATE_ANGULAR_VELOCITY:
+ case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY:
set_angular_velocity(p_variant);
break;
- case PhysicsServer::BODY_STATE_SLEEPING:
+ case PhysicsServer3D::BODY_STATE_SLEEPING:
set_activation_state(!bool(p_variant));
break;
- case PhysicsServer::BODY_STATE_CAN_SLEEP:
+ case PhysicsServer3D::BODY_STATE_CAN_SLEEP:
can_sleep = bool(p_variant);
if (!can_sleep) {
// Can't sleep
@@ -606,17 +606,17 @@ void RigidBodyBullet::set_state(PhysicsServer::BodyState p_state, const Variant
}
}
-Variant RigidBodyBullet::get_state(PhysicsServer::BodyState p_state) const {
+Variant RigidBodyBullet::get_state(PhysicsServer3D::BodyState p_state) const {
switch (p_state) {
- case PhysicsServer::BODY_STATE_TRANSFORM:
+ case PhysicsServer3D::BODY_STATE_TRANSFORM:
return get_transform();
- case PhysicsServer::BODY_STATE_LINEAR_VELOCITY:
+ case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY:
return get_linear_velocity();
- case PhysicsServer::BODY_STATE_ANGULAR_VELOCITY:
+ case PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY:
return get_angular_velocity();
- case PhysicsServer::BODY_STATE_SLEEPING:
+ case PhysicsServer3D::BODY_STATE_SLEEPING:
return !is_active();
- case PhysicsServer::BODY_STATE_CAN_SLEEP:
+ case PhysicsServer3D::BODY_STATE_CAN_SLEEP:
return can_sleep;
default:
WARN_PRINT("This state " + itos(p_state) + " is not supported by Bullet");
@@ -714,7 +714,7 @@ Vector3 RigidBodyBullet::get_applied_torque() const {
return gTotTorq;
}
-void RigidBodyBullet::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) {
+void RigidBodyBullet::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock) {
if (lock) {
locked_axis |= p_axis;
} else {
@@ -724,18 +724,18 @@ void RigidBodyBullet::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) {
reload_axis_lock();
}
-bool RigidBodyBullet::is_axis_locked(PhysicsServer::BodyAxis p_axis) const {
+bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const {
return locked_axis & p_axis;
}
void RigidBodyBullet::reload_axis_lock() {
- btBody->setLinearFactor(btVector3(float(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_X)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Y)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Z))));
- if (PhysicsServer::BODY_MODE_CHARACTER == mode) {
+ btBody->setLinearFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z))));
+ if (PhysicsServer3D::BODY_MODE_CHARACTER == mode) {
/// When character angular is always locked
btBody->setAngularFactor(btVector3(0., 0., 0.));
} else {
- btBody->setAngularFactor(btVector3(float(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_X)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Y)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Z))));
+ btBody->setAngularFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_ANGULAR_Z))));
}
}
@@ -794,7 +794,7 @@ Vector3 RigidBodyBullet::get_angular_velocity() const {
}
void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transform) {
- if (mode == PhysicsServer::BODY_MODE_KINEMATIC) {
+ if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
if (space && space->get_delta_time() != 0)
btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time());
// The kinematic use MotionState class
@@ -847,7 +847,7 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) {
}
for (int i = 0; i < areaWhereIamCount; ++i) {
- if (NULL == areasWhereIam[i]) {
+ if (nullptr == areasWhereIam[i]) {
// This area has the highest priority
areasWhereIam.write[i] = p_area;
break;
@@ -862,7 +862,7 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) {
}
}
}
- if (PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
+ if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
scratch_space_override_modificator();
}
@@ -894,8 +894,8 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
}
--areaWhereIamCount;
- areasWhereIam.write[areaWhereIamCount] = NULL; // Even if this is not required, I clear the last element to be safe
- if (PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
+ areasWhereIam.write[areaWhereIamCount] = nullptr; // Even if this is not required, I clear the last element to be safe
+ if (PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) {
scratch_space_override_modificator();
}
}
@@ -904,7 +904,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
void RigidBodyBullet::reload_space_override_modificator() {
// Make sure that kinematic bodies have their total gravity calculated
- if (!is_active() && PhysicsServer::BODY_MODE_KINEMATIC != mode)
+ if (!is_active() && PhysicsServer3D::BODY_MODE_KINEMATIC != mode)
return;
Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude());
@@ -920,7 +920,7 @@ void RigidBodyBullet::reload_space_override_modificator() {
currentArea = areasWhereIam[i];
- if (!currentArea || PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) {
+ if (!currentArea || PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) {
continue;
}
@@ -954,11 +954,11 @@ void RigidBodyBullet::reload_space_override_modificator() {
}
switch (currentArea->get_spOv_mode()) {
- case PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED:
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED:
/// This area does not affect gravity/damp. These are generally areas
/// that exist only to detect collisions, and objects entering or exiting them.
break;
- case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE:
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE:
/// This area adds its gravity/damp values to whatever has been
/// calculated so far. This way, many overlapping areas can combine
/// their physics to make interesting
@@ -967,7 +967,7 @@ void RigidBodyBullet::reload_space_override_modificator() {
newAngularDamp += currentArea->get_spOv_angularDamp();
++countCombined;
break;
- case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE:
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE:
/// This area adds its gravity/damp values to whatever has been calculated
/// so far. Then stops taking into account the rest of the areas, even the
/// default one.
@@ -976,7 +976,7 @@ void RigidBodyBullet::reload_space_override_modificator() {
newAngularDamp += currentArea->get_spOv_angularDamp();
++countCombined;
goto endAreasCycle;
- case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE:
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE:
/// This area replaces any gravity/damp, even the default one, and
/// stops taking into account the rest of the areas.
newGravity = support_gravity;
@@ -984,7 +984,7 @@ void RigidBodyBullet::reload_space_override_modificator() {
newAngularDamp = currentArea->get_spOv_angularDamp();
countCombined = 1;
goto endAreasCycle;
- case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE_COMBINE:
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE:
/// This area replaces any gravity/damp calculated so far, but keeps
/// calculating the rest of the areas, down to the default one.
newGravity = support_gravity;
@@ -1032,14 +1032,14 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
const bool isDynamic = p_mass != 0.f;
if (isDynamic) {
- if (PhysicsServer::BODY_MODE_RIGID != mode && PhysicsServer::BODY_MODE_CHARACTER != mode)
+ if (PhysicsServer3D::BODY_MODE_RIGID != mode && PhysicsServer3D::BODY_MODE_CHARACTER != mode)
return;
m_isStatic = false;
if (mainShape)
mainShape->calculateLocalInertia(p_mass, localInertia);
- if (PhysicsServer::BODY_MODE_RIGID == mode) {
+ if (PhysicsServer3D::BODY_MODE_RIGID == mode) {
btBody->setCollisionFlags(clearedCurrentFlags); // Just set the flags without Kin and Static
} else {
@@ -1054,11 +1054,11 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
}
} else {
- if (PhysicsServer::BODY_MODE_STATIC != mode && PhysicsServer::BODY_MODE_KINEMATIC != mode)
+ if (PhysicsServer3D::BODY_MODE_STATIC != mode && PhysicsServer3D::BODY_MODE_KINEMATIC != mode)
return;
m_isStatic = true;
- if (PhysicsServer::BODY_MODE_STATIC == mode) {
+ if (PhysicsServer3D::BODY_MODE_STATIC == mode) {
btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_STATIC_OBJECT);
} else {
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index ca599f7a77..420b5cc443 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -45,37 +45,37 @@ class AreaBullet;
class SpaceBullet;
class btRigidBody;
class GodotMotionState;
-class BulletPhysicsDirectBodyState;
+class BulletPhysicsDirectBodyState3D;
/// This class could be used in multi thread with few changes but currently
/// is set to be only in one single thread.
///
/// In the system there is only one object at a time that manage all bodies and is
-/// created by BulletPhysicsServer and is held by the "singleton" variable of this class
+/// created by BulletPhysicsServer3D and is held by the "singleton" variable of this class
/// Each time something require it, the body must be set again.
-class BulletPhysicsDirectBodyState : public PhysicsDirectBodyState {
- GDCLASS(BulletPhysicsDirectBodyState, PhysicsDirectBodyState);
+class BulletPhysicsDirectBodyState3D : public PhysicsDirectBodyState3D {
+ GDCLASS(BulletPhysicsDirectBodyState3D, PhysicsDirectBodyState3D);
- static BulletPhysicsDirectBodyState *singleton;
+ static BulletPhysicsDirectBodyState3D *singleton;
public:
/// This class avoid the creation of more object of this class
static void initSingleton() {
if (!singleton) {
- singleton = memnew(BulletPhysicsDirectBodyState);
+ singleton = memnew(BulletPhysicsDirectBodyState3D);
}
}
static void destroySingleton() {
memdelete(singleton);
- singleton = NULL;
+ singleton = nullptr;
}
static void singleton_setDeltaTime(real_t p_deltaTime) {
singleton->deltaTime = p_deltaTime;
}
- static BulletPhysicsDirectBodyState *get_singleton(RigidBodyBullet *p_body) {
+ static BulletPhysicsDirectBodyState3D *get_singleton(RigidBodyBullet *p_body) {
singleton->body = p_body;
return singleton;
}
@@ -85,7 +85,7 @@ public:
real_t deltaTime;
private:
- BulletPhysicsDirectBodyState() {}
+ BulletPhysicsDirectBodyState3D() {}
public:
virtual Vector3 get_total_gravity() const;
@@ -117,7 +117,7 @@ public:
virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
virtual void apply_torque_impulse(const Vector3 &p_impulse);
- virtual void set_sleep_state(bool p_enable);
+ virtual void set_sleep_state(bool p_sleep);
virtual bool is_sleeping() const;
virtual int get_contact_count() const;
@@ -138,7 +138,7 @@ public:
// Skip the execution of this function
}
- virtual PhysicsDirectSpaceState *get_space_state();
+ virtual PhysicsDirectSpaceState3D *get_space_state();
};
class RigidBodyBullet : public RigidCollisionObjectBullet {
@@ -166,7 +166,7 @@ public:
btTransform transform;
KinematicShape() :
- shape(NULL) {}
+ shape(nullptr) {}
bool is_active() const { return shape; }
};
@@ -187,12 +187,12 @@ public:
};
private:
- friend class BulletPhysicsDirectBodyState;
+ friend class BulletPhysicsDirectBodyState3D;
// This is required only for Kinematic movement
KinematicUtilities *kinematic_utilities;
- PhysicsServer::BodyMode mode;
+ PhysicsServer3D::BodyMode mode;
GodotMotionState *godotMotionState;
btRigidBody *btBody;
uint16_t locked_axis;
@@ -278,14 +278,14 @@ public:
void set_omit_forces_integration(bool p_omit);
_FORCE_INLINE_ bool get_omit_forces_integration() const { return omit_forces_integration; }
- void set_param(PhysicsServer::BodyParameter p_param, real_t);
- real_t get_param(PhysicsServer::BodyParameter p_param) const;
+ void set_param(PhysicsServer3D::BodyParameter p_param, real_t);
+ real_t get_param(PhysicsServer3D::BodyParameter p_param) const;
- void set_mode(PhysicsServer::BodyMode p_mode);
- PhysicsServer::BodyMode get_mode() const;
+ void set_mode(PhysicsServer3D::BodyMode p_mode);
+ PhysicsServer3D::BodyMode get_mode() const;
- void set_state(PhysicsServer::BodyState p_state, const Variant &p_variant);
- Variant get_state(PhysicsServer::BodyState p_state) const;
+ void set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant);
+ Variant get_state(PhysicsServer3D::BodyState p_state) const;
void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse);
void apply_central_impulse(const Vector3 &p_impulse);
@@ -300,8 +300,8 @@ public:
void set_applied_torque(const Vector3 &p_torque);
Vector3 get_applied_torque() const;
- void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock);
- bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const;
+ void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool lock);
+ bool is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const;
void reload_axis_lock();
/// Doc:
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index f46db09e4a..8ac26a0fdb 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -122,8 +122,8 @@ btBoxShape *ShapeBullet::create_shape_box(const btVector3 &boxHalfExtents) {
return bulletnew(btBoxShape(boxHalfExtents));
}
-btCapsuleShapeZ *ShapeBullet::create_shape_capsule(btScalar radius, btScalar height) {
- return bulletnew(btCapsuleShapeZ(radius, height));
+btCapsuleShape *ShapeBullet::create_shape_capsule(btScalar radius, btScalar height) {
+ return bulletnew(btCapsuleShape(radius, height));
}
btCylinderShape *ShapeBullet::create_shape_cylinder(btScalar radius, btScalar height) {
@@ -138,19 +138,19 @@ btScaledBvhTriangleMeshShape *ShapeBullet::create_shape_concave(btBvhTriangleMes
if (p_mesh_shape) {
return bulletnew(btScaledBvhTriangleMeshShape(p_mesh_shape, p_local_scaling));
} else {
- return NULL;
+ return nullptr;
}
}
-btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) {
+btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) {
const btScalar ignoredHeightScale(1);
const int YAxis = 1; // 0=X, 1=Y, 2=Z
const bool flipQuadEdges = false;
- const void *heightsPtr = p_heights.read().ptr();
+ const void *heightsPtr = p_heights.ptr();
btHeightfieldTerrainShape *heightfield = bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, p_min_height, p_max_height, YAxis, PHY_FLOAT, flipQuadEdges));
- // The shape can be created without params when you do PhysicsServer.shape_create(PhysicsServer.SHAPE_HEIGHTMAP)
+ // The shape can be created without params when you do PhysicsServer3D.shape_create(PhysicsServer3D.SHAPE_HEIGHTMAP)
if (heightsPtr)
heightfield->buildAccelerator(16);
@@ -176,8 +176,8 @@ Variant PlaneShapeBullet::get_data() const {
return plane;
}
-PhysicsServer::ShapeType PlaneShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_PLANE;
+PhysicsServer3D::ShapeType PlaneShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_PLANE;
}
void PlaneShapeBullet::setup(const Plane &p_plane) {
@@ -204,8 +204,8 @@ Variant SphereShapeBullet::get_data() const {
return radius;
}
-PhysicsServer::ShapeType SphereShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_SPHERE;
+PhysicsServer3D::ShapeType SphereShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_SPHERE;
}
void SphereShapeBullet::setup(real_t p_radius) {
@@ -231,8 +231,8 @@ Variant BoxShapeBullet::get_data() const {
return g_half_extents;
}
-PhysicsServer::ShapeType BoxShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_BOX;
+PhysicsServer3D::ShapeType BoxShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_BOX;
}
void BoxShapeBullet::setup(const Vector3 &p_half_extents) {
@@ -263,8 +263,8 @@ Variant CapsuleShapeBullet::get_data() const {
return d;
}
-PhysicsServer::ShapeType CapsuleShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_CAPSULE;
+PhysicsServer3D::ShapeType CapsuleShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_CAPSULE;
}
void CapsuleShapeBullet::setup(real_t p_height, real_t p_radius) {
@@ -296,8 +296,8 @@ Variant CylinderShapeBullet::get_data() const {
return d;
}
-PhysicsServer::ShapeType CylinderShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_CYLINDER;
+PhysicsServer3D::ShapeType CylinderShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_CYLINDER;
}
void CylinderShapeBullet::setup(real_t p_height, real_t p_radius) {
@@ -334,8 +334,8 @@ Variant ConvexPolygonShapeBullet::get_data() const {
return out_vertices;
}
-PhysicsServer::ShapeType ConvexPolygonShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_CONVEX_POLYGON;
+PhysicsServer3D::ShapeType ConvexPolygonShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_CONVEX_POLYGON;
}
void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) {
@@ -362,7 +362,7 @@ btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_i
ConcavePolygonShapeBullet::ConcavePolygonShapeBullet() :
ShapeBullet(),
- meshShape(NULL) {}
+ meshShape(nullptr) {}
ConcavePolygonShapeBullet::~ConcavePolygonShapeBullet() {
if (meshShape) {
@@ -370,7 +370,7 @@ ConcavePolygonShapeBullet::~ConcavePolygonShapeBullet() {
delete meshShape->getTriangleInfoMap();
bulletdelete(meshShape);
}
- faces = PoolVector<Vector3>();
+ faces = Vector<Vector3>();
}
void ConcavePolygonShapeBullet::set_data(const Variant &p_data) {
@@ -381,11 +381,11 @@ Variant ConcavePolygonShapeBullet::get_data() const {
return faces;
}
-PhysicsServer::ShapeType ConcavePolygonShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_CONCAVE_POLYGON;
+PhysicsServer3D::ShapeType ConcavePolygonShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_CONCAVE_POLYGON;
}
-void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
+void ConcavePolygonShapeBullet::setup(Vector<Vector3> p_faces) {
faces = p_faces;
if (meshShape) {
/// Clear previous created shape
@@ -401,8 +401,8 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
btTriangleMesh *shapeInterface = bulletnew(btTriangleMesh);
src_face_count /= 3;
- PoolVector<Vector3>::Read r = p_faces.read();
- const Vector3 *facesr = r.ptr();
+ const Vector3 *r = p_faces.ptr();
+ const Vector3 *facesr = r;
btVector3 supVec_0;
btVector3 supVec_1;
@@ -425,7 +425,7 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
btGenerateInternalEdgeInfo(meshShape, triangleInfoMap);
}
} else {
- meshShape = NULL;
+ meshShape = nullptr;
ERR_PRINT("The faces count are 0, the mesh shape cannot be created");
}
notifyShapeChanged();
@@ -434,7 +434,7 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) {
btCollisionShape *cs = ShapeBullet::create_shape_concave(meshShape);
if (!cs)
- // This is necessary since if 0 faces the creation of concave return NULL
+ // This is necessary since if 0 faces the creation of concave return null
cs = ShapeBullet::create_shape_empty();
cs->setLocalScaling(p_implicit_scale);
prepare(cs);
@@ -471,10 +471,10 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
// TODO This code will need adjustments if real_t is set to `double`,
// because that precision is unnecessary for a heightmap and Bullet doesn't support it...
- PoolVector<real_t> l_heights;
+ Vector<real_t> l_heights;
Variant l_heights_v = d["heights"];
- if (l_heights_v.get_type() == Variant::POOL_REAL_ARRAY) {
+ if (l_heights_v.get_type() == Variant::PACKED_FLOAT32_ARRAY) {
// Ready-to-use heights can be passed
l_heights = l_heights_v;
@@ -491,13 +491,13 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
// We could convert here automatically but it's better to not be intrusive and let the caller do it if necessary.
ERR_FAIL_COND(l_image->get_format() != Image::FORMAT_RF);
- PoolByteArray im_data = l_image->get_data();
+ PackedByteArray im_data = l_image->get_data();
l_heights.resize(l_image->get_width() * l_image->get_height());
- PoolRealArray::Write w = l_heights.write();
- PoolByteArray::Read r = im_data.read();
- float *rp = (float *)r.ptr();
+ real_t *w = l_heights.ptrw();
+ const uint8_t *r = im_data.ptr();
+ float *rp = (float *)r;
// At this point, `rp` could be used directly for Bullet, but I don't know how safe it would be.
for (int i = 0; i < l_heights.size(); ++i) {
@@ -505,7 +505,7 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
}
} else {
- ERR_FAIL_MSG("Expected PoolRealArray or float Image.");
+ ERR_FAIL_MSG("Expected PackedFloat32Array or float Image.");
}
ERR_FAIL_COND(l_width <= 0);
@@ -515,7 +515,7 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
// Compute min and max heights if not specified.
if (!d.has("min_height") && !d.has("max_height")) {
- PoolVector<real_t>::Read r = l_heights.read();
+ const real_t *r = l_heights.ptr();
int heights_size = l_heights.size();
for (int i = 0; i < heights_size; ++i) {
@@ -536,11 +536,11 @@ Variant HeightMapShapeBullet::get_data() const {
ERR_FAIL_V(Variant());
}
-PhysicsServer::ShapeType HeightMapShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_HEIGHTMAP;
+PhysicsServer3D::ShapeType HeightMapShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_HEIGHTMAP;
}
-void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) {
+void HeightMapShapeBullet::setup(Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) {
// TODO cell size must be tweaked using localScaling, which is a shared property for all Bullet shapes
// If this array is resized outside of here, it should be preserved due to CoW
@@ -580,8 +580,8 @@ Variant RayShapeBullet::get_data() const {
return d;
}
-PhysicsServer::ShapeType RayShapeBullet::get_type() const {
- return PhysicsServer::SHAPE_RAY;
+PhysicsServer3D::ShapeType RayShapeBullet::get_type() const {
+ return PhysicsServer3D::SHAPE_RAY;
}
void RayShapeBullet::setup(real_t p_length, bool p_slips_on_slope) {
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index 8d3512cab4..0dbc616fe5 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -34,7 +34,7 @@
#include "core/math/geometry.h"
#include "core/variant.h"
#include "rid_bullet.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
#include <LinearMath/btAlignedObjectArray.h>
#include <LinearMath/btScalar.h>
@@ -78,19 +78,19 @@ public:
virtual void set_data(const Variant &p_data) = 0;
virtual Variant get_data() const = 0;
- virtual PhysicsServer::ShapeType get_type() const = 0;
+ virtual PhysicsServer3D::ShapeType get_type() const = 0;
public:
static class btEmptyShape *create_shape_empty();
static class btStaticPlaneShape *create_shape_plane(const btVector3 &planeNormal, btScalar planeConstant);
static class btSphereShape *create_shape_sphere(btScalar radius);
static class btBoxShape *create_shape_box(const btVector3 &boxHalfExtents);
- static class btCapsuleShapeZ *create_shape_capsule(btScalar radius, btScalar height);
+ static class btCapsuleShape *create_shape_capsule(btScalar radius, btScalar height);
static class btCylinderShape *create_shape_cylinder(btScalar radius, btScalar height);
/// IMPORTANT: Remember to delete the shape interface by calling: delete my_shape->getMeshInterface();
static class btConvexPointCloudShape *create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling = btVector3(1, 1, 1));
static class btScaledBvhTriangleMeshShape *create_shape_concave(btBvhTriangleMeshShape *p_mesh_shape, const btVector3 &p_local_scaling = btVector3(1, 1, 1));
- static class btHeightfieldTerrainShape *create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height);
+ static class btHeightfieldTerrainShape *create_shape_height_field(Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height);
static class btRayShape *create_shape_ray(real_t p_length, bool p_slips_on_slope);
};
@@ -103,7 +103,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
@@ -120,7 +120,7 @@ public:
_FORCE_INLINE_ real_t get_radius() { return radius; }
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
@@ -137,7 +137,7 @@ public:
_FORCE_INLINE_ const btVector3 &get_half_extents() { return half_extents; }
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
@@ -156,7 +156,7 @@ public:
_FORCE_INLINE_ real_t get_radius() { return radius; }
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
@@ -175,7 +175,7 @@ public:
_FORCE_INLINE_ real_t get_radius() { return radius; }
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0);
private:
@@ -192,7 +192,7 @@ public:
virtual void set_data(const Variant &p_data);
void get_vertices(Vector<Vector3> &out_vertices);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
@@ -203,24 +203,24 @@ class ConcavePolygonShapeBullet : public ShapeBullet {
class btBvhTriangleMeshShape *meshShape;
public:
- PoolVector<Vector3> faces;
+ Vector<Vector3> faces;
ConcavePolygonShapeBullet();
virtual ~ConcavePolygonShapeBullet();
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
- void setup(PoolVector<Vector3> p_faces);
+ void setup(Vector<Vector3> p_faces);
};
class HeightMapShapeBullet : public ShapeBullet {
public:
- PoolVector<real_t> heights;
+ Vector<real_t> heights;
int width;
int depth;
real_t min_height;
@@ -230,11 +230,11 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
- void setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height);
+ void setup(Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height);
};
class RayShapeBullet : public ShapeBullet {
@@ -247,7 +247,7 @@ public:
virtual void set_data(const Variant &p_data);
virtual Variant get_data() const;
- virtual PhysicsServer::ShapeType get_type() const;
+ virtual PhysicsServer3D::ShapeType get_type() const;
virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0);
private:
diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp
index d9ebb9d580..f193daef39 100644
--- a/modules/bullet/slider_joint_bullet.cpp
+++ b/modules/bullet/slider_joint_bullet.cpp
@@ -342,58 +342,58 @@ real_t SliderJointBullet::getLinearPos() {
;
}
-void SliderJointBullet::set_param(PhysicsServer::SliderJointParam p_param, real_t p_value) {
+void SliderJointBullet::set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER: setUpperLinLimit(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER: setLowerLinLimit(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: setSoftnessLimLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: setRestitutionLimLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: setDampingLimLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: setSoftnessDirLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: setRestitutionDirLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_DAMPING: setDampingDirLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: setDampingOrthoLin(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: setUpperAngLimit(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: setLowerAngLimit(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: setSoftnessLimAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: setRestitutionLimAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: setDampingLimAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: setSoftnessDirAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: setRestitutionDirAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: setDampingDirAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: setDampingOrthoAng(p_value); break;
- case PhysicsServer::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: setUpperLinLimit(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: setLowerLinLimit(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: setSoftnessLimLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: setRestitutionLimLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: setDampingLimLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: setSoftnessDirLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: setRestitutionDirLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: setDampingDirLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: setDampingOrthoLin(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: setUpperAngLimit(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: setLowerAngLimit(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: setSoftnessLimAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: setRestitutionLimAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: setDampingLimAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: setSoftnessDirAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: setRestitutionDirAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: setDampingDirAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: setDampingOrthoAng(p_value); break;
+ case PhysicsServer3D::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning
}
}
-real_t SliderJointBullet::get_param(PhysicsServer::SliderJointParam p_param) const {
+real_t SliderJointBullet::get_param(PhysicsServer3D::SliderJointParam p_param) const {
switch (p_param) {
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER: return getUpperLinLimit();
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER: return getLowerLinLimit();
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: return getSoftnessLimLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: return getRestitutionLimLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: return getDampingLimLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: return getSoftnessDirLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: return getRestitutionDirLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_MOTION_DAMPING: return getDampingDirLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoLin();
- case PhysicsServer::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: return getDampingOrthoLin();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: return getUpperAngLimit();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: return getLowerAngLimit();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: return getSoftnessLimAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: return getRestitutionLimAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: return getDampingLimAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: return getSoftnessDirAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: return getRestitutionDirAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: return getDampingDirAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoAng();
- case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: return getDampingOrthoAng();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: return getUpperLinLimit();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: return getLowerLinLimit();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: return getSoftnessLimLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: return getRestitutionLimLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: return getDampingLimLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: return getSoftnessDirLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: return getRestitutionDirLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: return getDampingDirLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: return getDampingOrthoLin();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: return getUpperAngLimit();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: return getLowerAngLimit();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: return getSoftnessLimAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: return getRestitutionLimAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: return getDampingLimAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: return getSoftnessDirAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: return getRestitutionDirAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: return getDampingDirAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: return getDampingOrthoAng();
default:
return 0;
}
diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h
index d98a1b8c95..6410b952ed 100644
--- a/modules/bullet/slider_joint_bullet.h
+++ b/modules/bullet/slider_joint_bullet.h
@@ -46,7 +46,7 @@ public:
/// Reference frame is A
SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB);
- virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_SLIDER; }
+ virtual PhysicsServer3D::JointType get_type() const { return PhysicsServer3D::JOINT_SLIDER; }
const RigidBodyBullet *getRigidBodyA() const;
const RigidBodyBullet *getRigidBodyB() const;
@@ -115,7 +115,7 @@ public:
real_t getMaxAngMotorForce();
real_t getLinearPos();
- void set_param(PhysicsServer::SliderJointParam p_param, real_t p_value);
- real_t get_param(PhysicsServer::SliderJointParam p_param) const;
+ void set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value);
+ real_t get_param(PhysicsServer3D::SliderJointParam p_param) const;
};
#endif
diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp
index f4c0ffa6eb..236bdc7c8a 100644
--- a/modules/bullet/soft_body_bullet.cpp
+++ b/modules/bullet/soft_body_bullet.cpp
@@ -32,12 +32,12 @@
#include "bullet_types_converter.h"
#include "bullet_utilities.h"
-#include "scene/3d/soft_body.h"
+#include "scene/3d/soft_body_3d.h"
#include "space_bullet.h"
SoftBodyBullet::SoftBodyBullet() :
CollisionObjectBullet(CollisionObjectBullet::TYPE_SOFT_BODY),
- bt_soft_body(NULL),
+ bt_soft_body(nullptr),
isScratched(false),
simulation_precision(5),
total_mass(1.),
@@ -76,7 +76,7 @@ void SoftBodyBullet::on_enter_area(AreaBullet *p_area) {}
void SoftBodyBullet::on_exit_area(AreaBullet *p_area) {}
-void SoftBodyBullet::update_visual_server(SoftBodyVisualServerHandler *p_visual_server_handler) {
+void SoftBodyBullet::update_rendering_server(SoftBodyRenderingServerHandler *p_rendering_server_handler) {
if (!bt_soft_body)
return;
@@ -96,8 +96,8 @@ void SoftBodyBullet::update_visual_server(SoftBodyVisualServerHandler *p_visual_
const int vs_indices_size(vs_indices->size());
for (int x = 0; x < vs_indices_size; ++x) {
- p_visual_server_handler->set_vertex((*vs_indices)[x], vertex_position);
- p_visual_server_handler->set_normal((*vs_indices)[x], vertex_normal);
+ p_rendering_server_handler->set_vertex((*vs_indices)[x], vertex_position);
+ p_rendering_server_handler->set_normal((*vs_indices)[x], vertex_normal);
}
}
@@ -112,7 +112,7 @@ void SoftBodyBullet::update_visual_server(SoftBodyVisualServerHandler *p_visual_
B_TO_G(aabb_min, aabb.position);
B_TO_G(size, aabb.size);
- p_visual_server_handler->set_aabb(aabb);
+ p_rendering_server_handler->set_aabb(aabb);
}
void SoftBodyBullet::set_soft_mesh(const Ref<Mesh> &p_mesh) {
@@ -129,8 +129,8 @@ void SoftBodyBullet::set_soft_mesh(const Ref<Mesh> &p_mesh) {
}
Array arrays = soft_mesh->surface_get_arrays(0);
- ERR_FAIL_COND(!(soft_mesh->surface_get_format(0) & VS::ARRAY_FORMAT_INDEX));
- set_trimesh_body_shape(arrays[VS::ARRAY_INDEX], arrays[VS::ARRAY_VERTEX]);
+ ERR_FAIL_COND(!(soft_mesh->surface_get_format(0) & RS::ARRAY_FORMAT_INDEX));
+ set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]);
}
void SoftBodyBullet::destroy_soft_body() {
@@ -144,7 +144,7 @@ void SoftBodyBullet::destroy_soft_body() {
}
destroyBulletCollisionObject();
- bt_soft_body = NULL;
+ bt_soft_body = nullptr;
}
void SoftBodyBullet::set_soft_transform(const Transform &p_transform) {
@@ -168,6 +168,7 @@ void SoftBodyBullet::set_node_position(int p_node_index, const Vector3 &p_global
void SoftBodyBullet::set_node_position(int p_node_index, const btVector3 &p_global_position) {
if (bt_soft_body) {
+ bt_soft_body->m_nodes[p_node_index].m_q = bt_soft_body->m_nodes[p_node_index].m_x;
bt_soft_body->m_nodes[p_node_index].m_x = p_global_position;
}
}
@@ -183,7 +184,7 @@ void SoftBodyBullet::get_node_offset(int p_node_index, Vector3 &r_offset) const
return;
Array arrays = soft_mesh->surface_get_arrays(0);
- PoolVector<Vector3> vertices(arrays[VS::ARRAY_VERTEX]);
+ Vector<Vector3> vertices(arrays[RS::ARRAY_VERTEX]);
if (0 <= p_node_index && vertices.size() > p_node_index) {
r_offset = vertices[p_node_index];
@@ -229,8 +230,8 @@ void SoftBodyBullet::reset_all_node_positions() {
return;
Array arrays = soft_mesh->surface_get_arrays(0);
- PoolVector<Vector3> vs_vertices(arrays[VS::ARRAY_VERTEX]);
- PoolVector<Vector3>::Read vs_vertices_read = vs_vertices.read();
+ Vector<Vector3> vs_vertices(arrays[RS::ARRAY_VERTEX]);
+ const Vector3 *vs_vertices_read = vs_vertices.ptr();
for (int vertex_index = bt_soft_body->m_nodes.size() - 1; 0 <= vertex_index; --vertex_index) {
@@ -319,7 +320,7 @@ void SoftBodyBullet::set_drag_coefficient(real_t p_val) {
}
}
-void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVector<Vector3> p_vertices) {
+void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices) {
/// Assert the current soft body is destroyed
destroy_soft_body();
@@ -338,7 +339,7 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVecto
const int vs_vertices_size(p_vertices.size());
- PoolVector<Vector3>::Read p_vertices_read = p_vertices.read();
+ const Vector3 *p_vertices_read = p_vertices.ptr();
for (int vs_vertex_index = 0; vs_vertex_index < vs_vertices_size; ++vs_vertex_index) {
@@ -365,7 +366,7 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVecto
{ // Parse vertices to bullet
bt_vertices.resize(indices_map_size * 3);
- PoolVector<Vector3>::Read p_vertices_read = p_vertices.read();
+ const Vector3 *p_vertices_read = p_vertices.ptr();
for (int i = 0; i < indices_map_size; ++i) {
bt_vertices.write[3 * i + 0] = p_vertices_read[indices_table[i][0]].x;
@@ -381,7 +382,7 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVecto
bt_triangles.resize(triangles_size * 3);
- PoolVector<int>::Read p_indices_read = p_indices.read();
+ const int *p_indices_read = p_indices.ptr();
for (int i = 0; i < triangles_size; ++i) {
bt_triangles.write[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]];
@@ -403,7 +404,7 @@ void SoftBodyBullet::setup_soft_body() {
// Soft body setup
setupBulletCollisionObject(bt_soft_body);
- bt_soft_body->m_worldInfo = NULL; // Remove fake world info
+ bt_soft_body->m_worldInfo = nullptr; // Remove fake world info
bt_soft_body->getCollisionShape()->setMargin(0.01);
bt_soft_body->setCollisionFlags(bt_soft_body->getCollisionFlags() & (~(btCollisionObject::CF_KINEMATIC_OBJECT | btCollisionObject::CF_STATIC_OBJECT)));
diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h
index b98116b073..3c6871e0d6 100644
--- a/modules/bullet/soft_body_bullet.h
+++ b/modules/bullet/soft_body_bullet.h
@@ -43,7 +43,7 @@
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "collision_object_bullet.h"
#include "scene/resources/mesh.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
#ifdef x11_None
/// This is required to re add the macro None defined by x11 compiler
@@ -59,7 +59,7 @@ class SoftBodyBullet : public CollisionObjectBullet {
private:
btSoftBody *bt_soft_body;
- Vector<Vector<int> > indices_table;
+ Vector<Vector<int>> indices_table;
btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody
bool isScratched;
@@ -100,7 +100,7 @@ public:
_FORCE_INLINE_ btSoftBody *get_bt_soft_body() const { return bt_soft_body; }
- void update_visual_server(class SoftBodyVisualServerHandler *p_visual_server_handler);
+ void update_rendering_server(class SoftBodyRenderingServerHandler *p_rendering_server_handler);
void set_soft_mesh(const Ref<Mesh> &p_mesh);
void destroy_soft_body();
@@ -152,7 +152,7 @@ public:
_FORCE_INLINE_ real_t get_drag_coefficient() const { return drag_coefficient; }
private:
- void set_trimesh_body_shape(PoolVector<int> p_indices, PoolVector<Vector3> p_vertices);
+ void set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices);
void setup_soft_body();
void pin_node(int p_node_index);
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 762637ce75..1659664ff9 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -39,7 +39,7 @@
#include "godot_collision_configuration.h"
#include "godot_collision_dispatcher.h"
#include "rigid_body_bullet.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
#include "soft_body_bullet.h"
#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
@@ -59,7 +59,7 @@
*/
BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_space) :
- PhysicsDirectSpaceState(),
+ PhysicsDirectSpaceState3D(),
space(p_space) {}
int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
@@ -108,7 +108,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V
r_result.shape = btResult.m_shapeId;
r_result.rid = gObj->get_self();
r_result.collider_id = gObj->get_instance_id();
- r_result.collider = 0 == r_result.collider_id ? NULL : ObjectDB::get_instance(r_result.collider_id);
+ r_result.collider = r_result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(r_result.collider_id);
} else {
WARN_PRINT("The raycast performed has hit a collision object that is not part of Godot scene, please check it.");
}
@@ -122,7 +122,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
if (p_result_max <= 0)
return 0;
- ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale_abs(), p_margin);
if (!btShape->isConvex()) {
@@ -152,7 +152,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra
}
bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
- ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin);
if (!btShape->isConvex()) {
@@ -207,7 +207,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
if (p_result_max <= 0)
return 0;
- ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin);
if (!btShape->isConvex()) {
@@ -239,7 +239,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
- ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape);
+ ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin);
if (!btShape->isConvex()) {
@@ -309,7 +309,7 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_
btPointCollector result;
btGjkPairDetector gjk_pair_detector(&point_shape, convex_shape, space->gjk_simplex_solver, space->gjk_epa_pen_solver);
- gjk_pair_detector.getClosestPoints(input, result, 0);
+ gjk_pair_detector.getClosestPoints(input, result, nullptr);
if (out_distance > result.m_distance) {
out_distance = result.m_distance;
@@ -332,14 +332,14 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_
}
SpaceBullet::SpaceBullet() :
- broadphase(NULL),
- collisionConfiguration(NULL),
- dispatcher(NULL),
- solver(NULL),
- dynamicsWorld(NULL),
- soft_body_world_info(NULL),
- ghostPairCallback(NULL),
- godotFilterCallback(NULL),
+ broadphase(nullptr),
+ collisionConfiguration(nullptr),
+ dispatcher(nullptr),
+ solver(nullptr),
+ dynamicsWorld(nullptr),
+ soft_body_world_info(nullptr),
+ ghostPairCallback(nullptr),
+ godotFilterCallback(nullptr),
gravityDirection(0, -1, 0),
gravityMagnitude(10),
contactDebugCount(0),
@@ -366,27 +366,27 @@ void SpaceBullet::step(real_t p_delta_time) {
dynamicsWorld->stepSimulation(p_delta_time, 0, 0);
}
-void SpaceBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value) {
+void SpaceBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) {
assert(dynamicsWorld);
switch (p_param) {
- case PhysicsServer::AREA_PARAM_GRAVITY:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY:
gravityMagnitude = p_value;
update_gravity();
break;
- case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR:
gravityDirection = p_value;
update_gravity();
break;
- case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
- case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
break; // No damp
- case PhysicsServer::AREA_PARAM_PRIORITY:
+ case PhysicsServer3D::AREA_PARAM_PRIORITY:
// Priority is always 0, the lower
break;
- case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
- case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
- case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
break;
default:
WARN_PRINT("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it.");
@@ -394,22 +394,22 @@ void SpaceBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant
}
}
-Variant SpaceBullet::get_param(PhysicsServer::AreaParameter p_param) {
+Variant SpaceBullet::get_param(PhysicsServer3D::AreaParameter p_param) {
switch (p_param) {
- case PhysicsServer::AREA_PARAM_GRAVITY:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY:
return gravityMagnitude;
- case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR:
return gravityDirection;
- case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
- case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
+ case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
return 0; // No damp
- case PhysicsServer::AREA_PARAM_PRIORITY:
+ case PhysicsServer3D::AREA_PARAM_PRIORITY:
return 0; // Priority is always 0, the lower
- case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT:
return false;
- case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
return 0;
- case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
return 0;
default:
WARN_PRINT("This get parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it.");
@@ -417,32 +417,32 @@ Variant SpaceBullet::get_param(PhysicsServer::AreaParameter p_param) {
}
}
-void SpaceBullet::set_param(PhysicsServer::SpaceParameter p_param, real_t p_value) {
+void SpaceBullet::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
- case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION:
- case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
- case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
- case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
- case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP:
- case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
- case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
+ case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
default:
WARN_PRINT("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it.");
break;
}
}
-real_t SpaceBullet::get_param(PhysicsServer::SpaceParameter p_param) {
+real_t SpaceBullet::get_param(PhysicsServer3D::SpaceParameter p_param) {
switch (p_param) {
- case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
- case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION:
- case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
- case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
- case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
- case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP:
- case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
- case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
+ case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
default:
WARN_PRINT("The SpaceBullet doesn't support this get parameter (" + itos(p_param) + "), 0 is returned.");
return 0.f;
@@ -511,7 +511,7 @@ void SpaceBullet::remove_soft_body(SoftBodyBullet *p_body) {
if (is_using_soft_world()) {
if (p_body->get_bt_soft_body()) {
static_cast<btSoftRigidDynamicsWorld *>(dynamicsWorld)->removeSoftBody(p_body->get_bt_soft_body());
- p_body->get_bt_soft_body()->m_worldInfo = NULL;
+ p_body->get_bt_soft_body()->m_worldInfo = nullptr;
}
}
}
@@ -539,7 +539,7 @@ void SpaceBullet::remove_all_collision_objects() {
for (int i = dynamicsWorld->getNumCollisionObjects() - 1; 0 <= i; --i) {
btCollisionObject *btObj = dynamicsWorld->getCollisionObjectArray()[i];
CollisionObjectBullet *colObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
- colObj->set_space(NULL);
+ colObj->set_space(nullptr);
}
}
@@ -636,8 +636,8 @@ void SpaceBullet::destroy_world() {
/// The world elements (like: Collision Objects, Constraints, Shapes) are managed by godot
- dynamicsWorld->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(NULL);
- dynamicsWorld->getPairCache()->setOverlapFilterCallback(NULL);
+ dynamicsWorld->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(nullptr);
+ dynamicsWorld->getPairCache()->setOverlapFilterCallback(nullptr);
bulletdelete(ghostPairCallback);
bulletdelete(godotFilterCallback);
@@ -645,7 +645,7 @@ void SpaceBullet::destroy_world() {
// Deallocate world
dynamicsWorld->~btDiscreteDynamicsWorld();
free(dynamicsWorld);
- dynamicsWorld = NULL;
+ dynamicsWorld = nullptr;
bulletdelete(solver);
bulletdelete(broadphase);
@@ -726,9 +726,6 @@ void SpaceBullet::check_ghost_overlaps() {
other_body_shape = static_cast<btCollisionShape *>(otherObject->get_bt_shape(z));
- if (other_body_shape->isConcave())
- continue;
-
btTransform other_shape_transform(otherObject->get_bt_shape_transform(z));
other_shape_transform.getOrigin() *= other_body_scale;
@@ -744,7 +741,7 @@ void SpaceBullet::check_ghost_overlaps() {
static_cast<btConvexShape *>(other_body_shape),
gjk_simplex_solver,
gjk_epa_pen_solver);
- gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
+ gjk_pair_detector.getClosestPoints(gjk_input, result, nullptr);
if (0 >= result.m_distance) {
hasOverlap = true;
@@ -753,10 +750,10 @@ void SpaceBullet::check_ghost_overlaps() {
} else {
- btCollisionObjectWrapper obA(NULL, area_shape, area->get_bt_ghost(), gjk_input.m_transformA, -1, y);
- btCollisionObjectWrapper obB(NULL, other_body_shape, otherObject->get_bt_collision_object(), gjk_input.m_transformB, -1, z);
+ btCollisionObjectWrapper obA(nullptr, area_shape, area->get_bt_ghost(), gjk_input.m_transformA, -1, y);
+ btCollisionObjectWrapper obB(nullptr, other_body_shape, otherObject->get_bt_collision_object(), gjk_input.m_transformB, -1, z);
- btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CONTACT_POINT_ALGORITHMS);
+ btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, nullptr, BT_CONTACT_POINT_ALGORITHMS);
if (!algorithm)
continue;
@@ -888,41 +885,41 @@ void SpaceBullet::update_gravity() {
#include "scene/3d/immediate_geometry.h"
-static ImmediateGeometry *motionVec(NULL);
-static ImmediateGeometry *normalLine(NULL);
-static Ref<SpatialMaterial> red_mat;
-static Ref<SpatialMaterial> blue_mat;
+static ImmediateGeometry3D *motionVec(nullptr);
+static ImmediateGeometry3D *normalLine(nullptr);
+static Ref<StandardMaterial3D> red_mat;
+static Ref<StandardMaterial3D> blue_mat;
#endif
-bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer::MotionResult *r_result, bool p_exclude_raycast_shapes) {
+bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes) {
#if debug_test_motion
/// Yes I know this is not good, but I've used it as fast debugging hack.
/// I'm leaving it here just for speedup the other eventual debugs
if (!normalLine) {
- motionVec = memnew(ImmediateGeometry);
- normalLine = memnew(ImmediateGeometry);
+ motionVec = memnew(ImmediateGeometry3D);
+ normalLine = memnew(ImmediateGeometry3D);
SceneTree::get_singleton()->get_current_scene()->add_child(motionVec);
SceneTree::get_singleton()->get_current_scene()->add_child(normalLine);
motionVec->set_as_toplevel(true);
normalLine->set_as_toplevel(true);
- red_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- red_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ red_mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ red_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
red_mat->set_line_width(20.0);
- red_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- red_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- red_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ red_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ red_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ red_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
red_mat->set_albedo(Color(1, 0, 0, 1));
motionVec->set_material_override(red_mat);
- blue_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- blue_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ blue_mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ blue_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
blue_mat->set_line_width(20.0);
- blue_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- blue_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- blue_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ blue_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ blue_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ blue_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
blue_mat->set_albedo(Color(0, 0, 1, 1));
normalLine->set_material_override(blue_mat);
}
@@ -954,7 +951,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
Vector3 sup_line;
B_TO_G(body_safe_position.getOrigin(), sup_line);
motionVec->clear();
- motionVec->begin(Mesh::PRIMITIVE_LINES, NULL);
+ motionVec->begin(Mesh::PRIMITIVE_LINES, nullptr);
motionVec->add_vertex(sup_line);
motionVec->add_vertex(sup_line + p_motion * 10);
motionVec->end();
@@ -1031,7 +1028,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
Vector3 sup_line2;
B_TO_G(motion, sup_line2);
normalLine->clear();
- normalLine->begin(Mesh::PRIMITIVE_LINES, NULL);
+ normalLine->begin(Mesh::PRIMITIVE_LINES, nullptr);
normalLine->add_vertex(r_result->collision_point);
normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10);
normalLine->end();
@@ -1045,7 +1042,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
return has_penetration;
}
-int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer::SeparationResult *r_results, int p_result_max, float p_margin) {
+int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin) {
btTransform body_transform;
G_TO_B(p_transform, body_transform);
@@ -1057,7 +1054,7 @@ int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p
int rays_found_this_round = 0;
for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) {
- PhysicsServer::SeparationResult *next_results = &r_results[rays_found];
+ PhysicsServer3D::SeparationResult *next_results = &r_results[rays_found];
rays_found_this_round = recover_from_penetration_ray(p_body, body_transform, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, p_result_max - rays_found, recover_motion, next_results);
rays_found += rays_found_this_round;
@@ -1127,7 +1124,7 @@ public:
if (cs->getNumChildShapes() > 1) {
const btDbvt *tree = cs->getDynamicAabbTree();
- ERR_FAIL_COND_V(tree == NULL, true);
+ ERR_FAIL_COND_V(tree == nullptr, true);
// Transform bounds into compound shape local space
const btTransform other_in_compound_space = co->getWorldTransform().inverse();
@@ -1278,7 +1275,7 @@ bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const bt
// Perform GJK test
btPointCollector result;
btGjkPairDetector gjk_pair_detector(p_shapeA, p_shapeB, gjk_simplex_solver, gjk_epa_pen_solver);
- gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
+ gjk_pair_detector.getClosestPoints(gjk_input, result, nullptr);
if (0 > result.m_distance) {
// Has penetration
r_delta_recover_movement += result.m_normalOnBInWorld * (result.m_distance * -1 * p_recover_movement_scale);
@@ -1305,10 +1302,10 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC
btTransform tA(p_transformA);
- btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, tA, -1, p_shapeId_A);
- btCollisionObjectWrapper obB(NULL, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B);
+ btCollisionObjectWrapper obA(nullptr, p_shapeA, p_objectA, tA, -1, p_shapeId_A);
+ btCollisionObjectWrapper obB(nullptr, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B);
- btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CONTACT_POINT_ALGORITHMS);
+ btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, nullptr, BT_CONTACT_POINT_ALGORITHMS);
if (algorithm) {
GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB);
//discrete collision detection query
@@ -1336,7 +1333,7 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC
return false;
}
-int SpaceBullet::add_separation_result(PhysicsServer::SeparationResult *r_result, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const {
+int SpaceBullet::add_separation_result(PhysicsServer3D::SeparationResult *r_result, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const {
// optimize results (ignore non-colliding)
if (p_recover_result.penetration_distance < 0.0) {
@@ -1358,7 +1355,7 @@ int SpaceBullet::add_separation_result(PhysicsServer::SeparationResult *r_result
}
}
-int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer::SeparationResult *r_results) {
+int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer3D::SeparationResult *r_results) {
// Calculate the cumulative AABB of all shapes of the kinematic body
btVector3 aabb_min, aabb_max;
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index 32372f1630..f9a8c063fd 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -35,7 +35,7 @@
#include "core/vector.h"
#include "godot_result_callbacks.h"
#include "rid_bullet.h"
-#include "servers/physics_server.h"
+#include "servers/physics_server_3d.h"
#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
#include <BulletCollision/BroadphaseCollision/btOverlappingPairCache.h>
@@ -67,8 +67,8 @@ class btGjkEpaPenetrationDepthSolver;
extern ContactAddedCallback gContactAddedCallback;
-class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState {
- GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState);
+class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState3D {
+ GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState3D);
private:
SpaceBullet *space;
@@ -79,7 +79,7 @@ public:
virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_ray = false);
virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
- virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = NULL);
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, ShapeRestInfo *r_info = nullptr);
/// Returns the list of contacts pairs in this order: Local contact, other body contact
virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
@@ -131,15 +131,15 @@ public:
/// @param p_param:
/// AREA_PARAM_GRAVITY to set the gravity magnitude of entire world
/// AREA_PARAM_GRAVITY_VECTOR to set the gravity direction of entire world
- void set_param(PhysicsServer::AreaParameter p_param, const Variant &p_value);
+ void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value);
/// Used to get some parameters to Bullet world
/// @param p_param:
/// AREA_PARAM_GRAVITY to get the gravity magnitude of entire world
/// AREA_PARAM_GRAVITY_VECTOR to get the gravity direction of entire world
- Variant get_param(PhysicsServer::AreaParameter p_param);
+ Variant get_param(PhysicsServer3D::AreaParameter p_param);
- void set_param(PhysicsServer::SpaceParameter p_param, real_t p_value);
- real_t get_param(PhysicsServer::SpaceParameter p_param);
+ void set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value);
+ real_t get_param(PhysicsServer3D::SpaceParameter p_param);
void add_area(AreaBullet *p_area);
void remove_area(AreaBullet *p_area);
@@ -177,8 +177,8 @@ public:
void update_gravity();
- bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer::MotionResult *r_result, bool p_exclude_raycast_shapes);
- int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer::SeparationResult *r_results, int p_result_max, float p_margin);
+ bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes);
+ int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin);
private:
void create_empty_world(bool p_create_soft_world);
@@ -201,19 +201,19 @@ private:
pointWorld(0, 0, 0),
penetration_distance(1e20),
other_compound_shape_index(0),
- other_collision_object(NULL),
+ other_collision_object(nullptr),
local_shape_most_recovered(0) {}
};
- bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
+ bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = nullptr);
/// This is an API that recover a kinematic object from penetration
/// This allow only Convex Convex test and it always use GJK algorithm, With this API we don't benefit of Bullet special accelerated functions
- bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
+ bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = nullptr);
/// This is an API that recover a kinematic object from penetration
/// Using this we leave Bullet to select the best algorithm, For example GJK in case we have Convex Convex, or a Bullet accelerated algorithm
- bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
+ bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = nullptr);
- int add_separation_result(PhysicsServer::SeparationResult *r_results, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const;
- int recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer::SeparationResult *r_results);
+ int add_separation_result(PhysicsServer3D::SeparationResult *r_results, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const;
+ int recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer3D::SeparationResult *r_results);
};
#endif
diff --git a/modules/camera/SCsub b/modules/camera/SCsub
index 23f031f06e..63c4e9fbab 100644
--- a/modules/camera/SCsub
+++ b/modules/camera/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_camera = env_modules.Clone()
@@ -10,7 +10,7 @@ if env["platform"] == "iphone":
modules_sources = []
env_camera.add_source_files(modules_sources, "register_types.cpp")
env_camera.add_source_files(modules_sources, "camera_ios.mm")
- mod_lib = env_modules.add_library('#bin/libgodot_camera_module' + env['LIBSUFFIX'], modules_sources)
+ mod_lib = env_modules.add_library("#bin/libgodot_camera_module" + env["LIBSUFFIX"], modules_sources)
elif env["platform"] == "windows":
env_camera.add_source_files(env.modules_sources, "register_types.cpp")
@@ -19,4 +19,3 @@ elif env["platform"] == "windows":
elif env["platform"] == "osx":
env_camera.add_source_files(env.modules_sources, "register_types.cpp")
env_camera.add_source_files(env.modules_sources, "camera_osx.mm")
-
diff --git a/modules/camera/camera_ios.h b/modules/camera/camera_ios.h
index 89620f788b..7da43e4851 100644
--- a/modules/camera/camera_ios.h
+++ b/modules/camera/camera_ios.h
@@ -42,4 +42,4 @@ public:
void update_feeds();
};
-#endif /* CAMERAIOS_H */ \ No newline at end of file
+#endif /* CAMERAIOS_H */
diff --git a/modules/camera/camera_ios.mm b/modules/camera/camera_ios.mm
index 8059277503..f01135f251 100644
--- a/modules/camera/camera_ios.mm
+++ b/modules/camera/camera_ios.mm
@@ -44,7 +44,7 @@
Ref<CameraFeed> feed;
size_t width[2];
size_t height[2];
- PoolVector<uint8_t> img_data[2];
+ Vector<uint8_t> img_data[2];
AVCaptureDeviceInput *input;
AVCaptureVideoDataOutput *output;
@@ -175,7 +175,7 @@
img_data[0].resize(new_width * new_height);
}
- PoolVector<uint8_t>::Write w = img_data[0].write();
+ uint8_t *w = img_data[0].ptrw();
memcpy(w.ptr(), dataY, new_width * new_height);
img[0].instance();
@@ -196,7 +196,7 @@
img_data[1].resize(2 * new_width * new_height);
}
- PoolVector<uint8_t>::Write w = img_data[1].write();
+ uint8_t *w = img_data[1].ptrw();
memcpy(w.ptr(), dataCbCr, 2 * new_width * new_height);
///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion
diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm
index 658ddb728b..9a72174723 100644
--- a/modules/camera/camera_osx.mm
+++ b/modules/camera/camera_osx.mm
@@ -42,7 +42,7 @@
Ref<CameraFeed> feed;
size_t width[2];
size_t height[2];
- PoolVector<uint8_t> img_data[2];
+ Vector<uint8_t> img_data[2];
AVCaptureDeviceInput *input;
AVCaptureVideoDataOutput *output;
@@ -159,8 +159,8 @@
img_data[0].resize(new_width * new_height);
}
- PoolVector<uint8_t>::Write w = img_data[0].write();
- memcpy(w.ptr(), dataY, new_width * new_height);
+ uint8_t *w = img_data[0].ptrw();
+ memcpy(w, dataY, new_width * new_height);
img[0].instance();
img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]);
@@ -177,8 +177,8 @@
img_data[1].resize(2 * new_width * new_height);
}
- PoolVector<uint8_t>::Write w = img_data[1].write();
- memcpy(w.ptr(), dataCbCr, 2 * new_width * new_height);
+ uint8_t *w = img_data[1].ptrw();
+ memcpy(w, dataCbCr, 2 * new_width * new_height);
///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion
img[1].instance();
diff --git a/modules/camera/config.py b/modules/camera/config.py
index d308c04195..87d7542741 100644
--- a/modules/camera/config.py
+++ b/modules/camera/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return platform == 'iphone' or platform == 'osx' or platform == 'windows'
+ return platform == "iphone" or platform == "osx" or platform == "windows"
+
def configure(env):
pass
diff --git a/modules/csg/SCsub b/modules/csg/SCsub
index 57c504efd8..641a42c187 100644
--- a/modules/csg/SCsub
+++ b/modules/csg/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_csg = env_modules.Clone()
diff --git a/modules/csg/config.py b/modules/csg/config.py
index 38ccc66d91..9106cbceca 100644
--- a/modules/csg/config.py
+++ b/modules/csg/config.py
@@ -1,21 +1,24 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
- "CSGBox",
- "CSGCombiner",
- "CSGCylinder",
- "CSGMesh",
- "CSGPolygon",
- "CSGPrimitive",
- "CSGShape",
- "CSGSphere",
- "CSGTorus",
+ "CSGBox3D",
+ "CSGCombiner3D",
+ "CSGCylinder3D",
+ "CSGMesh3D",
+ "CSGPolygon3D",
+ "CSGPrimitive3D",
+ "CSGShape3D",
+ "CSGSphere3D",
+ "CSGTorus3D",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index cc3bbed27f..3f61e2852f 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -29,70 +29,215 @@
/*************************************************************************/
#include "csg.h"
-#include "core/math/face3.h"
+
#include "core/math/geometry.h"
-#include "core/os/os.h"
+#include "core/math/math_funcs.h"
#include "core/sort_array.h"
-#include "thirdparty/misc/triangulator.h"
-void CSGBrush::clear() {
- faces.clear();
+// Static helper functions.
+
+inline static bool is_snapable(const Vector3 &p_point1, const Vector3 &p_point2, real_t p_distance) {
+
+ return (p_point1 - p_point2).length_squared() < p_distance * p_distance;
+}
+
+inline static Vector2 interpolate_segment_uv(const Vector2 p_segement_points[2], const Vector2 p_uvs[2], const Vector2 &p_interpolation_point) {
+
+ float segment_length = (p_segement_points[1] - p_segement_points[0]).length();
+ if (segment_length < CMP_EPSILON)
+ return p_uvs[0];
+
+ float distance = (p_interpolation_point - p_segement_points[0]).length();
+ float fraction = distance / segment_length;
+
+ return p_uvs[0].linear_interpolate(p_uvs[1], fraction);
+}
+
+inline static Vector2 interpolate_triangle_uv(const Vector2 p_vertices[3], const Vector2 p_uvs[3], const Vector2 &p_interpolation_point) {
+
+ if (p_interpolation_point.distance_squared_to(p_vertices[0]) < CMP_EPSILON2)
+ return p_uvs[0];
+ if (p_interpolation_point.distance_squared_to(p_vertices[1]) < CMP_EPSILON2)
+ return p_uvs[1];
+ if (p_interpolation_point.distance_squared_to(p_vertices[2]) < CMP_EPSILON2)
+ return p_uvs[2];
+
+ Vector2 edge1 = p_vertices[1] - p_vertices[0];
+ Vector2 edge2 = p_vertices[2] - p_vertices[0];
+ Vector2 interpolation = p_interpolation_point - p_vertices[0];
+
+ float edge1_on_edge1 = edge1.dot(edge1);
+ float edge1_on_edge2 = edge1.dot(edge2);
+ float edge2_on_edge2 = edge2.dot(edge2);
+ float inter_on_edge1 = interpolation.dot(edge1);
+ float inter_on_edge2 = interpolation.dot(edge2);
+ float scale = (edge1_on_edge1 * edge2_on_edge2 - edge1_on_edge2 * edge1_on_edge2);
+ if (scale == 0)
+ return p_uvs[0];
+
+ float v = (edge2_on_edge2 * inter_on_edge1 - edge1_on_edge2 * inter_on_edge2) / scale;
+ float w = (edge1_on_edge1 * inter_on_edge2 - edge1_on_edge2 * inter_on_edge1) / scale;
+ float u = 1.0f - v - w;
+
+ return p_uvs[0] * u + p_uvs[1] * v + p_uvs[2] * w;
+}
+
+static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 p_vertices[3], float p_tolerance, Vector3 &r_intersection_point) {
+
+ Vector3 edge1 = p_vertices[1] - p_vertices[0];
+ Vector3 edge2 = p_vertices[2] - p_vertices[0];
+ Vector3 h = p_dir.cross(edge2);
+ real_t a = edge1.dot(h);
+ // Check if ray is parallel to triangle.
+ if (Math::is_zero_approx(a))
+ return false;
+ real_t f = 1.0 / a;
+
+ Vector3 s = p_from - p_vertices[0];
+ real_t u = f * s.dot(h);
+ if (u < 0.0 - p_tolerance || u > 1.0 + p_tolerance)
+ return false;
+
+ Vector3 q = s.cross(edge1);
+ real_t v = f * p_dir.dot(q);
+ if (v < 0.0 - p_tolerance || u + v > 1.0 + p_tolerance)
+ return false;
+
+ // Ray intersects triangle.
+ // Calculate distance.
+ real_t t = f * edge2.dot(q);
+ // Confirm triangle is in front of ray.
+ if (t >= p_tolerance) {
+ r_intersection_point = p_from + p_dir * t;
+ return true;
+ } else
+ return false;
+}
+
+inline bool is_point_in_triangle(const Vector3 &p_point, const Vector3 p_vertices[3], int p_shifted = 0) {
+
+ real_t det = p_vertices[0].dot(p_vertices[1].cross(p_vertices[2]));
+
+ // If determinant is, zero try shift the triangle and the point.
+ if (Math::is_zero_approx(det)) {
+ if (p_shifted > 2) {
+ // Triangle appears degenerate, so ignore it.
+ return false;
+ }
+ Vector3 shift_by;
+ shift_by[p_shifted] = 1;
+ Vector3 shifted_point = p_point + shift_by;
+ Vector3 shifted_vertices[3] = { p_vertices[0] + shift_by, p_vertices[1] + shift_by, p_vertices[2] + shift_by };
+ return is_point_in_triangle(shifted_point, shifted_vertices, p_shifted + 1);
+ }
+
+ // Find the barycentric coordinates of the point with respect to the vertices.
+ real_t lambda[3];
+ lambda[0] = p_vertices[1].cross(p_vertices[2]).dot(p_point) / det;
+ lambda[1] = p_vertices[2].cross(p_vertices[0]).dot(p_point) / det;
+ lambda[2] = p_vertices[0].cross(p_vertices[1]).dot(p_point) / det;
+
+ // Point is in the plane if all lambdas sum to 1.
+ if (!Math::is_equal_approx(lambda[0] + lambda[1] + lambda[2], 1)) return false;
+
+ // Point is inside the triangle if all lambdas are positive.
+ if (lambda[0] < 0 || lambda[1] < 0 || lambda[2] < 0) return false;
+
+ return true;
}
-void CSGBrush::build_from_faces(const PoolVector<Vector3> &p_vertices, const PoolVector<Vector2> &p_uvs, const PoolVector<bool> &p_smooth, const PoolVector<Ref<Material> > &p_materials, const PoolVector<bool> &p_invert_faces) {
+inline static bool are_segements_parallel(const Vector2 p_segment1_points[2], const Vector2 p_segment2_points[2], float p_vertex_snap2) {
+
+ Vector2 segment1 = p_segment1_points[1] - p_segment1_points[0];
+ Vector2 segment2 = p_segment2_points[1] - p_segment2_points[0];
+ real_t segment1_length2 = segment1.dot(segment1);
+ real_t segment2_length2 = segment2.dot(segment2);
+ real_t segment_onto_segment = segment2.dot(segment1);
+
+ if (segment1_length2 < p_vertex_snap2 || segment2_length2 < p_vertex_snap2)
+ return true;
+
+ real_t max_separation2;
+ if (segment1_length2 > segment2_length2) {
+ max_separation2 = segment2_length2 - segment_onto_segment * segment_onto_segment / segment1_length2;
+ } else {
+ max_separation2 = segment1_length2 - segment_onto_segment * segment_onto_segment / segment2_length2;
+ }
+
+ return max_separation2 < p_vertex_snap2;
+}
+
+// CSGBrush
+
+void CSGBrush::_regen_face_aabbs() {
+
+ for (int i = 0; i < faces.size(); i++) {
+ faces.write[i].aabb = AABB();
+ faces.write[i].aabb.position = faces[i].vertices[0];
+ faces.write[i].aabb.expand_to(faces[i].vertices[1]);
+ faces.write[i].aabb.expand_to(faces[i].vertices[2]);
+ }
+}
- clear();
+void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials, const Vector<bool> &p_invert_faces) {
+
+ faces.clear();
int vc = p_vertices.size();
ERR_FAIL_COND((vc % 3) != 0);
- PoolVector<Vector3>::Read rv = p_vertices.read();
+ const Vector3 *rv = p_vertices.ptr();
int uvc = p_uvs.size();
- PoolVector<Vector2>::Read ruv = p_uvs.read();
+ const Vector2 *ruv = p_uvs.ptr();
int sc = p_smooth.size();
- PoolVector<bool>::Read rs = p_smooth.read();
+ const bool *rs = p_smooth.ptr();
int mc = p_materials.size();
- PoolVector<Ref<Material> >::Read rm = p_materials.read();
+ const Ref<Material> *rm = p_materials.ptr();
int ic = p_invert_faces.size();
- PoolVector<bool>::Read ri = p_invert_faces.read();
+ const bool *ri = p_invert_faces.ptr();
Map<Ref<Material>, int> material_map;
faces.resize(p_vertices.size() / 3);
for (int i = 0; i < faces.size(); i++) {
+
Face &f = faces.write[i];
f.vertices[0] = rv[i * 3 + 0];
f.vertices[1] = rv[i * 3 + 1];
f.vertices[2] = rv[i * 3 + 2];
+
if (uvc == vc) {
f.uvs[0] = ruv[i * 3 + 0];
f.uvs[1] = ruv[i * 3 + 1];
f.uvs[2] = ruv[i * 3 + 2];
}
- if (sc == vc / 3) {
+
+ if (sc == vc / 3)
f.smooth = rs[i];
- } else {
+ else
f.smooth = false;
- }
- if (ic == vc / 3) {
+ if (ic == vc / 3)
f.invert = ri[i];
- } else {
+ else
f.invert = false;
- }
if (mc == vc / 3) {
+
Ref<Material> mat = rm[i];
if (mat.is_valid()) {
+
const Map<Ref<Material>, int>::Element *E = material_map.find(mat);
+
if (E) {
f.material = E->get();
} else {
f.material = material_map.size();
material_map[mat] = f.material;
}
+
} else {
f.material = -1;
}
@@ -107,17 +252,6 @@ void CSGBrush::build_from_faces(const PoolVector<Vector3> &p_vertices, const Poo
_regen_face_aabbs();
}
-void CSGBrush::_regen_face_aabbs() {
-
- for (int i = 0; i < faces.size(); i++) {
-
- faces.write[i].aabb.position = faces[i].vertices[0];
- faces.write[i].aabb.expand_to(faces[i].vertices[1]);
- faces.write[i].aabb.expand_to(faces[i].vertices[2]);
- faces.write[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision errors
- }
-}
-
void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform &p_xform) {
faces = p_brush.faces;
@@ -132,908 +266,218 @@ void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform &p_xform) {
_regen_face_aabbs();
}
-////////////////////////
-
-void CSGBrushOperation::BuildPoly::create(const CSGBrush *p_brush, int p_face, MeshMerge &mesh_merge, bool p_for_B) {
-
- //creates the initial face that will be used for clipping against the other faces
-
- Vector3 va[3] = {
- p_brush->faces[p_face].vertices[0],
- p_brush->faces[p_face].vertices[1],
- p_brush->faces[p_face].vertices[2],
- };
-
- plane = Plane(va[0], va[1], va[2]);
-
- to_world.origin = va[0];
-
- to_world.basis.set_axis(2, plane.normal);
- to_world.basis.set_axis(0, (va[1] - va[2]).normalized());
- to_world.basis.set_axis(1, to_world.basis.get_axis(0).cross(to_world.basis.get_axis(2)).normalized());
-
- to_poly = to_world.affine_inverse();
-
- face_index = p_face;
-
- for (int i = 0; i < 3; i++) {
-
- Point p;
- Vector3 localp = to_poly.xform(va[i]);
- p.point.x = localp.x;
- p.point.y = localp.y;
- p.uv = p_brush->faces[p_face].uvs[i];
-
- points.push_back(p);
-
- ///edge
-
- Edge e;
- e.points[0] = i;
- e.points[1] = (i + 1) % 3;
- e.outer = true;
- edges.push_back(e);
- }
-
- smooth = p_brush->faces[p_face].smooth;
- invert = p_brush->faces[p_face].invert;
-
- if (p_brush->faces[p_face].material != -1) {
- material = p_brush->materials[p_brush->faces[p_face].material];
- }
-
- base_edges = 3;
-}
-
-static Vector2 interpolate_uv(const Vector2 &p_vertex_a, const Vector2 &p_vertex_b, const Vector2 &p_vertex_c, const Vector2 &p_uv_a, const Vector2 &p_uv_c) {
-
- float len_a_c = (p_vertex_c - p_vertex_a).length();
- if (len_a_c < CMP_EPSILON) {
- return p_uv_a;
- }
-
- float len_a_b = (p_vertex_b - p_vertex_a).length();
-
- float c = len_a_b / len_a_c;
-
- return p_uv_a.linear_interpolate(p_uv_c, c);
-}
-
-static Vector2 interpolate_triangle_uv(const Vector2 &p_pos, const Vector2 *p_vtx, const Vector2 *p_uv) {
-
- if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2) {
- return p_uv[0];
- }
- if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2) {
- return p_uv[1];
- }
- if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2) {
- return p_uv[2];
- }
-
- Vector2 v0 = p_vtx[1] - p_vtx[0];
- Vector2 v1 = p_vtx[2] - p_vtx[0];
- Vector2 v2 = p_pos - p_vtx[0];
-
- float d00 = v0.dot(v0);
- float d01 = v0.dot(v1);
- float d11 = v1.dot(v1);
- float d20 = v2.dot(v0);
- float d21 = v2.dot(v1);
- float denom = (d00 * d11 - d01 * d01);
- if (denom == 0) {
- return p_uv[0];
- }
- float v = (d11 * d20 - d01 * d21) / denom;
- float w = (d00 * d21 - d01 * d20) / denom;
- float u = 1.0f - v - w;
-
- return p_uv[0] * u + p_uv[1] * v + p_uv[2] * w;
-}
-
-void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_face, const Vector2 *segment, MeshMerge &mesh_merge, bool p_for_B) {
+// CSGBrushOperation
- //keep track of what was inserted
- Vector<int> inserted_points;
+void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_brush_a, const CSGBrush &p_brush_b, CSGBrush &r_merged_brush, float p_vertex_snap) {
- //keep track of point indices for what was inserted, allowing reuse of points.
- int segment_idx[2] = { -1, -1 };
-
- //check if edge and poly share a vertex, of so, assign it to segment_idx
- for (int i = 0; i < points.size(); i++) {
- for (int j = 0; j < 2; j++) {
- if (segment[j].is_equal_approx(points[i].point)) {
- segment_idx[j] = i;
- inserted_points.push_back(i);
- break;
+ // Check for face collisions and add necessary faces.
+ Build2DFaceCollection build2DFaceCollection;
+ for (int i = 0; i < p_brush_a.faces.size(); i++) {
+ for (int j = 0; j < p_brush_b.faces.size(); j++) {
+ if (p_brush_a.faces[i].aabb.intersects_inclusive(p_brush_b.faces[j].aabb)) {
+ update_faces(p_brush_a, i, p_brush_b, j, build2DFaceCollection, p_vertex_snap);
}
}
}
- //check if both segment points are shared with other vertices
- if (segment_idx[0] != -1 && segment_idx[1] != -1) {
-
- if (segment_idx[0] == segment_idx[1]) {
- return; //segment was too tiny, both mapped to same point
- }
-
- bool found = false;
-
- //check if the segment already exists
- for (int i = 0; i < edges.size(); i++) {
-
- if (
- (edges[i].points[0] == segment_idx[0] && edges[i].points[1] == segment_idx[1]) ||
- (edges[i].points[0] == segment_idx[1] && edges[i].points[1] == segment_idx[0])) {
- found = true;
- break;
- }
- }
-
- if (found) {
- //it does already exist, do nothing
- return;
- }
-
- //directly add the new segment
- Edge new_edge;
- new_edge.points[0] = segment_idx[0];
- new_edge.points[1] = segment_idx[1];
- edges.push_back(new_edge);
- return;
- }
-
- //check edge by edge against the segment points to see if intersects
-
- for (int i = 0; i < base_edges; i++) {
-
- //if a point is shared with one of the edge points, then this edge must not be tested, as it will result in a numerical precision error.
- bool edge_valid = true;
- for (int j = 0; j < 2; j++) {
-
- if (edges[i].points[0] == segment_idx[0] || edges[i].points[1] == segment_idx[1] || edges[i].points[0] == segment_idx[1] || edges[i].points[1] == segment_idx[0]) {
- edge_valid = false; //segment has this point, can't check against this
- break;
- }
- }
-
- if (!edge_valid) //already hit a point in this edge, so don't test it
- continue;
-
- //see if either points are within the edge isntead of crossing it
- Vector2 res;
- bool found = false;
- int assign_segment_id = -1;
-
- for (int j = 0; j < 2; j++) {
+ // Add faces to MeshMerge.
+ MeshMerge mesh_merge;
+ mesh_merge.vertex_snap = p_vertex_snap;
- Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point };
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg);
+ for (int i = 0; i < p_brush_a.faces.size(); i++) {
- if (closest.is_equal_approx(segment[j])) {
- //point rest of this edge
- res = closest;
- found = true;
- assign_segment_id = j;
- }
- }
-
- //test if the point crosses the edge
- if (!found && Geometry::segment_intersects_segment_2d(segment[0], segment[1], points[edges[i].points[0]].point, points[edges[i].points[1]].point, &res)) {
- //point does cross the edge
- found = true;
+ Ref<Material> material;
+ if (p_brush_a.faces[i].material != -1) {
+ material = p_brush_a.materials[p_brush_a.faces[i].material];
}
- //check whether an intersection against the segment happened
- if (found) {
-
- //It did! so first, must slice the segment
- Point new_point;
- new_point.point = res;
- //make sure to interpolate UV too
- new_point.uv = interpolate_uv(points[edges[i].points[0]].point, new_point.point, points[edges[i].points[1]].point, points[edges[i].points[0]].uv, points[edges[i].points[1]].uv);
-
- int point_idx = points.size();
- points.push_back(new_point);
-
- //split the edge in 2
- Edge new_edge;
- new_edge.points[0] = edges[i].points[0];
- new_edge.points[1] = point_idx;
- new_edge.outer = edges[i].outer;
- edges.write[i].points[0] = point_idx;
- edges.insert(i, new_edge);
- i++; //skip newly inserted edge
- base_edges++; //will need an extra one in the base triangle
- if (assign_segment_id >= 0) {
- //point did split a segment, so make sure to remember this
- segment_idx[assign_segment_id] = point_idx;
+ if (build2DFaceCollection.build2DFacesA.has(i)) {
+ build2DFaceCollection.build2DFacesA[i].addFacesToMesh(mesh_merge, p_brush_a.faces[i].smooth, p_brush_a.faces[i].invert, material, false);
+ } else {
+ Vector3 points[3];
+ Vector2 uvs[3];
+ for (int j = 0; j < 3; j++) {
+ points[j] = p_brush_a.faces[i].vertices[j];
+ uvs[j] = p_brush_a.faces[i].uvs[j];
}
- inserted_points.push_back(point_idx);
+ mesh_merge.add_face(points, uvs, p_brush_a.faces[i].smooth, p_brush_a.faces[i].invert, material, false);
}
}
- //final step: after cutting the original triangle, try to see if we can still insert
- //this segment
-
- //if already inserted two points, just use them for a segment
-
- if (inserted_points.size() >= 2) { //should never be >2 on non-manifold geometry, but cope with error
- //two points were inserted, create the new edge
- Edge new_edge;
- new_edge.points[0] = inserted_points[0];
- new_edge.points[1] = inserted_points[1];
- edges.push_back(new_edge);
- return;
- }
-
- // One or no points were inserted (besides splitting), so try to see if extra points can be placed inside the triangle.
- // This needs to be done here, after the previous tests were exhausted
- for (int i = 0; i < 2; i++) {
-
- if (segment_idx[i] != -1)
- continue; //already assigned to something, so skip
-
- //check whether one of the segment endpoints is inside the triangle. If it is, this points needs to be inserted
- if (Geometry::is_point_in_triangle(segment[i], points[0].point, points[1].point, points[2].point)) {
-
- Point new_point;
- new_point.point = segment[i];
+ for (int i = 0; i < p_brush_b.faces.size(); i++) {
- Vector2 point3[3] = { points[0].point, points[1].point, points[2].point };
- Vector2 uv3[3] = { points[0].uv, points[1].uv, points[2].uv };
-
- new_point.uv = interpolate_triangle_uv(new_point.point, point3, uv3);
-
- int point_idx = points.size();
- points.push_back(new_point);
- inserted_points.push_back(point_idx);
+ Ref<Material> material;
+ if (p_brush_b.faces[i].material != -1) {
+ material = p_brush_b.materials[p_brush_b.faces[i].material];
}
- }
-
- //check again whether two points were inserted, if so then create the new edge
- if (inserted_points.size() >= 2) { //should never be >2 on non-manifold geometry, but cope with error
- Edge new_edge;
- new_edge.points[0] = inserted_points[0];
- new_edge.points[1] = inserted_points[1];
- edges.push_back(new_edge);
- }
-}
-
-void CSGBrushOperation::BuildPoly::clip(const CSGBrush *p_brush, int p_face, MeshMerge &mesh_merge, bool p_for_B) {
-
- //Clip function.. find triangle points that will be mapped to the plane and form a segment
-
- Vector2 segment[3]; //2D
- int src_points = 0;
-
- for (int i = 0; i < 3; i++) {
- Vector3 p = p_brush->faces[p_face].vertices[i];
- if (plane.has_point(p)) {
- Vector3 pp = plane.project(p);
- pp = to_poly.xform(pp);
- segment[src_points++] = Vector2(pp.x, pp.y);
+ if (build2DFaceCollection.build2DFacesB.has(i)) {
+ build2DFaceCollection.build2DFacesB[i].addFacesToMesh(mesh_merge, p_brush_b.faces[i].smooth, p_brush_b.faces[i].invert, material, true);
} else {
- Vector3 q = p_brush->faces[p_face].vertices[(i + 1) % 3];
- if (plane.has_point(q))
- continue; //next point is in plane, will be added eventually
- if (plane.is_point_over(p) == plane.is_point_over(q))
- continue; // both on same side of the plane, don't add
-
- Vector3 res;
- if (plane.intersects_segment(p, q, &res)) {
- res = to_poly.xform(res);
- segment[src_points++] = Vector2(res.x, res.y);
- }
- }
- }
-
- //all above or all below, nothing to do. Should not happen though since a precheck was done before.
- if (src_points == 0)
- return;
-
- //just one point in plane is not worth doing anything
- if (src_points == 1)
- return;
-
- //transform A points to 2D
-
- if (segment[0].is_equal_approx(segment[1]))
- return; //too small
-
- _clip_segment(p_brush, p_face, segment, mesh_merge, p_for_B);
-}
-
-void CSGBrushOperation::_collision_callback(const CSGBrush *A, int p_face_a, Map<int, BuildPoly> &build_polys_a, const CSGBrush *B, int p_face_b, Map<int, BuildPoly> &build_polys_b, MeshMerge &mesh_merge) {
-
- //construct a frame of reference for both transforms, in order to do intersection test
- Vector3 va[3] = {
- A->faces[p_face_a].vertices[0],
- A->faces[p_face_a].vertices[1],
- A->faces[p_face_a].vertices[2],
- };
- Vector3 vb[3] = {
- B->faces[p_face_b].vertices[0],
- B->faces[p_face_b].vertices[1],
- B->faces[p_face_b].vertices[2],
- };
-
- {
- //check if either is a degenerate
- if (va[0].is_equal_approx(va[1]) || va[0].is_equal_approx(va[2]) || va[1].is_equal_approx(va[2]))
- return;
-
- if (vb[0].is_equal_approx(vb[1]) || vb[0].is_equal_approx(vb[2]) || vb[1].is_equal_approx(vb[2]))
- return;
- }
-
- {
- //check if points are the same
- int equal_count = 0;
-
- for (int i = 0; i < 3; i++) {
-
+ Vector3 points[3];
+ Vector2 uvs[3];
for (int j = 0; j < 3; j++) {
- if (va[i].distance_to(vb[j]) < mesh_merge.vertex_snap) {
- equal_count++;
- break;
- }
+ points[j] = p_brush_b.faces[i].vertices[j];
+ uvs[j] = p_brush_b.faces[i].uvs[j];
}
- }
-
- //if 2 or 3 points are the same, there is no point in doing anything. They can't
- //be clipped either, so add both.
- if (equal_count == 2 || equal_count == 3) {
- return;
+ mesh_merge.add_face(points, uvs, p_brush_b.faces[i].smooth, p_brush_b.faces[i].invert, material, true);
}
}
- // do a quick pre-check for no-intersection using the SAT theorem
-
- {
-
- //b under or over a plane
- int over_count = 0, in_plane_count = 0, under_count = 0;
- Plane plane_a(va[0], va[1], va[2]);
- if (plane_a.normal == Vector3()) {
- return; //degenerate
- }
-
- for (int i = 0; i < 3; i++) {
- if (plane_a.has_point(vb[i]))
- in_plane_count++;
- else if (plane_a.is_point_over(vb[i]))
- over_count++;
- else
- under_count++;
- }
-
- if (over_count == 0 || under_count == 0)
- return; //no intersection, something needs to be under AND over
-
- //a under or over b plane
- over_count = 0;
- under_count = 0;
- in_plane_count = 0;
-
- Plane plane_b(vb[0], vb[1], vb[2]);
- if (plane_b.normal == Vector3())
- return; //degenerate
+ // Mark faces that ended up inside the intersection.
+ mesh_merge.mark_inside_faces();
- for (int i = 0; i < 3; i++) {
- if (plane_b.has_point(va[i]))
- in_plane_count++;
- else if (plane_b.is_point_over(va[i]))
- over_count++;
- else
- under_count++;
- }
+ // Create new brush and fill with new faces.
+ r_merged_brush.faces.clear();
- if (over_count == 0 || under_count == 0)
- return; //no intersection, something needs to be under AND over
+ switch (p_operation) {
- //edge pairs (cross product combinations), see SAT theorem
+ case OPERATION_UNION: {
- for (int i = 0; i < 3; i++) {
+ int outside_count = 0;
- Vector3 axis_a = (va[i] - va[(i + 1) % 3]).normalized();
+ for (int i = 0; i < mesh_merge.faces.size(); i++) {
+ if (mesh_merge.faces[i].inside)
+ continue;
+ outside_count++;
+ }
- for (int j = 0; j < 3; j++) {
+ r_merged_brush.faces.resize(outside_count);
- Vector3 axis_b = (vb[j] - vb[(j + 1) % 3]).normalized();
+ outside_count = 0;
- Vector3 sep_axis = axis_a.cross(axis_b);
- if (sep_axis == Vector3())
- continue; //colineal
- sep_axis.normalize();
+ for (int i = 0; i < mesh_merge.faces.size(); i++) {
- real_t min_a = 1e20, max_a = -1e20;
- real_t min_b = 1e20, max_b = -1e20;
+ if (mesh_merge.faces[i].inside)
+ continue;
- for (int k = 0; k < 3; k++) {
- real_t d = sep_axis.dot(va[k]);
- min_a = MIN(min_a, d);
- max_a = MAX(max_a, d);
- d = sep_axis.dot(vb[k]);
- min_b = MIN(min_b, d);
- max_b = MAX(max_b, d);
+ for (int j = 0; j < 3; j++) {
+ r_merged_brush.faces.write[outside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
+ r_merged_brush.faces.write[outside_count].uvs[j] = mesh_merge.faces[i].uvs[j];
}
- min_b -= (max_a - min_a) * 0.5;
- max_b += (max_a - min_a) * 0.5;
-
- real_t dmin = min_b - (min_a + max_a) * 0.5;
- real_t dmax = max_b - (min_a + max_a) * 0.5;
-
- if (dmin > CMP_EPSILON || dmax < -CMP_EPSILON) {
- return; //does not contain zero, so they don't overlap
- }
+ r_merged_brush.faces.write[outside_count].smooth = mesh_merge.faces[i].smooth;
+ r_merged_brush.faces.write[outside_count].invert = mesh_merge.faces[i].invert;
+ r_merged_brush.faces.write[outside_count].material = mesh_merge.faces[i].material_idx;
+ outside_count++;
}
- }
- }
-
- //if we are still here, it means they most likely intersect, so create BuildPolys if they don't exist
-
- BuildPoly *poly_a = NULL;
-
- if (!build_polys_a.has(p_face_a)) {
- BuildPoly bp;
- bp.create(A, p_face_a, mesh_merge, false);
- build_polys_a[p_face_a] = bp;
- }
-
- poly_a = &build_polys_a[p_face_a];
-
- BuildPoly *poly_b = NULL;
+ r_merged_brush._regen_face_aabbs();
- if (!build_polys_b.has(p_face_b)) {
-
- BuildPoly bp;
- bp.create(B, p_face_b, mesh_merge, true);
- build_polys_b[p_face_b] = bp;
- }
-
- poly_b = &build_polys_b[p_face_b];
-
- //clip each other, this could be improved by using vertex unique IDs (more vertices may be shared instead of using snap)
- poly_a->clip(B, p_face_b, mesh_merge, false);
- poly_b->clip(A, p_face_a, mesh_merge, true);
-}
-
-void CSGBrushOperation::_add_poly_points(const BuildPoly &p_poly, int p_edge, int p_from_point, int p_to_point, const Vector<Vector<int> > &vertex_process, Vector<bool> &edge_process, Vector<PolyPoints> &r_poly) {
-
- //this function follows the polygon points counter clockwise and adds them. It creates lists of unique polygons
- //every time an unused edge is found, it's pushed to a stack and continues from there.
-
- List<EdgeSort> edge_stack;
-
- {
- EdgeSort es;
- es.angle = 0; //won't be checked here
- es.edge = p_edge;
- es.prev_point = p_from_point;
- es.edge_point = p_to_point;
-
- edge_stack.push_back(es);
- }
-
- //attempt to empty the stack.
- while (edge_stack.size()) {
-
- EdgeSort e = edge_stack.front()->get();
- edge_stack.pop_front();
-
- if (edge_process[e.edge]) {
- //nothing to do here
- continue;
- }
-
- Vector<int> points;
- points.push_back(e.prev_point);
-
- int prev_point = e.prev_point;
- int to_point = e.edge_point;
- int current_edge = e.edge;
-
- edge_process.write[e.edge] = true; //mark as processed
-
- int limit = p_poly.points.size() * 4; //avoid infinite recursion
-
- while (to_point != e.prev_point && limit) {
-
- Vector2 segment[2] = { p_poly.points[prev_point].point, p_poly.points[to_point].point };
-
- //construct a basis transform from the segment, which will be used to check the angle
- Transform2D t2d;
- t2d[0] = (segment[1] - segment[0]).normalized(); //use as Y
- t2d[1] = Vector2(-t2d[0].y, t2d[0].x); // use as tangent
- t2d[2] = segment[1]; //origin
-
- if (t2d.basis_determinant() == 0)
- break; //abort poly
-
- t2d.affine_invert();
-
- //push all edges found here, they will be sorted by minimum angle later.
- Vector<EdgeSort> next_edges;
-
- for (int i = 0; i < vertex_process[to_point].size(); i++) {
+ } break;
- int edge = vertex_process[to_point][i];
- int opposite_point = p_poly.edges[edge].points[0] == to_point ? p_poly.edges[edge].points[1] : p_poly.edges[edge].points[0];
- if (opposite_point == prev_point)
- continue; //not going back
+ case OPERATION_INTERSECTION: {
- EdgeSort e2;
- Vector2 local_vec = t2d.xform(p_poly.points[opposite_point].point);
- e2.angle = -local_vec.angle(); //negate so we can sort by minimum angle
- e2.edge = edge;
- e2.edge_point = opposite_point;
- e2.prev_point = to_point;
+ int inside_count = 0;
- next_edges.push_back(e2);
+ for (int i = 0; i < mesh_merge.faces.size(); i++) {
+ if (!mesh_merge.faces[i].inside)
+ continue;
+ inside_count++;
}
- //finally, sort by minimum angle
- next_edges.sort();
+ r_merged_brush.faces.resize(inside_count);
- int next_point = -1;
- int next_edge = -1;
+ inside_count = 0;
- for (int i = 0; i < next_edges.size(); i++) {
+ for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (i == 0) {
- //minimum angle found is the next point
- next_point = next_edges[i].edge_point;
- next_edge = next_edges[i].edge;
+ if (!mesh_merge.faces[i].inside)
+ continue;
- } else {
- //the rest are pushed to the stack IF they were not processed yet.
- if (!edge_process[next_edges[i].edge]) {
- edge_stack.push_back(next_edges[i]);
- }
+ for (int j = 0; j < 3; j++) {
+ r_merged_brush.faces.write[inside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
+ r_merged_brush.faces.write[inside_count].uvs[j] = mesh_merge.faces[i].uvs[j];
}
- }
- if (next_edge == -1) {
- //did not find anything, may be a dead-end edge (this should normally not happen)
- //just flip the direction and go back
- next_point = prev_point;
- next_edge = current_edge;
+ r_merged_brush.faces.write[inside_count].smooth = mesh_merge.faces[i].smooth;
+ r_merged_brush.faces.write[inside_count].invert = mesh_merge.faces[i].invert;
+ r_merged_brush.faces.write[inside_count].material = mesh_merge.faces[i].material_idx;
+ inside_count++;
}
- points.push_back(to_point);
-
- prev_point = to_point;
- to_point = next_point;
- edge_process.write[next_edge] = true; //mark this edge as processed
- current_edge = next_edge;
-
- limit--;
- }
-
- //if more than 2 points were added to the polygon, add it to the list of polygons.
- if (points.size() > 2) {
- PolyPoints pp;
- pp.points = points;
- r_poly.push_back(pp);
- }
- }
-}
-
-void CSGBrushOperation::_add_poly_outline(const BuildPoly &p_poly, int p_from_point, int p_to_point, const Vector<Vector<int> > &vertex_process, Vector<int> &r_outline) {
-
- //this is the opposite of the function above. It adds polygon outlines instead.
- //this is used for triangulating holes.
- //no stack is used here because only the bigger outline is interesting.
-
- r_outline.push_back(p_from_point);
+ r_merged_brush._regen_face_aabbs();
- int prev_point = p_from_point;
- int to_point = p_to_point;
-
- int limit = p_poly.points.size() * 4; //avoid infinite recursion
-
- while (to_point != p_from_point && limit) {
-
- Vector2 segment[2] = { p_poly.points[prev_point].point, p_poly.points[to_point].point };
- //again create a transform to compute the angle.
- Transform2D t2d;
- t2d[0] = (segment[1] - segment[0]).normalized(); //use as Y
- t2d[1] = Vector2(-t2d[0].y, t2d[0].x); // use as tangent
- t2d[2] = segment[1]; //origin
-
- if (t2d.basis_determinant() == 0)
- break; //abort poly
-
- t2d.affine_invert();
-
- float max_angle = 0;
- int next_point_angle = -1;
+ } break;
- for (int i = 0; i < vertex_process[to_point].size(); i++) {
+ case OPERATION_SUBSTRACTION: {
- int edge = vertex_process[to_point][i];
- int opposite_point = p_poly.edges[edge].points[0] == to_point ? p_poly.edges[edge].points[1] : p_poly.edges[edge].points[0];
- if (opposite_point == prev_point)
- continue; //not going back
+ int face_count = 0;
- float angle = -t2d.xform(p_poly.points[opposite_point].point).angle();
- if (next_point_angle == -1 || angle > max_angle) { //same as before but use greater to check.
- max_angle = angle;
- next_point_angle = opposite_point;
+ for (int i = 0; i < mesh_merge.faces.size(); i++) {
+ if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
+ continue;
+ if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
+ continue;
+ face_count++;
}
- }
-
- if (next_point_angle == -1) {
- //go back because no route found
- next_point_angle = prev_point;
- }
-
- r_outline.push_back(to_point);
- prev_point = to_point;
- to_point = next_point_angle;
-
- limit--;
- }
-}
-
-void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const BuildPoly &p_poly, bool p_from_b) {
-
- //finally, merge the 2D polygon back to 3D
-
- Vector<Vector<int> > vertex_process;
- Vector<bool> edge_process;
-
- vertex_process.resize(p_poly.points.size());
- edge_process.resize(p_poly.edges.size());
-
- //none processed by default
- for (int i = 0; i < edge_process.size(); i++) {
- edge_process.write[i] = false;
- }
-
- //put edges in points, so points can go through them
- for (int i = 0; i < p_poly.edges.size(); i++) {
- vertex_process.write[p_poly.edges[i].points[0]].push_back(i);
- vertex_process.write[p_poly.edges[i].points[1]].push_back(i);
- }
- Vector<PolyPoints> polys;
+ r_merged_brush.faces.resize(face_count);
- //process points that were not processed
- for (int i = 0; i < edge_process.size(); i++) {
- if (edge_process[i])
- continue; //already processed
-
- int intersect_poly = -1;
-
- if (i > 0) {
- //this is disconnected, so it's clearly a hole. lets find where it belongs
- Vector2 ref_point = p_poly.points[p_poly.edges[i].points[0]].point;
-
- for (int j = 0; j < polys.size(); j++) {
-
- //find a point outside poly
- Vector2 out_point(-1e20, -1e20);
-
- const PolyPoints &pp = polys[j];
-
- for (int k = 0; k < pp.points.size(); k++) {
- Vector2 p = p_poly.points[pp.points[k]].point;
- out_point.x = MAX(out_point.x, p.x);
- out_point.y = MAX(out_point.y, p.y);
- }
-
- out_point += Vector2(0.12341234, 0.4123412); // move to a random place to avoid direct edge-point chances
+ face_count = 0;
- int intersections = 0;
+ for (int i = 0; i < mesh_merge.faces.size(); i++) {
- for (int k = 0; k < pp.points.size(); k++) {
- Vector2 p1 = p_poly.points[pp.points[k]].point;
- Vector2 p2 = p_poly.points[pp.points[(k + 1) % pp.points.size()]].point;
+ if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
+ continue;
+ if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
+ continue;
- if (Geometry::segment_intersects_segment_2d(ref_point, out_point, p1, p2, NULL)) {
- intersections++;
- }
+ for (int j = 0; j < 3; j++) {
+ r_merged_brush.faces.write[face_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
+ r_merged_brush.faces.write[face_count].uvs[j] = mesh_merge.faces[i].uvs[j];
}
- if (intersections % 2 == 1) {
- //hole is inside this poly
- intersect_poly = j;
- break;
+ if (mesh_merge.faces[i].from_b) {
+ //invert facing of insides of B
+ SWAP(r_merged_brush.faces.write[face_count].vertices[1], r_merged_brush.faces.write[face_count].vertices[2]);
+ SWAP(r_merged_brush.faces.write[face_count].uvs[1], r_merged_brush.faces.write[face_count].uvs[2]);
}
- }
- }
- if (intersect_poly != -1) {
- //must add this as a hole
- Vector<int> outline;
- _add_poly_outline(p_poly, p_poly.edges[i].points[0], p_poly.edges[i].points[1], vertex_process, outline);
-
- if (outline.size() > 1) {
- polys.write[intersect_poly].holes.push_back(outline);
+ r_merged_brush.faces.write[face_count].smooth = mesh_merge.faces[i].smooth;
+ r_merged_brush.faces.write[face_count].invert = mesh_merge.faces[i].invert;
+ r_merged_brush.faces.write[face_count].material = mesh_merge.faces[i].material_idx;
+ face_count++;
}
- }
- _add_poly_points(p_poly, i, p_poly.edges[i].points[0], p_poly.edges[i].points[1], vertex_process, edge_process, polys);
- }
-
- //get rid of holes, not the most optiomal way, but also not a common case at all to be inoptimal
- for (int i = 0; i < polys.size(); i++) {
-
- if (!polys[i].holes.size())
- continue;
-
- //repeat until no more holes are left to be merged
- while (polys[i].holes.size()) {
-
- //try to merge a hole with the outline
- bool added_hole = false;
-
- for (int j = 0; j < polys[i].holes.size(); j++) {
-
- //try hole vertices
- int with_outline_vertex = -1;
- int from_hole_vertex = -1;
-
- bool found = false;
-
- for (int k = 0; k < polys[i].holes[j].size(); k++) {
-
- int from_idx = polys[i].holes[j][k];
- Vector2 from = p_poly.points[from_idx].point;
-
- //try a segment from hole vertex to outline vertices
- from_hole_vertex = k;
-
- bool valid = true;
-
- for (int l = 0; l < polys[i].points.size(); l++) {
-
- int to_idx = polys[i].points[l];
- Vector2 to = p_poly.points[to_idx].point;
- with_outline_vertex = l;
-
- //try against outline (other points) first
-
- valid = true;
-
- for (int m = 0; m < polys[i].points.size(); m++) {
- int m_next = (m + 1) % polys[i].points.size();
- if (m == with_outline_vertex || m_next == with_outline_vertex) //do not test with edges that share this point
- continue;
+ r_merged_brush._regen_face_aabbs();
- if (Geometry::segment_intersects_segment_2d(from, to, p_poly.points[polys[i].points[m]].point, p_poly.points[polys[i].points[m_next]].point, NULL)) {
- valid = false;
- break;
- }
- }
-
- if (!valid)
- continue;
-
- //try against all holes including self
-
- for (int m = 0; m < polys[i].holes.size(); m++) {
-
- for (int n = 0; n < polys[i].holes[m].size(); n++) {
-
- int n_next = (n + 1) % polys[i].holes[m].size();
- if (m == j && (n == from_hole_vertex || n_next == from_hole_vertex)) //contains vertex being tested from current hole, skip
- continue;
-
- if (Geometry::segment_intersects_segment_2d(from, to, p_poly.points[polys[i].holes[m][n]].point, p_poly.points[polys[i].holes[m][n_next]].point, NULL)) {
- valid = false;
- break;
- }
- }
-
- if (!valid)
- break;
- }
-
- if (valid) //all passed! exit loop
- break;
- else
- continue; //something went wrong, go on.
- }
-
- if (valid) {
- found = true; //if in the end this was valid, use it
- break;
- }
- }
-
- if (found) {
-
- //hook this hole with outline, and remove from list of holes
-
- //duplicate point
- int insert_at = with_outline_vertex;
- int point = polys[i].points[insert_at];
- polys.write[i].points.insert(insert_at, point);
- insert_at++;
- //insert all others, outline should be backwards (must check)
- int holesize = polys[i].holes[j].size();
- for (int k = 0; k <= holesize; k++) {
- int idx = (from_hole_vertex + k) % holesize;
- int point2 = polys[i].holes[j][idx];
- polys.write[i].points.insert(insert_at, point2);
- insert_at++;
- }
-
- added_hole = true;
- polys.write[i].holes.remove(j);
- break; //got rid of hole, break and continue
- }
- }
-
- ERR_BREAK(!added_hole);
- }
+ } break;
}
- //triangulate polygons
-
- for (int i = 0; i < polys.size(); i++) {
-
- Vector<Vector2> vertices;
- vertices.resize(polys[i].points.size());
- for (int j = 0; j < vertices.size(); j++) {
- vertices.write[j] = p_poly.points[polys[i].points[j]].point;
- }
-
- Vector<int> indices = Geometry::triangulate_polygon(vertices);
-
- for (int j = 0; j < indices.size(); j += 3) {
-
- //obtain the vertex
-
- Vector3 face[3];
- Vector2 uv[3];
- float cp = Geometry::vec2_cross(p_poly.points[polys[i].points[indices[j + 0]]].point, p_poly.points[polys[i].points[indices[j + 1]]].point, p_poly.points[polys[i].points[indices[j + 2]]].point);
- if (Math::abs(cp) < CMP_EPSILON)
- continue;
-
- for (int k = 0; k < 3; k++) {
-
- Vector2 p = p_poly.points[polys[i].points[indices[j + k]]].point;
- face[k] = p_poly.to_world.xform(Vector3(p.x, p.y, 0));
- uv[k] = p_poly.points[polys[i].points[indices[j + k]]].uv;
- }
-
- mesh.add_face(face[0], face[1], face[2], uv[0], uv[1], uv[2], p_poly.smooth, p_poly.invert, p_poly.material, p_from_b);
- }
+ // Update the list of materials.
+ r_merged_brush.materials.resize(mesh_merge.materials.size());
+ for (const Map<Ref<Material>, int>::Element *E = mesh_merge.materials.front(); E; E = E->next()) {
+ r_merged_brush.materials.write[E->get()] = E->key();
}
}
-//use a limit to speed up bvh and limit the depth
+// CSGBrushOperation::MeshMerge
+
+// Use a limit to speed up bvh and limit the depth.
#define BVH_LIMIT 8
-int CSGBrushOperation::MeshMerge::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {
+int CSGBrushOperation::MeshMerge::_create_bvh(FaceBVH *facebvhptr, FaceBVH **facebvhptrptr, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc) {
- if (p_depth > max_depth) {
- max_depth = p_depth;
+ if (p_depth > r_max_depth) {
+ r_max_depth = p_depth;
}
if (p_size == 0) {
-
return -1;
- } else if (p_size <= BVH_LIMIT) {
+ }
+ if (p_size <= BVH_LIMIT) {
for (int i = 0; i < p_size - 1; i++) {
- p_bb[p_from + i]->next = p_bb[p_from + i + 1] - p_bvh;
+ facebvhptrptr[p_from + i]->next = facebvhptrptr[p_from + i + 1] - facebvhptr;
}
- return p_bb[p_from] - p_bvh;
+ return facebvhptrptr[p_from] - facebvhptr;
}
AABB aabb;
- aabb = p_bb[p_from]->aabb;
+ aabb = facebvhptrptr[p_from]->aabb;
for (int i = 1; i < p_size; i++) {
-
- aabb.merge_with(p_bb[p_from + i]->aabb);
+ aabb.merge_with(facebvhptrptr[p_from + i]->aabb);
}
int li = aabb.get_longest_axis_index();
@@ -1041,28 +485,29 @@ int CSGBrushOperation::MeshMerge::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from
switch (li) {
case Vector3::AXIS_X: {
- SortArray<BVH *, BVHCmpX> sort_x;
- sort_x.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
+ SortArray<FaceBVH *, FaceBVHCmpX> sort_x;
+ sort_x.nth_element(0, p_size, p_size / 2, &facebvhptrptr[p_from]);
//sort_x.sort(&p_bb[p_from],p_size);
} break;
+
case Vector3::AXIS_Y: {
- SortArray<BVH *, BVHCmpY> sort_y;
- sort_y.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
+ SortArray<FaceBVH *, FaceBVHCmpY> sort_y;
+ sort_y.nth_element(0, p_size, p_size / 2, &facebvhptrptr[p_from]);
//sort_y.sort(&p_bb[p_from],p_size);
} break;
+
case Vector3::AXIS_Z: {
- SortArray<BVH *, BVHCmpZ> sort_z;
- sort_z.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
+ SortArray<FaceBVH *, FaceBVHCmpZ> sort_z;
+ sort_z.nth_element(0, p_size, p_size / 2, &facebvhptrptr[p_from]);
//sort_z.sort(&p_bb[p_from],p_size);
-
} break;
}
- int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, max_depth, max_alloc);
- int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, max_depth, max_alloc);
+ int left = _create_bvh(facebvhptr, facebvhptrptr, p_from, p_size / 2, p_depth + 1, r_max_depth, r_max_alloc);
+ int right = _create_bvh(facebvhptr, facebvhptrptr, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, r_max_depth, r_max_alloc);
- int index = max_alloc++;
- BVH *_new = &p_bvh[index];
+ int index = r_max_alloc++;
+ FaceBVH *_new = &facebvhptr[index];
_new->aabb = aabb;
_new->center = aabb.position + aabb.size * 0.5;
_new->face = -1;
@@ -1073,7 +518,27 @@ int CSGBrushOperation::MeshMerge::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from
return index;
}
-int CSGBrushOperation::MeshMerge::_bvh_count_intersections(BVH *bvhptr, int p_max_depth, int p_bvh_first, const Vector3 &p_begin, const Vector3 &p_end, int p_exclude) const {
+void CSGBrushOperation::MeshMerge::_add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const {
+
+ List<real_t> &intersections = p_from_B ? r_intersectionsB : r_intersectionsA;
+
+ // Check if distance exists.
+ for (const List<real_t>::Element *E = intersections.front(); E; E = E->next())
+ if (Math::abs(**E - p_distance) < vertex_snap) return;
+
+ intersections.push_back(p_distance);
+}
+
+bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const {
+
+ Face face = faces[p_face_idx];
+ Vector3 face_points[3] = {
+ points[face.points[0]],
+ points[face.points[1]],
+ points[face.points[2]]
+ };
+ Vector3 face_center = (face_points[0] + face_points[1] + face_points[2]) / 3.0;
+ Vector3 face_normal = Plane(face_points[0], face_points[1], face_points[2]).normal;
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * p_max_depth);
@@ -1084,54 +549,58 @@ int CSGBrushOperation::MeshMerge::_bvh_count_intersections(BVH *bvhptr, int p_ma
VISIT_DONE_BIT = 3,
VISITED_BIT_SHIFT = 29,
NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1,
- VISITED_BIT_MASK = ~NODE_IDX_MASK,
-
+ VISITED_BIT_MASK = ~NODE_IDX_MASK
};
- int intersections = 0;
+ List<real_t> intersectionsA;
+ List<real_t> intersectionsB;
int level = 0;
-
- const Vector3 *vertexptr = points.ptr();
- const Face *facesptr = faces.ptr();
- AABB segment_aabb;
- segment_aabb.position = p_begin;
- segment_aabb.expand_to(p_end);
-
int pos = p_bvh_first;
-
stack[0] = pos;
+
while (true) {
uint32_t node = stack[level] & NODE_IDX_MASK;
- const BVH &b = bvhptr[node];
+ const FaceBVH *current_facebvhptr = &(facebvhptr[node]);
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
- case TEST_AABB_BIT: {
-
- if (b.face >= 0) {
-
- const BVH *bp = &b;
- while (bp) {
-
- bool valid = segment_aabb.intersects(bp->aabb) && bp->aabb.intersects_segment(p_begin, p_end);
-
- if (valid && p_exclude != bp->face) {
- const Face &s = facesptr[bp->face];
- Face3 f3(vertexptr[s.points[0]], vertexptr[s.points[1]], vertexptr[s.points[2]]);
-
- Vector3 res;
+ case TEST_AABB_BIT: {
- if (f3.intersects_segment(p_begin, p_end, &res)) {
- intersections++;
+ if (current_facebvhptr->face >= 0) {
+
+ while (current_facebvhptr) {
+
+ if (p_face_idx != current_facebvhptr->face &&
+ current_facebvhptr->aabb.intersects_ray(face_center, face_normal)) {
+
+ const Face &current_face = faces[current_facebvhptr->face];
+ Vector3 current_points[3] = {
+ points[current_face.points[0]],
+ points[current_face.points[1]],
+ points[current_face.points[2]]
+ };
+ Vector3 current_normal = Plane(current_points[0], current_points[1], current_points[2]).normal;
+ Vector3 intersection_point;
+
+ // Check if faces are co-planar.
+ if ((current_normal - face_normal).length_squared() < CMP_EPSILON2 &&
+ is_point_in_triangle(face_center, current_points)) {
+ // Only add an intersection if checking a B face.
+ if (face.from_b)
+ _add_distance(intersectionsA, intersectionsB, current_face.from_b, 0);
+ } else if (ray_intersects_triangle(face_center, face_normal, current_points, CMP_EPSILON, intersection_point)) {
+ real_t distance = (intersection_point - face_center).length();
+ _add_distance(intersectionsA, intersectionsB, current_face.from_b, distance);
}
}
- if (bp->next != -1) {
- bp = &bvhptr[bp->next];
+
+ if (current_facebvhptr->next != -1) {
+ current_facebvhptr = &facebvhptr[current_facebvhptr->next];
} else {
- bp = NULL;
+ current_facebvhptr = nullptr;
}
}
@@ -1139,32 +608,33 @@ int CSGBrushOperation::MeshMerge::_bvh_count_intersections(BVH *bvhptr, int p_ma
} else {
- bool valid = segment_aabb.intersects(b.aabb) && b.aabb.intersects_segment(p_begin, p_end);
+ bool valid = current_facebvhptr->aabb.intersects_ray(face_center, face_normal);
if (!valid) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
-
} else {
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
continue;
}
+
case VISIT_LEFT_BIT: {
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
- stack[level + 1] = b.left | TEST_AABB_BIT;
+ stack[level + 1] = current_facebvhptr->left | TEST_AABB_BIT;
level++;
continue;
}
+
case VISIT_RIGHT_BIT: {
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
- stack[level + 1] = b.right | TEST_AABB_BIT;
+ stack[level + 1] = current_facebvhptr->right | TEST_AABB_BIT;
level++;
continue;
}
+
case VISIT_DONE_BIT: {
if (level == 0) {
@@ -1180,130 +650,112 @@ int CSGBrushOperation::MeshMerge::_bvh_count_intersections(BVH *bvhptr, int p_ma
break;
}
- return intersections;
+ // Inside if face normal intersects other faces an odd number of times.
+ return (intersectionsA.size() + intersectionsB.size()) & 1;
}
void CSGBrushOperation::MeshMerge::mark_inside_faces() {
- // mark faces that are inside. This helps later do the boolean ops when merging.
- // this approach is very brute force (with a bunch of optimizatios, such as BVH and pre AABB intersection test)
+ // Mark faces that are inside. This helps later do the boolean ops when merging.
+ // This approach is very brute force with a bunch of optimizations,
+ // such as BVH and pre AABB intersection test.
- AABB aabb;
+ Vector<FaceBVH> bvhvec;
+ bvhvec.resize(faces.size() * 3); // Will never be larger than this (TODO: Make better)
+ FaceBVH *facebvh = bvhvec.ptrw();
- for (int i = 0; i < points.size(); i++) {
- if (i == 0) {
- aabb.position = points[i];
- } else {
- aabb.expand_to(points[i]);
- }
- }
-
- float max_distance = aabb.size.length() * 1.2;
-
- Vector<BVH> bvhvec;
- bvhvec.resize(faces.size() * 3); //will never be larger than this (todo make better)
- BVH *bvh = bvhvec.ptrw();
-
- AABB faces_a;
- AABB faces_b;
+ AABB aabb_a;
+ AABB aabb_b;
bool first_a = true;
bool first_b = true;
for (int i = 0; i < faces.size(); i++) {
- bvh[i].left = -1;
- bvh[i].right = -1;
- bvh[i].face = i;
- bvh[i].aabb.position = points[faces[i].points[0]];
- bvh[i].aabb.expand_to(points[faces[i].points[1]]);
- bvh[i].aabb.expand_to(points[faces[i].points[2]]);
- bvh[i].center = bvh[i].aabb.position + bvh[i].aabb.size * 0.5;
- bvh[i].next = -1;
+ facebvh[i].left = -1;
+ facebvh[i].right = -1;
+ facebvh[i].face = i;
+ facebvh[i].aabb.position = points[faces[i].points[0]];
+ facebvh[i].aabb.expand_to(points[faces[i].points[1]]);
+ facebvh[i].aabb.expand_to(points[faces[i].points[2]]);
+ facebvh[i].center = facebvh[i].aabb.position + facebvh[i].aabb.size * 0.5;
+ facebvh[i].aabb.grow_by(vertex_snap);
+ facebvh[i].next = -1;
+
if (faces[i].from_b) {
if (first_b) {
- faces_b = bvh[i].aabb;
+ aabb_b = facebvh[i].aabb;
first_b = false;
} else {
- faces_b.merge_with(bvh[i].aabb);
+ aabb_b.merge_with(facebvh[i].aabb);
}
} else {
if (first_a) {
- faces_a = bvh[i].aabb;
+ aabb_a = facebvh[i].aabb;
first_a = false;
} else {
- faces_a.merge_with(bvh[i].aabb);
+ aabb_a.merge_with(facebvh[i].aabb);
}
}
}
- AABB intersection_aabb = faces_a.intersection(faces_b);
- intersection_aabb.grow_by(intersection_aabb.get_longest_axis_size() * 0.01); //grow a little, avoid numerical error
+ AABB intersection_aabb = aabb_a.intersection(aabb_b);
- if (intersection_aabb.size == Vector3()) //AABB do not intersect, so neither do shapes.
+ // Check if shape AABBs intersect.
+ if (intersection_aabb.size == Vector3())
return;
- Vector<BVH *> bvhtrvec;
+ Vector<FaceBVH *> bvhtrvec;
bvhtrvec.resize(faces.size());
- BVH **bvhptr = bvhtrvec.ptrw();
+ FaceBVH **bvhptr = bvhtrvec.ptrw();
for (int i = 0; i < faces.size(); i++) {
-
- bvhptr[i] = &bvh[i];
+ bvhptr[i] = &facebvh[i];
}
int max_depth = 0;
int max_alloc = faces.size();
- _create_bvh(bvh, bvhptr, 0, faces.size(), 1, max_depth, max_alloc);
+ _create_bvh(facebvh, bvhptr, 0, faces.size(), 1, max_depth, max_alloc);
for (int i = 0; i < faces.size(); i++) {
- if (!intersection_aabb.intersects(bvh[i].aabb))
- continue; //not in AABB intersection, so not in face intersection
- Vector3 center = points[faces[i].points[0]];
- center += points[faces[i].points[1]];
- center += points[faces[i].points[2]];
- center /= 3.0;
-
- Plane plane(points[faces[i].points[0]], points[faces[i].points[1]], points[faces[i].points[2]]);
- Vector3 target = center + plane.normal * max_distance + Vector3(0.0001234, 0.000512, 0.00013423); //reduce chance of edge hits by doing a small increment
-
- int intersections = _bvh_count_intersections(bvh, max_depth, max_alloc - 1, center, target, i);
+ // Check if face AABB intersects the intersection AABB.
+ if (!intersection_aabb.intersects_inclusive(facebvh[i].aabb))
+ continue;
- if (intersections & 1) {
+ if (_bvh_inside(facebvh, max_depth, max_alloc - 1, i))
faces.write[i].inside = true;
- }
}
}
-void CSGBrushOperation::MeshMerge::add_face(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, const Vector2 &p_uv_a, const Vector2 &p_uv_b, const Vector2 &p_uv_c, bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) {
+void CSGBrushOperation::MeshMerge::add_face(const Vector3 p_points[], const Vector2 p_uvs[], bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) {
- Vector3 src_points[3] = { p_a, p_b, p_c };
- Vector2 src_uvs[3] = { p_uv_a, p_uv_b, p_uv_c };
int indices[3];
for (int i = 0; i < 3; i++) {
VertexKey vk;
- vk.x = int((double(src_points[i].x) + double(vertex_snap) * 0.31234) / double(vertex_snap));
- vk.y = int((double(src_points[i].y) + double(vertex_snap) * 0.31234) / double(vertex_snap));
- vk.z = int((double(src_points[i].z) + double(vertex_snap) * 0.31234) / double(vertex_snap));
+ vk.x = int((double(p_points[i].x) + double(vertex_snap) * 0.31234) / double(vertex_snap));
+ vk.y = int((double(p_points[i].y) + double(vertex_snap) * 0.31234) / double(vertex_snap));
+ vk.z = int((double(p_points[i].z) + double(vertex_snap) * 0.31234) / double(vertex_snap));
int res;
if (snap_cache.lookup(vk, res)) {
indices[i] = res;
} else {
indices[i] = points.size();
- points.push_back(src_points[i]);
+ points.push_back(p_points[i]);
snap_cache.set(vk, indices[i]);
}
}
+ // Don't add degenerate faces.
if (indices[0] == indices[2] || indices[0] == indices[1] || indices[1] == indices[2])
- return; //not adding degenerate
+ return;
MeshMerge::Face face;
face.from_b = p_from_b;
face.inside = false;
face.smooth = p_smooth;
face.invert = p_invert;
+
if (p_material.is_valid()) {
if (!materials.has(p_material)) {
face.material_idx = materials.size();
@@ -1316,205 +768,708 @@ void CSGBrushOperation::MeshMerge::add_face(const Vector3 &p_a, const Vector3 &p
}
for (int k = 0; k < 3; k++) {
-
face.points[k] = indices[k];
- face.uvs[k] = src_uvs[k];
- ;
+ face.uvs[k] = p_uvs[k];
}
faces.push_back(face);
}
-void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_A, const CSGBrush &p_B, CSGBrush &result, float p_snap) {
+// CSGBrushOperation::Build2DFaces
- CallbackData cd;
- cd.self = this;
- cd.A = &p_A;
- cd.B = &p_B;
+int CSGBrushOperation::Build2DFaces::_get_point_idx(const Vector2 &p_point) {
- MeshMerge mesh_merge;
- mesh_merge.vertex_snap = p_snap;
-
- //check intersections between faces. Use AABB to speed up precheck
- //this generates list of buildpolys and clips them.
- //this was originally BVH optimized, but its not really worth it.
- for (int i = 0; i < p_A.faces.size(); i++) {
- cd.face_a = i;
- for (int j = 0; j < p_B.faces.size(); j++) {
- if (p_A.faces[i].aabb.intersects(p_B.faces[j].aabb)) {
- _collision_callback(&p_A, i, cd.build_polys_A, &p_B, j, cd.build_polys_B, mesh_merge);
- }
- }
+ for (int vertex_idx = 0; vertex_idx < vertices.size(); ++vertex_idx) {
+ if ((p_point - vertices[vertex_idx].point).length_squared() < vertex_snap2)
+ return vertex_idx;
}
+ return -1;
+}
- //merge the already cliped polys back to 3D
- for (Map<int, BuildPoly>::Element *E = cd.build_polys_A.front(); E; E = E->next()) {
- _merge_poly(mesh_merge, E->key(), E->get(), false);
- }
+int CSGBrushOperation::Build2DFaces::_add_vertex(const Vertex2D &p_vertex) {
- for (Map<int, BuildPoly>::Element *E = cd.build_polys_B.front(); E; E = E->next()) {
- _merge_poly(mesh_merge, E->key(), E->get(), true);
- }
+ // Check if vertex exists.
+ int vertex_id = _get_point_idx(p_vertex.point);
+ if (vertex_id != -1) return vertex_id;
- //merge the non clipped faces back
+ vertices.push_back(p_vertex);
+ return vertices.size() - 1;
+}
- for (int i = 0; i < p_A.faces.size(); i++) {
+void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vertex_indices, int p_new_vertex_index) {
- if (cd.build_polys_A.has(i))
- continue; //made from buildpoly, skipping
+ if (p_new_vertex_index >= 0 && r_vertex_indices.find(p_new_vertex_index) == -1) {
+ ERR_FAIL_COND_MSG(p_new_vertex_index >= vertices.size(), "Invalid vertex index.");
- Vector3 points[3];
- Vector2 uvs[3];
- for (int j = 0; j < 3; j++) {
- points[j] = p_A.faces[i].vertices[j];
- uvs[j] = p_A.faces[i].uvs[j];
- }
- Ref<Material> material;
- if (p_A.faces[i].material != -1) {
- material = p_A.materials[p_A.faces[i].material];
+ // The first vertex.
+ if (r_vertex_indices.size() == 0) {
+ // Simply add it.
+ r_vertex_indices.push_back(p_new_vertex_index);
+ return;
}
- mesh_merge.add_face(points[0], points[1], points[2], uvs[0], uvs[1], uvs[2], p_A.faces[i].smooth, p_A.faces[i].invert, material, false);
- }
- for (int i = 0; i < p_B.faces.size(); i++) {
+ // The second vertex.
+ if (r_vertex_indices.size() == 1) {
- if (cd.build_polys_B.has(i))
- continue; //made from buildpoly, skipping
+ Vector2 first_point = vertices[r_vertex_indices[0]].point;
+ Vector2 new_point = vertices[p_new_vertex_index].point;
- Vector3 points[3];
- Vector2 uvs[3];
- for (int j = 0; j < 3; j++) {
- points[j] = p_B.faces[i].vertices[j];
- uvs[j] = p_B.faces[i].uvs[j];
+ // Sort along the axis with the greatest difference.
+ int axis = 0;
+ if (Math::abs(new_point.x - first_point.x) < Math::abs(new_point.y - first_point.y)) axis = 1;
+
+ // Add it to the beginning or the end appropriately.
+ if (new_point[axis] < first_point[axis])
+ r_vertex_indices.insert(0, p_new_vertex_index);
+ else
+ r_vertex_indices.push_back(p_new_vertex_index);
+
+ return;
}
- Ref<Material> material;
- if (p_B.faces[i].material != -1) {
- material = p_B.materials[p_B.faces[i].material];
+
+ // Third or later vertices.
+ Vector2 first_point = vertices[r_vertex_indices[0]].point;
+ Vector2 last_point = vertices[r_vertex_indices[r_vertex_indices.size() - 1]].point;
+ Vector2 new_point = vertices[p_new_vertex_index].point;
+
+ // Determine axis being sorted against i.e. the axis with the greatest difference.
+ int axis = 0;
+ if (Math::abs(last_point.x - first_point.x) < Math::abs(last_point.y - first_point.y)) axis = 1;
+
+ // Insert the point at the appropriate index.
+ for (int insert_idx = 0; insert_idx < r_vertex_indices.size(); ++insert_idx) {
+ Vector2 insert_point = vertices[r_vertex_indices[insert_idx]].point;
+ if (new_point[axis] < insert_point[axis]) {
+ r_vertex_indices.insert(insert_idx, p_new_vertex_index);
+ return;
+ }
}
- mesh_merge.add_face(points[0], points[1], points[2], uvs[0], uvs[1], uvs[2], p_B.faces[i].smooth, p_B.faces[i].invert, material, true);
+
+ // New largest, add it to the end.
+ r_vertex_indices.push_back(p_new_vertex_index);
}
+}
- //mark faces that ended up inside the intersection
- mesh_merge.mark_inside_faces();
+void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_indices) {
- //regen new brush to start filling it again
- result.clear();
+ int segments = p_segment_indices.size() - 1;
+ if (segments < 2) return;
- switch (p_operation) {
+ // Faces around an inner vertex are merged by moving the inner vertex to the first vertex.
+ for (int sorted_idx = 1; sorted_idx < segments; ++sorted_idx) {
- case OPERATION_UNION: {
+ int closest_idx = 0;
+ int inner_idx = p_segment_indices[sorted_idx];
- int outside_count = 0;
+ if (sorted_idx > segments / 2) {
+ // Merge to other segment end.
+ closest_idx = segments;
+ // Reverse the merge order.
+ inner_idx = p_segment_indices[segments + segments / 2 - sorted_idx];
+ }
- for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (mesh_merge.faces[i].inside)
- continue;
+ // Find the mergeable faces.
+ Vector<int> merge_faces_idx;
+ Vector<Face2D> merge_faces;
+ Vector<int> merge_faces_inner_vertex_idx;
+ for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
+ for (int face_vertex_idx = 0; face_vertex_idx < 3; ++face_vertex_idx) {
+ if (faces[face_idx].vertex_idx[face_vertex_idx] == inner_idx) {
+ merge_faces_idx.push_back(face_idx);
+ merge_faces.push_back(faces[face_idx]);
+ merge_faces_inner_vertex_idx.push_back(face_vertex_idx);
+ }
+ }
+ }
- outside_count++;
+ Vector<int> degenerate_points;
+
+ // Create the new faces.
+ for (int merge_idx = 0; merge_idx < merge_faces.size(); ++merge_idx) {
+
+ int outer_edge_idx[2];
+ outer_edge_idx[0] = merge_faces[merge_idx].vertex_idx[(merge_faces_inner_vertex_idx[merge_idx] + 1) % 3];
+ outer_edge_idx[1] = merge_faces[merge_idx].vertex_idx[(merge_faces_inner_vertex_idx[merge_idx] + 2) % 3];
+
+ // Skip flattened faces.
+ if (outer_edge_idx[0] == p_segment_indices[closest_idx] ||
+ outer_edge_idx[1] == p_segment_indices[closest_idx]) continue;
+
+ //Don't create degenerate triangles.
+ Vector2 edge1[2] = {
+ vertices[outer_edge_idx[0]].point,
+ vertices[p_segment_indices[closest_idx]].point
+ };
+ Vector2 edge2[2] = {
+ vertices[outer_edge_idx[1]].point,
+ vertices[p_segment_indices[closest_idx]].point
+ };
+ if (are_segements_parallel(edge1, edge2, vertex_snap2)) {
+ degenerate_points.push_back(outer_edge_idx[0]);
+ degenerate_points.push_back(outer_edge_idx[1]);
+ continue;
}
- result.faces.resize(outside_count);
+ // Create new faces.
+ Face2D new_face;
+ new_face.vertex_idx[0] = p_segment_indices[closest_idx];
+ new_face.vertex_idx[1] = outer_edge_idx[0];
+ new_face.vertex_idx[2] = outer_edge_idx[1];
+ faces.push_back(new_face);
+ }
- outside_count = 0;
+ // Delete the old faces in reverse index order.
+ merge_faces_idx.sort();
+ merge_faces_idx.invert();
+ for (int i = 0; i < merge_faces_idx.size(); ++i)
+ faces.remove(merge_faces_idx[i]);
+
+ if (degenerate_points.size() == 0) continue;
+
+ // Split faces using degenerate points.
+ for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
+
+ Face2D face = faces[face_idx];
+ Vertex2D face_vertices[3] = {
+ vertices[face.vertex_idx[0]],
+ vertices[face.vertex_idx[1]],
+ vertices[face.vertex_idx[2]]
+ };
+ Vector2 face_points[3] = {
+ face_vertices[0].point,
+ face_vertices[1].point,
+ face_vertices[2].point
+ };
+
+ for (int point_idx = 0; point_idx < degenerate_points.size(); ++point_idx) {
+
+ int degenerate_idx = degenerate_points[point_idx];
+ Vector2 point_2D = vertices[degenerate_idx].point;
+
+ // Check if point is existing face vertex.
+ bool existing = false;
+ for (int i = 0; i < 3; ++i) {
+ if ((point_2D - face_vertices[i].point).length_squared() < vertex_snap2) {
+ existing = true;
+ break;
+ }
+ }
+ if (existing) continue;
- for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (mesh_merge.faces[i].inside)
- continue;
- for (int j = 0; j < 3; j++) {
- result.faces.write[outside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
- result.faces.write[outside_count].uvs[j] = mesh_merge.faces[i].uvs[j];
+ // Check if point is on an each edge.
+ for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) {
+
+ Vector2 edge_points[2] = {
+ face_points[face_edge_idx],
+ face_points[(face_edge_idx + 1) % 3]
+ };
+ Vector2 closest_point = Geometry::get_closest_point_to_segment_2d(point_2D, edge_points);
+
+ if ((closest_point - point_2D).length_squared() < vertex_snap2) {
+
+ int opposite_vertex_idx = face.vertex_idx[(face_edge_idx + 2) % 3];
+
+ // If new vertex snaps to degenerate vertex, just delete this face.
+ if (degenerate_idx == opposite_vertex_idx) {
+ faces.remove(face_idx);
+ // Update index.
+ --face_idx;
+ break;
+ }
+
+ // Create two new faces around the new edge and remove this face.
+ // The new edge is the last edge.
+ Face2D left_face;
+ left_face.vertex_idx[0] = degenerate_idx;
+ left_face.vertex_idx[1] = face.vertex_idx[(face_edge_idx + 1) % 3];
+ left_face.vertex_idx[2] = opposite_vertex_idx;
+ Face2D right_face;
+ right_face.vertex_idx[0] = opposite_vertex_idx;
+ right_face.vertex_idx[1] = face.vertex_idx[face_edge_idx];
+ right_face.vertex_idx[2] = degenerate_idx;
+ faces.remove(face_idx);
+ faces.insert(face_idx, right_face);
+ faces.insert(face_idx, left_face);
+
+ // Don't check against the new faces.
+ ++face_idx;
+
+ // No need to check other edges.
+ break;
+ }
}
+ }
+ }
+ }
+}
- result.faces.write[outside_count].smooth = mesh_merge.faces[i].smooth;
- result.faces.write[outside_count].invert = mesh_merge.faces[i].invert;
- result.faces.write[outside_count].material = mesh_merge.faces[i].material_idx;
- outside_count++;
+void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_segment_points[2], Vector<int> &r_segment_indices) {
+
+ // For each face.
+ for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
+
+ Face2D face = faces[face_idx];
+ Vertex2D face_vertices[3] = {
+ vertices[face.vertex_idx[0]],
+ vertices[face.vertex_idx[1]],
+ vertices[face.vertex_idx[2]]
+ };
+
+ // Check each edge.
+ for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) {
+
+ Vector2 edge_points[2] = {
+ face_vertices[face_edge_idx].point,
+ face_vertices[(face_edge_idx + 1) % 3].point
+ };
+ Vector2 edge_uvs[2] = {
+ face_vertices[face_edge_idx].uv,
+ face_vertices[(face_edge_idx + 1) % 3].uv
+ };
+ Vector2 intersection_point;
+
+ // First check if the ends of the segment are on the edge.
+ bool on_edge = false;
+ for (int edge_point_idx = 0; edge_point_idx < 2; ++edge_point_idx) {
+ intersection_point = Geometry::get_closest_point_to_segment_2d(p_segment_points[edge_point_idx], edge_points);
+ if ((intersection_point - p_segment_points[edge_point_idx]).length_squared() < vertex_snap2) {
+ on_edge = true;
+ break;
+ }
}
- result._regen_face_aabbs();
+ // Else check if the segment intersects the edge.
+ if (on_edge || Geometry::segment_intersects_segment_2d(p_segment_points[0], p_segment_points[1], edge_points[0], edge_points[1], &intersection_point)) {
+
+ // Check if intersection point is an edge point.
+ if ((intersection_point - edge_points[0]).length_squared() < vertex_snap2 ||
+ (intersection_point - edge_points[1]).length_squared() < vertex_snap2) continue;
+
+ // Check if edge exists, by checking if the intersecting segment is parallel to the edge.
+ if (are_segements_parallel(p_segment_points, edge_points, vertex_snap2)) continue;
+
+ // Add the intersection point as a new vertex.
+ Vertex2D new_vertex;
+ new_vertex.point = intersection_point;
+ new_vertex.uv = interpolate_segment_uv(edge_points, edge_uvs, intersection_point);
+ int new_vertex_idx = _add_vertex(new_vertex);
+ int opposite_vertex_idx = face.vertex_idx[(face_edge_idx + 2) % 3];
+ _add_vertex_idx_sorted(r_segment_indices, new_vertex_idx);
+
+ // If new vertex snaps to opposite vertex, just delete this face.
+ if (new_vertex_idx == opposite_vertex_idx) {
+ faces.remove(face_idx);
+ // Update index.
+ --face_idx;
+ break;
+ }
- } break;
- case OPERATION_INTERSECTION: {
+ // Don't create degenerate triangles.
+ Vector2 split_edge1[2] = { vertices[new_vertex_idx].point, edge_points[0] };
+ Vector2 split_edge2[2] = { vertices[new_vertex_idx].point, edge_points[1] };
+ Vector2 new_edge[2] = { vertices[new_vertex_idx].point, vertices[opposite_vertex_idx].point };
+ if (are_segements_parallel(split_edge1, new_edge, vertex_snap2) &&
+ are_segements_parallel(split_edge2, new_edge, vertex_snap2)) {
+ break;
+ }
- int inside_count = 0;
+ // If opposite point is on the segemnt, add its index to segment indices too.
+ Vector2 closest_point = Geometry::get_closest_point_to_segment_2d(vertices[opposite_vertex_idx].point, p_segment_points);
+ if ((closest_point - vertices[opposite_vertex_idx].point).length_squared() < vertex_snap2)
+ _add_vertex_idx_sorted(r_segment_indices, opposite_vertex_idx);
+
+ // Create two new faces around the new edge and remove this face.
+ // The new edge is the last edge.
+ Face2D left_face;
+ left_face.vertex_idx[0] = new_vertex_idx;
+ left_face.vertex_idx[1] = face.vertex_idx[(face_edge_idx + 1) % 3];
+ left_face.vertex_idx[2] = opposite_vertex_idx;
+ Face2D right_face;
+ right_face.vertex_idx[0] = opposite_vertex_idx;
+ right_face.vertex_idx[1] = face.vertex_idx[face_edge_idx];
+ right_face.vertex_idx[2] = new_vertex_idx;
+ faces.remove(face_idx);
+ faces.insert(face_idx, right_face);
+ faces.insert(face_idx, left_face);
+
+ // Check against the new faces.
+ --face_idx;
+ break;
+ }
+ }
+ }
+}
- for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (!mesh_merge.faces[i].inside)
- continue;
+int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) {
+
+ int new_vertex_idx = -1;
+
+ for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
+
+ Face2D face = faces[face_idx];
+ Vertex2D face_vertices[3] = {
+ vertices[face.vertex_idx[0]],
+ vertices[face.vertex_idx[1]],
+ vertices[face.vertex_idx[2]]
+ };
+ Vector2 points[3] = {
+ face_vertices[0].point,
+ face_vertices[1].point,
+ face_vertices[2].point
+ };
+ Vector2 uvs[3] = {
+ face_vertices[0].uv,
+ face_vertices[1].uv,
+ face_vertices[2].uv
+ };
+
+ // Check if point is existing face vertex.
+ for (int i = 0; i < 3; ++i) {
+ if ((p_point - face_vertices[i].point).length_squared() < vertex_snap2)
+ return face.vertex_idx[i];
+ }
- inside_count++;
- }
+ // Check if point is on an each edge.
+ bool on_edge = false;
+ for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) {
+
+ Vector2 edge_points[2] = {
+ points[face_edge_idx],
+ points[(face_edge_idx + 1) % 3]
+ };
+ Vector2 edge_uvs[2] = {
+ uvs[face_edge_idx],
+ uvs[(face_edge_idx + 1) % 3]
+ };
+
+ Vector2 closest_point = Geometry::get_closest_point_to_segment_2d(p_point, edge_points);
+ if ((closest_point - p_point).length_squared() < vertex_snap2) {
+ on_edge = true;
+
+ // Add the point as a new vertex.
+ Vertex2D new_vertex;
+ new_vertex.point = p_point;
+ new_vertex.uv = interpolate_segment_uv(edge_points, edge_uvs, p_point);
+ new_vertex_idx = _add_vertex(new_vertex);
+ int opposite_vertex_idx = face.vertex_idx[(face_edge_idx + 2) % 3];
+
+ // If new vertex snaps to opposite vertex, just delete this face.
+ if (new_vertex_idx == opposite_vertex_idx) {
+ faces.remove(face_idx);
+ // Update index.
+ --face_idx;
+ break;
+ }
- result.faces.resize(inside_count);
+ // Don't create degenerate triangles.
+ Vector2 split_edge1[2] = { vertices[new_vertex_idx].point, edge_points[0] };
+ Vector2 split_edge2[2] = { vertices[new_vertex_idx].point, edge_points[1] };
+ Vector2 new_edge[2] = { vertices[new_vertex_idx].point, vertices[opposite_vertex_idx].point };
+ if (are_segements_parallel(split_edge1, new_edge, vertex_snap2) &&
+ are_segements_parallel(split_edge2, new_edge, vertex_snap2)) {
+ break;
+ }
- inside_count = 0;
+ // Create two new faces around the new edge and remove this face.
+ // The new edge is the last edge.
+ Face2D left_face;
+ left_face.vertex_idx[0] = new_vertex_idx;
+ left_face.vertex_idx[1] = face.vertex_idx[(face_edge_idx + 1) % 3];
+ left_face.vertex_idx[2] = opposite_vertex_idx;
+ Face2D right_face;
+ right_face.vertex_idx[0] = opposite_vertex_idx;
+ right_face.vertex_idx[1] = face.vertex_idx[face_edge_idx];
+ right_face.vertex_idx[2] = new_vertex_idx;
+ faces.remove(face_idx);
+ faces.insert(face_idx, right_face);
+ faces.insert(face_idx, left_face);
+
+ // Don't check against the new faces.
+ ++face_idx;
+
+ // No need to check other edges.
+ break;
+ }
+ }
- for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (!mesh_merge.faces[i].inside)
+ // If not on an edge, check if the point is inside the face.
+ if (!on_edge && Geometry::is_point_in_triangle(p_point, face_vertices[0].point, face_vertices[1].point, face_vertices[2].point)) {
+
+ // Add the point as a new vertex.
+ Vertex2D new_vertex;
+ new_vertex.point = p_point;
+ new_vertex.uv = interpolate_triangle_uv(points, uvs, p_point);
+ new_vertex_idx = _add_vertex(new_vertex);
+
+ // Create three new faces around this point and remove this face.
+ // The new vertex is the last vertex.
+ for (int i = 0; i < 3; ++i) {
+
+ // Don't create degenerate triangles.
+ Vector2 edge[2] = { points[i], points[(i + 1) % 3] };
+ Vector2 new_edge1[2] = { vertices[new_vertex_idx].point, points[i] };
+ Vector2 new_edge2[2] = { vertices[new_vertex_idx].point, points[(i + 1) % 3] };
+ if (are_segements_parallel(edge, new_edge1, vertex_snap2) &&
+ are_segements_parallel(edge, new_edge2, vertex_snap2)) {
continue;
- for (int j = 0; j < 3; j++) {
- result.faces.write[inside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
- result.faces.write[inside_count].uvs[j] = mesh_merge.faces[i].uvs[j];
}
- result.faces.write[inside_count].smooth = mesh_merge.faces[i].smooth;
- result.faces.write[inside_count].invert = mesh_merge.faces[i].invert;
- result.faces.write[inside_count].material = mesh_merge.faces[i].material_idx;
- inside_count++;
+ Face2D new_face;
+ new_face.vertex_idx[0] = face.vertex_idx[i];
+ new_face.vertex_idx[1] = face.vertex_idx[(i + 1) % 3];
+ new_face.vertex_idx[2] = new_vertex_idx;
+ faces.push_back(new_face);
}
+ faces.remove(face_idx);
- result._regen_face_aabbs();
+ // No need to check other faces.
+ break;
+ }
+ }
- } break;
- case OPERATION_SUBSTRACTION: {
+ return new_vertex_idx;
+}
- int face_count = 0;
+void CSGBrushOperation::Build2DFaces::insert(const CSGBrush &p_brush, int p_face_idx) {
- for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
- continue;
- if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
- continue;
+ // Find edge points that cross the plane and face points that are in the plane.
+ // Map those points to 2D.
+ // Create new faces from those points.
- face_count++;
+ Vector2 points_2D[3];
+ int points_count = 0;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 point_3D = p_brush.faces[p_face_idx].vertices[i];
+
+ if (plane.has_point(point_3D)) {
+ // Point is in the plane, add it.
+ Vector3 point_2D = plane.project(point_3D);
+ point_2D = to_2D.xform(point_2D);
+ points_2D[points_count++] = Vector2(point_2D.x, point_2D.y);
+
+ } else {
+
+ Vector3 next_point_3D = p_brush.faces[p_face_idx].vertices[(i + 1) % 3];
+
+ if (plane.has_point(next_point_3D))
+ continue; // Next point is in plane, it will be added separately.
+ if (plane.is_point_over(point_3D) == plane.is_point_over(next_point_3D))
+ continue; // Both points on the same side of the plane, ignore.
+
+ // Edge crosses the plane, find and add the intersection point.
+ Vector3 point_2D;
+ if (plane.intersects_segment(point_3D, next_point_3D, &point_2D)) {
+ point_2D = to_2D.xform(point_2D);
+ points_2D[points_count++] = Vector2(point_2D.x, point_2D.y);
}
+ }
+ }
- result.faces.resize(face_count);
+ Vector<int> segment_indices;
+ Vector2 segment[2];
+ int inserted_index[3] = { -1, -1, -1 };
- face_count = 0;
+ // Insert points.
+ for (int i = 0; i < points_count; ++i) {
+ inserted_index[i] = _insert_point(points_2D[i]);
+ }
- for (int i = 0; i < mesh_merge.faces.size(); i++) {
+ if (points_count == 2) {
+ // Insert a single segment.
+ segment[0] = points_2D[0];
+ segment[1] = points_2D[1];
+ _find_edge_intersections(segment, segment_indices);
+ for (int i = 0; i < 2; ++i) {
+ _add_vertex_idx_sorted(segment_indices, inserted_index[i]);
+ }
+ _merge_faces(segment_indices);
+ }
- if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
- continue;
- if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
- continue;
+ if (points_count == 3) {
+ // Insert three segments.
+ for (int edge_idx = 0; edge_idx < 3; ++edge_idx) {
+ segment[0] = points_2D[edge_idx];
+ segment[1] = points_2D[(edge_idx + 1) % 3];
+ _find_edge_intersections(segment, segment_indices);
+ for (int i = 0; i < 2; ++i) {
+ _add_vertex_idx_sorted(segment_indices, inserted_index[(edge_idx + i) % 3]);
+ }
+ _merge_faces(segment_indices);
+ segment_indices.clear();
+ }
+ }
+}
- for (int j = 0; j < 3; j++) {
- result.faces.write[face_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
- result.faces.write[face_count].uvs[j] = mesh_merge.faces[i].uvs[j];
- }
+void CSGBrushOperation::Build2DFaces::addFacesToMesh(MeshMerge &r_mesh_merge, bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) {
- if (mesh_merge.faces[i].from_b) {
- //invert facing of insides of B
- SWAP(result.faces.write[face_count].vertices[1], result.faces.write[face_count].vertices[2]);
- SWAP(result.faces.write[face_count].uvs[1], result.faces.write[face_count].uvs[2]);
+ for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
+ Face2D face = faces[face_idx];
+ Vertex2D fv[3] = {
+ vertices[face.vertex_idx[0]],
+ vertices[face.vertex_idx[1]],
+ vertices[face.vertex_idx[2]]
+ };
+
+ // Convert 2D vertex points to 3D.
+ Vector3 points_3D[3];
+ Vector2 uvs[3];
+ for (int i = 0; i < 3; ++i) {
+ Vector3 point_2D(fv[i].point.x, fv[i].point.y, 0);
+ points_3D[i] = to_3D.xform(point_2D);
+ uvs[i] = fv[i].uv;
+ }
+
+ r_mesh_merge.add_face(points_3D, uvs, p_smooth, p_invert, p_material, p_from_b);
+ }
+}
+
+CSGBrushOperation::Build2DFaces::Build2DFaces(const CSGBrush &p_brush, int p_face_idx, float p_vertex_snap2) :
+ vertex_snap2(p_vertex_snap2 * p_vertex_snap2) {
+
+ // Convert 3D vertex points to 2D.
+ Vector3 points_3D[3] = {
+ p_brush.faces[p_face_idx].vertices[0],
+ p_brush.faces[p_face_idx].vertices[1],
+ p_brush.faces[p_face_idx].vertices[2],
+ };
+
+ plane = Plane(points_3D[0], points_3D[1], points_3D[2]);
+ to_3D.origin = points_3D[0];
+ to_3D.basis.set_axis(2, plane.normal);
+ to_3D.basis.set_axis(0, (points_3D[1] - points_3D[2]).normalized());
+ to_3D.basis.set_axis(1, to_3D.basis.get_axis(0).cross(to_3D.basis.get_axis(2)).normalized());
+ to_2D = to_3D.affine_inverse();
+
+ Face2D face;
+ for (int i = 0; i < 3; i++) {
+ Vertex2D vertex;
+ Vector3 point_2D = to_2D.xform(points_3D[i]);
+ vertex.point.x = point_2D.x;
+ vertex.point.y = point_2D.y;
+ vertex.uv = p_brush.faces[p_face_idx].uvs[i];
+ vertices.push_back(vertex);
+ face.vertex_idx[i] = i;
+ }
+ faces.push_back(face);
+}
+
+void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face_idx_a, const CSGBrush &p_brush_b, const int p_face_idx_b, Build2DFaceCollection &p_collection, float p_vertex_snap) {
+
+ Vector3 vertices_a[3] = {
+ p_brush_a.faces[p_face_idx_a].vertices[0],
+ p_brush_a.faces[p_face_idx_a].vertices[1],
+ p_brush_a.faces[p_face_idx_a].vertices[2],
+ };
+
+ Vector3 vertices_b[3] = {
+ p_brush_b.faces[p_face_idx_b].vertices[0],
+ p_brush_b.faces[p_face_idx_b].vertices[1],
+ p_brush_b.faces[p_face_idx_b].vertices[2],
+ };
+
+ // Don't use degenerate faces.
+ bool has_degenerate = false;
+ if (is_snapable(vertices_a[0], vertices_a[1], p_vertex_snap) ||
+ is_snapable(vertices_a[0], vertices_a[2], p_vertex_snap) ||
+ is_snapable(vertices_a[1], vertices_a[2], p_vertex_snap)) {
+ p_collection.build2DFacesA[p_face_idx_a] = Build2DFaces();
+ has_degenerate = true;
+ }
+
+ if (is_snapable(vertices_b[0], vertices_b[1], p_vertex_snap) ||
+ is_snapable(vertices_b[0], vertices_b[2], p_vertex_snap) ||
+ is_snapable(vertices_b[1], vertices_b[2], p_vertex_snap)) {
+ p_collection.build2DFacesB[p_face_idx_b] = Build2DFaces();
+ has_degenerate = true;
+ }
+ if (has_degenerate) return;
+
+ // Ensure B has points either side of or in the plane of A.
+ int in_plane_count = 0, over_count = 0, under_count = 0;
+ Plane plane_a(vertices_a[0], vertices_a[1], vertices_a[2]);
+ ERR_FAIL_COND_MSG(plane_a.normal == Vector3(), "Couldn't form plane from Brush A face.");
+
+ for (int i = 0; i < 3; i++) {
+ if (plane_a.has_point(vertices_b[i]))
+ in_plane_count++;
+ else if (plane_a.is_point_over(vertices_b[i]))
+ over_count++;
+ else
+ under_count++;
+ }
+ // If all points under or over the plane, there is no intesection.
+ if (over_count == 3 || under_count == 3) return;
+
+ // Ensure A has points either side of or in the plane of B.
+ in_plane_count = 0;
+ over_count = 0;
+ under_count = 0;
+ Plane plane_b(vertices_b[0], vertices_b[1], vertices_b[2]);
+ ERR_FAIL_COND_MSG(plane_b.normal == Vector3(), "Couldn't form plane from Brush B face.");
+
+ for (int i = 0; i < 3; i++) {
+ if (plane_b.has_point(vertices_a[i]))
+ in_plane_count++;
+ else if (plane_b.is_point_over(vertices_a[i]))
+ over_count++;
+ else
+ under_count++;
+ }
+ // If all points under or over the plane, there is no intesection.
+ if (over_count == 3 || under_count == 3) return;
+
+ // Check for intersection using the SAT theorem.
+ {
+
+ // Edge pair cross product combinations.
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 axis_a = (vertices_a[i] - vertices_a[(i + 1) % 3]).normalized();
+
+ for (int j = 0; j < 3; j++) {
+
+ Vector3 axis_b = (vertices_b[j] - vertices_b[(j + 1) % 3]).normalized();
+
+ Vector3 sep_axis = axis_a.cross(axis_b);
+ if (sep_axis == Vector3())
+ continue; //colineal
+ sep_axis.normalize();
+
+ real_t min_a = 1e20, max_a = -1e20;
+ real_t min_b = 1e20, max_b = -1e20;
+
+ for (int k = 0; k < 3; k++) {
+ real_t d = sep_axis.dot(vertices_a[k]);
+ min_a = MIN(min_a, d);
+ max_a = MAX(max_a, d);
+ d = sep_axis.dot(vertices_b[k]);
+ min_b = MIN(min_b, d);
+ max_b = MAX(max_b, d);
}
- result.faces.write[face_count].smooth = mesh_merge.faces[i].smooth;
- result.faces.write[face_count].invert = mesh_merge.faces[i].invert;
- result.faces.write[face_count].material = mesh_merge.faces[i].material_idx;
- face_count++;
- }
+ min_b -= (max_a - min_a) * 0.5;
+ max_b += (max_a - min_a) * 0.5;
- result._regen_face_aabbs();
+ real_t dmin = min_b - (min_a + max_a) * 0.5;
+ real_t dmax = max_b - (min_a + max_a) * 0.5;
- } break;
+ if (dmin > CMP_EPSILON || dmax < -CMP_EPSILON) {
+ return; // Does not contain zero, so they don't overlap.
+ }
+ }
+ }
}
- //updatelist of materials
- result.materials.resize(mesh_merge.materials.size());
- for (const Map<Ref<Material>, int>::Element *E = mesh_merge.materials.front(); E; E = E->next()) {
- result.materials.write[E->get()] = E->key();
+ // If we're still here, the faces probably intersect, so add new faces.
+ if (!p_collection.build2DFacesA.has(p_face_idx_a)) {
+ p_collection.build2DFacesA[p_face_idx_a] = Build2DFaces(p_brush_a, p_face_idx_a, p_vertex_snap);
+ }
+ p_collection.build2DFacesA[p_face_idx_a].insert(p_brush_b, p_face_idx_b);
+
+ if (!p_collection.build2DFacesB.has(p_face_idx_b)) {
+ p_collection.build2DFacesB[p_face_idx_b] = Build2DFaces(p_brush_b, p_face_idx_b, p_vertex_snap);
}
+ p_collection.build2DFacesB[p_face_idx_b].insert(p_brush_a, p_face_idx_a);
}
diff --git a/modules/csg/csg.h b/modules/csg/csg.h
index a11e55c72a..d389cbc283 100644
--- a/modules/csg/csg.h
+++ b/modules/csg/csg.h
@@ -31,20 +31,21 @@
#ifndef CSG_H
#define CSG_H
+#include "core/list.h"
#include "core/map.h"
#include "core/math/aabb.h"
#include "core/math/plane.h"
-#include "core/math/rect2.h"
#include "core/math/transform.h"
+#include "core/math/vector2.h"
#include "core/math/vector3.h"
#include "core/oa_hash_map.h"
-#include "core/pool_vector.h"
+#include "core/reference.h"
+#include "core/vector.h"
#include "scene/resources/material.h"
struct CSGBrush {
struct Face {
-
Vector3 vertices[3];
Vector2 uvs[3];
AABB aabb;
@@ -54,14 +55,13 @@ struct CSGBrush {
};
Vector<Face> faces;
- Vector<Ref<Material> > materials;
+ Vector<Ref<Material>> materials;
- void _regen_face_aabbs();
- //create a brush from faces
- void build_from_faces(const PoolVector<Vector3> &p_vertices, const PoolVector<Vector2> &p_uvs, const PoolVector<bool> &p_smooth, const PoolVector<Ref<Material> > &p_materials, const PoolVector<bool> &p_invert_faces);
- void copy_from(const CSGBrush &p_brush, const Transform &p_xform);
+ inline void _regen_face_aabbs();
- void clear();
+ // Create a brush from faces.
+ void build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials, const Vector<bool> &p_invert_faces);
+ void copy_from(const CSGBrush &p_brush, const Transform &p_xform);
};
struct CSGBrushOperation {
@@ -70,12 +70,23 @@ struct CSGBrushOperation {
OPERATION_UNION,
OPERATION_INTERSECTION,
OPERATION_SUBSTRACTION,
-
};
+ void merge_brushes(Operation p_operation, const CSGBrush &p_brush_a, const CSGBrush &p_brush_b, CSGBrush &r_merged_brush, float p_vertex_snap);
+
struct MeshMerge {
- struct BVH {
+ struct Face {
+ bool from_b;
+ bool inside;
+ int points[3];
+ Vector2 uvs[3];
+ bool smooth;
+ bool invert;
+ int material_idx;
+ };
+
+ struct FaceBVH {
int face;
int left;
int right;
@@ -84,32 +95,23 @@ struct CSGBrushOperation {
AABB aabb;
};
- struct BVHCmpX {
-
- bool operator()(const BVH *p_left, const BVH *p_right) const {
-
+ struct FaceBVHCmpX {
+ _FORCE_INLINE_ bool operator()(const FaceBVH *p_left, const FaceBVH *p_right) const {
return p_left->center.x < p_right->center.x;
}
};
- struct BVHCmpY {
-
- bool operator()(const BVH *p_left, const BVH *p_right) const {
-
+ struct FaceBVHCmpY {
+ _FORCE_INLINE_ bool operator()(const FaceBVH *p_left, const FaceBVH *p_right) const {
return p_left->center.y < p_right->center.y;
}
};
- struct BVHCmpZ {
-
- bool operator()(const BVH *p_left, const BVH *p_right) const {
-
+ struct FaceBVHCmpZ {
+ _FORCE_INLINE_ bool operator()(const FaceBVH *p_left, const FaceBVH *p_right) const {
return p_left->center.z < p_right->center.z;
}
};
- int _bvh_count_intersections(BVH *bvhptr, int p_max_depth, int p_bvh_first, const Vector3 &p_begin, const Vector3 &p_end, int p_exclude) const;
- int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc);
-
struct VertexKey {
int32_t x, y, z;
_FORCE_INLINE_ bool operator<(const VertexKey &p_key) const {
@@ -138,99 +140,59 @@ struct CSGBrushOperation {
}
};
- OAHashMap<VertexKey, int, VertexKeyHash> snap_cache;
-
Vector<Vector3> points;
-
- struct Face {
- bool from_b;
- bool inside;
- int points[3];
- Vector2 uvs[3];
- bool smooth;
- bool invert;
- int material_idx;
- };
-
Vector<Face> faces;
-
Map<Ref<Material>, int> materials;
-
Map<Vector3, int> vertex_map;
- void add_face(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, const Vector2 &p_uv_a, const Vector2 &p_uv_b, const Vector2 &p_uv_c, bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b);
- // void add_face(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, bool p_from_b);
-
+ OAHashMap<VertexKey, int, VertexKeyHash> snap_cache;
float vertex_snap;
+
+ inline void _add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const;
+ inline bool _bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const;
+ inline int _create_bvh(FaceBVH *facebvhptr, FaceBVH **facebvhptrptr, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc);
+
+ void add_face(const Vector3 p_points[3], const Vector2 p_uvs[3], bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b);
void mark_inside_faces();
};
- struct BuildPoly {
+ struct Build2DFaces {
- Plane plane;
- Transform to_poly;
- Transform to_world;
- int face_index;
-
- struct Point {
+ struct Vertex2D {
Vector2 point;
Vector2 uv;
};
- Vector<Point> points;
-
- struct Edge {
- bool outer;
- int points[2];
- Edge() {
- outer = false;
- }
+ struct Face2D {
+ int vertex_idx[3];
};
- Vector<Edge> edges;
- Ref<Material> material;
- bool smooth;
- bool invert;
-
- int base_edges; //edges from original triangle, even if split
-
- void _clip_segment(const CSGBrush *p_brush, int p_face, const Vector2 *segment, MeshMerge &mesh_merge, bool p_for_B);
-
- void create(const CSGBrush *p_brush, int p_face, MeshMerge &mesh_merge, bool p_for_B);
- void clip(const CSGBrush *p_brush, int p_face, MeshMerge &mesh_merge, bool p_for_B);
- };
-
- struct PolyPoints {
-
- Vector<int> points;
-
- Vector<Vector<int> > holes;
- };
-
- struct EdgeSort {
- int edge;
- int prev_point;
- int edge_point;
- float angle;
- bool operator<(const EdgeSort &p_edge) const { return angle < p_edge.angle; }
+ Vector<Vertex2D> vertices;
+ Vector<Face2D> faces;
+ Plane plane;
+ Transform to_2D;
+ Transform to_3D;
+ float vertex_snap2;
+
+ inline int _get_point_idx(const Vector2 &p_point);
+ inline int _add_vertex(const Vertex2D &p_vertex);
+ inline void _add_vertex_idx_sorted(Vector<int> &r_vertex_indices, int p_new_vertex_index);
+ inline void _merge_faces(const Vector<int> &p_segment_indices);
+ inline void _find_edge_intersections(const Vector2 p_segment_points[2], Vector<int> &r_segment_indices);
+ inline int _insert_point(const Vector2 &p_point);
+
+ void insert(const CSGBrush &p_brush, int p_brush_face);
+ void addFacesToMesh(MeshMerge &r_mesh_merge, bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b);
+
+ Build2DFaces() {}
+ Build2DFaces(const CSGBrush &p_brush, int p_brush_face, float p_vertex_snap2);
};
- struct CallbackData {
- const CSGBrush *A;
- const CSGBrush *B;
- int face_a;
- CSGBrushOperation *self;
- Map<int, BuildPoly> build_polys_A;
- Map<int, BuildPoly> build_polys_B;
+ struct Build2DFaceCollection {
+ Map<int, Build2DFaces> build2DFacesA;
+ Map<int, Build2DFaces> build2DFacesB;
};
- void _add_poly_points(const BuildPoly &p_poly, int p_edge, int p_from_point, int p_to_point, const Vector<Vector<int> > &vertex_process, Vector<bool> &edge_process, Vector<PolyPoints> &r_poly);
- void _add_poly_outline(const BuildPoly &p_poly, int p_from_point, int p_to_point, const Vector<Vector<int> > &vertex_process, Vector<int> &r_outline);
- void _merge_poly(MeshMerge &mesh, int p_face_idx, const BuildPoly &p_poly, bool p_from_b);
-
- void _collision_callback(const CSGBrush *A, int p_face_a, Map<int, BuildPoly> &build_polys_a, const CSGBrush *B, int p_face_b, Map<int, BuildPoly> &build_polys_b, MeshMerge &mesh_merge);
-
- static void _collision_callbacks(void *ud, int p_face_b);
- void merge_brushes(Operation p_operation, const CSGBrush &p_A, const CSGBrush &p_B, CSGBrush &result, float p_snap = 0.001);
+ void update_faces(const CSGBrush &p_brush_a, const int p_face_idx_a, const CSGBrush &p_brush_b, const int p_face_idx_b, Build2DFaceCollection &p_collection, float p_vertex_snap);
};
#endif // CSG_H
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index 49387606f3..fa176cb94e 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -32,7 +32,7 @@
///////////
-CSGShapeSpatialGizmoPlugin::CSGShapeSpatialGizmoPlugin() {
+CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.0, 0.4, 1, 0.15));
create_material("shape_union_material", gizmo_color);
@@ -49,46 +49,46 @@ CSGShapeSpatialGizmoPlugin::CSGShapeSpatialGizmoPlugin() {
create_handle_material("handles");
}
-String CSGShapeSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
- CSGShape *cs = Object::cast_to<CSGShape>(p_gizmo->get_spatial_node());
+ CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
- if (Object::cast_to<CSGSphere>(cs)) {
+ if (Object::cast_to<CSGSphere3D>(cs)) {
return "Radius";
}
- if (Object::cast_to<CSGBox>(cs)) {
+ if (Object::cast_to<CSGBox3D>(cs)) {
static const char *hname[3] = { "Width", "Height", "Depth" };
return hname[p_idx];
}
- if (Object::cast_to<CSGCylinder>(cs)) {
+ if (Object::cast_to<CSGCylinder3D>(cs)) {
return p_idx == 0 ? "Radius" : "Height";
}
- if (Object::cast_to<CSGTorus>(cs)) {
+ if (Object::cast_to<CSGTorus3D>(cs)) {
return p_idx == 0 ? "InnerRadius" : "OuterRadius";
}
return "";
}
-Variant CSGShapeSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
- CSGShape *cs = Object::cast_to<CSGShape>(p_gizmo->get_spatial_node());
+ CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
- if (Object::cast_to<CSGSphere>(cs)) {
+ if (Object::cast_to<CSGSphere3D>(cs)) {
- CSGSphere *s = Object::cast_to<CSGSphere>(cs);
+ CSGSphere3D *s = Object::cast_to<CSGSphere3D>(cs);
return s->get_radius();
}
- if (Object::cast_to<CSGBox>(cs)) {
+ if (Object::cast_to<CSGBox3D>(cs)) {
- CSGBox *s = Object::cast_to<CSGBox>(cs);
+ CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
switch (p_idx) {
case 0: return s->get_width();
case 1: return s->get_height();
@@ -96,23 +96,23 @@ Variant CSGShapeSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo
}
}
- if (Object::cast_to<CSGCylinder>(cs)) {
+ if (Object::cast_to<CSGCylinder3D>(cs)) {
- CSGCylinder *s = Object::cast_to<CSGCylinder>(cs);
+ CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
return p_idx == 0 ? s->get_radius() : s->get_height();
}
- if (Object::cast_to<CSGTorus>(cs)) {
+ if (Object::cast_to<CSGTorus3D>(cs)) {
- CSGTorus *s = Object::cast_to<CSGTorus>(cs);
+ CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
return p_idx == 0 ? s->get_inner_radius() : s->get_outer_radius();
}
return Variant();
}
-void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
- CSGShape *cs = Object::cast_to<CSGShape>(p_gizmo->get_spatial_node());
+ CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
Transform gt = cs->get_global_transform();
//gt.orthonormalize();
@@ -123,15 +123,15 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
- if (Object::cast_to<CSGSphere>(cs)) {
+ if (Object::cast_to<CSGSphere3D>(cs)) {
- CSGSphere *s = Object::cast_to<CSGSphere>(cs);
+ CSGSphere3D *s = Object::cast_to<CSGSphere3D>(cs);
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
float d = ra.x;
- if (SpatialEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ if (Node3DEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001)
@@ -140,17 +140,17 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
s->set_radius(d);
}
- if (Object::cast_to<CSGBox>(cs)) {
+ if (Object::cast_to<CSGBox3D>(cs)) {
- CSGBox *s = Object::cast_to<CSGBox>(cs);
+ CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
Vector3 axis;
axis[p_idx] = 1.0;
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
- if (SpatialEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ if (Node3DEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001)
@@ -163,17 +163,17 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
}
}
- if (Object::cast_to<CSGCylinder>(cs)) {
+ if (Object::cast_to<CSGCylinder3D>(cs)) {
- CSGCylinder *s = Object::cast_to<CSGCylinder>(cs);
+ CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
Vector3 axis;
axis[p_idx == 0 ? 0 : 1] = 1.0;
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
- if (SpatialEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ if (Node3DEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001)
@@ -185,17 +185,17 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
s->set_height(d * 2.0);
}
- if (Object::cast_to<CSGTorus>(cs)) {
+ if (Object::cast_to<CSGTorus3D>(cs)) {
- CSGTorus *s = Object::cast_to<CSGTorus>(cs);
+ CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
Vector3 axis;
axis[0] = 1.0;
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
- if (SpatialEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap());
+ if (Node3DEditor::get_singleton()->is_snap_enabled()) {
+ d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
if (d < 0.001)
@@ -207,26 +207,26 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
s->set_outer_radius(d);
}
}
-void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
- CSGShape *cs = Object::cast_to<CSGShape>(p_gizmo->get_spatial_node());
+ CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
- if (Object::cast_to<CSGSphere>(cs)) {
- CSGSphere *s = Object::cast_to<CSGSphere>(cs);
+ if (Object::cast_to<CSGSphere3D>(cs)) {
+ CSGSphere3D *s = Object::cast_to<CSGSphere3D>(cs);
if (p_cancel) {
s->set_radius(p_restore);
return;
}
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change Sphere Shape Radius"));
ur->add_do_method(s, "set_radius", s->get_radius());
ur->add_undo_method(s, "set_radius", p_restore);
ur->commit_action();
}
- if (Object::cast_to<CSGBox>(cs)) {
- CSGBox *s = Object::cast_to<CSGBox>(cs);
+ if (Object::cast_to<CSGBox3D>(cs)) {
+ CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
if (p_cancel) {
switch (p_idx) {
case 0: s->set_width(p_restore); break;
@@ -236,7 +236,7 @@ void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int
return;
}
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change Box Shape Extents"));
static const char *method[3] = { "set_width", "set_height", "set_depth" };
float current = 0;
@@ -251,8 +251,8 @@ void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int
ur->commit_action();
}
- if (Object::cast_to<CSGCylinder>(cs)) {
- CSGCylinder *s = Object::cast_to<CSGCylinder>(cs);
+ if (Object::cast_to<CSGCylinder3D>(cs)) {
+ CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
if (p_cancel) {
if (p_idx == 0)
s->set_radius(p_restore);
@@ -261,7 +261,7 @@ void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int
return;
}
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
if (p_idx == 0) {
ur->create_action(TTR("Change Cylinder Radius"));
ur->add_do_method(s, "set_radius", s->get_radius());
@@ -275,8 +275,8 @@ void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int
ur->commit_action();
}
- if (Object::cast_to<CSGTorus>(cs)) {
- CSGTorus *s = Object::cast_to<CSGTorus>(cs);
+ if (Object::cast_to<CSGTorus3D>(cs)) {
+ CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
if (p_cancel) {
if (p_idx == 0)
s->set_inner_radius(p_restore);
@@ -285,7 +285,7 @@ void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int
return;
}
- UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
if (p_idx == 0) {
ur->create_action(TTR("Change Torus Inner Radius"));
ur->add_do_method(s, "set_inner_radius", s->get_inner_radius());
@@ -299,49 +299,49 @@ void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int
ur->commit_action();
}
}
-bool CSGShapeSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
- return Object::cast_to<CSGSphere>(p_spatial) || Object::cast_to<CSGBox>(p_spatial) || Object::cast_to<CSGCylinder>(p_spatial) || Object::cast_to<CSGTorus>(p_spatial) || Object::cast_to<CSGMesh>(p_spatial) || Object::cast_to<CSGPolygon>(p_spatial);
+bool CSGShape3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
+ return Object::cast_to<CSGSphere3D>(p_spatial) || Object::cast_to<CSGBox3D>(p_spatial) || Object::cast_to<CSGCylinder3D>(p_spatial) || Object::cast_to<CSGTorus3D>(p_spatial) || Object::cast_to<CSGMesh3D>(p_spatial) || Object::cast_to<CSGPolygon3D>(p_spatial);
}
-String CSGShapeSpatialGizmoPlugin::get_name() const {
- return "CSGShapes";
+String CSGShape3DGizmoPlugin::get_name() const {
+ return "CSGShape3D";
}
-int CSGShapeSpatialGizmoPlugin::get_priority() const {
+int CSGShape3DGizmoPlugin::get_priority() const {
return -1;
}
-bool CSGShapeSpatialGizmoPlugin::is_selectable_when_hidden() const {
+bool CSGShape3DGizmoPlugin::is_selectable_when_hidden() const {
return true;
}
-void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
- CSGShape *cs = Object::cast_to<CSGShape>(p_gizmo->get_spatial_node());
+ CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
Ref<Material> material;
switch (cs->get_operation()) {
- case CSGShape::OPERATION_UNION:
+ case CSGShape3D::OPERATION_UNION:
material = get_material("shape_union_material", p_gizmo);
break;
- case CSGShape::OPERATION_INTERSECTION:
+ case CSGShape3D::OPERATION_INTERSECTION:
material = get_material("shape_intersection_material", p_gizmo);
break;
- case CSGShape::OPERATION_SUBTRACTION:
+ case CSGShape3D::OPERATION_SUBTRACTION:
material = get_material("shape_subtraction_material", p_gizmo);
break;
}
Ref<Material> handles_material = get_material("handles");
- PoolVector<Vector3> faces = cs->get_brush_faces();
+ Vector<Vector3> faces = cs->get_brush_faces();
Vector<Vector3> lines;
lines.resize(faces.size() * 2);
{
- PoolVector<Vector3>::Read r = faces.read();
+ const Vector3 *r = faces.ptr();
for (int i = 0; i < lines.size(); i += 6) {
int f = i / 6;
@@ -366,13 +366,13 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
Ref<Material> solid_material;
switch (cs->get_operation()) {
- case CSGShape::OPERATION_UNION:
+ case CSGShape3D::OPERATION_UNION:
solid_material = get_material("shape_union_solid_material", p_gizmo);
break;
- case CSGShape::OPERATION_INTERSECTION:
+ case CSGShape3D::OPERATION_INTERSECTION:
solid_material = get_material("shape_intersection_solid_material", p_gizmo);
break;
- case CSGShape::OPERATION_SUBTRACTION:
+ case CSGShape3D::OPERATION_SUBTRACTION:
solid_material = get_material("shape_subtraction_solid_material", p_gizmo);
break;
}
@@ -380,8 +380,8 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), solid_material);
}
- if (Object::cast_to<CSGSphere>(cs)) {
- CSGSphere *s = Object::cast_to<CSGSphere>(cs);
+ if (Object::cast_to<CSGSphere3D>(cs)) {
+ CSGSphere3D *s = Object::cast_to<CSGSphere3D>(cs);
float r = s->get_radius();
Vector<Vector3> handles;
@@ -389,8 +389,8 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
p_gizmo->add_handles(handles, handles_material);
}
- if (Object::cast_to<CSGBox>(cs)) {
- CSGBox *s = Object::cast_to<CSGBox>(cs);
+ if (Object::cast_to<CSGBox3D>(cs)) {
+ CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
Vector<Vector3> handles;
handles.push_back(Vector3(s->get_width() * 0.5, 0, 0));
@@ -399,8 +399,8 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
p_gizmo->add_handles(handles, handles_material);
}
- if (Object::cast_to<CSGCylinder>(cs)) {
- CSGCylinder *s = Object::cast_to<CSGCylinder>(cs);
+ if (Object::cast_to<CSGCylinder3D>(cs)) {
+ CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
Vector<Vector3> handles;
handles.push_back(Vector3(s->get_radius(), 0, 0));
@@ -408,8 +408,8 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
p_gizmo->add_handles(handles, handles_material);
}
- if (Object::cast_to<CSGTorus>(cs)) {
- CSGTorus *s = Object::cast_to<CSGTorus>(cs);
+ if (Object::cast_to<CSGTorus3D>(cs)) {
+ CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
Vector<Vector3> handles;
handles.push_back(Vector3(s->get_inner_radius(), 0, 0));
@@ -419,6 +419,6 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
}
EditorPluginCSG::EditorPluginCSG(EditorNode *p_editor) {
- Ref<CSGShapeSpatialGizmoPlugin> gizmo_plugin = Ref<CSGShapeSpatialGizmoPlugin>(memnew(CSGShapeSpatialGizmoPlugin));
- SpatialEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin);
+ Ref<CSGShape3DGizmoPlugin> gizmo_plugin = Ref<CSGShape3DGizmoPlugin>(memnew(CSGShape3DGizmoPlugin));
+ Node3DEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin);
}
diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h
index 966b654802..7763989b2a 100644
--- a/modules/csg/csg_gizmos.h
+++ b/modules/csg/csg_gizmos.h
@@ -33,25 +33,25 @@
#include "csg_shape.h"
#include "editor/editor_plugin.h"
-#include "editor/spatial_editor_gizmos.h"
+#include "editor/node_3d_editor_gizmos.h"
-class CSGShapeSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
+class CSGShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
- GDCLASS(CSGShapeSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
+ GDCLASS(CSGShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
- bool has_gizmo(Spatial *p_spatial);
+ bool has_gizmo(Node3D *p_spatial);
String get_name() const;
int get_priority() const;
bool is_selectable_when_hidden() const;
- void redraw(EditorSpatialGizmo *p_gizmo);
+ void redraw(EditorNode3DGizmo *p_gizmo);
- String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
- Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
- void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
- void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel);
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point);
+ void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel);
- CSGShapeSpatialGizmoPlugin();
+ CSGShape3DGizmoPlugin();
};
class EditorPluginCSG : public EditorPlugin {
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index c8a72ff813..5557da3014 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "csg_shape.h"
-#include "scene/3d/path.h"
+#include "scene/3d/path_3d.h"
-void CSGShape::set_use_collision(bool p_enable) {
+void CSGShape3D::set_use_collision(bool p_enable) {
if (use_collision == p_enable)
return;
@@ -43,52 +43,52 @@ void CSGShape::set_use_collision(bool p_enable) {
if (use_collision) {
root_collision_shape.instance();
- root_collision_instance = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
- PhysicsServer::get_singleton()->body_set_state(root_collision_instance, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
- PhysicsServer::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
- PhysicsServer::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
- PhysicsServer::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
+ root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
+ PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
+ PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
+ PhysicsServer3D::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
set_collision_layer(collision_layer);
set_collision_mask(collision_mask);
_make_dirty(); //force update
} else {
- PhysicsServer::get_singleton()->free(root_collision_instance);
+ PhysicsServer3D::get_singleton()->free(root_collision_instance);
root_collision_instance = RID();
root_collision_shape.unref();
}
_change_notify();
}
-bool CSGShape::is_using_collision() const {
+bool CSGShape3D::is_using_collision() const {
return use_collision;
}
-void CSGShape::set_collision_layer(uint32_t p_layer) {
+void CSGShape3D::set_collision_layer(uint32_t p_layer) {
collision_layer = p_layer;
if (root_collision_instance.is_valid()) {
- PhysicsServer::get_singleton()->body_set_collision_layer(root_collision_instance, p_layer);
+ PhysicsServer3D::get_singleton()->body_set_collision_layer(root_collision_instance, p_layer);
}
}
-uint32_t CSGShape::get_collision_layer() const {
+uint32_t CSGShape3D::get_collision_layer() const {
return collision_layer;
}
-void CSGShape::set_collision_mask(uint32_t p_mask) {
+void CSGShape3D::set_collision_mask(uint32_t p_mask) {
collision_mask = p_mask;
if (root_collision_instance.is_valid()) {
- PhysicsServer::get_singleton()->body_set_collision_mask(root_collision_instance, p_mask);
+ PhysicsServer3D::get_singleton()->body_set_collision_mask(root_collision_instance, p_mask);
}
}
-uint32_t CSGShape::get_collision_mask() const {
+uint32_t CSGShape3D::get_collision_mask() const {
return collision_mask;
}
-void CSGShape::set_collision_mask_bit(int p_bit, bool p_value) {
+void CSGShape3D::set_collision_mask_bit(int p_bit, bool p_value) {
uint32_t mask = get_collision_mask();
if (p_value)
@@ -98,12 +98,12 @@ void CSGShape::set_collision_mask_bit(int p_bit, bool p_value) {
set_collision_mask(mask);
}
-bool CSGShape::get_collision_mask_bit(int p_bit) const {
+bool CSGShape3D::get_collision_mask_bit(int p_bit) const {
return get_collision_mask() & (1 << p_bit);
}
-void CSGShape::set_collision_layer_bit(int p_bit, bool p_value) {
+void CSGShape3D::set_collision_layer_bit(int p_bit, bool p_value) {
uint32_t mask = get_collision_layer();
if (p_value)
@@ -113,25 +113,25 @@ void CSGShape::set_collision_layer_bit(int p_bit, bool p_value) {
set_collision_layer(mask);
}
-bool CSGShape::get_collision_layer_bit(int p_bit) const {
+bool CSGShape3D::get_collision_layer_bit(int p_bit) const {
return get_collision_layer() & (1 << p_bit);
}
-bool CSGShape::is_root_shape() const {
+bool CSGShape3D::is_root_shape() const {
return !parent;
}
-void CSGShape::set_snap(float p_snap) {
+void CSGShape3D::set_snap(float p_snap) {
snap = p_snap;
}
-float CSGShape::get_snap() const {
+float CSGShape3D::get_snap() const {
return snap;
}
-void CSGShape::_make_dirty() {
+void CSGShape3D::_make_dirty() {
if (!is_inside_tree())
return;
@@ -150,19 +150,19 @@ void CSGShape::_make_dirty() {
}
}
-CSGBrush *CSGShape::_get_brush() {
+CSGBrush *CSGShape3D::_get_brush() {
if (dirty) {
if (brush) {
memdelete(brush);
}
- brush = NULL;
+ brush = nullptr;
CSGBrush *n = _build_brush();
for (int i = 0; i < get_child_count(); i++) {
- CSGShape *child = Object::cast_to<CSGShape>(get_child(i));
+ CSGShape3D *child = Object::cast_to<CSGShape3D>(get_child(i));
if (!child)
continue;
if (!child->is_visible_in_tree())
@@ -185,9 +185,9 @@ CSGBrush *CSGShape::_get_brush() {
CSGBrushOperation bop;
switch (child->get_operation()) {
- case CSGShape::OPERATION_UNION: bop.merge_brushes(CSGBrushOperation::OPERATION_UNION, *n, *nn2, *nn, snap); break;
- case CSGShape::OPERATION_INTERSECTION: bop.merge_brushes(CSGBrushOperation::OPERATION_INTERSECTION, *n, *nn2, *nn, snap); break;
- case CSGShape::OPERATION_SUBTRACTION: bop.merge_brushes(CSGBrushOperation::OPERATION_SUBSTRACTION, *n, *nn2, *nn, snap); break;
+ case CSGShape3D::OPERATION_UNION: bop.merge_brushes(CSGBrushOperation::OPERATION_UNION, *n, *nn2, *nn, snap); break;
+ case CSGShape3D::OPERATION_INTERSECTION: bop.merge_brushes(CSGBrushOperation::OPERATION_INTERSECTION, *n, *nn2, *nn, snap); break;
+ case CSGShape3D::OPERATION_SUBTRACTION: bop.merge_brushes(CSGBrushOperation::OPERATION_SUBSTRACTION, *n, *nn2, *nn, snap); break;
}
memdelete(n);
memdelete(nn2);
@@ -218,18 +218,18 @@ CSGBrush *CSGShape::_get_brush() {
return brush;
}
-int CSGShape::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
+int CSGShape3D::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
ShapeUpdateSurface &surface = *((ShapeUpdateSurface *)pContext->m_pUserData);
return surface.vertices.size() / 3;
}
-int CSGShape::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
+int CSGShape3D::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
// always 3
return 3;
}
-void CSGShape::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
+void CSGShape3D::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
ShapeUpdateSurface &surface = *((ShapeUpdateSurface *)pContext->m_pUserData);
Vector3 v = surface.verticesw[iFace * 3 + iVert];
@@ -238,7 +238,7 @@ void CSGShape::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosO
fvPosOut[2] = v.z;
}
-void CSGShape::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) {
+void CSGShape3D::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) {
ShapeUpdateSurface &surface = *((ShapeUpdateSurface *)pContext->m_pUserData);
Vector3 n = surface.normalsw[iFace * 3 + iVert];
@@ -247,7 +247,7 @@ void CSGShape::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOu
fvNormOut[2] = n.z;
}
-void CSGShape::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
+void CSGShape3D::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
ShapeUpdateSurface &surface = *((ShapeUpdateSurface *)pContext->m_pUserData);
Vector2 t = surface.uvsw[iFace * 3 + iVert];
@@ -255,7 +255,7 @@ void CSGShape::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexc
fvTexcOut[1] = t.y;
}
-void CSGShape::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
+void CSGShape3D::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
ShapeUpdateSurface &surface = *((ShapeUpdateSurface *)pContext->m_pUserData);
@@ -273,7 +273,7 @@ void CSGShape::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const f
surface.tansw[i++] = d < 0 ? -1 : 1;
}
-void CSGShape::_update_shape() {
+void CSGShape3D::_update_shape() {
if (parent)
return;
@@ -334,16 +334,16 @@ void CSGShape::_update_shape() {
surfaces.write[i].material = n->materials[i];
}
- surfaces.write[i].verticesw = surfaces.write[i].vertices.write();
- surfaces.write[i].normalsw = surfaces.write[i].normals.write();
- surfaces.write[i].uvsw = surfaces.write[i].uvs.write();
+ surfaces.write[i].verticesw = surfaces.write[i].vertices.ptrw();
+ surfaces.write[i].normalsw = surfaces.write[i].normals.ptrw();
+ surfaces.write[i].uvsw = surfaces.write[i].uvs.ptrw();
if (calculate_tangents) {
- surfaces.write[i].tansw = surfaces.write[i].tans.write();
+ surfaces.write[i].tansw = surfaces.write[i].tans.ptrw();
}
}
//fill arrays
- PoolVector<Vector3> physics_faces;
+ Vector<Vector3> physics_faces;
bool fill_physics_faces = false;
if (root_collision_shape.is_valid()) {
physics_faces.resize(n->faces.size() * 3);
@@ -351,10 +351,10 @@ void CSGShape::_update_shape() {
}
{
- PoolVector<Vector3>::Write physicsw;
+ Vector3 *physicsw;
if (fill_physics_faces) {
- physicsw = physics_faces.write();
+ physicsw = physics_faces.ptrw();
}
for (int i = 0; i < n->faces.size(); i++) {
@@ -427,7 +427,7 @@ void CSGShape::_update_shape() {
mkif.m_getPosition = mikktGetPosition;
mkif.m_getTexCoord = mikktGetTexCoord;
mkif.m_setTSpace = mikktSetTSpaceDefault;
- mkif.m_setTSpaceBasic = NULL;
+ mkif.m_setTSpaceBasic = nullptr;
SMikkTSpaceContext msc;
msc.m_pInterface = &mkif;
@@ -435,12 +435,6 @@ void CSGShape::_update_shape() {
have_tangents = genTangSpaceDefault(&msc);
}
- // unset write access
- surfaces.write[i].verticesw.release();
- surfaces.write[i].normalsw.release();
- surfaces.write[i].uvsw.release();
- surfaces.write[i].tansw.release();
-
if (surfaces[i].last_added == 0)
continue;
@@ -466,22 +460,22 @@ void CSGShape::_update_shape() {
set_base(root_mesh->get_rid());
}
-AABB CSGShape::get_aabb() const {
+AABB CSGShape3D::get_aabb() const {
return node_aabb;
}
-PoolVector<Vector3> CSGShape::get_brush_faces() {
- ERR_FAIL_COND_V(!is_inside_tree(), PoolVector<Vector3>());
+Vector<Vector3> CSGShape3D::get_brush_faces() {
+ ERR_FAIL_COND_V(!is_inside_tree(), Vector<Vector3>());
CSGBrush *b = _get_brush();
if (!b) {
- return PoolVector<Vector3>();
+ return Vector<Vector3>();
}
- PoolVector<Vector3> faces;
+ Vector<Vector3> faces;
int fc = b->faces.size();
faces.resize(fc * 3);
{
- PoolVector<Vector3>::Write w = faces.write();
+ Vector3 *w = faces.ptrw();
for (int i = 0; i < fc; i++) {
w[i * 3 + 0] = b->faces[i].vertices[0];
w[i * 3 + 1] = b->faces[i].vertices[1];
@@ -492,18 +486,18 @@ PoolVector<Vector3> CSGShape::get_brush_faces() {
return faces;
}
-PoolVector<Face3> CSGShape::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> CSGShape3D::get_faces(uint32_t p_usage_flags) const {
- return PoolVector<Face3>();
+ return Vector<Face3>();
}
-void CSGShape::_notification(int p_what) {
+void CSGShape3D::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
Node *parentn = get_parent();
if (parentn) {
- parent = Object::cast_to<CSGShape>(parentn);
+ parent = Object::cast_to<CSGShape3D>(parentn);
if (parent) {
set_base(RID());
root_mesh.unref();
@@ -512,11 +506,11 @@ void CSGShape::_notification(int p_what) {
if (use_collision && is_root_shape()) {
root_collision_shape.instance();
- root_collision_instance = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
- PhysicsServer::get_singleton()->body_set_state(root_collision_instance, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
- PhysicsServer::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
- PhysicsServer::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
- PhysicsServer::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
+ root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
+ PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
+ PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
+ PhysicsServer3D::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
set_collision_layer(collision_layer);
set_collision_mask(collision_mask);
}
@@ -542,10 +536,10 @@ void CSGShape::_notification(int p_what) {
if (parent)
parent->_make_dirty();
- parent = NULL;
+ parent = nullptr;
if (use_collision && is_root_shape() && root_collision_instance.is_valid()) {
- PhysicsServer::get_singleton()->free(root_collision_instance);
+ PhysicsServer3D::get_singleton()->free(root_collision_instance);
root_collision_instance = RID();
root_collision_shape.unref();
}
@@ -553,27 +547,27 @@ void CSGShape::_notification(int p_what) {
}
}
-void CSGShape::set_operation(Operation p_operation) {
+void CSGShape3D::set_operation(Operation p_operation) {
operation = p_operation;
_make_dirty();
update_gizmo();
}
-CSGShape::Operation CSGShape::get_operation() const {
+CSGShape3D::Operation CSGShape3D::get_operation() const {
return operation;
}
-void CSGShape::set_calculate_tangents(bool p_calculate_tangents) {
+void CSGShape3D::set_calculate_tangents(bool p_calculate_tangents) {
calculate_tangents = p_calculate_tangents;
_make_dirty();
}
-bool CSGShape::is_calculating_tangents() const {
+bool CSGShape3D::is_calculating_tangents() const {
return calculate_tangents;
}
-void CSGShape::_validate_property(PropertyInfo &property) const {
+void CSGShape3D::_validate_property(PropertyInfo &property) const {
bool is_collision_prefixed = property.name.begins_with("collision_");
if ((is_collision_prefixed || property.name.begins_with("use_collision")) && is_inside_tree() && !is_root_shape()) {
//hide collision if not root
@@ -583,7 +577,7 @@ void CSGShape::_validate_property(PropertyInfo &property) const {
}
}
-Array CSGShape::get_meshes() const {
+Array CSGShape3D::get_meshes() const {
if (root_mesh.is_valid()) {
Array arr;
@@ -595,39 +589,39 @@ Array CSGShape::get_meshes() const {
return Array();
}
-void CSGShape::_bind_methods() {
+void CSGShape3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_update_shape"), &CSGShape::_update_shape);
- ClassDB::bind_method(D_METHOD("is_root_shape"), &CSGShape::is_root_shape);
+ ClassDB::bind_method(D_METHOD("_update_shape"), &CSGShape3D::_update_shape);
+ ClassDB::bind_method(D_METHOD("is_root_shape"), &CSGShape3D::is_root_shape);
- ClassDB::bind_method(D_METHOD("set_operation", "operation"), &CSGShape::set_operation);
- ClassDB::bind_method(D_METHOD("get_operation"), &CSGShape::get_operation);
+ ClassDB::bind_method(D_METHOD("set_operation", "operation"), &CSGShape3D::set_operation);
+ ClassDB::bind_method(D_METHOD("get_operation"), &CSGShape3D::get_operation);
- ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CSGShape::set_snap);
- ClassDB::bind_method(D_METHOD("get_snap"), &CSGShape::get_snap);
+ ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CSGShape3D::set_snap);
+ ClassDB::bind_method(D_METHOD("get_snap"), &CSGShape3D::get_snap);
- ClassDB::bind_method(D_METHOD("set_use_collision", "operation"), &CSGShape::set_use_collision);
- ClassDB::bind_method(D_METHOD("is_using_collision"), &CSGShape::is_using_collision);
+ ClassDB::bind_method(D_METHOD("set_use_collision", "operation"), &CSGShape3D::set_use_collision);
+ ClassDB::bind_method(D_METHOD("is_using_collision"), &CSGShape3D::is_using_collision);
- ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &CSGShape::set_collision_layer);
- ClassDB::bind_method(D_METHOD("get_collision_layer"), &CSGShape::get_collision_layer);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &CSGShape3D::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &CSGShape3D::get_collision_layer);
- ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &CSGShape::set_collision_mask);
- ClassDB::bind_method(D_METHOD("get_collision_mask"), &CSGShape::get_collision_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &CSGShape3D::set_collision_mask);
+ ClassDB::bind_method(D_METHOD("get_collision_mask"), &CSGShape3D::get_collision_mask);
- ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &CSGShape::set_collision_mask_bit);
- ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &CSGShape::get_collision_mask_bit);
+ ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &CSGShape3D::set_collision_mask_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &CSGShape3D::get_collision_mask_bit);
- ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &CSGShape::set_collision_layer_bit);
- ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &CSGShape::get_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &CSGShape3D::set_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &CSGShape3D::get_collision_layer_bit);
- ClassDB::bind_method(D_METHOD("set_calculate_tangents", "enabled"), &CSGShape::set_calculate_tangents);
- ClassDB::bind_method(D_METHOD("is_calculating_tangents"), &CSGShape::is_calculating_tangents);
+ ClassDB::bind_method(D_METHOD("set_calculate_tangents", "enabled"), &CSGShape3D::set_calculate_tangents);
+ ClassDB::bind_method(D_METHOD("is_calculating_tangents"), &CSGShape3D::is_calculating_tangents);
- ClassDB::bind_method(D_METHOD("get_meshes"), &CSGShape::get_meshes);
+ ClassDB::bind_method(D_METHOD("get_meshes"), &CSGShape3D::get_meshes);
ADD_PROPERTY(PropertyInfo(Variant::INT, "operation", PROPERTY_HINT_ENUM, "Union,Intersection,Subtraction"), "set_operation", "get_operation");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "snap", PROPERTY_HINT_RANGE, "0.0001,1,0.001"), "set_snap", "get_snap");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_RANGE, "0.0001,1,0.001"), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_tangents"), "set_calculate_tangents", "is_calculating_tangents");
ADD_GROUP("Collision", "collision_");
@@ -640,10 +634,10 @@ void CSGShape::_bind_methods() {
BIND_ENUM_CONSTANT(OPERATION_SUBTRACTION);
}
-CSGShape::CSGShape() {
+CSGShape3D::CSGShape3D() {
operation = OPERATION_UNION;
- parent = NULL;
- brush = NULL;
+ parent = nullptr;
+ brush = nullptr;
dirty = false;
snap = 0.001;
use_collision = false;
@@ -653,33 +647,33 @@ CSGShape::CSGShape() {
set_notify_local_transform(true);
}
-CSGShape::~CSGShape() {
+CSGShape3D::~CSGShape3D() {
if (brush) {
memdelete(brush);
- brush = NULL;
+ brush = nullptr;
}
}
//////////////////////////////////
-CSGBrush *CSGCombiner::_build_brush() {
+CSGBrush *CSGCombiner3D::_build_brush() {
- return NULL; //does not build anything
+ return nullptr; //does not build anything
}
-CSGCombiner::CSGCombiner() {
+CSGCombiner3D::CSGCombiner3D() {
}
/////////////////////
-CSGBrush *CSGPrimitive::_create_brush_from_arrays(const PoolVector<Vector3> &p_vertices, const PoolVector<Vector2> &p_uv, const PoolVector<bool> &p_smooth, const PoolVector<Ref<Material> > &p_materials) {
+CSGBrush *CSGPrimitive3D::_create_brush_from_arrays(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uv, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials) {
CSGBrush *brush = memnew(CSGBrush);
- PoolVector<bool> invert;
+ Vector<bool> invert;
invert.resize(p_vertices.size() / 3);
{
int ic = invert.size();
- PoolVector<bool>::Write w = invert.write();
+ bool *w = invert.ptrw();
for (int i = 0; i < ic; i++) {
w[i] = invert_faces;
}
@@ -689,15 +683,15 @@ CSGBrush *CSGPrimitive::_create_brush_from_arrays(const PoolVector<Vector3> &p_v
return brush;
}
-void CSGPrimitive::_bind_methods() {
+void CSGPrimitive3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_invert_faces", "invert_faces"), &CSGPrimitive::set_invert_faces);
- ClassDB::bind_method(D_METHOD("is_inverting_faces"), &CSGPrimitive::is_inverting_faces);
+ ClassDB::bind_method(D_METHOD("set_invert_faces", "invert_faces"), &CSGPrimitive3D::set_invert_faces);
+ ClassDB::bind_method(D_METHOD("is_inverting_faces"), &CSGPrimitive3D::is_inverting_faces);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_faces"), "set_invert_faces", "is_inverting_faces");
}
-void CSGPrimitive::set_invert_faces(bool p_invert) {
+void CSGPrimitive3D::set_invert_faces(bool p_invert) {
if (invert_faces == p_invert)
return;
@@ -706,25 +700,25 @@ void CSGPrimitive::set_invert_faces(bool p_invert) {
_make_dirty();
}
-bool CSGPrimitive::is_inverting_faces() {
+bool CSGPrimitive3D::is_inverting_faces() {
return invert_faces;
}
-CSGPrimitive::CSGPrimitive() {
+CSGPrimitive3D::CSGPrimitive3D() {
invert_faces = false;
}
/////////////////////
-CSGBrush *CSGMesh::_build_brush() {
+CSGBrush *CSGMesh3D::_build_brush() {
if (!mesh.is_valid())
- return NULL;
+ return nullptr;
- PoolVector<Vector3> vertices;
- PoolVector<bool> smooth;
- PoolVector<Ref<Material> > materials;
- PoolVector<Vector2> uvs;
+ Vector<Vector3> vertices;
+ Vector<bool> smooth;
+ Vector<Ref<Material>> materials;
+ Vector<Vector2> uvs;
Ref<Material> material = get_material();
for (int i = 0; i < mesh->get_surface_count(); i++) {
@@ -737,29 +731,25 @@ CSGBrush *CSGMesh::_build_brush() {
if (arrays.size() == 0) {
_make_dirty();
- ERR_FAIL_COND_V(arrays.size() == 0, NULL);
+ ERR_FAIL_COND_V(arrays.size() == 0, nullptr);
}
- PoolVector<Vector3> avertices = arrays[Mesh::ARRAY_VERTEX];
+ Vector<Vector3> avertices = arrays[Mesh::ARRAY_VERTEX];
if (avertices.size() == 0)
continue;
- PoolVector<Vector3>::Read vr = avertices.read();
+ const Vector3 *vr = avertices.ptr();
- PoolVector<Vector3> anormals = arrays[Mesh::ARRAY_NORMAL];
- PoolVector<Vector3>::Read nr;
- bool nr_used = false;
+ Vector<Vector3> anormals = arrays[Mesh::ARRAY_NORMAL];
+ const Vector3 *nr = nullptr;
if (anormals.size()) {
- nr = anormals.read();
- nr_used = true;
+ nr = anormals.ptr();
}
- PoolVector<Vector2> auvs = arrays[Mesh::ARRAY_TEX_UV];
- PoolVector<Vector2>::Read uvr;
- bool uvr_used = false;
+ Vector<Vector2> auvs = arrays[Mesh::ARRAY_TEX_UV];
+ const Vector2 *uvr = nullptr;
if (auvs.size()) {
- uvr = auvs.read();
- uvr_used = true;
+ uvr = auvs.ptr();
}
Ref<Material> mat;
@@ -769,7 +759,7 @@ CSGBrush *CSGMesh::_build_brush() {
mat = mesh->surface_get_material(i);
}
- PoolVector<int> aindices = arrays[Mesh::ARRAY_INDEX];
+ Vector<int> aindices = arrays[Mesh::ARRAY_INDEX];
if (aindices.size()) {
int as = vertices.size();
int is = aindices.size();
@@ -779,12 +769,12 @@ CSGBrush *CSGMesh::_build_brush() {
materials.resize((as + is) / 3);
uvs.resize(as + is);
- PoolVector<Vector3>::Write vw = vertices.write();
- PoolVector<bool>::Write sw = smooth.write();
- PoolVector<Vector2>::Write uvw = uvs.write();
- PoolVector<Ref<Material> >::Write mw = materials.write();
+ Vector3 *vw = vertices.ptrw();
+ bool *sw = smooth.ptrw();
+ Vector2 *uvw = uvs.ptrw();
+ Ref<Material> *mw = materials.ptrw();
- PoolVector<int>::Read ir = aindices.read();
+ const int *ir = aindices.ptr();
for (int j = 0; j < is; j += 3) {
@@ -795,10 +785,10 @@ CSGBrush *CSGMesh::_build_brush() {
for (int k = 0; k < 3; k++) {
int idx = ir[j + k];
vertex[k] = vr[idx];
- if (nr_used) {
+ if (nr) {
normal[k] = nr[idx];
}
- if (uvr_used) {
+ if (uvr) {
uv[k] = uvr[idx];
}
}
@@ -825,10 +815,10 @@ CSGBrush *CSGMesh::_build_brush() {
uvs.resize(as + is);
materials.resize((as + is) / 3);
- PoolVector<Vector3>::Write vw = vertices.write();
- PoolVector<bool>::Write sw = smooth.write();
- PoolVector<Vector2>::Write uvw = uvs.write();
- PoolVector<Ref<Material> >::Write mw = materials.write();
+ Vector3 *vw = vertices.ptrw();
+ bool *sw = smooth.ptrw();
+ Vector2 *uvw = uvs.ptrw();
+ Ref<Material> *mw = materials.ptrw();
for (int j = 0; j < is; j += 3) {
@@ -838,10 +828,10 @@ CSGBrush *CSGMesh::_build_brush() {
for (int k = 0; k < 3; k++) {
vertex[k] = vr[j + k];
- if (nr_used) {
+ if (nr) {
normal[k] = nr[j + k];
}
- if (uvr_used) {
+ if (uvr) {
uv[k] = uvr[j + k];
}
}
@@ -863,65 +853,63 @@ CSGBrush *CSGMesh::_build_brush() {
}
if (vertices.size() == 0)
- return NULL;
+ return nullptr;
return _create_brush_from_arrays(vertices, uvs, smooth, materials);
}
-void CSGMesh::_mesh_changed() {
+void CSGMesh3D::_mesh_changed() {
_make_dirty();
update_gizmo();
}
-void CSGMesh::set_material(const Ref<Material> &p_material) {
+void CSGMesh3D::set_material(const Ref<Material> &p_material) {
if (material == p_material)
return;
material = p_material;
_make_dirty();
}
-Ref<Material> CSGMesh::get_material() const {
+Ref<Material> CSGMesh3D::get_material() const {
return material;
}
-void CSGMesh::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &CSGMesh::set_mesh);
- ClassDB::bind_method(D_METHOD("get_mesh"), &CSGMesh::get_mesh);
+void CSGMesh3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_mesh_changed"), &CSGMesh::_mesh_changed);
+ ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &CSGMesh3D::set_mesh);
+ ClassDB::bind_method(D_METHOD("get_mesh"), &CSGMesh3D::get_mesh);
- ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGMesh::set_material);
- ClassDB::bind_method(D_METHOD("get_material"), &CSGMesh::get_material);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGMesh3D::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &CSGMesh3D::get_material);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
-void CSGMesh::set_mesh(const Ref<Mesh> &p_mesh) {
+void CSGMesh3D::set_mesh(const Ref<Mesh> &p_mesh) {
if (mesh == p_mesh)
return;
if (mesh.is_valid()) {
- mesh->disconnect("changed", this, "_mesh_changed");
+ mesh->disconnect("changed", callable_mp(this, &CSGMesh3D::_mesh_changed));
}
mesh = p_mesh;
if (mesh.is_valid()) {
- mesh->connect("changed", this, "_mesh_changed");
+ mesh->connect("changed", callable_mp(this, &CSGMesh3D::_mesh_changed));
}
_make_dirty();
}
-Ref<Mesh> CSGMesh::get_mesh() {
+Ref<Mesh> CSGMesh3D::get_mesh() {
return mesh;
}
////////////////////////////////
-CSGBrush *CSGSphere::_build_brush() {
+CSGBrush *CSGSphere3D::_build_brush() {
// set our bounding box
@@ -932,11 +920,11 @@ CSGBrush *CSGSphere::_build_brush() {
bool invert_val = is_inverting_faces();
Ref<Material> material = get_material();
- PoolVector<Vector3> faces;
- PoolVector<Vector2> uvs;
- PoolVector<bool> smooth;
- PoolVector<Ref<Material> > materials;
- PoolVector<bool> invert;
+ Vector<Vector3> faces;
+ Vector<Vector2> uvs;
+ Vector<bool> smooth;
+ Vector<Ref<Material>> materials;
+ Vector<bool> invert;
faces.resize(face_count * 3);
uvs.resize(face_count * 3);
@@ -947,11 +935,11 @@ CSGBrush *CSGSphere::_build_brush() {
{
- PoolVector<Vector3>::Write facesw = faces.write();
- PoolVector<Vector2>::Write uvsw = uvs.write();
- PoolVector<bool>::Write smoothw = smooth.write();
- PoolVector<Ref<Material> >::Write materialsw = materials.write();
- PoolVector<bool>::Write invertw = invert.write();
+ Vector3 *facesw = faces.ptrw();
+ Vector2 *uvsw = uvs.ptrw();
+ bool *smoothw = smooth.ptrw();
+ Ref<Material> *materialsw = materials.ptrw();
+ bool *invertw = invert.ptrw();
int face = 0;
@@ -1040,29 +1028,29 @@ CSGBrush *CSGSphere::_build_brush() {
return brush;
}
-void CSGSphere::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CSGSphere::set_radius);
- ClassDB::bind_method(D_METHOD("get_radius"), &CSGSphere::get_radius);
+void CSGSphere3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CSGSphere3D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &CSGSphere3D::get_radius);
- ClassDB::bind_method(D_METHOD("set_radial_segments", "radial_segments"), &CSGSphere::set_radial_segments);
- ClassDB::bind_method(D_METHOD("get_radial_segments"), &CSGSphere::get_radial_segments);
- ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CSGSphere::set_rings);
- ClassDB::bind_method(D_METHOD("get_rings"), &CSGSphere::get_rings);
+ ClassDB::bind_method(D_METHOD("set_radial_segments", "radial_segments"), &CSGSphere3D::set_radial_segments);
+ ClassDB::bind_method(D_METHOD("get_radial_segments"), &CSGSphere3D::get_radial_segments);
+ ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CSGSphere3D::set_rings);
+ ClassDB::bind_method(D_METHOD("get_rings"), &CSGSphere3D::get_rings);
- ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGSphere::set_smooth_faces);
- ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGSphere::get_smooth_faces);
+ ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGSphere3D::set_smooth_faces);
+ ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGSphere3D::get_smooth_faces);
- ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGSphere::set_material);
- ClassDB::bind_method(D_METHOD("get_material"), &CSGSphere::get_material);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGSphere3D::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &CSGSphere3D::get_material);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
-void CSGSphere::set_radius(const float p_radius) {
+void CSGSphere3D::set_radius(const float p_radius) {
ERR_FAIL_COND(p_radius <= 0);
radius = p_radius;
_make_dirty();
@@ -1070,51 +1058,51 @@ void CSGSphere::set_radius(const float p_radius) {
_change_notify("radius");
}
-float CSGSphere::get_radius() const {
+float CSGSphere3D::get_radius() const {
return radius;
}
-void CSGSphere::set_radial_segments(const int p_radial_segments) {
+void CSGSphere3D::set_radial_segments(const int p_radial_segments) {
radial_segments = p_radial_segments > 4 ? p_radial_segments : 4;
_make_dirty();
update_gizmo();
}
-int CSGSphere::get_radial_segments() const {
+int CSGSphere3D::get_radial_segments() const {
return radial_segments;
}
-void CSGSphere::set_rings(const int p_rings) {
+void CSGSphere3D::set_rings(const int p_rings) {
rings = p_rings > 1 ? p_rings : 1;
_make_dirty();
update_gizmo();
}
-int CSGSphere::get_rings() const {
+int CSGSphere3D::get_rings() const {
return rings;
}
-void CSGSphere::set_smooth_faces(const bool p_smooth_faces) {
+void CSGSphere3D::set_smooth_faces(const bool p_smooth_faces) {
smooth_faces = p_smooth_faces;
_make_dirty();
}
-bool CSGSphere::get_smooth_faces() const {
+bool CSGSphere3D::get_smooth_faces() const {
return smooth_faces;
}
-void CSGSphere::set_material(const Ref<Material> &p_material) {
+void CSGSphere3D::set_material(const Ref<Material> &p_material) {
material = p_material;
_make_dirty();
}
-Ref<Material> CSGSphere::get_material() const {
+Ref<Material> CSGSphere3D::get_material() const {
return material;
}
-CSGSphere::CSGSphere() {
+CSGSphere3D::CSGSphere3D() {
// defaults
radius = 1.0;
radial_segments = 12;
@@ -1124,7 +1112,7 @@ CSGSphere::CSGSphere() {
///////////////
-CSGBrush *CSGBox::_build_brush() {
+CSGBrush *CSGBox3D::_build_brush() {
// set our bounding box
@@ -1135,11 +1123,11 @@ CSGBrush *CSGBox::_build_brush() {
bool invert_val = is_inverting_faces();
Ref<Material> material = get_material();
- PoolVector<Vector3> faces;
- PoolVector<Vector2> uvs;
- PoolVector<bool> smooth;
- PoolVector<Ref<Material> > materials;
- PoolVector<bool> invert;
+ Vector<Vector3> faces;
+ Vector<Vector2> uvs;
+ Vector<bool> smooth;
+ Vector<Ref<Material>> materials;
+ Vector<bool> invert;
faces.resize(face_count * 3);
uvs.resize(face_count * 3);
@@ -1150,11 +1138,11 @@ CSGBrush *CSGBox::_build_brush() {
{
- PoolVector<Vector3>::Write facesw = faces.write();
- PoolVector<Vector2>::Write uvsw = uvs.write();
- PoolVector<bool>::Write smoothw = smooth.write();
- PoolVector<Ref<Material> >::Write materialsw = materials.write();
- PoolVector<bool>::Write invertw = invert.write();
+ Vector3 *facesw = faces.ptrw();
+ Vector2 *uvsw = uvs.ptrw();
+ bool *smoothw = smooth.ptrw();
+ Ref<Material> *materialsw = materials.ptrw();
+ bool *invertw = invert.ptrw();
int face = 0;
@@ -1229,71 +1217,71 @@ CSGBrush *CSGBox::_build_brush() {
return brush;
}
-void CSGBox::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_width", "width"), &CSGBox::set_width);
- ClassDB::bind_method(D_METHOD("get_width"), &CSGBox::get_width);
+void CSGBox3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_width", "width"), &CSGBox3D::set_width);
+ ClassDB::bind_method(D_METHOD("get_width"), &CSGBox3D::get_width);
- ClassDB::bind_method(D_METHOD("set_height", "height"), &CSGBox::set_height);
- ClassDB::bind_method(D_METHOD("get_height"), &CSGBox::get_height);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &CSGBox3D::set_height);
+ ClassDB::bind_method(D_METHOD("get_height"), &CSGBox3D::get_height);
- ClassDB::bind_method(D_METHOD("set_depth", "depth"), &CSGBox::set_depth);
- ClassDB::bind_method(D_METHOD("get_depth"), &CSGBox::get_depth);
+ ClassDB::bind_method(D_METHOD("set_depth", "depth"), &CSGBox3D::set_depth);
+ ClassDB::bind_method(D_METHOD("get_depth"), &CSGBox3D::get_depth);
- ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGBox::set_material);
- ClassDB::bind_method(D_METHOD("get_material"), &CSGBox::get_material);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGBox3D::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &CSGBox3D::get_material);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "width", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_width", "get_width");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_height", "get_height");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
-void CSGBox::set_width(const float p_width) {
+void CSGBox3D::set_width(const float p_width) {
width = p_width;
_make_dirty();
update_gizmo();
_change_notify("width");
}
-float CSGBox::get_width() const {
+float CSGBox3D::get_width() const {
return width;
}
-void CSGBox::set_height(const float p_height) {
+void CSGBox3D::set_height(const float p_height) {
height = p_height;
_make_dirty();
update_gizmo();
_change_notify("height");
}
-float CSGBox::get_height() const {
+float CSGBox3D::get_height() const {
return height;
}
-void CSGBox::set_depth(const float p_depth) {
+void CSGBox3D::set_depth(const float p_depth) {
depth = p_depth;
_make_dirty();
update_gizmo();
_change_notify("depth");
}
-float CSGBox::get_depth() const {
+float CSGBox3D::get_depth() const {
return depth;
}
-void CSGBox::set_material(const Ref<Material> &p_material) {
+void CSGBox3D::set_material(const Ref<Material> &p_material) {
material = p_material;
_make_dirty();
update_gizmo();
}
-Ref<Material> CSGBox::get_material() const {
+Ref<Material> CSGBox3D::get_material() const {
return material;
}
-CSGBox::CSGBox() {
+CSGBox3D::CSGBox3D() {
// defaults
width = 2.0;
height = 2.0;
@@ -1302,7 +1290,7 @@ CSGBox::CSGBox() {
///////////////
-CSGBrush *CSGCylinder::_build_brush() {
+CSGBrush *CSGCylinder3D::_build_brush() {
// set our bounding box
@@ -1313,11 +1301,11 @@ CSGBrush *CSGCylinder::_build_brush() {
bool invert_val = is_inverting_faces();
Ref<Material> material = get_material();
- PoolVector<Vector3> faces;
- PoolVector<Vector2> uvs;
- PoolVector<bool> smooth;
- PoolVector<Ref<Material> > materials;
- PoolVector<bool> invert;
+ Vector<Vector3> faces;
+ Vector<Vector2> uvs;
+ Vector<bool> smooth;
+ Vector<Ref<Material>> materials;
+ Vector<bool> invert;
faces.resize(face_count * 3);
uvs.resize(face_count * 3);
@@ -1328,11 +1316,11 @@ CSGBrush *CSGCylinder::_build_brush() {
{
- PoolVector<Vector3>::Write facesw = faces.write();
- PoolVector<Vector2>::Write uvsw = uvs.write();
- PoolVector<bool>::Write smoothw = smooth.write();
- PoolVector<Ref<Material> >::Write materialsw = materials.write();
- PoolVector<bool>::Write invertw = invert.write();
+ Vector3 *facesw = faces.ptrw();
+ Vector2 *uvsw = uvs.ptrw();
+ bool *smoothw = smooth.ptrw();
+ Ref<Material> *materialsw = materials.ptrw();
+ bool *invertw = invert.ptrw();
int face = 0;
@@ -1438,97 +1426,97 @@ CSGBrush *CSGCylinder::_build_brush() {
return brush;
}
-void CSGCylinder::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CSGCylinder::set_radius);
- ClassDB::bind_method(D_METHOD("get_radius"), &CSGCylinder::get_radius);
+void CSGCylinder3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CSGCylinder3D::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &CSGCylinder3D::get_radius);
- ClassDB::bind_method(D_METHOD("set_height", "height"), &CSGCylinder::set_height);
- ClassDB::bind_method(D_METHOD("get_height"), &CSGCylinder::get_height);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &CSGCylinder3D::set_height);
+ ClassDB::bind_method(D_METHOD("get_height"), &CSGCylinder3D::get_height);
- ClassDB::bind_method(D_METHOD("set_sides", "sides"), &CSGCylinder::set_sides);
- ClassDB::bind_method(D_METHOD("get_sides"), &CSGCylinder::get_sides);
+ ClassDB::bind_method(D_METHOD("set_sides", "sides"), &CSGCylinder3D::set_sides);
+ ClassDB::bind_method(D_METHOD("get_sides"), &CSGCylinder3D::get_sides);
- ClassDB::bind_method(D_METHOD("set_cone", "cone"), &CSGCylinder::set_cone);
- ClassDB::bind_method(D_METHOD("is_cone"), &CSGCylinder::is_cone);
+ ClassDB::bind_method(D_METHOD("set_cone", "cone"), &CSGCylinder3D::set_cone);
+ ClassDB::bind_method(D_METHOD("is_cone"), &CSGCylinder3D::is_cone);
- ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGCylinder::set_material);
- ClassDB::bind_method(D_METHOD("get_material"), &CSGCylinder::get_material);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGCylinder3D::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &CSGCylinder3D::get_material);
- ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGCylinder::set_smooth_faces);
- ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGCylinder::get_smooth_faces);
+ ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGCylinder3D::set_smooth_faces);
+ ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGCylinder3D::get_smooth_faces);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_radius", "get_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cone"), "set_cone", "is_cone");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
-void CSGCylinder::set_radius(const float p_radius) {
+void CSGCylinder3D::set_radius(const float p_radius) {
radius = p_radius;
_make_dirty();
update_gizmo();
_change_notify("radius");
}
-float CSGCylinder::get_radius() const {
+float CSGCylinder3D::get_radius() const {
return radius;
}
-void CSGCylinder::set_height(const float p_height) {
+void CSGCylinder3D::set_height(const float p_height) {
height = p_height;
_make_dirty();
update_gizmo();
_change_notify("height");
}
-float CSGCylinder::get_height() const {
+float CSGCylinder3D::get_height() const {
return height;
}
-void CSGCylinder::set_sides(const int p_sides) {
+void CSGCylinder3D::set_sides(const int p_sides) {
ERR_FAIL_COND(p_sides < 3);
sides = p_sides;
_make_dirty();
update_gizmo();
}
-int CSGCylinder::get_sides() const {
+int CSGCylinder3D::get_sides() const {
return sides;
}
-void CSGCylinder::set_cone(const bool p_cone) {
+void CSGCylinder3D::set_cone(const bool p_cone) {
cone = p_cone;
_make_dirty();
update_gizmo();
}
-bool CSGCylinder::is_cone() const {
+bool CSGCylinder3D::is_cone() const {
return cone;
}
-void CSGCylinder::set_smooth_faces(const bool p_smooth_faces) {
+void CSGCylinder3D::set_smooth_faces(const bool p_smooth_faces) {
smooth_faces = p_smooth_faces;
_make_dirty();
}
-bool CSGCylinder::get_smooth_faces() const {
+bool CSGCylinder3D::get_smooth_faces() const {
return smooth_faces;
}
-void CSGCylinder::set_material(const Ref<Material> &p_material) {
+void CSGCylinder3D::set_material(const Ref<Material> &p_material) {
material = p_material;
_make_dirty();
}
-Ref<Material> CSGCylinder::get_material() const {
+Ref<Material> CSGCylinder3D::get_material() const {
return material;
}
-CSGCylinder::CSGCylinder() {
+CSGCylinder3D::CSGCylinder3D() {
// defaults
radius = 1.0;
height = 1.0;
@@ -1539,7 +1527,7 @@ CSGCylinder::CSGCylinder() {
///////////////
-CSGBrush *CSGTorus::_build_brush() {
+CSGBrush *CSGTorus3D::_build_brush() {
// set our bounding box
@@ -1547,7 +1535,7 @@ CSGBrush *CSGTorus::_build_brush() {
float max_radius = outer_radius;
if (min_radius == max_radius)
- return NULL; //sorry, can't
+ return nullptr; //sorry, can't
if (min_radius > max_radius) {
SWAP(min_radius, max_radius);
@@ -1562,11 +1550,11 @@ CSGBrush *CSGTorus::_build_brush() {
bool invert_val = is_inverting_faces();
Ref<Material> material = get_material();
- PoolVector<Vector3> faces;
- PoolVector<Vector2> uvs;
- PoolVector<bool> smooth;
- PoolVector<Ref<Material> > materials;
- PoolVector<bool> invert;
+ Vector<Vector3> faces;
+ Vector<Vector2> uvs;
+ Vector<bool> smooth;
+ Vector<Ref<Material>> materials;
+ Vector<bool> invert;
faces.resize(face_count * 3);
uvs.resize(face_count * 3);
@@ -1577,11 +1565,11 @@ CSGBrush *CSGTorus::_build_brush() {
{
- PoolVector<Vector3>::Write facesw = faces.write();
- PoolVector<Vector2>::Write uvsw = uvs.write();
- PoolVector<bool>::Write smoothw = smooth.write();
- PoolVector<Ref<Material> >::Write materialsw = materials.write();
- PoolVector<bool>::Write invertw = invert.write();
+ Vector3 *facesw = faces.ptrw();
+ Vector2 *uvsw = uvs.ptrw();
+ bool *smoothw = smooth.ptrw();
+ Ref<Material> *materialsw = materials.ptrw();
+ bool *invertw = invert.ptrw();
int face = 0;
@@ -1665,98 +1653,98 @@ CSGBrush *CSGTorus::_build_brush() {
return brush;
}
-void CSGTorus::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_inner_radius", "radius"), &CSGTorus::set_inner_radius);
- ClassDB::bind_method(D_METHOD("get_inner_radius"), &CSGTorus::get_inner_radius);
+void CSGTorus3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_inner_radius", "radius"), &CSGTorus3D::set_inner_radius);
+ ClassDB::bind_method(D_METHOD("get_inner_radius"), &CSGTorus3D::get_inner_radius);
- ClassDB::bind_method(D_METHOD("set_outer_radius", "radius"), &CSGTorus::set_outer_radius);
- ClassDB::bind_method(D_METHOD("get_outer_radius"), &CSGTorus::get_outer_radius);
+ ClassDB::bind_method(D_METHOD("set_outer_radius", "radius"), &CSGTorus3D::set_outer_radius);
+ ClassDB::bind_method(D_METHOD("get_outer_radius"), &CSGTorus3D::get_outer_radius);
- ClassDB::bind_method(D_METHOD("set_sides", "sides"), &CSGTorus::set_sides);
- ClassDB::bind_method(D_METHOD("get_sides"), &CSGTorus::get_sides);
+ ClassDB::bind_method(D_METHOD("set_sides", "sides"), &CSGTorus3D::set_sides);
+ ClassDB::bind_method(D_METHOD("get_sides"), &CSGTorus3D::get_sides);
- ClassDB::bind_method(D_METHOD("set_ring_sides", "sides"), &CSGTorus::set_ring_sides);
- ClassDB::bind_method(D_METHOD("get_ring_sides"), &CSGTorus::get_ring_sides);
+ ClassDB::bind_method(D_METHOD("set_ring_sides", "sides"), &CSGTorus3D::set_ring_sides);
+ ClassDB::bind_method(D_METHOD("get_ring_sides"), &CSGTorus3D::get_ring_sides);
- ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGTorus::set_material);
- ClassDB::bind_method(D_METHOD("get_material"), &CSGTorus::get_material);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGTorus3D::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &CSGTorus3D::get_material);
- ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGTorus::set_smooth_faces);
- ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGTorus::get_smooth_faces);
+ ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGTorus3D::set_smooth_faces);
+ ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGTorus3D::get_smooth_faces);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "inner_radius", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_inner_radius", "get_inner_radius");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "outer_radius", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_outer_radius", "get_outer_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inner_radius", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_inner_radius", "get_inner_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "outer_radius", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_outer_radius", "get_outer_radius");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_ring_sides", "get_ring_sides");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
}
-void CSGTorus::set_inner_radius(const float p_inner_radius) {
+void CSGTorus3D::set_inner_radius(const float p_inner_radius) {
inner_radius = p_inner_radius;
_make_dirty();
update_gizmo();
_change_notify("inner_radius");
}
-float CSGTorus::get_inner_radius() const {
+float CSGTorus3D::get_inner_radius() const {
return inner_radius;
}
-void CSGTorus::set_outer_radius(const float p_outer_radius) {
+void CSGTorus3D::set_outer_radius(const float p_outer_radius) {
outer_radius = p_outer_radius;
_make_dirty();
update_gizmo();
_change_notify("outer_radius");
}
-float CSGTorus::get_outer_radius() const {
+float CSGTorus3D::get_outer_radius() const {
return outer_radius;
}
-void CSGTorus::set_sides(const int p_sides) {
+void CSGTorus3D::set_sides(const int p_sides) {
ERR_FAIL_COND(p_sides < 3);
sides = p_sides;
_make_dirty();
update_gizmo();
}
-int CSGTorus::get_sides() const {
+int CSGTorus3D::get_sides() const {
return sides;
}
-void CSGTorus::set_ring_sides(const int p_ring_sides) {
+void CSGTorus3D::set_ring_sides(const int p_ring_sides) {
ERR_FAIL_COND(p_ring_sides < 3);
ring_sides = p_ring_sides;
_make_dirty();
update_gizmo();
}
-int CSGTorus::get_ring_sides() const {
+int CSGTorus3D::get_ring_sides() const {
return ring_sides;
}
-void CSGTorus::set_smooth_faces(const bool p_smooth_faces) {
+void CSGTorus3D::set_smooth_faces(const bool p_smooth_faces) {
smooth_faces = p_smooth_faces;
_make_dirty();
}
-bool CSGTorus::get_smooth_faces() const {
+bool CSGTorus3D::get_smooth_faces() const {
return smooth_faces;
}
-void CSGTorus::set_material(const Ref<Material> &p_material) {
+void CSGTorus3D::set_material(const Ref<Material> &p_material) {
material = p_material;
_make_dirty();
}
-Ref<Material> CSGTorus::get_material() const {
+Ref<Material> CSGTorus3D::get_material() const {
return material;
}
-CSGTorus::CSGTorus() {
+CSGTorus3D::CSGTorus3D() {
// defaults
inner_radius = 2.0;
outer_radius = 3.0;
@@ -1767,12 +1755,12 @@ CSGTorus::CSGTorus() {
///////////////
-CSGBrush *CSGPolygon::_build_brush() {
+CSGBrush *CSGPolygon3D::_build_brush() {
// set our bounding box
if (polygon.size() < 3)
- return NULL;
+ return nullptr;
Vector<Point2> final_polygon = polygon;
@@ -1783,9 +1771,9 @@ CSGBrush *CSGPolygon::_build_brush() {
Vector<int> triangles = Geometry::triangulate_polygon(final_polygon);
if (triangles.size() < 3)
- return NULL;
+ return nullptr;
- Path *path = NULL;
+ Path3D *path = nullptr;
Ref<Curve3D> curve;
// get bounds for our polygon
@@ -1808,32 +1796,32 @@ CSGBrush *CSGPolygon::_build_brush() {
if (mode == MODE_PATH) {
if (!has_node(path_node))
- return NULL;
+ return nullptr;
Node *n = get_node(path_node);
if (!n)
- return NULL;
- path = Object::cast_to<Path>(n);
+ return nullptr;
+ path = Object::cast_to<Path3D>(n);
if (!path)
- return NULL;
+ return nullptr;
if (path != path_cache) {
if (path_cache) {
- path_cache->disconnect("tree_exited", this, "_path_exited");
- path_cache->disconnect("curve_changed", this, "_path_changed");
- path_cache = NULL;
+ path_cache->disconnect("tree_exited", callable_mp(this, &CSGPolygon3D::_path_exited));
+ path_cache->disconnect("curve_changed", callable_mp(this, &CSGPolygon3D::_path_changed));
+ path_cache = nullptr;
}
path_cache = path;
- path_cache->connect("tree_exited", this, "_path_exited");
- path_cache->connect("curve_changed", this, "_path_changed");
- path_cache = NULL;
+ path_cache->connect("tree_exited", callable_mp(this, &CSGPolygon3D::_path_exited));
+ path_cache->connect("curve_changed", callable_mp(this, &CSGPolygon3D::_path_changed));
+ path_cache = nullptr;
}
curve = path->get_curve();
if (curve.is_null())
- return NULL;
+ return nullptr;
if (curve->get_baked_length() <= 0)
- return NULL;
+ return nullptr;
}
CSGBrush *brush = memnew(CSGBrush);
@@ -1856,11 +1844,11 @@ CSGBrush *CSGPolygon::_build_brush() {
bool invert_val = is_inverting_faces();
Ref<Material> material = get_material();
- PoolVector<Vector3> faces;
- PoolVector<Vector2> uvs;
- PoolVector<bool> smooth;
- PoolVector<Ref<Material> > materials;
- PoolVector<bool> invert;
+ Vector<Vector3> faces;
+ Vector<Vector2> uvs;
+ Vector<bool> smooth;
+ Vector<Ref<Material>> materials;
+ Vector<bool> invert;
faces.resize(face_count * 3);
uvs.resize(face_count * 3);
@@ -1872,11 +1860,11 @@ CSGBrush *CSGPolygon::_build_brush() {
AABB aabb; //must be computed
{
- PoolVector<Vector3>::Write facesw = faces.write();
- PoolVector<Vector2>::Write uvsw = uvs.write();
- PoolVector<bool>::Write smoothw = smooth.write();
- PoolVector<Ref<Material> >::Write materialsw = materials.write();
- PoolVector<bool>::Write invertw = invert.write();
+ Vector3 *facesw = faces.ptrw();
+ Vector2 *uvsw = uvs.ptrw();
+ bool *smoothw = smooth.ptrw();
+ Ref<Material> *materialsw = materials.ptrw();
+ bool *invertw = invert.ptrw();
int face = 0;
@@ -2239,17 +2227,17 @@ CSGBrush *CSGPolygon::_build_brush() {
return brush;
}
-void CSGPolygon::_notification(int p_what) {
+void CSGPolygon3D::_notification(int p_what) {
if (p_what == NOTIFICATION_EXIT_TREE) {
if (path_cache) {
- path_cache->disconnect("tree_exited", this, "_path_exited");
- path_cache->disconnect("curve_changed", this, "_path_changed");
- path_cache = NULL;
+ path_cache->disconnect("tree_exited", callable_mp(this, &CSGPolygon3D::_path_exited));
+ path_cache->disconnect("curve_changed", callable_mp(this, &CSGPolygon3D::_path_changed));
+ path_cache = nullptr;
}
}
}
-void CSGPolygon::_validate_property(PropertyInfo &property) const {
+void CSGPolygon3D::_validate_property(PropertyInfo &property) const {
if (property.name.begins_with("spin") && mode != MODE_SPIN) {
property.usage = 0;
}
@@ -2260,77 +2248,74 @@ void CSGPolygon::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- CSGShape::_validate_property(property);
+ CSGShape3D::_validate_property(property);
}
-void CSGPolygon::_path_changed() {
+void CSGPolygon3D::_path_changed() {
_make_dirty();
update_gizmo();
}
-void CSGPolygon::_path_exited() {
- path_cache = NULL;
+void CSGPolygon3D::_path_exited() {
+ path_cache = nullptr;
}
-void CSGPolygon::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CSGPolygon::set_polygon);
- ClassDB::bind_method(D_METHOD("get_polygon"), &CSGPolygon::get_polygon);
-
- ClassDB::bind_method(D_METHOD("set_mode", "mode"), &CSGPolygon::set_mode);
- ClassDB::bind_method(D_METHOD("get_mode"), &CSGPolygon::get_mode);
+void CSGPolygon3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CSGPolygon3D::set_polygon);
+ ClassDB::bind_method(D_METHOD("get_polygon"), &CSGPolygon3D::get_polygon);
- ClassDB::bind_method(D_METHOD("set_depth", "depth"), &CSGPolygon::set_depth);
- ClassDB::bind_method(D_METHOD("get_depth"), &CSGPolygon::get_depth);
+ ClassDB::bind_method(D_METHOD("set_mode", "mode"), &CSGPolygon3D::set_mode);
+ ClassDB::bind_method(D_METHOD("get_mode"), &CSGPolygon3D::get_mode);
- ClassDB::bind_method(D_METHOD("set_spin_degrees", "degrees"), &CSGPolygon::set_spin_degrees);
- ClassDB::bind_method(D_METHOD("get_spin_degrees"), &CSGPolygon::get_spin_degrees);
+ ClassDB::bind_method(D_METHOD("set_depth", "depth"), &CSGPolygon3D::set_depth);
+ ClassDB::bind_method(D_METHOD("get_depth"), &CSGPolygon3D::get_depth);
- ClassDB::bind_method(D_METHOD("set_spin_sides", "spin_sides"), &CSGPolygon::set_spin_sides);
- ClassDB::bind_method(D_METHOD("get_spin_sides"), &CSGPolygon::get_spin_sides);
+ ClassDB::bind_method(D_METHOD("set_spin_degrees", "degrees"), &CSGPolygon3D::set_spin_degrees);
+ ClassDB::bind_method(D_METHOD("get_spin_degrees"), &CSGPolygon3D::get_spin_degrees);
- ClassDB::bind_method(D_METHOD("set_path_node", "path"), &CSGPolygon::set_path_node);
- ClassDB::bind_method(D_METHOD("get_path_node"), &CSGPolygon::get_path_node);
+ ClassDB::bind_method(D_METHOD("set_spin_sides", "spin_sides"), &CSGPolygon3D::set_spin_sides);
+ ClassDB::bind_method(D_METHOD("get_spin_sides"), &CSGPolygon3D::get_spin_sides);
- ClassDB::bind_method(D_METHOD("set_path_interval", "distance"), &CSGPolygon::set_path_interval);
- ClassDB::bind_method(D_METHOD("get_path_interval"), &CSGPolygon::get_path_interval);
+ ClassDB::bind_method(D_METHOD("set_path_node", "path"), &CSGPolygon3D::set_path_node);
+ ClassDB::bind_method(D_METHOD("get_path_node"), &CSGPolygon3D::get_path_node);
- ClassDB::bind_method(D_METHOD("set_path_rotation", "mode"), &CSGPolygon::set_path_rotation);
- ClassDB::bind_method(D_METHOD("get_path_rotation"), &CSGPolygon::get_path_rotation);
+ ClassDB::bind_method(D_METHOD("set_path_interval", "distance"), &CSGPolygon3D::set_path_interval);
+ ClassDB::bind_method(D_METHOD("get_path_interval"), &CSGPolygon3D::get_path_interval);
- ClassDB::bind_method(D_METHOD("set_path_local", "enable"), &CSGPolygon::set_path_local);
- ClassDB::bind_method(D_METHOD("is_path_local"), &CSGPolygon::is_path_local);
+ ClassDB::bind_method(D_METHOD("set_path_rotation", "mode"), &CSGPolygon3D::set_path_rotation);
+ ClassDB::bind_method(D_METHOD("get_path_rotation"), &CSGPolygon3D::get_path_rotation);
- ClassDB::bind_method(D_METHOD("set_path_continuous_u", "enable"), &CSGPolygon::set_path_continuous_u);
- ClassDB::bind_method(D_METHOD("is_path_continuous_u"), &CSGPolygon::is_path_continuous_u);
+ ClassDB::bind_method(D_METHOD("set_path_local", "enable"), &CSGPolygon3D::set_path_local);
+ ClassDB::bind_method(D_METHOD("is_path_local"), &CSGPolygon3D::is_path_local);
- ClassDB::bind_method(D_METHOD("set_path_joined", "enable"), &CSGPolygon::set_path_joined);
- ClassDB::bind_method(D_METHOD("is_path_joined"), &CSGPolygon::is_path_joined);
+ ClassDB::bind_method(D_METHOD("set_path_continuous_u", "enable"), &CSGPolygon3D::set_path_continuous_u);
+ ClassDB::bind_method(D_METHOD("is_path_continuous_u"), &CSGPolygon3D::is_path_continuous_u);
- ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGPolygon::set_material);
- ClassDB::bind_method(D_METHOD("get_material"), &CSGPolygon::get_material);
+ ClassDB::bind_method(D_METHOD("set_path_joined", "enable"), &CSGPolygon3D::set_path_joined);
+ ClassDB::bind_method(D_METHOD("is_path_joined"), &CSGPolygon3D::is_path_joined);
- ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGPolygon::set_smooth_faces);
- ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGPolygon::get_smooth_faces);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &CSGPolygon3D::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &CSGPolygon3D::get_material);
- ClassDB::bind_method(D_METHOD("_is_editable_3d_polygon"), &CSGPolygon::_is_editable_3d_polygon);
- ClassDB::bind_method(D_METHOD("_has_editable_3d_polygon_no_depth"), &CSGPolygon::_has_editable_3d_polygon_no_depth);
+ ClassDB::bind_method(D_METHOD("set_smooth_faces", "smooth_faces"), &CSGPolygon3D::set_smooth_faces);
+ ClassDB::bind_method(D_METHOD("get_smooth_faces"), &CSGPolygon3D::get_smooth_faces);
- ClassDB::bind_method(D_METHOD("_path_exited"), &CSGPolygon::_path_exited);
- ClassDB::bind_method(D_METHOD("_path_changed"), &CSGPolygon::_path_changed);
+ ClassDB::bind_method(D_METHOD("_is_editable_3d_polygon"), &CSGPolygon3D::_is_editable_3d_polygon);
+ ClassDB::bind_method(D_METHOD("_has_editable_3d_polygon_no_depth"), &CSGPolygon3D::_has_editable_3d_polygon_no_depth);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Depth,Spin,Path"), "set_mode", "get_mode");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees");
ADD_PROPERTY(PropertyInfo(Variant::INT, "spin_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_spin_sides", "get_spin_sides");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path"), "set_path_node", "get_path_node");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_interval", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_path_interval", "get_path_interval");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_interval", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_path_interval", "get_path_interval");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_rotation", PROPERTY_HINT_ENUM, "Polygon,Path,PathFollow"), "set_path_rotation", "get_path_rotation");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_local"), "set_path_local", "is_path_local");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_continuous_u"), "set_path_continuous_u", "is_path_continuous_u");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_joined"), "set_path_joined", "is_path_joined");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
BIND_ENUM_CONSTANT(MODE_DEPTH);
BIND_ENUM_CONSTANT(MODE_SPIN);
@@ -2341,148 +2326,148 @@ void CSGPolygon::_bind_methods() {
BIND_ENUM_CONSTANT(PATH_ROTATION_PATH_FOLLOW);
}
-void CSGPolygon::set_polygon(const Vector<Vector2> &p_polygon) {
+void CSGPolygon3D::set_polygon(const Vector<Vector2> &p_polygon) {
polygon = p_polygon;
_make_dirty();
update_gizmo();
}
-Vector<Vector2> CSGPolygon::get_polygon() const {
+Vector<Vector2> CSGPolygon3D::get_polygon() const {
return polygon;
}
-void CSGPolygon::set_mode(Mode p_mode) {
+void CSGPolygon3D::set_mode(Mode p_mode) {
mode = p_mode;
_make_dirty();
update_gizmo();
_change_notify();
}
-CSGPolygon::Mode CSGPolygon::get_mode() const {
+CSGPolygon3D::Mode CSGPolygon3D::get_mode() const {
return mode;
}
-void CSGPolygon::set_depth(const float p_depth) {
+void CSGPolygon3D::set_depth(const float p_depth) {
ERR_FAIL_COND(p_depth < 0.001);
depth = p_depth;
_make_dirty();
update_gizmo();
}
-float CSGPolygon::get_depth() const {
+float CSGPolygon3D::get_depth() const {
return depth;
}
-void CSGPolygon::set_path_continuous_u(bool p_enable) {
+void CSGPolygon3D::set_path_continuous_u(bool p_enable) {
path_continuous_u = p_enable;
_make_dirty();
}
-bool CSGPolygon::is_path_continuous_u() const {
+bool CSGPolygon3D::is_path_continuous_u() const {
return path_continuous_u;
}
-void CSGPolygon::set_spin_degrees(const float p_spin_degrees) {
+void CSGPolygon3D::set_spin_degrees(const float p_spin_degrees) {
ERR_FAIL_COND(p_spin_degrees < 0.01 || p_spin_degrees > 360);
spin_degrees = p_spin_degrees;
_make_dirty();
update_gizmo();
}
-float CSGPolygon::get_spin_degrees() const {
+float CSGPolygon3D::get_spin_degrees() const {
return spin_degrees;
}
-void CSGPolygon::set_spin_sides(const int p_spin_sides) {
+void CSGPolygon3D::set_spin_sides(const int p_spin_sides) {
ERR_FAIL_COND(p_spin_sides < 3);
spin_sides = p_spin_sides;
_make_dirty();
update_gizmo();
}
-int CSGPolygon::get_spin_sides() const {
+int CSGPolygon3D::get_spin_sides() const {
return spin_sides;
}
-void CSGPolygon::set_path_node(const NodePath &p_path) {
+void CSGPolygon3D::set_path_node(const NodePath &p_path) {
path_node = p_path;
_make_dirty();
update_gizmo();
}
-NodePath CSGPolygon::get_path_node() const {
+NodePath CSGPolygon3D::get_path_node() const {
return path_node;
}
-void CSGPolygon::set_path_interval(float p_interval) {
+void CSGPolygon3D::set_path_interval(float p_interval) {
ERR_FAIL_COND_MSG(p_interval < 0.001, "Path interval cannot be smaller than 0.001.");
path_interval = p_interval;
_make_dirty();
update_gizmo();
}
-float CSGPolygon::get_path_interval() const {
+float CSGPolygon3D::get_path_interval() const {
return path_interval;
}
-void CSGPolygon::set_path_rotation(PathRotation p_rotation) {
+void CSGPolygon3D::set_path_rotation(PathRotation p_rotation) {
path_rotation = p_rotation;
_make_dirty();
update_gizmo();
}
-CSGPolygon::PathRotation CSGPolygon::get_path_rotation() const {
+CSGPolygon3D::PathRotation CSGPolygon3D::get_path_rotation() const {
return path_rotation;
}
-void CSGPolygon::set_path_local(bool p_enable) {
+void CSGPolygon3D::set_path_local(bool p_enable) {
path_local = p_enable;
_make_dirty();
update_gizmo();
}
-bool CSGPolygon::is_path_local() const {
+bool CSGPolygon3D::is_path_local() const {
return path_local;
}
-void CSGPolygon::set_path_joined(bool p_enable) {
+void CSGPolygon3D::set_path_joined(bool p_enable) {
path_joined = p_enable;
_make_dirty();
update_gizmo();
}
-bool CSGPolygon::is_path_joined() const {
+bool CSGPolygon3D::is_path_joined() const {
return path_joined;
}
-void CSGPolygon::set_smooth_faces(const bool p_smooth_faces) {
+void CSGPolygon3D::set_smooth_faces(const bool p_smooth_faces) {
smooth_faces = p_smooth_faces;
_make_dirty();
}
-bool CSGPolygon::get_smooth_faces() const {
+bool CSGPolygon3D::get_smooth_faces() const {
return smooth_faces;
}
-void CSGPolygon::set_material(const Ref<Material> &p_material) {
+void CSGPolygon3D::set_material(const Ref<Material> &p_material) {
material = p_material;
_make_dirty();
}
-Ref<Material> CSGPolygon::get_material() const {
+Ref<Material> CSGPolygon3D::get_material() const {
return material;
}
-bool CSGPolygon::_is_editable_3d_polygon() const {
+bool CSGPolygon3D::_is_editable_3d_polygon() const {
return true;
}
-bool CSGPolygon::_has_editable_3d_polygon_no_depth() const {
+bool CSGPolygon3D::_has_editable_3d_polygon_no_depth() const {
return true;
}
-CSGPolygon::CSGPolygon() {
+CSGPolygon3D::CSGPolygon3D() {
// defaults
mode = MODE_DEPTH;
polygon.push_back(Vector2(0, 0));
@@ -2498,5 +2483,5 @@ CSGPolygon::CSGPolygon() {
path_local = false;
path_continuous_u = false;
path_joined = false;
- path_cache = NULL;
+ path_cache = nullptr;
}
diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h
index 1098feea51..abab1ded20 100644
--- a/modules/csg/csg_shape.h
+++ b/modules/csg/csg_shape.h
@@ -34,12 +34,12 @@
#define CSGJS_HEADER_ONLY
#include "csg.h"
-#include "scene/3d/visual_instance.h"
-#include "scene/resources/concave_polygon_shape.h"
+#include "scene/3d/visual_instance_3d.h"
+#include "scene/resources/concave_polygon_shape_3d.h"
#include "thirdparty/misc/mikktspace.h"
-class CSGShape : public GeometryInstance {
- GDCLASS(CSGShape, GeometryInstance);
+class CSGShape3D : public GeometryInstance3D {
+ GDCLASS(CSGShape3D, GeometryInstance3D);
public:
enum Operation {
@@ -51,7 +51,7 @@ public:
private:
Operation operation;
- CSGShape *parent;
+ CSGShape3D *parent;
CSGBrush *brush;
@@ -63,7 +63,7 @@ private:
bool use_collision;
uint32_t collision_layer;
uint32_t collision_mask;
- Ref<ConcavePolygonShape> root_collision_shape;
+ Ref<ConcavePolygonShape3D> root_collision_shape;
RID root_collision_instance;
bool calculate_tangents;
@@ -80,17 +80,17 @@ private:
};
struct ShapeUpdateSurface {
- PoolVector<Vector3> vertices;
- PoolVector<Vector3> normals;
- PoolVector<Vector2> uvs;
- PoolVector<float> tans;
+ Vector<Vector3> vertices;
+ Vector<Vector3> normals;
+ Vector<Vector2> uvs;
+ Vector<float> tans;
Ref<Material> material;
int last_added;
- PoolVector<Vector3>::Write verticesw;
- PoolVector<Vector3>::Write normalsw;
- PoolVector<Vector2>::Write uvsw;
- PoolVector<float>::Write tansw;
+ Vector3 *verticesw;
+ Vector3 *normalsw;
+ Vector2 *uvsw;
+ float *tansw;
};
//mikktspace callbacks
@@ -111,7 +111,7 @@ protected:
static void _bind_methods();
- friend class CSGCombiner;
+ friend class CSGCombiner3D;
CSGBrush *_get_brush();
virtual void _validate_property(PropertyInfo &property) const;
@@ -122,10 +122,10 @@ public:
void set_operation(Operation p_operation);
Operation get_operation() const;
- virtual PoolVector<Vector3> get_brush_faces();
+ virtual Vector<Vector3> get_brush_faces();
virtual AABB get_aabb() const;
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const;
void set_use_collision(bool p_enable);
bool is_using_collision() const;
@@ -149,41 +149,41 @@ public:
bool is_calculating_tangents() const;
bool is_root_shape() const;
- CSGShape();
- ~CSGShape();
+ CSGShape3D();
+ ~CSGShape3D();
};
-VARIANT_ENUM_CAST(CSGShape::Operation)
+VARIANT_ENUM_CAST(CSGShape3D::Operation)
-class CSGCombiner : public CSGShape {
- GDCLASS(CSGCombiner, CSGShape);
+class CSGCombiner3D : public CSGShape3D {
+ GDCLASS(CSGCombiner3D, CSGShape3D);
private:
virtual CSGBrush *_build_brush();
public:
- CSGCombiner();
+ CSGCombiner3D();
};
-class CSGPrimitive : public CSGShape {
- GDCLASS(CSGPrimitive, CSGShape);
+class CSGPrimitive3D : public CSGShape3D {
+ GDCLASS(CSGPrimitive3D, CSGShape3D);
private:
bool invert_faces;
protected:
- CSGBrush *_create_brush_from_arrays(const PoolVector<Vector3> &p_vertices, const PoolVector<Vector2> &p_uv, const PoolVector<bool> &p_smooth, const PoolVector<Ref<Material> > &p_materials);
+ CSGBrush *_create_brush_from_arrays(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uv, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials);
static void _bind_methods();
public:
void set_invert_faces(bool p_invert);
bool is_inverting_faces();
- CSGPrimitive();
+ CSGPrimitive3D();
};
-class CSGMesh : public CSGPrimitive {
- GDCLASS(CSGMesh, CSGPrimitive);
+class CSGMesh3D : public CSGPrimitive3D {
+ GDCLASS(CSGMesh3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
@@ -203,9 +203,9 @@ public:
Ref<Material> get_material() const;
};
-class CSGSphere : public CSGPrimitive {
+class CSGSphere3D : public CSGPrimitive3D {
- GDCLASS(CSGSphere, CSGPrimitive);
+ GDCLASS(CSGSphere3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -233,12 +233,12 @@ public:
void set_smooth_faces(bool p_smooth_faces);
bool get_smooth_faces() const;
- CSGSphere();
+ CSGSphere3D();
};
-class CSGBox : public CSGPrimitive {
+class CSGBox3D : public CSGPrimitive3D {
- GDCLASS(CSGBox, CSGPrimitive);
+ GDCLASS(CSGBox3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -262,12 +262,12 @@ public:
void set_material(const Ref<Material> &p_material);
Ref<Material> get_material() const;
- CSGBox();
+ CSGBox3D();
};
-class CSGCylinder : public CSGPrimitive {
+class CSGCylinder3D : public CSGPrimitive3D {
- GDCLASS(CSGCylinder, CSGPrimitive);
+ GDCLASS(CSGCylinder3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -299,12 +299,12 @@ public:
void set_material(const Ref<Material> &p_material);
Ref<Material> get_material() const;
- CSGCylinder();
+ CSGCylinder3D();
};
-class CSGTorus : public CSGPrimitive {
+class CSGTorus3D : public CSGPrimitive3D {
- GDCLASS(CSGTorus, CSGPrimitive);
+ GDCLASS(CSGTorus3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
Ref<Material> material;
@@ -336,12 +336,12 @@ public:
void set_material(const Ref<Material> &p_material);
Ref<Material> get_material() const;
- CSGTorus();
+ CSGTorus3D();
};
-class CSGPolygon : public CSGPrimitive {
+class CSGPolygon3D : public CSGPrimitive3D {
- GDCLASS(CSGPolygon, CSGPrimitive);
+ GDCLASS(CSGPolygon3D, CSGPrimitive3D);
public:
enum Mode {
@@ -431,10 +431,10 @@ public:
void set_material(const Ref<Material> &p_material);
Ref<Material> get_material() const;
- CSGPolygon();
+ CSGPolygon3D();
};
-VARIANT_ENUM_CAST(CSGPolygon::Mode)
-VARIANT_ENUM_CAST(CSGPolygon::PathRotation)
+VARIANT_ENUM_CAST(CSGPolygon3D::Mode)
+VARIANT_ENUM_CAST(CSGPolygon3D::PathRotation)
#endif // CSG_SHAPE_H
diff --git a/modules/csg/doc_classes/CSGBox.xml b/modules/csg/doc_classes/CSGBox3D.xml
index e2f0f8488a..492bf68c44 100644
--- a/modules/csg/doc_classes/CSGBox.xml
+++ b/modules/csg/doc_classes/CSGBox3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGBox" inherits="CSGPrimitive" version="4.0">
+<class name="CSGBox3D" inherits="CSGPrimitive3D" version="4.0">
<brief_description>
A CSG Box shape.
</brief_description>
diff --git a/modules/csg/doc_classes/CSGCombiner.xml b/modules/csg/doc_classes/CSGCombiner.xml
deleted file mode 100644
index ab95d3c3ee..0000000000
--- a/modules/csg/doc_classes/CSGCombiner.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGCombiner" inherits="CSGShape" version="4.0">
- <brief_description>
- A CSG node that allows you to combine other CSG modifiers.
- </brief_description>
- <description>
- For complex arrangements of shapes, it is sometimes needed to add structure to your CSG nodes. The CSGCombiner node allows you to create this structure. The node encapsulates the result of the CSG operations of its children. In this way, it is possible to do operations on one set of shapes that are children of one CSGCombiner node, and a set of separate operations on a second set of shapes that are children of a second CSGCombiner node, and then do an operation that takes the two end results as its input to create the final shape.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/csg/doc_classes/CSGCombiner3D.xml b/modules/csg/doc_classes/CSGCombiner3D.xml
new file mode 100644
index 0000000000..b55111eee4
--- /dev/null
+++ b/modules/csg/doc_classes/CSGCombiner3D.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="CSGCombiner3D" inherits="CSGShape3D" version="4.0">
+ <brief_description>
+ A CSG node that allows you to combine other CSG modifiers.
+ </brief_description>
+ <description>
+ For complex arrangements of shapes, it is sometimes needed to add structure to your CSG nodes. The CSGCombiner3D node allows you to create this structure. The node encapsulates the result of the CSG operations of its children. In this way, it is possible to do operations on one set of shapes that are children of one CSGCombiner3D node, and a set of separate operations on a second set of shapes that are children of a second CSGCombiner3D node, and then do an operation that takes the two end results as its input to create the final shape.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/modules/csg/doc_classes/CSGCylinder.xml b/modules/csg/doc_classes/CSGCylinder3D.xml
index 2dd8c6a8d0..bfd2a5d5f2 100644
--- a/modules/csg/doc_classes/CSGCylinder.xml
+++ b/modules/csg/doc_classes/CSGCylinder3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGCylinder" inherits="CSGPrimitive" version="4.0">
+<class name="CSGCylinder3D" inherits="CSGPrimitive3D" version="4.0">
<brief_description>
A CSG Cylinder shape.
</brief_description>
diff --git a/modules/csg/doc_classes/CSGMesh.xml b/modules/csg/doc_classes/CSGMesh3D.xml
index f1fe2c286b..1bab8f4ee9 100644
--- a/modules/csg/doc_classes/CSGMesh.xml
+++ b/modules/csg/doc_classes/CSGMesh3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGMesh" inherits="CSGPrimitive" version="4.0">
+<class name="CSGMesh3D" inherits="CSGPrimitive3D" version="4.0">
<brief_description>
A CSG Mesh shape that uses a mesh resource.
</brief_description>
diff --git a/modules/csg/doc_classes/CSGPolygon.xml b/modules/csg/doc_classes/CSGPolygon3D.xml
index 64ae46c69a..c55fa0983e 100644
--- a/modules/csg/doc_classes/CSGPolygon.xml
+++ b/modules/csg/doc_classes/CSGPolygon3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGPolygon" inherits="CSGPrimitive" version="4.0">
+<class name="CSGPolygon3D" inherits="CSGPrimitive3D" version="4.0">
<brief_description>
Extrudes a 2D polygon shape to create a 3D mesh.
</brief_description>
@@ -17,7 +17,7 @@
<member name="material" type="Material" setter="set_material" getter="get_material">
Material to use for the resulting mesh.
</member>
- <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="CSGPolygon.Mode" default="0">
+ <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="CSGPolygon3D.Mode" default="0">
Extrusion mode.
</member>
<member name="path_continuous_u" type="bool" setter="set_path_continuous_u" getter="is_path_continuous_u">
@@ -30,15 +30,15 @@
If [code]true[/code] the start and end of our path are joined together ensuring there is no seam when [member mode] is [constant MODE_PATH].
</member>
<member name="path_local" type="bool" setter="set_path_local" getter="is_path_local">
- If [code]false[/code] we extrude centered on our path, if [code]true[/code] we extrude in relation to the position of our CSGPolygon when [member mode] is [constant MODE_PATH].
+ If [code]false[/code] we extrude centered on our path, if [code]true[/code] we extrude in relation to the position of our CSGPolygon3D when [member mode] is [constant MODE_PATH].
</member>
<member name="path_node" type="NodePath" setter="set_path_node" getter="get_path_node">
- The [Shape] object containing the path along which we extrude when [member mode] is [constant MODE_PATH].
+ The [Shape3D] object containing the path along which we extrude when [member mode] is [constant MODE_PATH].
</member>
- <member name="path_rotation" type="int" setter="set_path_rotation" getter="get_path_rotation" enum="CSGPolygon.PathRotation">
+ <member name="path_rotation" type="int" setter="set_path_rotation" getter="get_path_rotation" enum="CSGPolygon3D.PathRotation">
The method by which each slice is rotated along the path when [member mode] is [constant MODE_PATH].
</member>
- <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon" default="PoolVector2Array( 0, 0, 0, 1, 1, 1, 1, 0 )">
+ <member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array( 0, 0, 0, 1, 1, 1, 1, 0 )">
Point array that defines the shape that we'll extrude.
</member>
<member name="smooth_faces" type="bool" setter="set_smooth_faces" getter="get_smooth_faces" default="false">
@@ -53,13 +53,13 @@
</members>
<constants>
<constant name="MODE_DEPTH" value="0" enum="Mode">
- Shape is extruded to [member depth].
+ Shape3D is extruded to [member depth].
</constant>
<constant name="MODE_SPIN" value="1" enum="Mode">
- Shape is extruded by rotating it around an axis.
+ Shape3D is extruded by rotating it around an axis.
</constant>
<constant name="MODE_PATH" value="2" enum="Mode">
- Shape is extruded along a path set by a [Shape] set in [member path_node].
+ Shape3D is extruded along a path set by a [Shape3D] set in [member path_node].
</constant>
<constant name="PATH_ROTATION_POLYGON" value="0" enum="PathRotation">
Slice is not rotated.
diff --git a/modules/csg/doc_classes/CSGPrimitive.xml b/modules/csg/doc_classes/CSGPrimitive3D.xml
index ba395b7edd..31b7360fac 100644
--- a/modules/csg/doc_classes/CSGPrimitive.xml
+++ b/modules/csg/doc_classes/CSGPrimitive3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGPrimitive" inherits="CSGShape" version="4.0">
+<class name="CSGPrimitive3D" inherits="CSGShape3D" version="4.0">
<brief_description>
Base class for CSG primitives.
</brief_description>
diff --git a/modules/csg/doc_classes/CSGShape.xml b/modules/csg/doc_classes/CSGShape3D.xml
index 64a2fb1840..43ce988c30 100644
--- a/modules/csg/doc_classes/CSGShape.xml
+++ b/modules/csg/doc_classes/CSGShape3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGShape" inherits="GeometryInstance" version="4.0">
+<class name="CSGShape3D" inherits="GeometryInstance3D" version="4.0">
<brief_description>
The CSG base class.
</brief_description>
@@ -76,7 +76,7 @@
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
The physics layers this CSG shape scans for collisions.
</member>
- <member name="operation" type="int" setter="set_operation" getter="get_operation" enum="CSGShape.Operation" default="0">
+ <member name="operation" type="int" setter="set_operation" getter="get_operation" enum="CSGShape3D.Operation" default="0">
The operation that is performed on this shape. This is ignored for the first CSG child node as the operation is between this node and the previous child of this nodes parent.
</member>
<member name="snap" type="float" setter="set_snap" getter="get_snap" default="0.001">
diff --git a/modules/csg/doc_classes/CSGSphere.xml b/modules/csg/doc_classes/CSGSphere3D.xml
index 847cc63586..4d5b3be099 100644
--- a/modules/csg/doc_classes/CSGSphere.xml
+++ b/modules/csg/doc_classes/CSGSphere3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGSphere" inherits="CSGPrimitive" version="4.0">
+<class name="CSGSphere3D" inherits="CSGPrimitive3D" version="4.0">
<brief_description>
A CSG Sphere shape.
</brief_description>
diff --git a/modules/csg/doc_classes/CSGTorus.xml b/modules/csg/doc_classes/CSGTorus3D.xml
index 84a08edaf5..abe3eab913 100644
--- a/modules/csg/doc_classes/CSGTorus.xml
+++ b/modules/csg/doc_classes/CSGTorus3D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSGTorus" inherits="CSGPrimitive" version="4.0">
+<class name="CSGTorus3D" inherits="CSGPrimitive3D" version="4.0">
<brief_description>
A CSG Torus shape.
</brief_description>
diff --git a/modules/csg/icons/icon_c_s_g_box.svg b/modules/csg/icons/CSGBox3D.svg
index 67e34df444..67e34df444 100644
--- a/modules/csg/icons/icon_c_s_g_box.svg
+++ b/modules/csg/icons/CSGBox3D.svg
diff --git a/modules/csg/icons/icon_c_s_g_capsule.svg b/modules/csg/icons/CSGCapsule3D.svg
index 92a7b5a870..92a7b5a870 100644
--- a/modules/csg/icons/icon_c_s_g_capsule.svg
+++ b/modules/csg/icons/CSGCapsule3D.svg
diff --git a/modules/csg/icons/icon_c_s_g_combiner.svg b/modules/csg/icons/CSGCombiner3D.svg
index cce2902e24..cce2902e24 100644
--- a/modules/csg/icons/icon_c_s_g_combiner.svg
+++ b/modules/csg/icons/CSGCombiner3D.svg
diff --git a/modules/csg/icons/icon_c_s_g_cylinder.svg b/modules/csg/icons/CSGCylinder3D.svg
index 645a74c79b..645a74c79b 100644
--- a/modules/csg/icons/icon_c_s_g_cylinder.svg
+++ b/modules/csg/icons/CSGCylinder3D.svg
diff --git a/modules/csg/icons/icon_c_s_g_mesh.svg b/modules/csg/icons/CSGMesh3D.svg
index 6e940a4aa5..6e940a4aa5 100644
--- a/modules/csg/icons/icon_c_s_g_mesh.svg
+++ b/modules/csg/icons/CSGMesh3D.svg
diff --git a/modules/csg/icons/icon_c_s_g_polygon.svg b/modules/csg/icons/CSGPolygon3D.svg
index 71b03cb8e6..71b03cb8e6 100644
--- a/modules/csg/icons/icon_c_s_g_polygon.svg
+++ b/modules/csg/icons/CSGPolygon3D.svg
diff --git a/modules/csg/icons/icon_c_s_g_sphere.svg b/modules/csg/icons/CSGSphere3D.svg
index f81b566993..f81b566993 100644
--- a/modules/csg/icons/icon_c_s_g_sphere.svg
+++ b/modules/csg/icons/CSGSphere3D.svg
diff --git a/modules/csg/icons/icon_c_s_g_torus.svg b/modules/csg/icons/CSGTorus3D.svg
index 3d30aa47b2..3d30aa47b2 100644
--- a/modules/csg/icons/icon_c_s_g_torus.svg
+++ b/modules/csg/icons/CSGTorus3D.svg
diff --git a/modules/csg/register_types.cpp b/modules/csg/register_types.cpp
index 677a20df38..40eef84b1b 100644
--- a/modules/csg/register_types.cpp
+++ b/modules/csg/register_types.cpp
@@ -37,15 +37,15 @@ void register_csg_types() {
#ifndef _3D_DISABLED
- ClassDB::register_virtual_class<CSGShape>();
- ClassDB::register_virtual_class<CSGPrimitive>();
- ClassDB::register_class<CSGMesh>();
- ClassDB::register_class<CSGSphere>();
- ClassDB::register_class<CSGBox>();
- ClassDB::register_class<CSGCylinder>();
- ClassDB::register_class<CSGTorus>();
- ClassDB::register_class<CSGPolygon>();
- ClassDB::register_class<CSGCombiner>();
+ ClassDB::register_virtual_class<CSGShape3D>();
+ ClassDB::register_virtual_class<CSGPrimitive3D>();
+ ClassDB::register_class<CSGMesh3D>();
+ ClassDB::register_class<CSGSphere3D>();
+ ClassDB::register_class<CSGBox3D>();
+ ClassDB::register_class<CSGCylinder3D>();
+ ClassDB::register_class<CSGTorus3D>();
+ ClassDB::register_class<CSGPolygon3D>();
+ ClassDB::register_class<CSGCombiner3D>();
#ifdef TOOLS_ENABLED
EditorPlugins::add_by_type<EditorPluginCSG>();
diff --git a/modules/csg/register_types.h b/modules/csg/register_types.h
index 4eadeea254..926e598561 100644
--- a/modules/csg/register_types.h
+++ b/modules/csg/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef CSG_REGISTER_TYPES_H
+#define CSG_REGISTER_TYPES_H
+
void register_csg_types();
void unregister_csg_types();
+
+#endif // CSG_REGISTER_TYPES_H
diff --git a/modules/cvtt/SCsub b/modules/cvtt/SCsub
index 746b23ca28..5438f7ebac 100644
--- a/modules/cvtt/SCsub
+++ b/modules/cvtt/SCsub
@@ -1,14 +1,14 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_cvtt = env_modules.Clone()
# Thirdparty source files
thirdparty_dir = "#thirdparty/cvtt/"
thirdparty_sources = [
- "ConvectionKernels.cpp"
+ "ConvectionKernels.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
diff --git a/modules/cvtt/config.py b/modules/cvtt/config.py
index 098f1eafa9..53b8f2f2e3 100644
--- a/modules/cvtt/config.py
+++ b/modules/cvtt/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return env['tools']
+ return env["tools"]
+
def configure(env):
pass
diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp
index c261350e89..9dbaa88202 100644
--- a/modules/cvtt/image_compress_cvtt.cpp
+++ b/modules/cvtt/image_compress_cvtt.cpp
@@ -136,7 +136,7 @@ static void _digest_job_queue(void *p_job_queue) {
}
}
-void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressSource p_source) {
+void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels) {
if (p_image->get_format() >= Image::FORMAT_BPTC_RGBA)
return; //do not compress, already compressed
@@ -167,7 +167,7 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS
flags |= cvtt::Flags::BC7_RespectPunchThrough;
- if (p_source == Image::COMPRESS_SOURCE_NORMAL) {
+ if (p_channels == Image::USED_CHANNELS_RG) { //guessing this is a normalmap
flags |= cvtt::Flags::Uniform;
}
@@ -179,7 +179,7 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS
p_image->convert(Image::FORMAT_RGBH);
}
- PoolVector<uint8_t>::Read rb = p_image->get_data().read();
+ const uint8_t *rb = p_image->get_data().ptr();
const uint16_t *source_data = reinterpret_cast<const uint16_t *>(&rb[0]);
int pixel_element_count = w * h * 3;
@@ -195,15 +195,15 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS
p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
}
- PoolVector<uint8_t>::Read rb = p_image->get_data().read();
+ const uint8_t *rb = p_image->get_data().ptr();
- PoolVector<uint8_t> data;
+ 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->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0;
data.resize(target_size);
int shift = Image::get_format_pixel_rshift(target_format);
- PoolVector<uint8_t>::Write wb = data.write();
+ uint8_t *wb = data.ptrw();
int dst_ofs = 0;
@@ -219,7 +219,7 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS
int num_job_threads = OS::get_singleton()->can_use_threads() ? (OS::get_singleton()->get_processor_count() - 1) : 0;
#endif
- PoolVector<CVTTCompressionRowTask> tasks;
+ Vector<CVTTCompressionRowTask> tasks;
for (int i = 0; i <= mm_count; i++) {
@@ -254,12 +254,12 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS
}
if (num_job_threads > 0) {
- PoolVector<Thread *> threads;
+ Vector<Thread *> threads;
threads.resize(num_job_threads);
- PoolVector<Thread *>::Write threads_wb = threads.write();
+ Thread **threads_wb = threads.ptrw();
- PoolVector<CVTTCompressionRowTask>::Read tasks_rb = tasks.read();
+ const CVTTCompressionRowTask *tasks_rb = tasks.ptr();
job_queue.job_tasks = &tasks_rb[0];
job_queue.current_task = 0;
@@ -304,14 +304,14 @@ void image_decompress_cvtt(Image *p_image) {
int w = p_image->get_width();
int h = p_image->get_height();
- PoolVector<uint8_t>::Read rb = p_image->get_data().read();
+ const uint8_t *rb = p_image->get_data().ptr();
- PoolVector<uint8_t> data;
+ 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();
data.resize(target_size);
- PoolVector<uint8_t>::Write wb = data.write();
+ uint8_t *wb = data.ptrw();
int bytes_per_pixel = is_hdr ? 6 : 4;
@@ -388,8 +388,5 @@ void image_decompress_cvtt(Image *p_image) {
h >>= 1;
}
- rb.release();
- wb.release();
-
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
}
diff --git a/modules/cvtt/image_compress_cvtt.h b/modules/cvtt/image_compress_cvtt.h
index ecb876ecc6..c1772199af 100644
--- a/modules/cvtt/image_compress_cvtt.h
+++ b/modules/cvtt/image_compress_cvtt.h
@@ -33,7 +33,7 @@
#include "core/image.h"
-void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressSource p_source);
+void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels);
void image_decompress_cvtt(Image *p_image);
#endif // IMAGE_COMPRESS_CVTT_H
diff --git a/modules/cvtt/register_types.h b/modules/cvtt/register_types.h
index 93f684cdd1..8472980c6a 100644
--- a/modules/cvtt/register_types.h
+++ b/modules/cvtt/register_types.h
@@ -29,6 +29,13 @@
/*************************************************************************/
#ifdef TOOLS_ENABLED
+
+#ifndef CVTT_REGISTER_TYPES_H
+#define CVTT_REGISTER_TYPES_H
+
void register_cvtt_types();
void unregister_cvtt_types();
-#endif
+
+#endif // CVTT_REGISTER_TYPES_H
+
+#endif // TOOLS_ENABLED
diff --git a/modules/dds/SCsub b/modules/dds/SCsub
index 3d92ff02d6..06980bd670 100644
--- a/modules/dds/SCsub
+++ b/modules/dds/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_dds = env_modules.Clone()
diff --git a/modules/dds/config.py b/modules/dds/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/dds/config.py
+++ b/modules/dds/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/dds/register_types.h b/modules/dds/register_types.h
index 1808a4af36..3cb7b5c2a6 100644
--- a/modules/dds/register_types.h
+++ b/modules/dds/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef DDS_REGISTER_TYPES_H
+#define DDS_REGISTER_TYPES_H
+
void register_dds_types();
void unregister_dds_types();
+
+#endif // DDS_REGISTER_TYPES_H
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index a7701329d8..294d594135 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = {
{ "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 }
};
-RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
@@ -222,7 +222,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
if (!(flags & DDSD_MIPMAPCOUNT))
mipmaps = 1;
- PoolVector<uint8_t> src_data;
+ Vector<uint8_t> src_data;
const DDSFormatInfo &info = dds_format_info[dds_format];
uint32_t w = width;
@@ -245,8 +245,8 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
}
src_data.resize(size);
- PoolVector<uint8_t>::Write wb = src_data.write();
- f->get_buffer(wb.ptr(), size);
+ uint8_t *wb = src_data.ptrw();
+ f->get_buffer(wb, size);
} else if (info.palette) {
@@ -278,8 +278,8 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
}
src_data.resize(size + 256 * colsize);
- PoolVector<uint8_t>::Write wb = src_data.write();
- f->get_buffer(wb.ptr(), size);
+ uint8_t *wb = src_data.ptrw();
+ f->get_buffer(wb, size);
for (int i = 0; i < 256; i++) {
@@ -309,8 +309,8 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
size = size * 2;
src_data.resize(size);
- PoolVector<uint8_t>::Write wb = src_data.write();
- f->get_buffer(wb.ptr(), size);
+ uint8_t *wb = src_data.ptrw();
+ f->get_buffer(wb, size);
switch (dds_format) {
@@ -457,7 +457,7 @@ void ResourceFormatDDS::get_recognized_extensions(List<String> *p_extensions) co
bool ResourceFormatDDS::handles_type(const String &p_type) const {
- return ClassDB::is_parent_class(p_type, "Texture");
+ return ClassDB::is_parent_class(p_type, "Texture2D");
}
String ResourceFormatDDS::get_resource_type(const String &p_path) const {
diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h
index 34f4e9b548..ef08967df7 100644
--- a/modules/dds/texture_loader_dds.h
+++ b/modules/dds/texture_loader_dds.h
@@ -36,7 +36,7 @@
class ResourceFormatDDS : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/enet/SCsub b/modules/enet/SCsub
index 485c33b1a8..c8f4b3885e 100644
--- a/modules/enet/SCsub
+++ b/modules/enet/SCsub
@@ -1,13 +1,13 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_enet = env_modules.Clone()
# Thirdparty source files
-if env['builtin_enet']:
+if env["builtin_enet"]:
thirdparty_dir = "#thirdparty/enet/"
thirdparty_sources = [
"godot.cpp",
diff --git a/modules/enet/config.py b/modules/enet/config.py
index 3e30bbe778..5fd343c75d 100644
--- a/modules/enet/config.py
+++ b/modules/enet/config.py
@@ -1,13 +1,16 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"NetworkedMultiplayerENet",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
index 76b3710e96..860da32a22 100644
--- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
+++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
@@ -104,6 +104,24 @@
The IP used when creating a server. This is set to the wildcard [code]"*"[/code] by default, which binds to all available interfaces. The given IP needs to be in IPv4 or IPv6 address format, for example: [code]"192.168.1.1"[/code].
</description>
</method>
+ <method name="set_dtls_certificate">
+ <return type="void">
+ </return>
+ <argument index="0" name="certificate" type="X509Certificate">
+ </argument>
+ <description>
+ Configure the [X509Certificate] to use when [member use_dtls] is [code]true[/code]. For servers, you must also setup the [CryptoKey] via [method set_dtls_key].
+ </description>
+ </method>
+ <method name="set_dtls_key">
+ <return type="void">
+ </return>
+ <argument index="0" name="key" type="CryptoKey">
+ </argument>
+ <description>
+ Configure the [CryptoKey] to use when [member use_dtls] is [code]true[/code]. Remember to also call [method set_dtls_certificate] to setup your [X509Certificate].
+ </description>
+ </method>
</methods>
<members>
<member name="always_ordered" type="bool" setter="set_always_ordered" getter="is_always_ordered" default="false">
@@ -115,6 +133,9 @@
<member name="compression_mode" type="int" setter="set_compression_mode" getter="get_compression_mode" enum="NetworkedMultiplayerENet.CompressionMode" default="0">
The compression method used for network packets. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all.
</member>
+ <member name="dtls_verify" type="bool" setter="set_dtls_verify_enabled" getter="is_dtls_verify_enabled" default="true">
+ Enable or disable certificate verification when [member use_dtls] [code]true[/code].
+ </member>
<member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" override="true" default="false" />
<member name="server_relay" type="bool" setter="set_server_relay_enabled" getter="is_server_relay_enabled" default="true">
Enable or disable the server feature that notifies clients of other peers' connection/disconnection, and relays messages between them. When this option is [code]false[/code], clients won't be automatically notified of other peers and won't be able to send them packets through the server.
@@ -123,6 +144,10 @@
Set the default channel to be used to transfer data. By default, this value is [code]-1[/code] which means that ENet will only use 2 channels, one for reliable and one for unreliable packets. Channel [code]0[/code] is reserved, and cannot be used. Setting this member to any value between [code]0[/code] and [member channel_count] (excluded) will force ENet to use that channel for sending data.
</member>
<member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" override="true" enum="NetworkedMultiplayerPeer.TransferMode" default="2" />
+ <member name="use_dtls" type="bool" setter="set_dtls_enabled" getter="is_dtls_enabled" default="false">
+ When enabled, the client or server created by this peer, will use [PacketPeerDTLS] instead of raw UDP sockets for communicating with the remote peer. This will make the communication encrypted with DTLS at the cost of higher resource usage and potentially larger packet size.
+ Note: When creating a DTLS server, make sure you setup the key/certificate pair via [method set_dtls_key] and [method set_dtls_certificate]. For DTLS clients, have a look at the [member dtls_verify] option, and configure the certificate accordingly via [method set_dtls_certificate].
+ </member>
</members>
<constants>
<constant name="COMPRESS_NONE" value="0" enum="CompressionMode">
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index 21dd758391..444ffae713 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -49,7 +49,7 @@ void NetworkedMultiplayerENet::set_target_peer(int p_peer) {
int NetworkedMultiplayerENet::get_packet_peer() const {
- ERR_FAIL_COND_V(!active, 1);
+ ERR_FAIL_COND_V_MSG(!active, 1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, 1);
return incoming_packets.front()->get().from;
@@ -57,7 +57,7 @@ int NetworkedMultiplayerENet::get_packet_peer() const {
int NetworkedMultiplayerENet::get_packet_channel() const {
- ERR_FAIL_COND_V(!active, -1);
+ ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, -1);
return incoming_packets.front()->get().channel;
@@ -65,7 +65,7 @@ int NetworkedMultiplayerENet::get_packet_channel() const {
int NetworkedMultiplayerENet::get_last_packet_channel() const {
- ERR_FAIL_COND_V(!active, -1);
+ ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(!current_packet.packet, -1);
return current_packet.channel;
@@ -73,11 +73,12 @@ int NetworkedMultiplayerENet::get_last_packet_channel() const {
Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
- ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
- ERR_FAIL_COND_V(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_in_bandwidth < 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_out_bandwidth < 0, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
+ ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The port number must be set between 0 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER, "The number of clients must be set between 1 and 4095 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
+ ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
+ ERR_FAIL_COND_V(dtls_enabled && (dtls_key.is_null() || dtls_cert.is_null()), ERR_INVALID_PARAMETER);
ENetAddress address;
memset(&address, 0, sizeof(address));
@@ -104,7 +105,12 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
p_in_bandwidth /* limit incoming bandwidth if > 0 */,
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
- ERR_FAIL_COND_V(!host, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create an ENet multiplayer server.");
+#ifdef GODOT_ENET
+ if (dtls_enabled) {
+ enet_host_dtls_server_setup(host, dtls_key.ptr(), dtls_cert.ptr());
+ }
+#endif
_setup_compressor();
active = true;
@@ -116,11 +122,11 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
}
Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_client_port) {
- ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
- ERR_FAIL_COND_V(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_client_port < 0 || p_client_port > 65535, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_in_bandwidth < 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_out_bandwidth < 0, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
+ ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The server port number must be set between 0 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_client_port < 0 || p_client_port > 65535, ERR_INVALID_PARAMETER, "The client port number must be set between 0 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(p_in_bandwidth < 0, ERR_INVALID_PARAMETER, "The incoming bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
+ ERR_FAIL_COND_V_MSG(p_out_bandwidth < 0, ERR_INVALID_PARAMETER, "The outgoing bandwidth limit must be greater than or equal to 0 (0 disables the limit).");
if (p_client_port != 0) {
ENetAddress c_client;
@@ -135,7 +141,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
if (bind_ip.is_wildcard()) {
c_client.host = 0;
} else {
- ERR_FAIL_COND_V(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER, "Wildcard IP addresses are only permitted in IPv4, not IPv6.");
c_client.host = *(uint32_t *)bind_ip.get_ipv4();
}
#endif
@@ -148,14 +154,19 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
p_in_bandwidth /* limit incoming bandwidth if > 0 */,
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
} else {
- host = enet_host_create(NULL /* create a client host */,
+ host = enet_host_create(nullptr /* create a client host */,
1 /* only allow 1 outgoing connection */,
channel_count /* allow up to channel_count to be used */,
p_in_bandwidth /* limit incoming bandwidth if > 0 */,
p_out_bandwidth /* limit outgoing bandwidth if > 0 */);
}
- ERR_FAIL_COND_V(!host, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(!host, ERR_CANT_CREATE, "Couldn't create the ENet client host.");
+#ifdef GODOT_ENET
+ if (dtls_enabled) {
+ enet_host_dtls_client_setup(host, dtls_cert.ptr(), dtls_verify, p_address.utf8().get_data());
+ }
+#endif
_setup_compressor();
@@ -169,14 +180,14 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
ip = IP::get_singleton()->resolve_hostname(p_address, IP::TYPE_IPV4);
#endif
- ERR_FAIL_COND_V(!ip.is_valid(), ERR_CANT_RESOLVE);
+ ERR_FAIL_COND_V_MSG(!ip.is_valid(), ERR_CANT_RESOLVE, "Couldn't resolve the server IP address or domain name.");
}
ENetAddress address;
#ifdef GODOT_ENET
enet_address_set_ip(&address, ip.get_ipv6(), 16);
#else
- ERR_FAIL_COND_V(!ip.is_ipv4(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(!ip.is_ipv4(), ERR_INVALID_PARAMETER, "Connecting to an IPv6 server isn't supported when using vanilla ENet. Recompile Godot with the bundled ENet library.");
address.host = *(uint32_t *)ip.get_ipv4();
#endif
address.port = p_port;
@@ -186,9 +197,9 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
// Initiate connection, allocating enough channels
ENetPeer *peer = enet_host_connect(host, &address, channel_count, unique_id);
- if (peer == NULL) {
+ if (peer == nullptr) {
enet_host_destroy(host);
- ERR_FAIL_COND_V(!peer, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(!peer, ERR_CANT_CREATE, "Couldn't connect to the ENet multiplayer server.");
}
// Technically safe to ignore the peer or anything else.
@@ -203,7 +214,7 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
void NetworkedMultiplayerENet::poll() {
- ERR_FAIL_COND(!active);
+ ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -265,12 +276,12 @@ void NetworkedMultiplayerENet::poll() {
if (E->key() == *new_id)
continue;
// Send existing peers to new peer
- ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
+ ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);
encode_uint32(E->key(), &packet->data[4]);
enet_peer_send(event.peer, SYSCH_CONFIG, packet);
// Send the new peer to existing peers
- packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
+ packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);
encode_uint32(*new_id, &packet->data[4]);
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
@@ -309,7 +320,7 @@ void NetworkedMultiplayerENet::poll() {
if (E->key() == *id)
continue;
- ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
+ ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
encode_uint32(*id, &packet->data[4]);
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
@@ -335,7 +346,7 @@ void NetworkedMultiplayerENet::poll() {
switch (msg) {
case SYSMSG_ADD_PEER: {
- peer_map[id] = NULL;
+ peer_map[id] = nullptr;
emit_signal("peer_connected", id);
} break;
@@ -435,14 +446,14 @@ void NetworkedMultiplayerENet::poll() {
}
bool NetworkedMultiplayerENet::is_server() const {
- ERR_FAIL_COND_V(!active, false);
+ ERR_FAIL_COND_V_MSG(!active, false, "The multiplayer instance isn't currently active.");
return server;
}
void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
- ERR_FAIL_COND(!active);
+ ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -474,9 +485,9 @@ void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
- ERR_FAIL_COND(!active);
- ERR_FAIL_COND(!is_server());
- ERR_FAIL_COND(!peer_map.has(p_peer));
+ ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
+ ERR_FAIL_COND_MSG(!is_server(), "Can't disconnect a peer when not acting as a server.");
+ ERR_FAIL_COND_MSG(!peer_map.has(p_peer), vformat("Peer ID %d not found in the list of peers.", p_peer));
if (now) {
int *id = (int *)peer_map[p_peer]->data;
@@ -491,7 +502,7 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
continue;
}
- ENetPacket *packet = enet_packet_create(NULL, 8, ENET_PACKET_FLAG_RELIABLE);
+ ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
encode_uint32(p_peer, &packet->data[4]);
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
@@ -515,7 +526,7 @@ int NetworkedMultiplayerENet::get_available_packet_count() const {
Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_FAIL_COND_V(incoming_packets.size() == 0, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V_MSG(incoming_packets.size() == 0, ERR_UNAVAILABLE, "No incoming packets available.");
_pop_current_packet();
@@ -530,8 +541,8 @@ Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buff
Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V(!active, ERR_UNCONFIGURED);
- ERR_FAIL_COND_V(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V_MSG(!active, ERR_UNCONFIGURED, "The multiplayer instance isn't currently active.");
+ ERR_FAIL_COND_V_MSG(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED, "The multiplayer instance isn't currently connected to any server or client.");
int packet_flags = 0;
int channel = SYSCH_RELIABLE;
@@ -557,15 +568,15 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
if (transfer_channel > SYSCH_CONFIG)
channel = transfer_channel;
- Map<int, ENetPeer *>::Element *E = NULL;
+ Map<int, ENetPeer *>::Element *E = nullptr;
if (target_peer != 0) {
E = peer_map.find(ABS(target_peer));
- ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, "Invalid target peer '" + itos(target_peer) + "'.");
+ ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, vformat("Invalid target peer: %d", target_peer));
}
- ENetPacket *packet = enet_packet_create(NULL, p_buffer_size + 8, packet_flags);
+ ENetPacket *packet = enet_packet_create(nullptr, p_buffer_size + 8, packet_flags);
encode_uint32(unique_id, &packet->data[0]); // Source ID
encode_uint32(target_peer, &packet->data[4]); // Dest ID
copymem(&packet->data[8], p_buffer, p_buffer_size);
@@ -614,7 +625,7 @@ void NetworkedMultiplayerENet::_pop_current_packet() {
if (current_packet.packet) {
enet_packet_destroy(current_packet.packet);
- current_packet.packet = NULL;
+ current_packet.packet = nullptr;
current_packet.from = 0;
current_packet.channel = -1;
}
@@ -650,7 +661,7 @@ uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
int NetworkedMultiplayerENet::get_unique_id() const {
- ERR_FAIL_COND_V(!active, 0);
+ ERR_FAIL_COND_V_MSG(!active, 0, "The multiplayer instance isn't currently active.");
return unique_id;
}
@@ -706,7 +717,7 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *
mode = Compression::MODE_ZSTD;
} break;
default: {
- ERR_FAIL_V(0);
+ ERR_FAIL_V_MSG(0, vformat("Invalid ENet compression mode: %d", enet->compression_mode));
}
}
@@ -760,7 +771,7 @@ void NetworkedMultiplayerENet::_setup_compressor() {
case COMPRESS_NONE: {
- enet_host_compress(host, NULL);
+ enet_host_compress(host, nullptr);
} break;
case COMPRESS_RANGE_CODER: {
enet_host_compress_with_range_coder(host);
@@ -781,9 +792,9 @@ void NetworkedMultiplayerENet::enet_compressor_destroy(void *context) {
IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
- ERR_FAIL_COND_V(!peer_map.has(p_peer_id), IP_Address());
- ERR_FAIL_COND_V(!is_server() && p_peer_id != 1, IP_Address());
- ERR_FAIL_COND_V(peer_map[p_peer_id] == NULL, IP_Address());
+ ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), IP_Address(), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
+ ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, IP_Address(), "Can't get the address of peers other than the server (ID -1) when acting as a client.");
+ ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == nullptr, IP_Address(), vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
IP_Address out;
#ifdef GODOT_ENET
@@ -797,9 +808,9 @@ IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
- ERR_FAIL_COND_V(!peer_map.has(p_peer_id), 0);
- ERR_FAIL_COND_V(!is_server() && p_peer_id != 1, 0);
- ERR_FAIL_COND_V(peer_map[p_peer_id] == NULL, 0);
+ ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), 0, vformat("Peer ID %d not found in the list of peers.", p_peer_id));
+ ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, 0, "Can't get the address of peers other than the server (ID -1) when acting as a client.");
+ ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == nullptr, 0, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
#ifdef GODOT_ENET
return peer_map[p_peer_id]->address.port;
#else
@@ -809,8 +820,8 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
- ERR_FAIL_COND(p_channel < -1 || p_channel >= channel_count);
- ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, "Channel " + itos(SYSCH_CONFIG) + " is reserved.");
+ ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel));
+ ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG));
transfer_channel = p_channel;
}
@@ -820,8 +831,8 @@ int NetworkedMultiplayerENet::get_transfer_channel() const {
void NetworkedMultiplayerENet::set_channel_count(int p_channel) {
- ERR_FAIL_COND(active);
- ERR_FAIL_COND(p_channel < SYSCH_MAX);
+ ERR_FAIL_COND_MSG(active, "The channel count can't be set while the multiplayer instance is active.");
+ ERR_FAIL_COND_MSG(p_channel < SYSCH_MAX, vformat("The channel count must be greater than or equal to %d to account for reserved channels (got %d).", SYSCH_MAX, p_channel));
channel_count = p_channel;
}
@@ -838,7 +849,7 @@ bool NetworkedMultiplayerENet::is_always_ordered() const {
}
void NetworkedMultiplayerENet::set_server_relay_enabled(bool p_enabled) {
- ERR_FAIL_COND(active);
+ ERR_FAIL_COND_MSG(active, "Server relaying can't be toggled while the multiplayer instance is active.");
server_relay = p_enabled;
}
@@ -856,6 +867,12 @@ void NetworkedMultiplayerENet::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_compression_mode", "mode"), &NetworkedMultiplayerENet::set_compression_mode);
ClassDB::bind_method(D_METHOD("get_compression_mode"), &NetworkedMultiplayerENet::get_compression_mode);
ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &NetworkedMultiplayerENet::set_bind_ip);
+ ClassDB::bind_method(D_METHOD("set_dtls_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_enabled);
+ ClassDB::bind_method(D_METHOD("is_dtls_enabled"), &NetworkedMultiplayerENet::is_dtls_enabled);
+ ClassDB::bind_method(D_METHOD("set_dtls_key", "key"), &NetworkedMultiplayerENet::set_dtls_key);
+ ClassDB::bind_method(D_METHOD("set_dtls_certificate", "certificate"), &NetworkedMultiplayerENet::set_dtls_certificate);
+ ClassDB::bind_method(D_METHOD("set_dtls_verify_enabled", "enabled"), &NetworkedMultiplayerENet::set_dtls_verify_enabled);
+ ClassDB::bind_method(D_METHOD("is_dtls_verify_enabled"), &NetworkedMultiplayerENet::is_dtls_verify_enabled);
ClassDB::bind_method(D_METHOD("get_peer_address", "id"), &NetworkedMultiplayerENet::get_peer_address);
ClassDB::bind_method(D_METHOD("get_peer_port", "id"), &NetworkedMultiplayerENet::get_peer_port);
@@ -875,6 +892,8 @@ void NetworkedMultiplayerENet::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel_count"), "set_channel_count", "get_channel_count");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "always_ordered"), "set_always_ordered", "is_always_ordered");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "server_relay"), "set_server_relay_enabled", "is_server_relay_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dtls_verify"), "set_dtls_verify_enabled", "is_dtls_verify_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_dtls"), "set_dtls_enabled", "is_dtls_enabled");
BIND_ENUM_CONSTANT(COMPRESS_NONE);
BIND_ENUM_CONSTANT(COMPRESS_RANGE_CODER);
@@ -891,7 +910,7 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
server_relay = true;
unique_id = 0;
target_peer = 0;
- current_packet.packet = NULL;
+ current_packet.packet = nullptr;
transfer_mode = TRANSFER_MODE_RELIABLE;
channel_count = SYSCH_MAX;
transfer_channel = -1;
@@ -904,6 +923,9 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
enet_compressor.destroy = enet_compressor_destroy;
bind_ip = IP_Address("*");
+
+ dtls_enabled = false;
+ dtls_verify = true;
}
NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
@@ -916,7 +938,35 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
// Sets IP for ENet to bind when using create_server or create_client
// if no IP is set, then ENet bind to ENET_HOST_ANY
void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) {
- ERR_FAIL_COND(!p_ip.is_valid() && !p_ip.is_wildcard());
+ ERR_FAIL_COND_MSG(!p_ip.is_valid() && !p_ip.is_wildcard(), vformat("Invalid bind IP address: %s", String(p_ip)));
bind_ip = p_ip;
}
+
+void NetworkedMultiplayerENet::set_dtls_enabled(bool p_enabled) {
+ ERR_FAIL_COND(active);
+ dtls_enabled = p_enabled;
+}
+
+bool NetworkedMultiplayerENet::is_dtls_enabled() const {
+ return dtls_enabled;
+}
+
+void NetworkedMultiplayerENet::set_dtls_verify_enabled(bool p_enabled) {
+ ERR_FAIL_COND(active);
+ dtls_verify = p_enabled;
+}
+
+bool NetworkedMultiplayerENet::is_dtls_verify_enabled() const {
+ return dtls_verify;
+}
+
+void NetworkedMultiplayerENet::set_dtls_key(Ref<CryptoKey> p_key) {
+ ERR_FAIL_COND(active);
+ dtls_key = p_key;
+}
+
+void NetworkedMultiplayerENet::set_dtls_certificate(Ref<X509Certificate> p_cert) {
+ ERR_FAIL_COND(active);
+ dtls_cert = p_cert;
+}
diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h
index 11487b99a5..ff436ce2c0 100644
--- a/modules/enet/networked_multiplayer_enet.h
+++ b/modules/enet/networked_multiplayer_enet.h
@@ -31,6 +31,7 @@
#ifndef NETWORKED_MULTIPLAYER_ENET_H
#define NETWORKED_MULTIPLAYER_ENET_H
+#include "core/crypto/crypto.h"
#include "core/io/compression.h"
#include "core/io/networked_multiplayer_peer.h"
@@ -111,6 +112,11 @@ private:
IP_Address bind_ip;
+ bool dtls_enabled;
+ Ref<CryptoKey> dtls_key;
+ Ref<X509Certificate> dtls_cert;
+ bool dtls_verify;
+
protected:
static void _bind_methods();
@@ -166,6 +172,12 @@ public:
~NetworkedMultiplayerENet();
void set_bind_ip(const IP_Address &p_ip);
+ void set_dtls_enabled(bool p_enabled);
+ bool is_dtls_enabled() const;
+ void set_dtls_verify_enabled(bool p_enabled);
+ bool is_dtls_verify_enabled() const;
+ void set_dtls_key(Ref<CryptoKey> p_key);
+ void set_dtls_certificate(Ref<X509Certificate> p_cert);
};
VARIANT_ENUM_CAST(NetworkedMultiplayerENet::CompressionMode);
diff --git a/modules/enet/register_types.h b/modules/enet/register_types.h
index 19f8c5a352..cac0a4f7ee 100644
--- a/modules/enet/register_types.h
+++ b/modules/enet/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef ENET_REGISTER_TYPES_H
+#define ENET_REGISTER_TYPES_H
+
void register_enet_types();
void unregister_enet_types();
+
+#endif // ENET_REGISTER_TYPES_H
diff --git a/modules/etc/SCsub b/modules/etc/SCsub
index 1742d3534f..383bbf83c3 100644
--- a/modules/etc/SCsub
+++ b/modules/etc/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_etc = env_modules.Clone()
@@ -9,21 +9,21 @@ env_etc = env_modules.Clone()
# Not unbundled so far since not widespread as shared library
thirdparty_dir = "#thirdparty/etc2comp/"
thirdparty_sources = [
- "EtcBlock4x4.cpp",
- "EtcBlock4x4Encoding.cpp",
- "EtcBlock4x4Encoding_ETC1.cpp",
- "EtcBlock4x4Encoding_R11.cpp",
- "EtcBlock4x4Encoding_RG11.cpp",
- "EtcBlock4x4Encoding_RGB8A1.cpp",
- "EtcBlock4x4Encoding_RGB8.cpp",
- "EtcBlock4x4Encoding_RGBA8.cpp",
- "Etc.cpp",
- "EtcDifferentialTrys.cpp",
- "EtcFilter.cpp",
- "EtcImage.cpp",
- "EtcIndividualTrys.cpp",
- "EtcMath.cpp",
- "EtcSortedBlockList.cpp",
+ "EtcBlock4x4.cpp",
+ "EtcBlock4x4Encoding.cpp",
+ "EtcBlock4x4Encoding_ETC1.cpp",
+ "EtcBlock4x4Encoding_R11.cpp",
+ "EtcBlock4x4Encoding_RG11.cpp",
+ "EtcBlock4x4Encoding_RGB8A1.cpp",
+ "EtcBlock4x4Encoding_RGB8.cpp",
+ "EtcBlock4x4Encoding_RGBA8.cpp",
+ "Etc.cpp",
+ "EtcDifferentialTrys.cpp",
+ "EtcFilter.cpp",
+ "EtcImage.cpp",
+ "EtcIndividualTrys.cpp",
+ "EtcMath.cpp",
+ "EtcSortedBlockList.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
diff --git a/modules/etc/config.py b/modules/etc/config.py
index 098f1eafa9..53b8f2f2e3 100644
--- a/modules/etc/config.py
+++ b/modules/etc/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return env['tools']
+ return env["tools"]
+
def configure(env):
pass
diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp
index b80138c99d..223830f445 100644
--- a/modules/etc/image_etc.cpp
+++ b/modules/etc/image_etc.cpp
@@ -36,18 +36,18 @@
#include "core/os/os.h"
#include "core/print_string.h"
-static Image::Format _get_etc2_mode(Image::DetectChannels format) {
+static Image::Format _get_etc2_mode(Image::UsedChannels format) {
switch (format) {
- case Image::DETECTED_R:
+ case Image::USED_CHANNELS_R:
return Image::FORMAT_ETC2_R11;
- case Image::DETECTED_RG:
+ case Image::USED_CHANNELS_RG:
return Image::FORMAT_ETC2_RG11;
- case Image::DETECTED_RGB:
+ case Image::USED_CHANNELS_RGB:
return Image::FORMAT_ETC2_RGB8;
- case Image::DETECTED_RGBA:
+ case Image::USED_CHANNELS_RGBA:
return Image::FORMAT_ETC2_RGBA8;
// TODO: would be nice if we could use FORMAT_ETC2_RGB8A1 for FORMAT_RGBA5551
@@ -88,47 +88,8 @@ static Etc::Image::Format _image_format_to_etc2comp_format(Image::Format format)
}
}
-static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_format, Image::CompressSource p_source) {
+static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_format, Image::UsedChannels p_channels) {
Image::Format img_format = p_img->get_format();
- Image::DetectChannels detected_channels = p_img->get_detected_channels();
-
- if (p_source == Image::COMPRESS_SOURCE_LAYERED) {
- //keep what comes in
- switch (p_img->get_format()) {
- case Image::FORMAT_L8: {
- detected_channels = Image::DETECTED_L;
- } break;
- case Image::FORMAT_LA8: {
- detected_channels = Image::DETECTED_LA;
- } break;
- case Image::FORMAT_R8: {
- detected_channels = Image::DETECTED_R;
- } break;
- case Image::FORMAT_RG8: {
- detected_channels = Image::DETECTED_RG;
- } break;
- case Image::FORMAT_RGB8: {
- detected_channels = Image::DETECTED_RGB;
- } break;
- case Image::FORMAT_RGBA8:
- case Image::FORMAT_RGBA4444:
- case Image::FORMAT_RGBA5551: {
- detected_channels = Image::DETECTED_RGBA;
- } break;
- default: {
- }
- }
- }
-
- if (p_source == Image::COMPRESS_SOURCE_SRGB && (detected_channels == Image::DETECTED_R || detected_channels == Image::DETECTED_RG)) {
- //R and RG do not support SRGB
- detected_channels = Image::DETECTED_RGB;
- }
-
- if (p_source == Image::COMPRESS_SOURCE_NORMAL) {
- //use RG channels only for normal
- detected_channels = Image::DETECTED_RG;
- }
if (img_format >= Image::FORMAT_DXT1) {
return; //do not compress, already compressed
@@ -139,21 +100,30 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
return;
}
+ // FIXME: Commented out during Vulkan rebase.
+ /*
if (force_etc1_format) {
// If VRAM compression is using ETC, but image has alpha, convert to RGBA4444 or LA8
// This saves space while maintaining the alpha channel
- if (detected_channels == Image::DETECTED_RGBA) {
+ if (detected_channels == Image::USED_CHANNELS_RGBA) {
+
+ if (p_img->has_mipmaps()) {
+ // Image doesn't support mipmaps with RGBA4444 textures
+ p_img->clear_mipmaps();
+ }
p_img->convert(Image::FORMAT_RGBA4444);
return;
- } else if (detected_channels == Image::DETECTED_LA) {
+ } else if (detected_channels == Image::USE_CHANNELS_LA) {
+
p_img->convert(Image::FORMAT_LA8);
return;
}
}
+ */
uint32_t imgw = p_img->get_width(), imgh = p_img->get_height();
- Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels);
+ Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(p_channels);
Ref<Image> img = p_img->duplicate();
@@ -179,16 +149,16 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
}
}
- PoolVector<uint8_t>::Read r = img->get_data().read();
- ERR_FAIL_COND(!r.ptr());
+ const uint8_t *r = img->get_data().ptr();
+ ERR_FAIL_COND(!r);
unsigned int target_size = Image::get_image_data_size(imgw, imgh, etc_format, p_img->has_mipmaps());
int mmc = 1 + (p_img->has_mipmaps() ? Image::get_image_required_mipmaps(imgw, imgh, etc_format) : 0);
- PoolVector<uint8_t> dst_data;
+ Vector<uint8_t> dst_data;
dst_data.resize(target_size);
- PoolVector<uint8_t>::Write w = dst_data.write();
+ uint8_t *w = dst_data.ptrw();
// prepare parameters to be passed to etc2comp
int num_cpus = OS::get_singleton()->get_processor_count();
@@ -222,7 +192,7 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
src_rgba_f[j] = Etc::ColorFloatRGBA::ConvertFromRGBA8(src[si], src[si + 1], src[si + 2], src[si + 3]);
}
- unsigned char *etc_data = NULL;
+ unsigned char *etc_data = nullptr;
unsigned int etc_data_len = 0;
unsigned int extended_width = 0, extended_height = 0;
Etc::Encode((float *)src_rgba_f, mipmap_w, mipmap_h, etc2comp_etc_format, error_metric, effort, num_cpus, num_cpus, &etc_data, &etc_data_len, &extended_width, &extended_height, &encoding_time);
@@ -241,11 +211,11 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
}
static void _compress_etc1(Image *p_img, float p_lossy_quality) {
- _compress_etc(p_img, p_lossy_quality, true, Image::COMPRESS_SOURCE_GENERIC);
+ _compress_etc(p_img, p_lossy_quality, true, Image::USED_CHANNELS_RGB);
}
-static void _compress_etc2(Image *p_img, float p_lossy_quality, Image::CompressSource p_source) {
- _compress_etc(p_img, p_lossy_quality, false, p_source);
+static void _compress_etc2(Image *p_img, float p_lossy_quality, Image::UsedChannels p_channels) {
+ _compress_etc(p_img, p_lossy_quality, false, p_channels);
}
void _register_etc_compress_func() {
diff --git a/modules/etc/register_types.h b/modules/etc/register_types.h
index fac83e7d17..247c7213af 100644
--- a/modules/etc/register_types.h
+++ b/modules/etc/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef ETC_REGISTER_TYPES_H
+#define ETC_REGISTER_TYPES_H
+
void register_etc_types();
void unregister_etc_types();
+
+#endif // ETC_REGISTER_TYPES_H
diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index 27c2358306..bfb2098dff 100644
--- a/modules/etc/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -42,7 +42,7 @@ struct ETC1Header {
uint16_t origHeight;
};
-RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
@@ -71,13 +71,12 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path,
h.origWidth = f->get_16();
h.origHeight = f->get_16();
- PoolVector<uint8_t> src_data;
+ Vector<uint8_t> src_data;
uint32_t size = h.texWidth * h.texHeight / 2;
src_data.resize(size);
- PoolVector<uint8_t>::Write wb = src_data.write();
- f->get_buffer(wb.ptr(), size);
- wb.release();
+ uint8_t *wb = src_data.ptrw();
+ f->get_buffer(wb, size);
int mipmaps = h.format;
int width = h.origWidth;
@@ -103,7 +102,7 @@ void ResourceFormatPKM::get_recognized_extensions(List<String> *p_extensions) co
bool ResourceFormatPKM::handles_type(const String &p_type) const {
- return ClassDB::is_parent_class(p_type, "Texture");
+ return ClassDB::is_parent_class(p_type, "Texture2D");
}
String ResourceFormatPKM::get_resource_type(const String &p_path) const {
diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h
index 3d52a9ea95..6507e0bdec 100644
--- a/modules/etc/texture_loader_pkm.h
+++ b/modules/etc/texture_loader_pkm.h
@@ -36,7 +36,7 @@
class ResourceFormatPKM : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub
index 7b66aa1c76..bfc1658bb4 100644
--- a/modules/freetype/SCsub
+++ b/modules/freetype/SCsub
@@ -1,14 +1,12 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
-
-from compat import isbasestring
+Import("env")
+Import("env_modules")
env_freetype = env_modules.Clone()
# Thirdparty source files
-if env['builtin_freetype']:
+if env["builtin_freetype"]:
thirdparty_dir = "#thirdparty/freetype/"
thirdparty_sources = [
"src/autofit/autofit.c",
@@ -55,31 +53,31 @@ if env['builtin_freetype']:
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
- if env['platform'] == 'uwp':
+ if env["platform"] == "uwp":
# Include header for UWP to fix build issues
- env_freetype.Append(CCFLAGS=['/FI', '"modules/freetype/uwpdef.h"'])
+ env_freetype.Append(CCFLAGS=["/FI", '"modules/freetype/uwpdef.h"'])
# Globally too, as freetype is used in scene (see bottom)
- env.Append(CCFLAGS=['/FI', '"modules/freetype/uwpdef.h"'])
+ env.Append(CCFLAGS=["/FI", '"modules/freetype/uwpdef.h"'])
env_freetype.Prepend(CPPPATH=[thirdparty_dir + "/include"])
# Also needed in main env for scene/
env.Prepend(CPPPATH=[thirdparty_dir + "/include"])
- env_freetype.Append(CPPDEFINES=['FT2_BUILD_LIBRARY', 'FT_CONFIG_OPTION_USE_PNG'])
- if (env['target'] == 'debug'):
- env_freetype.Append(CPPDEFINES=['ZLIB_DEBUG'])
+ env_freetype.Append(CPPDEFINES=["FT2_BUILD_LIBRARY", "FT_CONFIG_OPTION_USE_PNG"])
+ if env["target"] == "debug":
+ env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
# Also requires libpng headers
- if env['builtin_libpng']:
+ if env["builtin_libpng"]:
env_freetype.Prepend(CPPPATH=["#thirdparty/libpng"])
- sfnt = thirdparty_dir + 'src/sfnt/sfnt.c'
+ sfnt = thirdparty_dir + "src/sfnt/sfnt.c"
# Must be done after all CPPDEFINES are being set so we can copy them.
- if env['platform'] == 'javascript':
+ if env["platform"] == "javascript":
# Forcibly undefine this macro so SIMD is not used in this file,
# since currently unsupported in WASM
tmp_env = env_freetype.Clone()
- tmp_env.Append(CPPFLAGS=['-U__OPTIMIZE__'])
+ tmp_env.Append(CPPFLAGS=["-U__OPTIMIZE__"])
sfnt = tmp_env.Object(sfnt)
thirdparty_sources += [sfnt]
@@ -93,7 +91,7 @@ if env['builtin_freetype']:
# and then plain strings for system library. We insert between the two.
inserted = False
for idx, linklib in enumerate(env["LIBS"]):
- if isbasestring(linklib): # first system lib such as "X11", otherwise SCons lib object
+ if isinstance(linklib, (str, bytes)): # first system lib such as "X11", otherwise SCons lib object
env["LIBS"].insert(idx, lib)
inserted = True
break
diff --git a/modules/freetype/config.py b/modules/freetype/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/freetype/config.py
+++ b/modules/freetype/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/freetype/register_types.h b/modules/freetype/register_types.h
index 336969d079..aa8088d2e8 100644
--- a/modules/freetype/register_types.h
+++ b/modules/freetype/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef FREETYPE_REGISTER_TYPES_H
+#define FREETYPE_REGISTER_TYPES_H
+
void register_freetype_types();
void unregister_freetype_types();
+
+#endif // FREETYPE_REGISTER_TYPES_H
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index a18c75fa27..cab05549d2 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_gdnative = env_modules.Clone()
env_gdnative.add_source_files(env.modules_sources, "gdnative.cpp")
@@ -12,12 +12,12 @@ env_gdnative.add_source_files(env.modules_sources, "nativescript/*.cpp")
env_gdnative.add_source_files(env.modules_sources, "gdnative_library_singleton_editor.cpp")
env_gdnative.add_source_files(env.modules_sources, "gdnative_library_editor_plugin.cpp")
-env_gdnative.Prepend(CPPPATH=['#modules/gdnative/include/'])
+env_gdnative.Prepend(CPPPATH=["#modules/gdnative/include/"])
-Export('env_gdnative')
+Export("env_gdnative")
SConscript("net/SCsub")
-SConscript("arvr/SCsub")
+SConscript("xr/SCsub")
SConscript("pluginscript/SCsub")
SConscript("videodecoder/SCsub")
@@ -25,8 +25,11 @@ SConscript("videodecoder/SCsub")
from platform_methods import run_in_subprocess
import gdnative_builders
-_, gensource = env_gdnative.CommandNoCache(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'],
- 'gdnative_api.json', run_in_subprocess(gdnative_builders.build_gdnative_api_struct))
+_, gensource = env_gdnative.CommandNoCache(
+ ["include/gdnative_api_struct.gen.h", "gdnative_api_struct.gen.cpp"],
+ "gdnative_api.json",
+ run_in_subprocess(gdnative_builders.build_gdnative_api_struct),
+)
env_gdnative.add_source_files(env.modules_sources, [gensource])
env.use_ptrcall = True
diff --git a/modules/gdnative/android/android_gdn.cpp b/modules/gdnative/android/android_gdn.cpp
index 4be489cd46..bc39be1813 100644
--- a/modules/gdnative/android/android_gdn.cpp
+++ b/modules/gdnative/android/android_gdn.cpp
@@ -50,7 +50,7 @@ JNIEnv *GDAPI godot_android_get_env() {
#ifdef __ANDROID__
return ThreadAndroid::get_env();
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -59,7 +59,7 @@ jobject GDAPI godot_android_get_activity() {
OS_Android *os_android = (OS_Android *)OS::get_singleton();
return os_android->get_godot_java()->get_activity();
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -68,7 +68,7 @@ jobject GDAPI godot_android_get_surface() {
OS_Android *os_android = (OS_Android *)OS::get_singleton();
return os_android->get_godot_java()->get_surface();
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -83,4 +83,4 @@ bool GDAPI godot_android_is_activity_resumed() {
#ifdef __cplusplus
}
-#endif \ No newline at end of file
+#endif
diff --git a/modules/gdnative/arvr/SCsub b/modules/gdnative/arvr/SCsub
deleted file mode 100644
index 20eaa99592..0000000000
--- a/modules/gdnative/arvr/SCsub
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-Import('env_gdnative')
-
-env_gdnative.add_source_files(env.modules_sources, '*.cpp')
diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp
deleted file mode 100644
index 5efa915f62..0000000000
--- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/*************************************************************************/
-/* arvr_interface_gdnative.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 "arvr_interface_gdnative.h"
-#include "main/input_default.h"
-#include "servers/arvr/arvr_positional_tracker.h"
-#include "servers/visual/visual_server_globals.h"
-
-void ARVRInterfaceGDNative::_bind_methods() {
- ADD_PROPERTY_DEFAULT("interface_is_initialized", false);
- ADD_PROPERTY_DEFAULT("ar_is_anchor_detection_enabled", false);
-}
-
-ARVRInterfaceGDNative::ARVRInterfaceGDNative() {
- print_verbose("Construct gdnative interface\n");
-
- // we won't have our data pointer until our library gets set
- data = NULL;
-
- interface = NULL;
-}
-
-ARVRInterfaceGDNative::~ARVRInterfaceGDNative() {
- print_verbose("Destruct gdnative interface\n");
-
- if (interface != NULL && is_initialized()) {
- uninitialize();
- };
-
- // cleanup after ourselves
- cleanup();
-}
-
-void ARVRInterfaceGDNative::cleanup() {
- if (interface != NULL) {
- interface->destructor(data);
- data = NULL;
- interface = NULL;
- }
-}
-
-void ARVRInterfaceGDNative::set_interface(const godot_arvr_interface_gdnative *p_interface) {
- // this should only be called once, just being paranoid..
- if (interface) {
- cleanup();
- }
-
- // bind to our interface
- interface = p_interface;
-
- // Now we do our constructing...
- data = interface->constructor((godot_object *)this);
-}
-
-StringName ARVRInterfaceGDNative::get_name() const {
-
- ERR_FAIL_COND_V(interface == NULL, StringName());
-
- godot_string result = interface->get_name(data);
-
- StringName name = *(String *)&result;
-
- godot_string_destroy(&result);
-
- return name;
-}
-
-int ARVRInterfaceGDNative::get_capabilities() const {
- int capabilities;
-
- ERR_FAIL_COND_V(interface == NULL, 0); // 0 = None
-
- capabilities = interface->get_capabilities(data);
-
- return capabilities;
-}
-
-bool ARVRInterfaceGDNative::get_anchor_detection_is_enabled() const {
-
- ERR_FAIL_COND_V(interface == NULL, false);
-
- return interface->get_anchor_detection_is_enabled(data);
-}
-
-void ARVRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) {
-
- ERR_FAIL_COND(interface == NULL);
-
- interface->set_anchor_detection_is_enabled(data, p_enable);
-}
-
-int ARVRInterfaceGDNative::get_camera_feed_id() {
-
- ERR_FAIL_COND_V(interface == NULL, 0);
-
- if ((interface->version.major > 1) || ((interface->version.major) == 1 && (interface->version.minor >= 1))) {
- return (unsigned int)interface->get_camera_feed_id(data);
- } else {
- return 0;
- }
-}
-
-bool ARVRInterfaceGDNative::is_stereo() {
- bool stereo;
-
- ERR_FAIL_COND_V(interface == NULL, false);
-
- stereo = interface->is_stereo(data);
-
- return stereo;
-}
-
-bool ARVRInterfaceGDNative::is_initialized() const {
-
- ERR_FAIL_COND_V(interface == NULL, false);
-
- return interface->is_initialized(data);
-}
-
-bool ARVRInterfaceGDNative::initialize() {
- ERR_FAIL_COND_V(interface == NULL, false);
-
- bool initialized = interface->initialize(data);
-
- if (initialized) {
- // if we successfully initialize our interface and we don't have a primary interface yet, this becomes our primary interface
-
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if ((arvr_server != NULL) && (arvr_server->get_primary_interface() == NULL)) {
- arvr_server->set_primary_interface(this);
- };
- };
-
- return initialized;
-}
-
-void ARVRInterfaceGDNative::uninitialize() {
- ERR_FAIL_COND(interface == NULL);
-
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != NULL) {
- // Whatever happens, make sure this is no longer our primary interface
- arvr_server->clear_primary_interface_if(this);
- }
-
- interface->uninitialize(data);
-}
-
-Size2 ARVRInterfaceGDNative::get_render_targetsize() {
-
- ERR_FAIL_COND_V(interface == NULL, Size2());
-
- godot_vector2 result = interface->get_render_targetsize(data);
- Vector2 *vec = (Vector2 *)&result;
-
- return *vec;
-}
-
-Transform ARVRInterfaceGDNative::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
- Transform *ret;
-
- ERR_FAIL_COND_V(interface == NULL, Transform());
-
- godot_transform t = interface->get_transform_for_eye(data, (int)p_eye, (godot_transform *)&p_cam_transform);
-
- ret = (Transform *)&t;
-
- return *ret;
-}
-
-CameraMatrix ARVRInterfaceGDNative::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
- CameraMatrix cm;
-
- ERR_FAIL_COND_V(interface == NULL, CameraMatrix());
-
- interface->fill_projection_for_eye(data, (godot_real *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far);
-
- return cm;
-}
-
-unsigned int ARVRInterfaceGDNative::get_external_texture_for_eye(ARVRInterface::Eyes p_eye) {
-
- ERR_FAIL_COND_V(interface == NULL, 0);
-
- if ((interface->version.major > 1) || ((interface->version.major) == 1 && (interface->version.minor >= 1))) {
- return (unsigned int)interface->get_external_texture_for_eye(data, (godot_int)p_eye);
- } else {
- return 0;
- }
-}
-
-void ARVRInterfaceGDNative::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
-
- ERR_FAIL_COND(interface == NULL);
-
- interface->commit_for_eye(data, (godot_int)p_eye, (godot_rid *)&p_render_target, (godot_rect2 *)&p_screen_rect);
-}
-
-void ARVRInterfaceGDNative::process() {
- ERR_FAIL_COND(interface == NULL);
-
- interface->process(data);
-}
-
-void ARVRInterfaceGDNative::notification(int p_what) {
- ERR_FAIL_COND(interface == NULL);
-
- // this is only available in interfaces that implement 1.1 or later
- if ((interface->version.major > 1) || ((interface->version.major == 1) && (interface->version.minor > 0))) {
- interface->notification(data, p_what);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-// some helper callbacks
-
-extern "C" {
-
-void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface) {
- // If our major version is 0 or bigger then 10, we're likely looking at our constructor pointer from an older plugin
- ERR_FAIL_COND_MSG((p_interface->version.major == 0) || (p_interface->version.major > 10), "GDNative ARVR interfaces build for Godot 3.0 are not supported.");
-
- Ref<ARVRInterfaceGDNative> new_interface;
- new_interface.instance();
- new_interface->set_interface((const godot_arvr_interface_gdnative *)p_interface);
- ARVRServer::get_singleton()->add_interface(new_interface);
-}
-
-godot_real GDAPI godot_arvr_get_worldscale() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 1.0);
-
- return arvr_server->get_world_scale();
-}
-
-godot_transform GDAPI godot_arvr_get_reference_frame() {
- godot_transform reference_frame;
- Transform *reference_frame_ptr = (Transform *)&reference_frame;
-
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != NULL) {
- *reference_frame_ptr = arvr_server->get_reference_frame();
- } else {
- godot_transform_new_identity(&reference_frame);
- }
-
- return reference_frame;
-}
-
-void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) {
- // blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD
- ARVRInterface::Eyes eye = (ARVRInterface::Eyes)p_eye;
- RID *render_target = (RID *)p_render_target;
- Rect2 screen_rect = *(Rect2 *)p_rect;
-
- if (eye == ARVRInterface::EYE_LEFT) {
- screen_rect.size.x /= 2.0;
- } else if (p_eye == ARVRInterface::EYE_RIGHT) {
- screen_rect.size.x /= 2.0;
- screen_rect.position.x += screen_rect.size.x;
- }
-
- VSG::rasterizer->set_current_render_target(RID());
- VSG::rasterizer->blit_render_target_to_screen(*render_target, screen_rect, 0);
-}
-
-godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) {
- // In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID
- // This is a handy function to expose that.
- RID *render_target = (RID *)p_render_target;
-
- RID eye_texture = VSG::storage->render_target_get_texture(*render_target);
- uint32_t texid = VS::get_singleton()->texture_get_texid(eye_texture);
-
- return texid;
-}
-
-godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 0);
-
- InputDefault *input = (InputDefault *)Input::get_singleton();
- ERR_FAIL_NULL_V(input, 0);
-
- ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker);
- new_tracker->set_name(p_device_name);
- new_tracker->set_type(ARVRServer::TRACKER_CONTROLLER);
- if (p_hand == 1) {
- new_tracker->set_hand(ARVRPositionalTracker::TRACKER_LEFT_HAND);
- } else if (p_hand == 2) {
- new_tracker->set_hand(ARVRPositionalTracker::TRACKER_RIGHT_HAND);
- }
-
- // also register as joystick...
- int joyid = input->get_unused_joy_id();
- if (joyid != -1) {
- new_tracker->set_joy_id(joyid);
- input->joy_connection_changed(joyid, true, p_device_name, "");
- }
-
- if (p_tracks_orientation) {
- Basis orientation;
- new_tracker->set_orientation(orientation);
- }
- if (p_tracks_position) {
- Vector3 position;
- new_tracker->set_position(position);
- }
-
- // add our tracker to our server and remember its pointer
- arvr_server->add_tracker(new_tracker);
-
- // note, this ID is only unique within controllers!
- return new_tracker->get_tracker_id();
-}
-
-void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
-
- InputDefault *input = (InputDefault *)Input::get_singleton();
- ERR_FAIL_NULL(input);
-
- ARVRPositionalTracker *remove_tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
- if (remove_tracker != NULL) {
- // unset our joystick if applicable
- int joyid = remove_tracker->get_joy_id();
- if (joyid != -1) {
- input->joy_connection_changed(joyid, false, "", "");
- remove_tracker->set_joy_id(-1);
- }
-
- // remove our tracker from our server
- arvr_server->remove_tracker(remove_tracker);
- memdelete(remove_tracker);
- }
-}
-
-void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
-
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != NULL) {
- Transform *transform = (Transform *)p_transform;
- if (p_tracks_orientation) {
- tracker->set_orientation(transform->basis);
- }
- if (p_tracks_position) {
- tracker->set_rw_position(transform->origin);
- }
- }
-}
-
-void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
-
- InputDefault *input = (InputDefault *)Input::get_singleton();
- ERR_FAIL_NULL(input);
-
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != NULL) {
- int joyid = tracker->get_joy_id();
- if (joyid != -1) {
- input->joy_button(joyid, p_button, p_is_pressed);
- }
- }
-}
-
-void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL(arvr_server);
-
- InputDefault *input = (InputDefault *)Input::get_singleton();
- ERR_FAIL_NULL(input);
-
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != NULL) {
- int joyid = tracker->get_joy_id();
- if (joyid != -1) {
- InputDefault::JoyAxis jx;
- jx.min = p_can_be_negative ? -1 : 0;
- jx.value = p_value;
- input->joy_axis(joyid, p_axis, jx);
- }
- }
-}
-
-godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, 0.0);
-
- ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != NULL) {
- return tracker->get_rumble();
- }
-
- return 0.0;
-}
-}
diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py
index b9e5afcdf3..4b997e4bfe 100644
--- a/modules/gdnative/config.py
+++ b/modules/gdnative/config.py
@@ -1,13 +1,15 @@
def can_build(env, platform):
return True
+
def configure(env):
env.use_ptrcall = True
+
def get_doc_classes():
return [
"@NativeScript",
- "ARVRInterfaceGDNative",
+ "XRInterfaceGDNative",
"GDNative",
"GDNativeLibrary",
"MultiplayerPeerGDNative",
@@ -20,5 +22,6 @@ def get_doc_classes():
"WebRTCDataChannelGDNative",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
deleted file mode 100644
index e8405b64a3..0000000000
--- a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" version="4.0">
- <brief_description>
- GDNative wrapper for an ARVR interface.
- </brief_description>
- <description>
- This is a wrapper class for GDNative implementations of the ARVR interface. To use a GDNative ARVR interface, simply instantiate this object and set your GDNative library containing the ARVR interface implementation.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/gdnative/doc_classes/GDNative.xml b/modules/gdnative/doc_classes/GDNative.xml
index b4b63bf04a..44d9e32ed8 100644
--- a/modules/gdnative/doc_classes/GDNative.xml
+++ b/modules/gdnative/doc_classes/GDNative.xml
@@ -10,9 +10,9 @@
<method name="call_native">
<return type="Variant">
</return>
- <argument index="0" name="calling_type" type="String">
+ <argument index="0" name="calling_type" type="StringName">
</argument>
- <argument index="1" name="procedure_name" type="String">
+ <argument index="1" name="procedure_name" type="StringName">
</argument>
<argument index="2" name="arguments" type="Array">
</argument>
diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml
index 820f126dd1..1aab864102 100644
--- a/modules/gdnative/doc_classes/GDNativeLibrary.xml
+++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml
@@ -4,7 +4,7 @@
An external library containing functions or script classes to use in Godot.
</brief_description>
<description>
- A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as [ARVRInterfaceGDNative]. The library must be compiled for each platform and architecture that the project will run on.
+ A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as [XRInterfaceGDNative]. The library must be compiled for each platform and architecture that the project will run on.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-c-example.html</link>
@@ -12,7 +12,7 @@
</tutorials>
<methods>
<method name="get_current_dependencies" qualifiers="const">
- <return type="PoolStringArray">
+ <return type="PackedStringArray">
</return>
<description>
Returns paths to all dependency libraries for the current platform and architecture.
diff --git a/modules/gdnative/doc_classes/NativeScript.xml b/modules/gdnative/doc_classes/NativeScript.xml
index b21d16a6fd..f2e9cac6dc 100644
--- a/modules/gdnative/doc_classes/NativeScript.xml
+++ b/modules/gdnative/doc_classes/NativeScript.xml
@@ -17,7 +17,7 @@
<method name="get_method_documentation" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="method" type="String">
+ <argument index="0" name="method" type="StringName">
</argument>
<description>
Returns the documentation string that was previously set with [code]godot_nativescript_set_method_documentation[/code].
@@ -26,7 +26,7 @@
<method name="get_property_documentation" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="path" type="String">
+ <argument index="0" name="path" type="StringName">
</argument>
<description>
Returns the documentation string that was previously set with [code]godot_nativescript_set_property_documentation[/code].
@@ -35,7 +35,7 @@
<method name="get_signal_documentation" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="signal_name" type="String">
+ <argument index="0" name="signal_name" type="StringName">
</argument>
<description>
Returns the documentation string that was previously set with [code]godot_nativescript_set_signal_documentation[/code].
diff --git a/modules/gdnative/doc_classes/XRInterfaceGDNative.xml b/modules/gdnative/doc_classes/XRInterfaceGDNative.xml
new file mode 100644
index 0000000000..13de815793
--- /dev/null
+++ b/modules/gdnative/doc_classes/XRInterfaceGDNative.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="XRInterfaceGDNative" inherits="XRInterface" version="4.0">
+ <brief_description>
+ GDNative wrapper for an XR interface.
+ </brief_description>
+ <description>
+ This is a wrapper class for GDNative implementations of the XR interface. To use a GDNative XR interface, simply instantiate this object and set your GDNative library containing the XR interface implementation.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 1571b821a5..a131e3a78f 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -48,7 +48,7 @@ static const bool default_reloadable = true;
// Defined in gdnative_api_struct.gen.cpp
extern const godot_gdnative_core_api_struct api_struct;
-Map<String, Vector<Ref<GDNative> > > GDNativeLibrary::loaded_libraries;
+Map<String, Vector<Ref<GDNative>>> GDNativeLibrary::loaded_libraries;
GDNativeLibrary::GDNativeLibrary() {
config_file.instance();
@@ -248,7 +248,7 @@ void GDNativeLibrary::_bind_methods() {
}
GDNative::GDNative() {
- native_handle = NULL;
+ native_handle = nullptr;
initialized = false;
}
@@ -338,7 +338,7 @@ bool GDNative::initialize() {
if (err || !library_init) {
OS::get_singleton()->close_dynamic_library(native_handle);
- native_handle = NULL;
+ native_handle = nullptr;
ERR_PRINT("Failed to obtain " + library->get_symbol_prefix() + "gdnative_init symbol");
return false;
}
@@ -373,7 +373,7 @@ bool GDNative::initialize() {
initialized = true;
if (library->should_load_once() && !GDNativeLibrary::loaded_libraries.has(lib_path)) {
- Vector<Ref<GDNative> > gdnatives;
+ Vector<Ref<GDNative>> gdnatives;
gdnatives.resize(1);
gdnatives.write[0] = Ref<GDNative>(this);
GDNativeLibrary::loaded_libraries.insert(lib_path, gdnatives);
@@ -390,7 +390,7 @@ bool GDNative::terminate() {
}
if (library->should_load_once()) {
- Vector<Ref<GDNative> > *gdnatives = &GDNativeLibrary::loaded_libraries[library->get_current_library_path()];
+ Vector<Ref<GDNative>> *gdnatives = &GDNativeLibrary::loaded_libraries[library->get_current_library_path()];
if (gdnatives->size() > 1) {
// there are other GDNative's still using this library, so we actually don't terminate
gdnatives->erase(Ref<GDNative>(this));
@@ -408,7 +408,7 @@ bool GDNative::terminate() {
Error error = get_symbol(library->get_symbol_prefix() + terminate_symbol, library_terminate);
if (error || !library_terminate) {
OS::get_singleton()->close_dynamic_library(native_handle);
- native_handle = NULL;
+ native_handle = nullptr;
initialized = false;
return true;
}
@@ -426,7 +426,7 @@ bool GDNative::terminate() {
// GDNativeScriptLanguage::get_singleton()->initialized_libraries.erase(p_native_lib->path);
OS::get_singleton()->close_dynamic_library(native_handle);
- native_handle = NULL;
+ native_handle = nullptr;
return true;
}
@@ -466,7 +466,7 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced
p_procedure_name,
procedure_handle);
- if (err != OK || procedure_handle == NULL) {
+ if (err != OK || procedure_handle == nullptr) {
return Variant();
}
@@ -493,7 +493,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_
return result;
}
-RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
Ref<GDNativeLibrary> lib;
lib.instance();
@@ -544,11 +544,11 @@ Error GDNativeLibraryResourceSaver::save(const String &p_path, const RES &p_reso
}
bool GDNativeLibraryResourceSaver::recognize(const RES &p_resource) const {
- return Object::cast_to<GDNativeLibrary>(*p_resource) != NULL;
+ return Object::cast_to<GDNativeLibrary>(*p_resource) != nullptr;
}
void GDNativeLibraryResourceSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
- if (Object::cast_to<GDNativeLibrary>(*p_resource) != NULL) {
+ if (Object::cast_to<GDNativeLibrary>(*p_resource) != nullptr) {
p_extensions->push_back("gdnlib");
}
}
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index c0c2cdf24c..6d26c2141d 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -47,7 +47,7 @@ class GDNative;
class GDNativeLibrary : public Resource {
GDCLASS(GDNativeLibrary, Resource);
- static Map<String, Vector<Ref<GDNative> > > loaded_libraries;
+ static Map<String, Vector<Ref<GDNative>>> loaded_libraries;
friend class GDNativeLibraryResourceLoader;
friend class GDNative;
@@ -166,7 +166,7 @@ public:
class GDNativeLibraryResourceLoader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 4a0308edec..0c764ab8fd 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -34,7 +34,6 @@
#include "core/os/memory.h"
#include "core/color.h"
-#include "core/pool_vector.h"
#include "core/variant.h"
@@ -53,9 +52,9 @@ void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src) {
memnew_placement(dest, Array(*src));
}
-void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_pool_color_array *p_pca) {
+void GDAPI godot_array_new_packed_color_array(godot_array *r_dest, const godot_packed_color_array *p_pca) {
Array *dest = (Array *)r_dest;
- PoolVector<Color> *pca = (PoolVector<Color> *)p_pca;
+ Vector<Color> *pca = (Vector<Color> *)p_pca;
memnew_placement(dest, Array);
dest->resize(pca->size());
@@ -65,9 +64,9 @@ void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_poo
}
}
-void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_pool_vector3_array *p_pv3a) {
+void GDAPI godot_array_new_packed_vector3_array(godot_array *r_dest, const godot_packed_vector3_array *p_pv3a) {
Array *dest = (Array *)r_dest;
- PoolVector<Vector3> *pca = (PoolVector<Vector3> *)p_pv3a;
+ Vector<Vector3> *pca = (Vector<Vector3> *)p_pv3a;
memnew_placement(dest, Array);
dest->resize(pca->size());
@@ -77,9 +76,9 @@ void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_p
}
}
-void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_pool_vector2_array *p_pv2a) {
+void GDAPI godot_array_new_packed_vector2_array(godot_array *r_dest, const godot_packed_vector2_array *p_pv2a) {
Array *dest = (Array *)r_dest;
- PoolVector<Vector2> *pca = (PoolVector<Vector2> *)p_pv2a;
+ Vector<Vector2> *pca = (Vector<Vector2> *)p_pv2a;
memnew_placement(dest, Array);
dest->resize(pca->size());
@@ -89,9 +88,9 @@ void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_p
}
}
-void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_pool_string_array *p_psa) {
+void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_packed_string_array *p_psa) {
Array *dest = (Array *)r_dest;
- PoolVector<String> *pca = (PoolVector<String> *)p_psa;
+ Vector<String> *pca = (Vector<String> *)p_psa;
memnew_placement(dest, Array);
dest->resize(pca->size());
@@ -101,9 +100,9 @@ void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_po
}
}
-void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool_real_array *p_pra) {
+void GDAPI godot_array_new_packed_real_array(godot_array *r_dest, const godot_packed_real_array *p_pra) {
Array *dest = (Array *)r_dest;
- PoolVector<godot_real> *pca = (PoolVector<godot_real> *)p_pra;
+ Vector<godot_real> *pca = (Vector<godot_real> *)p_pra;
memnew_placement(dest, Array);
dest->resize(pca->size());
@@ -113,9 +112,9 @@ void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool
}
}
-void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_int_array *p_pia) {
+void GDAPI godot_array_new_packed_int_array(godot_array *r_dest, const godot_packed_int_array *p_pia) {
Array *dest = (Array *)r_dest;
- PoolVector<godot_int> *pca = (PoolVector<godot_int> *)p_pia;
+ Vector<godot_int> *pca = (Vector<godot_int> *)p_pia;
memnew_placement(dest, Array);
dest->resize(pca->size());
@@ -125,9 +124,9 @@ void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_
}
}
-void GDAPI godot_array_new_pool_byte_array(godot_array *r_dest, const godot_pool_byte_array *p_pba) {
+void GDAPI godot_array_new_packed_byte_array(godot_array *r_dest, const godot_packed_byte_array *p_pba) {
Array *dest = (Array *)r_dest;
- PoolVector<uint8_t> *pca = (PoolVector<uint8_t> *)p_pba;
+ Vector<uint8_t> *pca = (Vector<uint8_t> *)p_pba;
memnew_placement(dest, Array);
dest->resize(pca->size());
diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp
index 24587ce4a1..914d5b03f4 100644
--- a/modules/gdnative/gdnative/color.cpp
+++ b/modules/gdnative/gdnative/color.cpp
@@ -141,11 +141,6 @@ godot_int GDAPI godot_color_to_argb32(const godot_color *p_self) {
return self->to_argb32();
}
-godot_real GDAPI godot_color_gray(const godot_color *p_self) {
- const Color *self = (const Color *)p_self;
- return self->gray();
-}
-
godot_color GDAPI godot_color_inverted(const godot_color *p_self) {
godot_color dest;
const Color *self = (const Color *)p_self;
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 06334556d9..3175340448 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -79,7 +79,7 @@ godot_variant GDAPI godot_method_bind_call(godot_method_bind *p_method_bind, god
Variant *ret_val = (Variant *)&ret;
- Variant::CallError r_error;
+ Callable::CallError r_error;
*ret_val = mb->call(o, args, p_arg_count, r_error);
if (p_call_error) {
@@ -95,7 +95,7 @@ godot_class_constructor GDAPI godot_get_class_constructor(const char *p_classnam
ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname));
if (class_info)
return (godot_class_constructor)class_info->creation_func;
- return NULL;
+ return nullptr;
}
godot_dictionary GDAPI godot_get_global_constants() {
@@ -166,25 +166,21 @@ void _gdnative_report_loading_error(const godot_object *p_library, const char *p
_err_print_error("gdnative_init", library->get_current_library_path().utf8().ptr(), 0, message.utf8().ptr());
}
-bool GDAPI godot_is_instance_valid(const godot_object *p_object) {
- return ObjectDB::instance_validate((Object *)p_object);
-}
-
godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id) {
- return (godot_object *)ObjectDB::get_instance((ObjectID)p_instance_id);
+ return (godot_object *)ObjectDB::get_instance(ObjectID(p_instance_id));
}
void *godot_get_class_tag(const godot_string_name *p_class) {
StringName class_name = *(StringName *)p_class;
ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(class_name);
- return class_info ? class_info->class_ptr : NULL;
+ return class_info ? class_info->class_ptr : nullptr;
}
godot_object *godot_object_cast_to(const godot_object *p_object, void *p_class_tag) {
- if (!p_object) return NULL;
+ if (!p_object) return nullptr;
Object *o = (Object *)p_object;
- return o->is_class_ptr(p_class_tag) ? (godot_object *)o : NULL;
+ return o->is_class_ptr(p_class_tag) ? (godot_object *)o : nullptr;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp
index bae1290d59..589b4d4dfe 100644
--- a/modules/gdnative/gdnative/pool_arrays.cpp
+++ b/modules/gdnative/gdnative/pool_arrays.cpp
@@ -31,7 +31,7 @@
#include "gdnative/pool_arrays.h"
#include "core/array.h"
-#include "core/pool_vector.h"
+
#include "core/variant.h"
#include "core/color.h"
@@ -46,21 +46,21 @@ extern "C" {
// byte
-void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *r_dest) {
- PoolVector<uint8_t> *dest = (PoolVector<uint8_t> *)r_dest;
- memnew_placement(dest, PoolVector<uint8_t>);
+void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *r_dest) {
+ Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest;
+ memnew_placement(dest, Vector<uint8_t>);
}
-void GDAPI godot_pool_byte_array_new_copy(godot_pool_byte_array *r_dest, const godot_pool_byte_array *p_src) {
- PoolVector<uint8_t> *dest = (PoolVector<uint8_t> *)r_dest;
- const PoolVector<uint8_t> *src = (const PoolVector<uint8_t> *)p_src;
- memnew_placement(dest, PoolVector<uint8_t>(*src));
+void GDAPI godot_packed_byte_array_new_copy(godot_packed_byte_array *r_dest, const godot_packed_byte_array *p_src) {
+ Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest;
+ const Vector<uint8_t> *src = (const Vector<uint8_t> *)p_src;
+ memnew_placement(dest, Vector<uint8_t>(*src));
}
-void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *r_dest, const godot_array *p_a) {
- PoolVector<uint8_t> *dest = (PoolVector<uint8_t> *)r_dest;
+void GDAPI godot_packed_byte_array_new_with_array(godot_packed_byte_array *r_dest, const godot_array *p_a) {
+ Vector<uint8_t> *dest = (Vector<uint8_t> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, PoolVector<uint8_t>);
+ memnew_placement(dest, Vector<uint8_t>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -68,93 +68,83 @@ void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *r_dest, c
}
}
-void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_self, const uint8_t p_data) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
- self->append(p_data);
+void GDAPI godot_packed_byte_array_append(godot_packed_byte_array *p_self, const uint8_t p_data) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
+ self->push_back(p_data);
}
-void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_self, const godot_pool_byte_array *p_array) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
- PoolVector<uint8_t> *array = (PoolVector<uint8_t> *)p_array;
+void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self, const godot_packed_byte_array *p_array) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
+ Vector<uint8_t> *array = (Vector<uint8_t> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_self) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
self->invert();
}
-void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_self, const uint8_t p_data) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
self->push_back(p_data);
}
-void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_self, const godot_int p_idx) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+void GDAPI godot_packed_byte_array_remove(godot_packed_byte_array *p_self, const godot_int p_idx) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_self, const godot_int p_size) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+void GDAPI godot_packed_byte_array_resize(godot_packed_byte_array *p_self, const godot_int p_size) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
self->resize(p_size);
}
-godot_pool_byte_array_read_access GDAPI *godot_pool_byte_array_read(const godot_pool_byte_array *p_self) {
- const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
- return (godot_pool_byte_array_read_access *)memnew(PoolVector<uint8_t>::Read(self->read()));
-}
-
-godot_pool_byte_array_write_access GDAPI *godot_pool_byte_array_write(godot_pool_byte_array *p_self) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
- return (godot_pool_byte_array_write_access *)memnew(PoolVector<uint8_t>::Write(self->write()));
-}
-
-void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
- PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+void GDAPI godot_packed_byte_array_set(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
+ Vector<uint8_t> *self = (Vector<uint8_t> *)p_self;
self->set(p_idx, p_data);
}
-uint8_t GDAPI godot_pool_byte_array_get(const godot_pool_byte_array *p_self, const godot_int p_idx) {
- const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
+uint8_t GDAPI godot_packed_byte_array_get(const godot_packed_byte_array *p_self, const godot_int p_idx) {
+ const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self;
return self->get(p_idx);
}
-godot_int GDAPI godot_pool_byte_array_size(const godot_pool_byte_array *p_self) {
- const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
+godot_int GDAPI godot_packed_byte_array_size(const godot_packed_byte_array *p_self) {
+ const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_pool_byte_array_empty(const godot_pool_byte_array *p_self) {
- const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
+godot_bool GDAPI godot_packed_byte_array_empty(const godot_packed_byte_array *p_self) {
+ const Vector<uint8_t> *self = (const Vector<uint8_t> *)p_self;
return self->empty();
}
-void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_self) {
- ((PoolVector<uint8_t> *)p_self)->~PoolVector();
+void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self) {
+ ((Vector<uint8_t> *)p_self)->~Vector();
}
// int
-void GDAPI godot_pool_int_array_new(godot_pool_int_array *r_dest) {
- PoolVector<godot_int> *dest = (PoolVector<godot_int> *)r_dest;
- memnew_placement(dest, PoolVector<godot_int>);
+void GDAPI godot_packed_int_array_new(godot_packed_int_array *r_dest) {
+ Vector<godot_int> *dest = (Vector<godot_int> *)r_dest;
+ memnew_placement(dest, Vector<godot_int>);
}
-void GDAPI godot_pool_int_array_new_copy(godot_pool_int_array *r_dest, const godot_pool_int_array *p_src) {
- PoolVector<godot_int> *dest = (PoolVector<godot_int> *)r_dest;
- const PoolVector<godot_int> *src = (const PoolVector<godot_int> *)p_src;
- memnew_placement(dest, PoolVector<godot_int>(*src));
+void GDAPI godot_packed_int_array_new_copy(godot_packed_int_array *r_dest, const godot_packed_int_array *p_src) {
+ Vector<godot_int> *dest = (Vector<godot_int> *)r_dest;
+ const Vector<godot_int> *src = (const Vector<godot_int> *)p_src;
+ memnew_placement(dest, Vector<godot_int>(*src));
}
-void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *r_dest, const godot_array *p_a) {
- PoolVector<godot_int> *dest = (PoolVector<godot_int> *)r_dest;
+void GDAPI godot_packed_int_array_new_with_array(godot_packed_int_array *r_dest, const godot_array *p_a) {
+ Vector<godot_int> *dest = (Vector<godot_int> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, PoolVector<godot_int>);
+ memnew_placement(dest, Vector<godot_int>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -162,93 +152,83 @@ void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *r_dest, con
}
}
-void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_self, const godot_int p_data) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
- self->append(p_data);
+void GDAPI godot_packed_int_array_append(godot_packed_int_array *p_self, const godot_int p_data) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+ self->push_back(p_data);
}
-void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_self, const godot_pool_int_array *p_array) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
- PoolVector<godot_int> *array = (PoolVector<godot_int> *)p_array;
+void GDAPI godot_packed_int_array_append_array(godot_packed_int_array *p_self, const godot_packed_int_array *p_array) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+ Vector<godot_int> *array = (Vector<godot_int> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+godot_error GDAPI godot_packed_int_array_insert(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_self) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+void GDAPI godot_packed_int_array_invert(godot_packed_int_array *p_self) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
self->invert();
}
-void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_self, const godot_int p_data) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+void GDAPI godot_packed_int_array_push_back(godot_packed_int_array *p_self, const godot_int p_data) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
self->push_back(p_data);
}
-void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_self, const godot_int p_idx) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+void GDAPI godot_packed_int_array_remove(godot_packed_int_array *p_self, const godot_int p_idx) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_self, const godot_int p_size) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+void GDAPI godot_packed_int_array_resize(godot_packed_int_array *p_self, const godot_int p_size) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
self->resize(p_size);
}
-godot_pool_int_array_read_access GDAPI *godot_pool_int_array_read(const godot_pool_int_array *p_self) {
- const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
- return (godot_pool_int_array_read_access *)memnew(PoolVector<godot_int>::Read(self->read()));
-}
-
-godot_pool_int_array_write_access GDAPI *godot_pool_int_array_write(godot_pool_int_array *p_self) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
- return (godot_pool_int_array_write_access *)memnew(PoolVector<godot_int>::Write(self->write()));
-}
-
-void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
- PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+void GDAPI godot_packed_int_array_set(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
+ Vector<godot_int> *self = (Vector<godot_int> *)p_self;
self->set(p_idx, p_data);
}
-godot_int GDAPI godot_pool_int_array_get(const godot_pool_int_array *p_self, const godot_int p_idx) {
- const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
+godot_int GDAPI godot_packed_int_array_get(const godot_packed_int_array *p_self, const godot_int p_idx) {
+ const Vector<godot_int> *self = (const Vector<godot_int> *)p_self;
return self->get(p_idx);
}
-godot_int GDAPI godot_pool_int_array_size(const godot_pool_int_array *p_self) {
- const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
+godot_int GDAPI godot_packed_int_array_size(const godot_packed_int_array *p_self) {
+ const Vector<godot_int> *self = (const Vector<godot_int> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_pool_int_array_empty(const godot_pool_int_array *p_self) {
- const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
+godot_bool GDAPI godot_packed_int_array_empty(const godot_packed_int_array *p_self) {
+ const Vector<godot_int> *self = (const Vector<godot_int> *)p_self;
return self->empty();
}
-void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_self) {
- ((PoolVector<godot_int> *)p_self)->~PoolVector();
+void GDAPI godot_packed_int_array_destroy(godot_packed_int_array *p_self) {
+ ((Vector<godot_int> *)p_self)->~Vector();
}
// real
-void GDAPI godot_pool_real_array_new(godot_pool_real_array *r_dest) {
- PoolVector<godot_real> *dest = (PoolVector<godot_real> *)r_dest;
- memnew_placement(dest, PoolVector<godot_real>);
+void GDAPI godot_packed_real_array_new(godot_packed_real_array *r_dest) {
+ Vector<godot_real> *dest = (Vector<godot_real> *)r_dest;
+ memnew_placement(dest, Vector<godot_real>);
}
-void GDAPI godot_pool_real_array_new_copy(godot_pool_real_array *r_dest, const godot_pool_real_array *p_src) {
- PoolVector<godot_real> *dest = (PoolVector<godot_real> *)r_dest;
- const PoolVector<godot_real> *src = (const PoolVector<godot_real> *)p_src;
- memnew_placement(dest, PoolVector<godot_real>(*src));
+void GDAPI godot_packed_real_array_new_copy(godot_packed_real_array *r_dest, const godot_packed_real_array *p_src) {
+ Vector<godot_real> *dest = (Vector<godot_real> *)r_dest;
+ const Vector<godot_real> *src = (const Vector<godot_real> *)p_src;
+ memnew_placement(dest, Vector<godot_real>(*src));
}
-void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *r_dest, const godot_array *p_a) {
- PoolVector<godot_real> *dest = (PoolVector<godot_real> *)r_dest;
+void GDAPI godot_packed_real_array_new_with_array(godot_packed_real_array *r_dest, const godot_array *p_a) {
+ Vector<godot_real> *dest = (Vector<godot_real> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, PoolVector<godot_real>);
+ memnew_placement(dest, Vector<godot_real>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -256,93 +236,83 @@ void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *r_dest, c
}
}
-void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_self, const godot_real p_data) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
- self->append(p_data);
+void GDAPI godot_packed_real_array_append(godot_packed_real_array *p_self, const godot_real p_data) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+ self->push_back(p_data);
}
-void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_self, const godot_pool_real_array *p_array) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
- PoolVector<godot_real> *array = (PoolVector<godot_real> *)p_array;
+void GDAPI godot_packed_real_array_append_array(godot_packed_real_array *p_self, const godot_packed_real_array *p_array) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+ Vector<godot_real> *array = (Vector<godot_real> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+godot_error GDAPI godot_packed_real_array_insert(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_self) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+void GDAPI godot_packed_real_array_invert(godot_packed_real_array *p_self) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
self->invert();
}
-void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_self, const godot_real p_data) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+void GDAPI godot_packed_real_array_push_back(godot_packed_real_array *p_self, const godot_real p_data) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
self->push_back(p_data);
}
-void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_self, const godot_int p_idx) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+void GDAPI godot_packed_real_array_remove(godot_packed_real_array *p_self, const godot_int p_idx) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_self, const godot_int p_size) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+void GDAPI godot_packed_real_array_resize(godot_packed_real_array *p_self, const godot_int p_size) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
self->resize(p_size);
}
-godot_pool_real_array_read_access GDAPI *godot_pool_real_array_read(const godot_pool_real_array *p_self) {
- const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
- return (godot_pool_real_array_read_access *)memnew(PoolVector<godot_real>::Read(self->read()));
-}
-
-godot_pool_int_array_write_access GDAPI *godot_pool_real_array_write(godot_pool_real_array *p_self) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
- return (godot_pool_real_array_write_access *)memnew(PoolVector<godot_real>::Write(self->write()));
-}
-
-void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
- PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+void GDAPI godot_packed_real_array_set(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
+ Vector<godot_real> *self = (Vector<godot_real> *)p_self;
self->set(p_idx, p_data);
}
-godot_real GDAPI godot_pool_real_array_get(const godot_pool_real_array *p_self, const godot_int p_idx) {
- const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
+godot_real GDAPI godot_packed_real_array_get(const godot_packed_real_array *p_self, const godot_int p_idx) {
+ const Vector<godot_real> *self = (const Vector<godot_real> *)p_self;
return self->get(p_idx);
}
-godot_int GDAPI godot_pool_real_array_size(const godot_pool_real_array *p_self) {
- const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
+godot_int GDAPI godot_packed_real_array_size(const godot_packed_real_array *p_self) {
+ const Vector<godot_real> *self = (const Vector<godot_real> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_pool_real_array_empty(const godot_pool_real_array *p_self) {
- const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
+godot_bool GDAPI godot_packed_real_array_empty(const godot_packed_real_array *p_self) {
+ const Vector<godot_real> *self = (const Vector<godot_real> *)p_self;
return self->empty();
}
-void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_self) {
- ((PoolVector<godot_real> *)p_self)->~PoolVector();
+void GDAPI godot_packed_real_array_destroy(godot_packed_real_array *p_self) {
+ ((Vector<godot_real> *)p_self)->~Vector();
}
// string
-void GDAPI godot_pool_string_array_new(godot_pool_string_array *r_dest) {
- PoolVector<String> *dest = (PoolVector<String> *)r_dest;
- memnew_placement(dest, PoolVector<String>);
+void GDAPI godot_packed_string_array_new(godot_packed_string_array *r_dest) {
+ Vector<String> *dest = (Vector<String> *)r_dest;
+ memnew_placement(dest, Vector<String>);
}
-void GDAPI godot_pool_string_array_new_copy(godot_pool_string_array *r_dest, const godot_pool_string_array *p_src) {
- PoolVector<String> *dest = (PoolVector<String> *)r_dest;
- const PoolVector<String> *src = (const PoolVector<String> *)p_src;
- memnew_placement(dest, PoolVector<String>(*src));
+void GDAPI godot_packed_string_array_new_copy(godot_packed_string_array *r_dest, const godot_packed_string_array *p_src) {
+ Vector<String> *dest = (Vector<String> *)r_dest;
+ const Vector<String> *src = (const Vector<String> *)p_src;
+ memnew_placement(dest, Vector<String>(*src));
}
-void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *r_dest, const godot_array *p_a) {
- PoolVector<String> *dest = (PoolVector<String> *)r_dest;
+void GDAPI godot_packed_string_array_new_with_array(godot_packed_string_array *r_dest, const godot_array *p_a) {
+ Vector<String> *dest = (Vector<String> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, PoolVector<String>);
+ memnew_placement(dest, Vector<String>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -350,63 +320,53 @@ void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *r_des
}
}
-void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_self, const godot_string *p_data) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
+void GDAPI godot_packed_string_array_append(godot_packed_string_array *p_self, const godot_string *p_data) {
+ Vector<String> *self = (Vector<String> *)p_self;
String &s = *(String *)p_data;
- self->append(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_self, const godot_pool_string_array *p_array) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
- PoolVector<String> *array = (PoolVector<String> *)p_array;
+void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_self, const godot_packed_string_array *p_array) {
+ Vector<String> *self = (Vector<String> *)p_self;
+ Vector<String> *array = (Vector<String> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
+godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
+ Vector<String> *self = (Vector<String> *)p_self;
String &s = *(String *)p_data;
return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_self) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
+void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self) {
+ Vector<String> *self = (Vector<String> *)p_self;
self->invert();
}
-void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_self, const godot_string *p_data) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
+void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data) {
+ Vector<String> *self = (Vector<String> *)p_self;
String &s = *(String *)p_data;
self->push_back(s);
}
-void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_self, const godot_int p_idx) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
+void GDAPI godot_packed_string_array_remove(godot_packed_string_array *p_self, const godot_int p_idx) {
+ Vector<String> *self = (Vector<String> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_self, const godot_int p_size) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
+void GDAPI godot_packed_string_array_resize(godot_packed_string_array *p_self, const godot_int p_size) {
+ Vector<String> *self = (Vector<String> *)p_self;
self->resize(p_size);
}
-godot_pool_string_array_read_access GDAPI *godot_pool_string_array_read(const godot_pool_string_array *p_self) {
- const PoolVector<String> *self = (const PoolVector<String> *)p_self;
- return (godot_pool_string_array_read_access *)memnew(PoolVector<String>::Read(self->read()));
-}
-
-godot_pool_string_array_write_access GDAPI *godot_pool_string_array_write(godot_pool_string_array *p_self) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
- return (godot_pool_string_array_write_access *)memnew(PoolVector<String>::Write(self->write()));
-}
-
-void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
- PoolVector<String> *self = (PoolVector<String> *)p_self;
+void GDAPI godot_packed_string_array_set(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
+ Vector<String> *self = (Vector<String> *)p_self;
String &s = *(String *)p_data;
self->set(p_idx, s);
}
-godot_string GDAPI godot_pool_string_array_get(const godot_pool_string_array *p_self, const godot_int p_idx) {
- const PoolVector<String> *self = (const PoolVector<String> *)p_self;
+godot_string GDAPI godot_packed_string_array_get(const godot_packed_string_array *p_self, const godot_int p_idx) {
+ const Vector<String> *self = (const Vector<String> *)p_self;
godot_string str;
String *s = (String *)&str;
memnew_placement(s, String);
@@ -414,37 +374,37 @@ godot_string GDAPI godot_pool_string_array_get(const godot_pool_string_array *p_
return str;
}
-godot_int GDAPI godot_pool_string_array_size(const godot_pool_string_array *p_self) {
- const PoolVector<String> *self = (const PoolVector<String> *)p_self;
+godot_int GDAPI godot_packed_string_array_size(const godot_packed_string_array *p_self) {
+ const Vector<String> *self = (const Vector<String> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_pool_string_array_empty(const godot_pool_string_array *p_self) {
- const PoolVector<String> *self = (const PoolVector<String> *)p_self;
+godot_bool GDAPI godot_packed_string_array_empty(const godot_packed_string_array *p_self) {
+ const Vector<String> *self = (const Vector<String> *)p_self;
return self->empty();
}
-void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_self) {
- ((PoolVector<String> *)p_self)->~PoolVector();
+void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self) {
+ ((Vector<String> *)p_self)->~Vector();
}
// vector2
-void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *r_dest) {
- PoolVector<Vector2> *dest = (PoolVector<Vector2> *)r_dest;
- memnew_placement(dest, PoolVector<Vector2>);
+void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *r_dest) {
+ Vector<Vector2> *dest = (Vector<Vector2> *)r_dest;
+ memnew_placement(dest, Vector<Vector2>);
}
-void GDAPI godot_pool_vector2_array_new_copy(godot_pool_vector2_array *r_dest, const godot_pool_vector2_array *p_src) {
- PoolVector<Vector2> *dest = (PoolVector<Vector2> *)r_dest;
- const PoolVector<Vector2> *src = (const PoolVector<Vector2> *)p_src;
- memnew_placement(dest, PoolVector<Vector2>(*src));
+void GDAPI godot_packed_vector2_array_new_copy(godot_packed_vector2_array *r_dest, const godot_packed_vector2_array *p_src) {
+ Vector<Vector2> *dest = (Vector<Vector2> *)r_dest;
+ const Vector<Vector2> *src = (const Vector<Vector2> *)p_src;
+ memnew_placement(dest, Vector<Vector2>(*src));
}
-void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *r_dest, const godot_array *p_a) {
- PoolVector<Vector2> *dest = (PoolVector<Vector2> *)r_dest;
+void GDAPI godot_packed_vector2_array_new_with_array(godot_packed_vector2_array *r_dest, const godot_array *p_a) {
+ Vector<Vector2> *dest = (Vector<Vector2> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, PoolVector<Vector2>);
+ memnew_placement(dest, Vector<Vector2>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -452,100 +412,90 @@ void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *r_d
}
}
-void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_self, const godot_vector2 *p_data) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+void GDAPI godot_packed_vector2_array_append(godot_packed_vector2_array *p_self, const godot_vector2 *p_data) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
- self->append(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_self, const godot_pool_vector2_array *p_array) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
- PoolVector<Vector2> *array = (PoolVector<Vector2> *)p_array;
+void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p_self, const godot_packed_vector2_array *p_array) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
+ Vector<Vector2> *array = (Vector<Vector2> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_self) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
self->invert();
}
-void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_self, const godot_vector2 *p_data) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
self->push_back(s);
}
-void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_self, const godot_int p_idx) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+void GDAPI godot_packed_vector2_array_remove(godot_packed_vector2_array *p_self, const godot_int p_idx) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_self, const godot_int p_size) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+void GDAPI godot_packed_vector2_array_resize(godot_packed_vector2_array *p_self, const godot_int p_size) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
self->resize(p_size);
}
-godot_pool_vector2_array_read_access GDAPI *godot_pool_vector2_array_read(const godot_pool_vector2_array *p_self) {
- const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
- return (godot_pool_vector2_array_read_access *)memnew(PoolVector<Vector2>::Read(self->read()));
-}
-
-godot_pool_vector2_array_write_access GDAPI *godot_pool_vector2_array_write(godot_pool_vector2_array *p_self) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
- return (godot_pool_vector2_array_write_access *)memnew(PoolVector<Vector2>::Write(self->write()));
-}
-
-void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
- PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+void GDAPI godot_packed_vector2_array_set(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
+ Vector<Vector2> *self = (Vector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
self->set(p_idx, s);
}
-godot_vector2 GDAPI godot_pool_vector2_array_get(const godot_pool_vector2_array *p_self, const godot_int p_idx) {
- const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
+godot_vector2 GDAPI godot_packed_vector2_array_get(const godot_packed_vector2_array *p_self, const godot_int p_idx) {
+ const Vector<Vector2> *self = (const Vector<Vector2> *)p_self;
godot_vector2 v;
Vector2 *s = (Vector2 *)&v;
*s = self->get(p_idx);
return v;
}
-godot_int GDAPI godot_pool_vector2_array_size(const godot_pool_vector2_array *p_self) {
- const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
+godot_int GDAPI godot_packed_vector2_array_size(const godot_packed_vector2_array *p_self) {
+ const Vector<Vector2> *self = (const Vector<Vector2> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_pool_vector2_array_empty(const godot_pool_vector2_array *p_self) {
- const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
+godot_bool GDAPI godot_packed_vector2_array_empty(const godot_packed_vector2_array *p_self) {
+ const Vector<Vector2> *self = (const Vector<Vector2> *)p_self;
return self->empty();
}
-void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_self) {
- ((PoolVector<Vector2> *)p_self)->~PoolVector();
+void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self) {
+ ((Vector<Vector2> *)p_self)->~Vector();
}
// vector3
-void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *r_dest) {
- PoolVector<Vector3> *dest = (PoolVector<Vector3> *)r_dest;
- memnew_placement(dest, PoolVector<Vector3>);
+void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *r_dest) {
+ Vector<Vector3> *dest = (Vector<Vector3> *)r_dest;
+ memnew_placement(dest, Vector<Vector3>);
}
-void GDAPI godot_pool_vector3_array_new_copy(godot_pool_vector3_array *r_dest, const godot_pool_vector3_array *p_src) {
- PoolVector<Vector3> *dest = (PoolVector<Vector3> *)r_dest;
- const PoolVector<Vector3> *src = (const PoolVector<Vector3> *)p_src;
- memnew_placement(dest, PoolVector<Vector3>(*src));
+void GDAPI godot_packed_vector3_array_new_copy(godot_packed_vector3_array *r_dest, const godot_packed_vector3_array *p_src) {
+ Vector<Vector3> *dest = (Vector<Vector3> *)r_dest;
+ const Vector<Vector3> *src = (const Vector<Vector3> *)p_src;
+ memnew_placement(dest, Vector<Vector3>(*src));
}
-void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *r_dest, const godot_array *p_a) {
- PoolVector<Vector3> *dest = (PoolVector<Vector3> *)r_dest;
+void GDAPI godot_packed_vector3_array_new_with_array(godot_packed_vector3_array *r_dest, const godot_array *p_a) {
+ Vector<Vector3> *dest = (Vector<Vector3> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, PoolVector<Vector3>);
+ memnew_placement(dest, Vector<Vector3>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -553,100 +503,90 @@ void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *r_d
}
}
-void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_self, const godot_vector3 *p_data) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+void GDAPI godot_packed_vector3_array_append(godot_packed_vector3_array *p_self, const godot_vector3 *p_data) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
- self->append(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_self, const godot_pool_vector3_array *p_array) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
- PoolVector<Vector3> *array = (PoolVector<Vector3> *)p_array;
+void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p_self, const godot_packed_vector3_array *p_array) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
+ Vector<Vector3> *array = (Vector<Vector3> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_self) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
self->invert();
}
-void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_self, const godot_vector3 *p_data) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
self->push_back(s);
}
-void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_self, const godot_int p_idx) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+void GDAPI godot_packed_vector3_array_remove(godot_packed_vector3_array *p_self, const godot_int p_idx) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_self, const godot_int p_size) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+void GDAPI godot_packed_vector3_array_resize(godot_packed_vector3_array *p_self, const godot_int p_size) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
self->resize(p_size);
}
-godot_pool_vector3_array_read_access GDAPI *godot_pool_vector3_array_read(const godot_pool_vector3_array *p_self) {
- const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
- return (godot_pool_vector3_array_read_access *)memnew(PoolVector<Vector3>::Read(self->read()));
-}
-
-godot_pool_vector3_array_write_access GDAPI *godot_pool_vector3_array_write(godot_pool_vector3_array *p_self) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
- return (godot_pool_vector3_array_write_access *)memnew(PoolVector<Vector3>::Write(self->write()));
-}
-
-void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
- PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+void GDAPI godot_packed_vector3_array_set(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
+ Vector<Vector3> *self = (Vector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
self->set(p_idx, s);
}
-godot_vector3 GDAPI godot_pool_vector3_array_get(const godot_pool_vector3_array *p_self, const godot_int p_idx) {
- const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
+godot_vector3 GDAPI godot_packed_vector3_array_get(const godot_packed_vector3_array *p_self, const godot_int p_idx) {
+ const Vector<Vector3> *self = (const Vector<Vector3> *)p_self;
godot_vector3 v;
Vector3 *s = (Vector3 *)&v;
*s = self->get(p_idx);
return v;
}
-godot_int GDAPI godot_pool_vector3_array_size(const godot_pool_vector3_array *p_self) {
- const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
+godot_int GDAPI godot_packed_vector3_array_size(const godot_packed_vector3_array *p_self) {
+ const Vector<Vector3> *self = (const Vector<Vector3> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_pool_vector3_array_empty(const godot_pool_vector3_array *p_self) {
- const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
+godot_bool GDAPI godot_packed_vector3_array_empty(const godot_packed_vector3_array *p_self) {
+ const Vector<Vector3> *self = (const Vector<Vector3> *)p_self;
return self->empty();
}
-void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_self) {
- ((PoolVector<Vector3> *)p_self)->~PoolVector();
+void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self) {
+ ((Vector<Vector3> *)p_self)->~Vector();
}
// color
-void GDAPI godot_pool_color_array_new(godot_pool_color_array *r_dest) {
- PoolVector<Color> *dest = (PoolVector<Color> *)r_dest;
- memnew_placement(dest, PoolVector<Color>);
+void GDAPI godot_packed_color_array_new(godot_packed_color_array *r_dest) {
+ Vector<Color> *dest = (Vector<Color> *)r_dest;
+ memnew_placement(dest, Vector<Color>);
}
-void GDAPI godot_pool_color_array_new_copy(godot_pool_color_array *r_dest, const godot_pool_color_array *p_src) {
- PoolVector<Color> *dest = (PoolVector<Color> *)r_dest;
- const PoolVector<Color> *src = (const PoolVector<Color> *)p_src;
- memnew_placement(dest, PoolVector<Color>(*src));
+void GDAPI godot_packed_color_array_new_copy(godot_packed_color_array *r_dest, const godot_packed_color_array *p_src) {
+ Vector<Color> *dest = (Vector<Color> *)r_dest;
+ const Vector<Color> *src = (const Vector<Color> *)p_src;
+ memnew_placement(dest, Vector<Color>(*src));
}
-void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *r_dest, const godot_array *p_a) {
- PoolVector<Color> *dest = (PoolVector<Color> *)r_dest;
+void GDAPI godot_packed_color_array_new_with_array(godot_packed_color_array *r_dest, const godot_array *p_a) {
+ Vector<Color> *dest = (Vector<Color> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, PoolVector<Color>);
+ memnew_placement(dest, Vector<Color>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -654,327 +594,71 @@ void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *r_dest,
}
}
-void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_self, const godot_color *p_data) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+void GDAPI godot_packed_color_array_append(godot_packed_color_array *p_self, const godot_color *p_data) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
Color &s = *(Color *)p_data;
- self->append(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_self, const godot_pool_color_array *p_array) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
- PoolVector<Color> *array = (PoolVector<Color> *)p_array;
+void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_self, const godot_packed_color_array *p_array) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
+ Vector<Color> *array = (Vector<Color> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
Color &s = *(Color *)p_data;
return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_self) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
self->invert();
}
-void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_self, const godot_color *p_data) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
Color &s = *(Color *)p_data;
self->push_back(s);
}
-void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_self, const godot_int p_idx) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+void GDAPI godot_packed_color_array_remove(godot_packed_color_array *p_self, const godot_int p_idx) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_self, const godot_int p_size) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+void GDAPI godot_packed_color_array_resize(godot_packed_color_array *p_self, const godot_int p_size) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
self->resize(p_size);
}
-godot_pool_color_array_read_access GDAPI *godot_pool_color_array_read(const godot_pool_color_array *p_self) {
- const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
- return (godot_pool_color_array_read_access *)memnew(PoolVector<Color>::Read(self->read()));
-}
-
-godot_pool_color_array_write_access GDAPI *godot_pool_color_array_write(godot_pool_color_array *p_self) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
- return (godot_pool_color_array_write_access *)memnew(PoolVector<Color>::Write(self->write()));
-}
-
-void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
- PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+void GDAPI godot_packed_color_array_set(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
+ Vector<Color> *self = (Vector<Color> *)p_self;
Color &s = *(Color *)p_data;
self->set(p_idx, s);
}
-godot_color GDAPI godot_pool_color_array_get(const godot_pool_color_array *p_self, const godot_int p_idx) {
- const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
+godot_color GDAPI godot_packed_color_array_get(const godot_packed_color_array *p_self, const godot_int p_idx) {
+ const Vector<Color> *self = (const Vector<Color> *)p_self;
godot_color v;
Color *s = (Color *)&v;
*s = self->get(p_idx);
return v;
}
-godot_int GDAPI godot_pool_color_array_size(const godot_pool_color_array *p_self) {
- const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
+godot_int GDAPI godot_packed_color_array_size(const godot_packed_color_array *p_self) {
+ const Vector<Color> *self = (const Vector<Color> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_pool_color_array_empty(const godot_pool_color_array *p_self) {
- const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
+godot_bool GDAPI godot_packed_color_array_empty(const godot_packed_color_array *p_self) {
+ const Vector<Color> *self = (const Vector<Color> *)p_self;
return self->empty();
}
-void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self) {
- ((PoolVector<Color> *)p_self)->~PoolVector();
-}
-
-//
-// read accessor functions
-//
-
-godot_pool_byte_array_read_access GDAPI *godot_pool_byte_array_read_access_copy(const godot_pool_byte_array_read_access *p_other) {
- PoolVector<uint8_t>::Read *other = (PoolVector<uint8_t>::Read *)p_other;
- return (godot_pool_byte_array_read_access *)memnew(PoolVector<uint8_t>::Read(*other));
-}
-const uint8_t GDAPI *godot_pool_byte_array_read_access_ptr(const godot_pool_byte_array_read_access *p_read) {
- const PoolVector<uint8_t>::Read *read = (const PoolVector<uint8_t>::Read *)p_read;
- return read->ptr();
-}
-void GDAPI godot_pool_byte_array_read_access_operator_assign(godot_pool_byte_array_read_access *p_read, godot_pool_byte_array_read_access *p_other) {
- PoolVector<uint8_t>::Read *read = (PoolVector<uint8_t>::Read *)p_read;
- PoolVector<uint8_t>::Read *other = (PoolVector<uint8_t>::Read *)p_other;
- read->operator=(*other);
-}
-void GDAPI godot_pool_byte_array_read_access_destroy(godot_pool_byte_array_read_access *p_read) {
- memdelete((PoolVector<uint8_t>::Read *)p_read);
-}
-
-godot_pool_int_array_read_access GDAPI *godot_pool_int_array_read_access_copy(const godot_pool_int_array_read_access *p_other) {
- PoolVector<godot_int>::Read *other = (PoolVector<godot_int>::Read *)p_other;
- return (godot_pool_int_array_read_access *)memnew(PoolVector<godot_int>::Read(*other));
-}
-const godot_int GDAPI *godot_pool_int_array_read_access_ptr(const godot_pool_int_array_read_access *p_read) {
- const PoolVector<godot_int>::Read *read = (const PoolVector<godot_int>::Read *)p_read;
- return read->ptr();
-}
-void GDAPI godot_pool_int_array_read_access_operator_assign(godot_pool_int_array_read_access *p_read, godot_pool_int_array_read_access *p_other) {
- PoolVector<godot_int>::Read *read = (PoolVector<godot_int>::Read *)p_read;
- PoolVector<godot_int>::Read *other = (PoolVector<godot_int>::Read *)p_other;
- read->operator=(*other);
-}
-void GDAPI godot_pool_int_array_read_access_destroy(godot_pool_int_array_read_access *p_read) {
- memdelete((PoolVector<godot_int>::Read *)p_read);
-}
-
-godot_pool_real_array_read_access GDAPI *godot_pool_real_array_read_access_copy(const godot_pool_real_array_read_access *p_other) {
- PoolVector<godot_real>::Read *other = (PoolVector<godot_real>::Read *)p_other;
- return (godot_pool_real_array_read_access *)memnew(PoolVector<godot_real>::Read(*other));
-}
-const godot_real GDAPI *godot_pool_real_array_read_access_ptr(const godot_pool_real_array_read_access *p_read) {
- const PoolVector<godot_real>::Read *read = (const PoolVector<godot_real>::Read *)p_read;
- return read->ptr();
-}
-void GDAPI godot_pool_real_array_read_access_operator_assign(godot_pool_real_array_read_access *p_read, godot_pool_real_array_read_access *p_other) {
- PoolVector<godot_real>::Read *read = (PoolVector<godot_real>::Read *)p_read;
- PoolVector<godot_real>::Read *other = (PoolVector<godot_real>::Read *)p_other;
- read->operator=(*other);
-}
-void GDAPI godot_pool_real_array_read_access_destroy(godot_pool_real_array_read_access *p_read) {
- memdelete((PoolVector<godot_real>::Read *)p_read);
-}
-
-godot_pool_string_array_read_access GDAPI *godot_pool_string_array_read_access_copy(const godot_pool_string_array_read_access *p_other) {
- PoolVector<String>::Read *other = (PoolVector<String>::Read *)p_other;
- return (godot_pool_string_array_read_access *)memnew(PoolVector<String>::Read(*other));
-}
-const godot_string GDAPI *godot_pool_string_array_read_access_ptr(const godot_pool_string_array_read_access *p_read) {
- const PoolVector<String>::Read *read = (const PoolVector<String>::Read *)p_read;
- return (const godot_string *)read->ptr();
-}
-void GDAPI godot_pool_string_array_read_access_operator_assign(godot_pool_string_array_read_access *p_read, godot_pool_string_array_read_access *p_other) {
- PoolVector<String>::Read *read = (PoolVector<String>::Read *)p_read;
- PoolVector<String>::Read *other = (PoolVector<String>::Read *)p_other;
- read->operator=(*other);
-}
-void GDAPI godot_pool_string_array_read_access_destroy(godot_pool_string_array_read_access *p_read) {
- memdelete((PoolVector<String>::Read *)p_read);
-}
-
-godot_pool_vector2_array_read_access GDAPI *godot_pool_vector2_array_read_access_copy(const godot_pool_vector2_array_read_access *p_other) {
- PoolVector<Vector2>::Read *other = (PoolVector<Vector2>::Read *)p_other;
- return (godot_pool_vector2_array_read_access *)memnew(PoolVector<Vector2>::Read(*other));
-}
-const godot_vector2 GDAPI *godot_pool_vector2_array_read_access_ptr(const godot_pool_vector2_array_read_access *p_read) {
- const PoolVector<Vector2>::Read *read = (const PoolVector<Vector2>::Read *)p_read;
- return (const godot_vector2 *)read->ptr();
-}
-void GDAPI godot_pool_vector2_array_read_access_operator_assign(godot_pool_vector2_array_read_access *p_read, godot_pool_vector2_array_read_access *p_other) {
- PoolVector<Vector2>::Read *read = (PoolVector<Vector2>::Read *)p_read;
- PoolVector<Vector2>::Read *other = (PoolVector<Vector2>::Read *)p_other;
- read->operator=(*other);
-}
-void GDAPI godot_pool_vector2_array_read_access_destroy(godot_pool_vector2_array_read_access *p_read) {
- memdelete((PoolVector<Vector2>::Read *)p_read);
-}
-
-godot_pool_vector3_array_read_access GDAPI *godot_pool_vector3_array_read_access_copy(const godot_pool_vector3_array_read_access *p_other) {
- PoolVector<Vector3>::Read *other = (PoolVector<Vector3>::Read *)p_other;
- return (godot_pool_vector3_array_read_access *)memnew(PoolVector<Vector3>::Read(*other));
-}
-const godot_vector3 GDAPI *godot_pool_vector3_array_read_access_ptr(const godot_pool_vector3_array_read_access *p_read) {
- const PoolVector<Vector3>::Read *read = (const PoolVector<Vector3>::Read *)p_read;
- return (const godot_vector3 *)read->ptr();
-}
-void GDAPI godot_pool_vector3_array_read_access_operator_assign(godot_pool_vector3_array_read_access *p_read, godot_pool_vector3_array_read_access *p_other) {
- PoolVector<Vector3>::Read *read = (PoolVector<Vector3>::Read *)p_read;
- PoolVector<Vector3>::Read *other = (PoolVector<Vector3>::Read *)p_other;
- read->operator=(*other);
-}
-void GDAPI godot_pool_vector3_array_read_access_destroy(godot_pool_vector3_array_read_access *p_read) {
- memdelete((PoolVector<Vector2>::Read *)p_read);
-}
-
-godot_pool_color_array_read_access GDAPI *godot_pool_color_array_read_access_copy(const godot_pool_color_array_read_access *p_other) {
- PoolVector<Color>::Read *other = (PoolVector<Color>::Read *)p_other;
- return (godot_pool_color_array_read_access *)memnew(PoolVector<Color>::Read(*other));
-}
-const godot_color GDAPI *godot_pool_color_array_read_access_ptr(const godot_pool_color_array_read_access *p_read) {
- const PoolVector<Color>::Read *read = (const PoolVector<Color>::Read *)p_read;
- return (const godot_color *)read->ptr();
-}
-void GDAPI godot_pool_color_array_read_access_operator_assign(godot_pool_color_array_read_access *p_read, godot_pool_color_array_read_access *p_other) {
- PoolVector<Color>::Read *read = (PoolVector<Color>::Read *)p_read;
- PoolVector<Color>::Read *other = (PoolVector<Color>::Read *)p_other;
- read->operator=(*other);
-}
-void GDAPI godot_pool_color_array_read_access_destroy(godot_pool_color_array_read_access *p_read) {
- memdelete((PoolVector<Color>::Read *)p_read);
-}
-
-//
-// write accessor functions
-//
-
-godot_pool_byte_array_write_access GDAPI *godot_pool_byte_array_write_access_copy(const godot_pool_byte_array_write_access *p_other) {
- PoolVector<uint8_t>::Write *other = (PoolVector<uint8_t>::Write *)p_other;
- return (godot_pool_byte_array_write_access *)memnew(PoolVector<uint8_t>::Write(*other));
-}
-uint8_t GDAPI *godot_pool_byte_array_write_access_ptr(const godot_pool_byte_array_write_access *p_write) {
- PoolVector<uint8_t>::Write *write = (PoolVector<uint8_t>::Write *)p_write;
- return write->ptr();
-}
-void GDAPI godot_pool_byte_array_write_access_operator_assign(godot_pool_byte_array_write_access *p_write, godot_pool_byte_array_write_access *p_other) {
- PoolVector<uint8_t>::Write *write = (PoolVector<uint8_t>::Write *)p_write;
- PoolVector<uint8_t>::Write *other = (PoolVector<uint8_t>::Write *)p_other;
- write->operator=(*other);
-}
-void GDAPI godot_pool_byte_array_write_access_destroy(godot_pool_byte_array_write_access *p_write) {
- memdelete((PoolVector<uint8_t>::Write *)p_write);
-}
-
-godot_pool_int_array_write_access GDAPI *godot_pool_int_array_write_access_copy(const godot_pool_int_array_write_access *p_other) {
- PoolVector<godot_int>::Write *other = (PoolVector<godot_int>::Write *)p_other;
- return (godot_pool_int_array_write_access *)memnew(PoolVector<godot_int>::Write(*other));
-}
-godot_int GDAPI *godot_pool_int_array_write_access_ptr(const godot_pool_int_array_write_access *p_write) {
- PoolVector<godot_int>::Write *write = (PoolVector<godot_int>::Write *)p_write;
- return write->ptr();
-}
-void GDAPI godot_pool_int_array_write_access_operator_assign(godot_pool_int_array_write_access *p_write, godot_pool_int_array_write_access *p_other) {
- PoolVector<godot_int>::Write *write = (PoolVector<godot_int>::Write *)p_write;
- PoolVector<godot_int>::Write *other = (PoolVector<godot_int>::Write *)p_other;
- write->operator=(*other);
-}
-void GDAPI godot_pool_int_array_write_access_destroy(godot_pool_int_array_write_access *p_write) {
- memdelete((PoolVector<godot_int>::Write *)p_write);
-}
-
-godot_pool_real_array_write_access GDAPI *godot_pool_real_array_write_access_copy(const godot_pool_real_array_write_access *p_other) {
- PoolVector<godot_real>::Write *other = (PoolVector<godot_real>::Write *)p_other;
- return (godot_pool_real_array_write_access *)memnew(PoolVector<godot_real>::Write(*other));
-}
-godot_real GDAPI *godot_pool_real_array_write_access_ptr(const godot_pool_real_array_write_access *p_write) {
- PoolVector<godot_real>::Write *write = (PoolVector<godot_real>::Write *)p_write;
- return write->ptr();
-}
-void GDAPI godot_pool_real_array_write_access_operator_assign(godot_pool_real_array_write_access *p_write, godot_pool_real_array_write_access *p_other) {
- PoolVector<godot_real>::Write *write = (PoolVector<godot_real>::Write *)p_write;
- PoolVector<godot_real>::Write *other = (PoolVector<godot_real>::Write *)p_other;
- write->operator=(*other);
-}
-void GDAPI godot_pool_real_array_write_access_destroy(godot_pool_real_array_write_access *p_write) {
- memdelete((PoolVector<godot_real>::Write *)p_write);
-}
-
-godot_pool_string_array_write_access GDAPI *godot_pool_string_array_write_access_copy(const godot_pool_string_array_write_access *p_other) {
- PoolVector<String>::Write *other = (PoolVector<String>::Write *)p_other;
- return (godot_pool_string_array_write_access *)memnew(PoolVector<String>::Write(*other));
-}
-godot_string GDAPI *godot_pool_string_array_write_access_ptr(const godot_pool_string_array_write_access *p_write) {
- PoolVector<String>::Write *write = (PoolVector<String>::Write *)p_write;
- return (godot_string *)write->ptr();
-}
-void GDAPI godot_pool_string_array_write_access_operator_assign(godot_pool_string_array_write_access *p_write, godot_pool_string_array_write_access *p_other) {
- PoolVector<String>::Write *write = (PoolVector<String>::Write *)p_write;
- PoolVector<String>::Write *other = (PoolVector<String>::Write *)p_other;
- write->operator=(*other);
-}
-void GDAPI godot_pool_string_array_write_access_destroy(godot_pool_string_array_write_access *p_write) {
- memdelete((PoolVector<String>::Write *)p_write);
-}
-
-godot_pool_vector2_array_write_access GDAPI *godot_pool_vector2_array_write_access_copy(const godot_pool_vector2_array_write_access *p_other) {
- PoolVector<Vector2>::Write *other = (PoolVector<Vector2>::Write *)p_other;
- return (godot_pool_vector2_array_write_access *)memnew(PoolVector<Vector2>::Write(*other));
-}
-godot_vector2 GDAPI *godot_pool_vector2_array_write_access_ptr(const godot_pool_vector2_array_write_access *p_write) {
- PoolVector<Vector2>::Write *write = (PoolVector<Vector2>::Write *)p_write;
- return (godot_vector2 *)write->ptr();
-}
-void GDAPI godot_pool_vector2_array_write_access_operator_assign(godot_pool_vector2_array_write_access *p_write, godot_pool_vector2_array_write_access *p_other) {
- PoolVector<Vector2>::Write *write = (PoolVector<Vector2>::Write *)p_write;
- PoolVector<Vector2>::Write *other = (PoolVector<Vector2>::Write *)p_other;
- write->operator=(*other);
-}
-void GDAPI godot_pool_vector2_array_write_access_destroy(godot_pool_vector2_array_write_access *p_write) {
- memdelete((PoolVector<Vector2>::Write *)p_write);
-}
-
-godot_pool_vector3_array_write_access GDAPI *godot_pool_vector3_array_write_access_copy(const godot_pool_vector3_array_write_access *p_other) {
- PoolVector<Vector3>::Write *other = (PoolVector<Vector3>::Write *)p_other;
- return (godot_pool_vector3_array_write_access *)memnew(PoolVector<Vector3>::Write(*other));
-}
-godot_vector3 GDAPI *godot_pool_vector3_array_write_access_ptr(const godot_pool_vector3_array_write_access *p_write) {
- PoolVector<Vector3>::Write *write = (PoolVector<Vector3>::Write *)p_write;
- return (godot_vector3 *)write->ptr();
-}
-void GDAPI godot_pool_vector3_array_write_access_operator_assign(godot_pool_vector3_array_write_access *p_write, godot_pool_vector3_array_write_access *p_other) {
- PoolVector<Vector3>::Write *write = (PoolVector<Vector3>::Write *)p_write;
- PoolVector<Vector3>::Write *other = (PoolVector<Vector3>::Write *)p_other;
- write->operator=(*other);
-}
-void GDAPI godot_pool_vector3_array_write_access_destroy(godot_pool_vector3_array_write_access *p_write) {
- memdelete((PoolVector<Vector3>::Write *)p_write);
-}
-
-godot_pool_color_array_write_access GDAPI *godot_pool_color_array_write_access_copy(const godot_pool_color_array_write_access *p_other) {
- PoolVector<Color>::Write *other = (PoolVector<Color>::Write *)p_other;
- return (godot_pool_color_array_write_access *)memnew(PoolVector<Color>::Write(*other));
-}
-godot_color GDAPI *godot_pool_color_array_write_access_ptr(const godot_pool_color_array_write_access *p_write) {
- PoolVector<Color>::Write *write = (PoolVector<Color>::Write *)p_write;
- return (godot_color *)write->ptr();
-}
-void GDAPI godot_pool_color_array_write_access_operator_assign(godot_pool_color_array_write_access *p_write, godot_pool_color_array_write_access *p_other) {
- PoolVector<Color>::Write *write = (PoolVector<Color>::Write *)p_write;
- PoolVector<Color>::Write *other = (PoolVector<Color>::Write *)p_other;
- write->operator=(*other);
-}
-void GDAPI godot_pool_color_array_write_access_destroy(godot_pool_color_array_write_access *p_write) {
- memdelete((PoolVector<Color>::Write *)p_write);
+void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self) {
+ ((Vector<Color> *)p_self)->~Vector();
}
#ifdef __cplusplus
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 414b9b9eaf..4cb55900b0 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -250,7 +250,12 @@ godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, co
keys.write[i] = (*keys_proxy)[i];
}
- return self->findmk(keys, p_from, r_key);
+ int key;
+ int ret = self->findmk(keys, p_from, &key);
+ if (r_key) {
+ *r_key = key;
+ }
+ return ret;
}
godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what) {
@@ -1025,14 +1030,14 @@ uint32_t GDAPI godot_string_hash_utf8_chars_with_len(const wchar_t *p_str, godot
return String::hash(p_str, p_len);
}
-godot_pool_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) {
+godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) {
const String *self = (const String *)p_self;
Vector<uint8_t> tmp_result = self->md5_buffer();
- godot_pool_byte_array result;
- memnew_placement(&result, PoolByteArray);
- PoolByteArray *proxy = (PoolByteArray *)&result;
- PoolByteArray::Write proxy_writer = proxy->write();
+ godot_packed_byte_array result;
+ memnew_placement(&result, PackedByteArray);
+ PackedByteArray *proxy = (PackedByteArray *)&result;
+ uint8_t *proxy_writer = proxy->ptrw();
proxy->resize(tmp_result.size());
for (int i = 0; i < tmp_result.size(); i++) {
@@ -1050,14 +1055,14 @@ godot_string GDAPI godot_string_md5_text(const godot_string *p_self) {
return result;
}
-godot_pool_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) {
+godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) {
const String *self = (const String *)p_self;
Vector<uint8_t> tmp_result = self->sha256_buffer();
- godot_pool_byte_array result;
- memnew_placement(&result, PoolByteArray);
- PoolByteArray *proxy = (PoolByteArray *)&result;
- PoolByteArray::Write proxy_writer = proxy->write();
+ godot_packed_byte_array result;
+ memnew_placement(&result, PackedByteArray);
+ PackedByteArray *proxy = (PackedByteArray *)&result;
+ uint8_t *proxy_writer = proxy->ptrw();
proxy->resize(tmp_result.size());
for (int i = 0; i < tmp_result.size(); i++) {
@@ -1338,15 +1343,15 @@ godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_s
return result;
}
-godot_pool_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor,
+godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor,
const godot_bool p_allow_empty, const godot_int p_maxsplit) {
const String *self = (const String *)p_self;
String *divisor = (String *)p_divisor;
- godot_pool_string_array result;
- memnew_placement(&result, PoolStringArray);
- PoolStringArray *proxy = (PoolStringArray *)&result;
- PoolStringArray::Write proxy_writer = proxy->write();
+ godot_packed_string_array result;
+ memnew_placement(&result, PackedStringArray);
+ PackedStringArray *proxy = (PackedStringArray *)&result;
+ String *proxy_writer = proxy->ptrw();
Vector<String> tmp_result = self->rsplit(*divisor, p_allow_empty, p_maxsplit);
proxy->resize(tmp_result.size());
diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp
index 11b6448e34..f0fc44ae8a 100644
--- a/modules/gdnative/gdnative/variant.cpp
+++ b/modules/gdnative/gdnative/variant.cpp
@@ -178,7 +178,7 @@ void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p
ref = REF(reference);
}
if (!ref.is_null()) {
- memnew_placement_custom(dest, Variant, Variant(ref.get_ref_ptr()));
+ memnew_placement_custom(dest, Variant, Variant(ref));
} else {
#if defined(DEBUG_METHODS_ENABLED)
if (reference) {
@@ -201,45 +201,45 @@ void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_a
memnew_placement_custom(dest, Variant, Variant(*arr));
}
-void GDAPI godot_variant_new_pool_byte_array(godot_variant *r_dest, const godot_pool_byte_array *p_pba) {
+void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba) {
Variant *dest = (Variant *)r_dest;
- PoolByteArray *pba = (PoolByteArray *)p_pba;
+ PackedByteArray *pba = (PackedByteArray *)p_pba;
memnew_placement_custom(dest, Variant, Variant(*pba));
}
-void GDAPI godot_variant_new_pool_int_array(godot_variant *r_dest, const godot_pool_int_array *p_pia) {
+void GDAPI godot_variant_new_packed_int_array(godot_variant *r_dest, const godot_packed_int_array *p_pia) {
Variant *dest = (Variant *)r_dest;
- PoolIntArray *pia = (PoolIntArray *)p_pia;
+ PackedInt32Array *pia = (PackedInt32Array *)p_pia;
memnew_placement_custom(dest, Variant, Variant(*pia));
}
-void GDAPI godot_variant_new_pool_real_array(godot_variant *r_dest, const godot_pool_real_array *p_pra) {
+void GDAPI godot_variant_new_packed_real_array(godot_variant *r_dest, const godot_packed_real_array *p_pra) {
Variant *dest = (Variant *)r_dest;
- PoolRealArray *pra = (PoolRealArray *)p_pra;
+ PackedFloat32Array *pra = (PackedFloat32Array *)p_pra;
memnew_placement_custom(dest, Variant, Variant(*pra));
}
-void GDAPI godot_variant_new_pool_string_array(godot_variant *r_dest, const godot_pool_string_array *p_psa) {
+void GDAPI godot_variant_new_packed_string_array(godot_variant *r_dest, const godot_packed_string_array *p_psa) {
Variant *dest = (Variant *)r_dest;
- PoolStringArray *psa = (PoolStringArray *)p_psa;
+ PackedStringArray *psa = (PackedStringArray *)p_psa;
memnew_placement_custom(dest, Variant, Variant(*psa));
}
-void GDAPI godot_variant_new_pool_vector2_array(godot_variant *r_dest, const godot_pool_vector2_array *p_pv2a) {
+void GDAPI godot_variant_new_packed_vector2_array(godot_variant *r_dest, const godot_packed_vector2_array *p_pv2a) {
Variant *dest = (Variant *)r_dest;
- PoolVector2Array *pv2a = (PoolVector2Array *)p_pv2a;
+ PackedVector2Array *pv2a = (PackedVector2Array *)p_pv2a;
memnew_placement_custom(dest, Variant, Variant(*pv2a));
}
-void GDAPI godot_variant_new_pool_vector3_array(godot_variant *r_dest, const godot_pool_vector3_array *p_pv3a) {
+void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const godot_packed_vector3_array *p_pv3a) {
Variant *dest = (Variant *)r_dest;
- PoolVector3Array *pv3a = (PoolVector3Array *)p_pv3a;
+ PackedVector3Array *pv3a = (PackedVector3Array *)p_pv3a;
memnew_placement_custom(dest, Variant, Variant(*pv3a));
}
-void GDAPI godot_variant_new_pool_color_array(godot_variant *r_dest, const godot_pool_color_array *p_pca) {
+void GDAPI godot_variant_new_packed_color_array(godot_variant *r_dest, const godot_packed_color_array *p_pca) {
Variant *dest = (Variant *)r_dest;
- PoolColorArray *pca = (PoolColorArray *)p_pca;
+ PackedColorArray *pca = (PackedColorArray *)p_pca;
memnew_placement_custom(dest, Variant, Variant(*pca));
}
@@ -390,65 +390,65 @@ godot_array GDAPI godot_variant_as_array(const godot_variant *p_self) {
return raw_dest;
}
-godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_self) {
- godot_pool_byte_array raw_dest;
+godot_packed_byte_array GDAPI godot_variant_as_packed_byte_array(const godot_variant *p_self) {
+ godot_packed_byte_array raw_dest;
const Variant *self = (const Variant *)p_self;
- PoolByteArray *dest = (PoolByteArray *)&raw_dest;
- memnew_placement(dest, PoolByteArray(self->operator PoolByteArray())); // operator = is overloaded by PoolByteArray
+ PackedByteArray *dest = (PackedByteArray *)&raw_dest;
+ memnew_placement(dest, PackedByteArray(self->operator PackedByteArray())); // operator = is overloaded by PackedByteArray
*dest = *self;
return raw_dest;
}
-godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_self) {
- godot_pool_int_array raw_dest;
+godot_packed_int_array GDAPI godot_variant_as_packed_int_array(const godot_variant *p_self) {
+ godot_packed_int_array raw_dest;
const Variant *self = (const Variant *)p_self;
- PoolIntArray *dest = (PoolIntArray *)&raw_dest;
- memnew_placement(dest, PoolIntArray(self->operator PoolIntArray())); // operator = is overloaded by PoolIntArray
+ PackedInt32Array *dest = (PackedInt32Array *)&raw_dest;
+ memnew_placement(dest, PackedInt32Array(self->operator PackedInt32Array())); // operator = is overloaded by PackedInt32Array
*dest = *self;
return raw_dest;
}
-godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_self) {
- godot_pool_real_array raw_dest;
+godot_packed_real_array GDAPI godot_variant_as_packed_real_array(const godot_variant *p_self) {
+ godot_packed_real_array raw_dest;
const Variant *self = (const Variant *)p_self;
- PoolRealArray *dest = (PoolRealArray *)&raw_dest;
- memnew_placement(dest, PoolRealArray(self->operator PoolRealArray())); // operator = is overloaded by PoolRealArray
+ PackedFloat32Array *dest = (PackedFloat32Array *)&raw_dest;
+ memnew_placement(dest, PackedFloat32Array(self->operator PackedFloat32Array())); // operator = is overloaded by PackedFloat32Array
*dest = *self;
return raw_dest;
}
-godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_self) {
- godot_pool_string_array raw_dest;
+godot_packed_string_array GDAPI godot_variant_as_packed_string_array(const godot_variant *p_self) {
+ godot_packed_string_array raw_dest;
const Variant *self = (const Variant *)p_self;
- PoolStringArray *dest = (PoolStringArray *)&raw_dest;
- memnew_placement(dest, PoolStringArray(self->operator PoolStringArray())); // operator = is overloaded by PoolStringArray
+ PackedStringArray *dest = (PackedStringArray *)&raw_dest;
+ memnew_placement(dest, PackedStringArray(self->operator PackedStringArray())); // operator = is overloaded by PackedStringArray
*dest = *self;
return raw_dest;
}
-godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_self) {
- godot_pool_vector2_array raw_dest;
+godot_packed_vector2_array GDAPI godot_variant_as_packed_vector2_array(const godot_variant *p_self) {
+ godot_packed_vector2_array raw_dest;
const Variant *self = (const Variant *)p_self;
- PoolVector2Array *dest = (PoolVector2Array *)&raw_dest;
- memnew_placement(dest, PoolVector2Array(self->operator PoolVector2Array())); // operator = is overloaded by PoolVector2Array
+ PackedVector2Array *dest = (PackedVector2Array *)&raw_dest;
+ memnew_placement(dest, PackedVector2Array(self->operator PackedVector2Array())); // operator = is overloaded by PackedVector2Array
*dest = *self;
return raw_dest;
}
-godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_self) {
- godot_pool_vector3_array raw_dest;
+godot_packed_vector3_array GDAPI godot_variant_as_packed_vector3_array(const godot_variant *p_self) {
+ godot_packed_vector3_array raw_dest;
const Variant *self = (const Variant *)p_self;
- PoolVector3Array *dest = (PoolVector3Array *)&raw_dest;
- memnew_placement(dest, PoolVector3Array(self->operator PoolVector3Array())); // operator = is overloaded by PoolVector3Array
+ PackedVector3Array *dest = (PackedVector3Array *)&raw_dest;
+ memnew_placement(dest, PackedVector3Array(self->operator PackedVector3Array())); // operator = is overloaded by PackedVector3Array
*dest = *self;
return raw_dest;
}
-godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_self) {
- godot_pool_color_array raw_dest;
+godot_packed_color_array GDAPI godot_variant_as_packed_color_array(const godot_variant *p_self) {
+ godot_packed_color_array raw_dest;
const Variant *self = (const Variant *)p_self;
- PoolColorArray *dest = (PoolColorArray *)&raw_dest;
- memnew_placement(dest, PoolColorArray(self->operator PoolColorArray())); // operator = is overloaded by PoolColorArray
+ PackedColorArray *dest = (PackedColorArray *)&raw_dest;
+ memnew_placement(dest, PackedColorArray(self->operator PackedColorArray())); // operator = is overloaded by PackedColorArray
*dest = *self;
return raw_dest;
}
@@ -459,7 +459,7 @@ godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string
const Variant **args = (const Variant **)p_args;
godot_variant raw_dest;
Variant *dest = (Variant *)&raw_dest;
- Variant::CallError error;
+ Callable::CallError error;
memnew_placement_custom(dest, Variant, Variant(self->call(*method, args, p_argcount, error)));
if (r_error) {
r_error->error = (godot_variant_call_error_error)error.error;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 8ccb8d2286..9473a3d419 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -93,52 +93,52 @@
]
},
{
- "name": "godot_pool_byte_array_empty",
+ "name": "godot_packed_byte_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_pool_byte_array *", "p_self"]
+ ["const godot_packed_byte_array *", "p_self"]
]
},
{
- "name": "godot_pool_int_array_empty",
+ "name": "godot_packed_int_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_pool_int_array *", "p_self"]
+ ["const godot_packed_int_array *", "p_self"]
]
},
{
- "name": "godot_pool_real_array_empty",
+ "name": "godot_packed_real_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_pool_real_array *", "p_self"]
+ ["const godot_packed_real_array *", "p_self"]
]
},
{
- "name": "godot_pool_string_array_empty",
+ "name": "godot_packed_string_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_pool_string_array *", "p_self"]
+ ["const godot_packed_string_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector2_array_empty",
+ "name": "godot_packed_vector2_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_pool_vector2_array *", "p_self"]
+ ["const godot_packed_vector2_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector3_array_empty",
+ "name": "godot_packed_vector3_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_pool_vector3_array *", "p_self"]
+ ["const godot_packed_vector3_array *", "p_self"]
]
},
{
- "name": "godot_pool_color_array_empty",
+ "name": "godot_packed_color_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_pool_color_array *", "p_self"]
+ ["const godot_packed_color_array *", "p_self"]
]
},
{
@@ -352,7 +352,7 @@
},
{
"name": "godot_string_rsplit",
- "return_type": "godot_pool_string_array",
+ "return_type": "godot_packed_string_array",
"arguments": [
["const godot_string *", "p_self"],
["const godot_string *", "p_divisor"],
@@ -404,13 +404,6 @@
]
},
{
- "name": "godot_is_instance_valid",
- "return_type": "bool",
- "arguments": [
- ["const godot_object *", "p_object"]
- ]
- },
- {
"name": "godot_quat_new_with_basis",
"return_type": "void",
"arguments": [
@@ -579,13 +572,6 @@
]
},
{
- "name": "godot_color_gray",
- "return_type": "godot_real",
- "arguments": [
- ["const godot_color *", "p_self"]
- ]
- },
- {
"name": "godot_color_inverted",
"return_type": "godot_color",
"arguments": [
@@ -1671,1277 +1657,773 @@
]
},
{
- "name": "godot_pool_byte_array_new",
+ "name": "godot_packed_byte_array_new",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "r_dest"]
+ ["godot_packed_byte_array *", "r_dest"]
]
},
{
- "name": "godot_pool_byte_array_new_copy",
+ "name": "godot_packed_byte_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "r_dest"],
- ["const godot_pool_byte_array *", "p_src"]
+ ["godot_packed_byte_array *", "r_dest"],
+ ["const godot_packed_byte_array *", "p_src"]
]
},
{
- "name": "godot_pool_byte_array_new_with_array",
+ "name": "godot_packed_byte_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "r_dest"],
+ ["godot_packed_byte_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_pool_byte_array_append",
+ "name": "godot_packed_byte_array_append",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"],
+ ["godot_packed_byte_array *", "p_self"],
["const uint8_t", "p_data"]
]
},
{
- "name": "godot_pool_byte_array_append_array",
+ "name": "godot_packed_byte_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"],
- ["const godot_pool_byte_array *", "p_array"]
+ ["godot_packed_byte_array *", "p_self"],
+ ["const godot_packed_byte_array *", "p_array"]
]
},
{
- "name": "godot_pool_byte_array_insert",
+ "name": "godot_packed_byte_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_pool_byte_array *", "p_self"],
+ ["godot_packed_byte_array *", "p_self"],
["const godot_int", "p_idx"],
["const uint8_t", "p_data"]
]
},
{
- "name": "godot_pool_byte_array_invert",
+ "name": "godot_packed_byte_array_invert",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"]
+ ["godot_packed_byte_array *", "p_self"]
]
},
{
- "name": "godot_pool_byte_array_push_back",
+ "name": "godot_packed_byte_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"],
+ ["godot_packed_byte_array *", "p_self"],
["const uint8_t", "p_data"]
]
},
{
- "name": "godot_pool_byte_array_remove",
+ "name": "godot_packed_byte_array_remove",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"],
+ ["godot_packed_byte_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_byte_array_resize",
+ "name": "godot_packed_byte_array_resize",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"],
+ ["godot_packed_byte_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_pool_byte_array_read",
- "return_type": "godot_pool_byte_array_read_access *",
- "arguments": [
- ["const godot_pool_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_byte_array_write",
- "return_type": "godot_pool_byte_array_write_access *",
- "arguments": [
- ["godot_pool_byte_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_byte_array_set",
+ "name": "godot_packed_byte_array_set",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"],
+ ["godot_packed_byte_array *", "p_self"],
["const godot_int", "p_idx"],
["const uint8_t", "p_data"]
]
},
{
- "name": "godot_pool_byte_array_get",
+ "name": "godot_packed_byte_array_get",
"return_type": "uint8_t",
"arguments": [
- ["const godot_pool_byte_array *", "p_self"],
+ ["const godot_packed_byte_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_byte_array_size",
+ "name": "godot_packed_byte_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_byte_array *", "p_self"]
+ ["const godot_packed_byte_array *", "p_self"]
]
},
{
- "name": "godot_pool_byte_array_destroy",
+ "name": "godot_packed_byte_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_pool_byte_array *", "p_self"]
+ ["godot_packed_byte_array *", "p_self"]
]
},
{
- "name": "godot_pool_int_array_new",
+ "name": "godot_packed_int_array_new",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "r_dest"]
+ ["godot_packed_int_array *", "r_dest"]
]
},
{
- "name": "godot_pool_int_array_new_copy",
+ "name": "godot_packed_int_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "r_dest"],
- ["const godot_pool_int_array *", "p_src"]
+ ["godot_packed_int_array *", "r_dest"],
+ ["const godot_packed_int_array *", "p_src"]
]
},
{
- "name": "godot_pool_int_array_new_with_array",
+ "name": "godot_packed_int_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "r_dest"],
+ ["godot_packed_int_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_pool_int_array_append",
+ "name": "godot_packed_int_array_append",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"],
+ ["godot_packed_int_array *", "p_self"],
["const godot_int", "p_data"]
]
},
{
- "name": "godot_pool_int_array_append_array",
+ "name": "godot_packed_int_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"],
- ["const godot_pool_int_array *", "p_array"]
+ ["godot_packed_int_array *", "p_self"],
+ ["const godot_packed_int_array *", "p_array"]
]
},
{
- "name": "godot_pool_int_array_insert",
+ "name": "godot_packed_int_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_pool_int_array *", "p_self"],
+ ["godot_packed_int_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_int", "p_data"]
]
},
{
- "name": "godot_pool_int_array_invert",
+ "name": "godot_packed_int_array_invert",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"]
+ ["godot_packed_int_array *", "p_self"]
]
},
{
- "name": "godot_pool_int_array_push_back",
+ "name": "godot_packed_int_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"],
+ ["godot_packed_int_array *", "p_self"],
["const godot_int", "p_data"]
]
},
{
- "name": "godot_pool_int_array_remove",
+ "name": "godot_packed_int_array_remove",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"],
+ ["godot_packed_int_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_int_array_resize",
+ "name": "godot_packed_int_array_resize",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"],
+ ["godot_packed_int_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_pool_int_array_read",
- "return_type": "godot_pool_int_array_read_access *",
- "arguments": [
- ["const godot_pool_int_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_int_array_write",
- "return_type": "godot_pool_int_array_write_access *",
- "arguments": [
- ["godot_pool_int_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_int_array_set",
+ "name": "godot_packed_int_array_set",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"],
+ ["godot_packed_int_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_int", "p_data"]
]
},
{
- "name": "godot_pool_int_array_get",
+ "name": "godot_packed_int_array_get",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_int_array *", "p_self"],
+ ["const godot_packed_int_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_int_array_size",
+ "name": "godot_packed_int_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_int_array *", "p_self"]
+ ["const godot_packed_int_array *", "p_self"]
]
},
{
- "name": "godot_pool_int_array_destroy",
+ "name": "godot_packed_int_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_pool_int_array *", "p_self"]
+ ["godot_packed_int_array *", "p_self"]
]
},
{
- "name": "godot_pool_real_array_new",
+ "name": "godot_packed_real_array_new",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "r_dest"]
+ ["godot_packed_real_array *", "r_dest"]
]
},
{
- "name": "godot_pool_real_array_new_copy",
+ "name": "godot_packed_real_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "r_dest"],
- ["const godot_pool_real_array *", "p_src"]
+ ["godot_packed_real_array *", "r_dest"],
+ ["const godot_packed_real_array *", "p_src"]
]
},
{
- "name": "godot_pool_real_array_new_with_array",
+ "name": "godot_packed_real_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "r_dest"],
+ ["godot_packed_real_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_pool_real_array_append",
+ "name": "godot_packed_real_array_append",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"],
+ ["godot_packed_real_array *", "p_self"],
["const godot_real", "p_data"]
]
},
{
- "name": "godot_pool_real_array_append_array",
+ "name": "godot_packed_real_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"],
- ["const godot_pool_real_array *", "p_array"]
+ ["godot_packed_real_array *", "p_self"],
+ ["const godot_packed_real_array *", "p_array"]
]
},
{
- "name": "godot_pool_real_array_insert",
+ "name": "godot_packed_real_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_pool_real_array *", "p_self"],
+ ["godot_packed_real_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_real", "p_data"]
]
},
{
- "name": "godot_pool_real_array_invert",
+ "name": "godot_packed_real_array_invert",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"]
+ ["godot_packed_real_array *", "p_self"]
]
},
{
- "name": "godot_pool_real_array_push_back",
+ "name": "godot_packed_real_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"],
+ ["godot_packed_real_array *", "p_self"],
["const godot_real", "p_data"]
]
},
{
- "name": "godot_pool_real_array_remove",
+ "name": "godot_packed_real_array_remove",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"],
+ ["godot_packed_real_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_real_array_resize",
+ "name": "godot_packed_real_array_resize",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"],
+ ["godot_packed_real_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_pool_real_array_read",
- "return_type": "godot_pool_real_array_read_access *",
- "arguments": [
- ["const godot_pool_real_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_real_array_write",
- "return_type": "godot_pool_real_array_write_access *",
- "arguments": [
- ["godot_pool_real_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_real_array_set",
+ "name": "godot_packed_real_array_set",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"],
+ ["godot_packed_real_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_real", "p_data"]
]
},
{
- "name": "godot_pool_real_array_get",
+ "name": "godot_packed_real_array_get",
"return_type": "godot_real",
"arguments": [
- ["const godot_pool_real_array *", "p_self"],
+ ["const godot_packed_real_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_real_array_size",
+ "name": "godot_packed_real_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_real_array *", "p_self"]
+ ["const godot_packed_real_array *", "p_self"]
]
},
{
- "name": "godot_pool_real_array_destroy",
+ "name": "godot_packed_real_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_pool_real_array *", "p_self"]
+ ["godot_packed_real_array *", "p_self"]
]
},
{
- "name": "godot_pool_string_array_new",
+ "name": "godot_packed_string_array_new",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "r_dest"]
+ ["godot_packed_string_array *", "r_dest"]
]
},
{
- "name": "godot_pool_string_array_new_copy",
+ "name": "godot_packed_string_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "r_dest"],
- ["const godot_pool_string_array *", "p_src"]
+ ["godot_packed_string_array *", "r_dest"],
+ ["const godot_packed_string_array *", "p_src"]
]
},
{
- "name": "godot_pool_string_array_new_with_array",
+ "name": "godot_packed_string_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "r_dest"],
+ ["godot_packed_string_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_pool_string_array_append",
+ "name": "godot_packed_string_array_append",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"],
+ ["godot_packed_string_array *", "p_self"],
["const godot_string *", "p_data"]
]
},
{
- "name": "godot_pool_string_array_append_array",
+ "name": "godot_packed_string_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"],
- ["const godot_pool_string_array *", "p_array"]
+ ["godot_packed_string_array *", "p_self"],
+ ["const godot_packed_string_array *", "p_array"]
]
},
{
- "name": "godot_pool_string_array_insert",
+ "name": "godot_packed_string_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_pool_string_array *", "p_self"],
+ ["godot_packed_string_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_string *", "p_data"]
]
},
{
- "name": "godot_pool_string_array_invert",
+ "name": "godot_packed_string_array_invert",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"]
+ ["godot_packed_string_array *", "p_self"]
]
},
{
- "name": "godot_pool_string_array_push_back",
+ "name": "godot_packed_string_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"],
+ ["godot_packed_string_array *", "p_self"],
["const godot_string *", "p_data"]
]
},
{
- "name": "godot_pool_string_array_remove",
+ "name": "godot_packed_string_array_remove",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"],
+ ["godot_packed_string_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_string_array_resize",
+ "name": "godot_packed_string_array_resize",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"],
+ ["godot_packed_string_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_pool_string_array_read",
- "return_type": "godot_pool_string_array_read_access *",
- "arguments": [
- ["const godot_pool_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_string_array_write",
- "return_type": "godot_pool_string_array_write_access *",
- "arguments": [
- ["godot_pool_string_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_string_array_set",
+ "name": "godot_packed_string_array_set",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"],
+ ["godot_packed_string_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_string *", "p_data"]
]
},
{
- "name": "godot_pool_string_array_get",
+ "name": "godot_packed_string_array_get",
"return_type": "godot_string",
"arguments": [
- ["const godot_pool_string_array *", "p_self"],
+ ["const godot_packed_string_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_string_array_size",
+ "name": "godot_packed_string_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_string_array *", "p_self"]
+ ["const godot_packed_string_array *", "p_self"]
]
},
{
- "name": "godot_pool_string_array_destroy",
+ "name": "godot_packed_string_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_pool_string_array *", "p_self"]
+ ["godot_packed_string_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector2_array_new",
+ "name": "godot_packed_vector2_array_new",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "r_dest"]
+ ["godot_packed_vector2_array *", "r_dest"]
]
},
{
- "name": "godot_pool_vector2_array_new_copy",
+ "name": "godot_packed_vector2_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "r_dest"],
- ["const godot_pool_vector2_array *", "p_src"]
+ ["godot_packed_vector2_array *", "r_dest"],
+ ["const godot_packed_vector2_array *", "p_src"]
]
},
{
- "name": "godot_pool_vector2_array_new_with_array",
+ "name": "godot_packed_vector2_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "r_dest"],
+ ["godot_packed_vector2_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_pool_vector2_array_append",
+ "name": "godot_packed_vector2_array_append",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"],
+ ["godot_packed_vector2_array *", "p_self"],
["const godot_vector2 *", "p_data"]
]
},
{
- "name": "godot_pool_vector2_array_append_array",
+ "name": "godot_packed_vector2_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"],
- ["const godot_pool_vector2_array *", "p_array"]
+ ["godot_packed_vector2_array *", "p_self"],
+ ["const godot_packed_vector2_array *", "p_array"]
]
},
{
- "name": "godot_pool_vector2_array_insert",
+ "name": "godot_packed_vector2_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"],
+ ["godot_packed_vector2_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_vector2 *", "p_data"]
]
},
{
- "name": "godot_pool_vector2_array_invert",
+ "name": "godot_packed_vector2_array_invert",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"]
+ ["godot_packed_vector2_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector2_array_push_back",
+ "name": "godot_packed_vector2_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"],
+ ["godot_packed_vector2_array *", "p_self"],
["const godot_vector2 *", "p_data"]
]
},
{
- "name": "godot_pool_vector2_array_remove",
+ "name": "godot_packed_vector2_array_remove",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"],
+ ["godot_packed_vector2_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_vector2_array_resize",
+ "name": "godot_packed_vector2_array_resize",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"],
+ ["godot_packed_vector2_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_pool_vector2_array_read",
- "return_type": "godot_pool_vector2_array_read_access *",
- "arguments": [
- ["const godot_pool_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_write",
- "return_type": "godot_pool_vector2_array_write_access *",
- "arguments": [
- ["godot_pool_vector2_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_set",
+ "name": "godot_packed_vector2_array_set",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"],
+ ["godot_packed_vector2_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_vector2 *", "p_data"]
]
},
{
- "name": "godot_pool_vector2_array_get",
+ "name": "godot_packed_vector2_array_get",
"return_type": "godot_vector2",
"arguments": [
- ["const godot_pool_vector2_array *", "p_self"],
+ ["const godot_packed_vector2_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_vector2_array_size",
+ "name": "godot_packed_vector2_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_vector2_array *", "p_self"]
+ ["const godot_packed_vector2_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector2_array_destroy",
+ "name": "godot_packed_vector2_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_pool_vector2_array *", "p_self"]
+ ["godot_packed_vector2_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector3_array_new",
+ "name": "godot_packed_vector3_array_new",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "r_dest"]
+ ["godot_packed_vector3_array *", "r_dest"]
]
},
{
- "name": "godot_pool_vector3_array_new_copy",
+ "name": "godot_packed_vector3_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "r_dest"],
- ["const godot_pool_vector3_array *", "p_src"]
+ ["godot_packed_vector3_array *", "r_dest"],
+ ["const godot_packed_vector3_array *", "p_src"]
]
},
{
- "name": "godot_pool_vector3_array_new_with_array",
+ "name": "godot_packed_vector3_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "r_dest"],
+ ["godot_packed_vector3_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_pool_vector3_array_append",
+ "name": "godot_packed_vector3_array_append",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"],
+ ["godot_packed_vector3_array *", "p_self"],
["const godot_vector3 *", "p_data"]
]
},
{
- "name": "godot_pool_vector3_array_append_array",
+ "name": "godot_packed_vector3_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"],
- ["const godot_pool_vector3_array *", "p_array"]
+ ["godot_packed_vector3_array *", "p_self"],
+ ["const godot_packed_vector3_array *", "p_array"]
]
},
{
- "name": "godot_pool_vector3_array_insert",
+ "name": "godot_packed_vector3_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"],
+ ["godot_packed_vector3_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_vector3 *", "p_data"]
]
},
{
- "name": "godot_pool_vector3_array_invert",
+ "name": "godot_packed_vector3_array_invert",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"]
+ ["godot_packed_vector3_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector3_array_push_back",
+ "name": "godot_packed_vector3_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"],
+ ["godot_packed_vector3_array *", "p_self"],
["const godot_vector3 *", "p_data"]
]
},
{
- "name": "godot_pool_vector3_array_remove",
+ "name": "godot_packed_vector3_array_remove",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"],
+ ["godot_packed_vector3_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_vector3_array_resize",
+ "name": "godot_packed_vector3_array_resize",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"],
+ ["godot_packed_vector3_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_pool_vector3_array_read",
- "return_type": "godot_pool_vector3_array_read_access *",
- "arguments": [
- ["const godot_pool_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_write",
- "return_type": "godot_pool_vector3_array_write_access *",
- "arguments": [
- ["godot_pool_vector3_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_set",
+ "name": "godot_packed_vector3_array_set",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"],
+ ["godot_packed_vector3_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_vector3 *", "p_data"]
]
},
{
- "name": "godot_pool_vector3_array_get",
+ "name": "godot_packed_vector3_array_get",
"return_type": "godot_vector3",
"arguments": [
- ["const godot_pool_vector3_array *", "p_self"],
+ ["const godot_packed_vector3_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_vector3_array_size",
+ "name": "godot_packed_vector3_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_vector3_array *", "p_self"]
+ ["const godot_packed_vector3_array *", "p_self"]
]
},
{
- "name": "godot_pool_vector3_array_destroy",
+ "name": "godot_packed_vector3_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_pool_vector3_array *", "p_self"]
+ ["godot_packed_vector3_array *", "p_self"]
]
},
{
- "name": "godot_pool_color_array_new",
+ "name": "godot_packed_color_array_new",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "r_dest"]
+ ["godot_packed_color_array *", "r_dest"]
]
},
{
- "name": "godot_pool_color_array_new_copy",
+ "name": "godot_packed_color_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "r_dest"],
- ["const godot_pool_color_array *", "p_src"]
+ ["godot_packed_color_array *", "r_dest"],
+ ["const godot_packed_color_array *", "p_src"]
]
},
{
- "name": "godot_pool_color_array_new_with_array",
+ "name": "godot_packed_color_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "r_dest"],
+ ["godot_packed_color_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_pool_color_array_append",
+ "name": "godot_packed_color_array_append",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "p_self"],
+ ["godot_packed_color_array *", "p_self"],
["const godot_color *", "p_data"]
]
},
{
- "name": "godot_pool_color_array_append_array",
+ "name": "godot_packed_color_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "p_self"],
- ["const godot_pool_color_array *", "p_array"]
+ ["godot_packed_color_array *", "p_self"],
+ ["const godot_packed_color_array *", "p_array"]
]
},
{
- "name": "godot_pool_color_array_insert",
+ "name": "godot_packed_color_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_pool_color_array *", "p_self"],
+ ["godot_packed_color_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_color *", "p_data"]
]
},
{
- "name": "godot_pool_color_array_invert",
+ "name": "godot_packed_color_array_invert",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "p_self"]
+ ["godot_packed_color_array *", "p_self"]
]
},
{
- "name": "godot_pool_color_array_push_back",
+ "name": "godot_packed_color_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "p_self"],
+ ["godot_packed_color_array *", "p_self"],
["const godot_color *", "p_data"]
]
},
{
- "name": "godot_pool_color_array_remove",
+ "name": "godot_packed_color_array_remove",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "p_self"],
+ ["godot_packed_color_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_color_array_resize",
+ "name": "godot_packed_color_array_resize",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "p_self"],
+ ["godot_packed_color_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_pool_color_array_read",
- "return_type": "godot_pool_color_array_read_access *",
- "arguments": [
- ["const godot_pool_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_color_array_write",
- "return_type": "godot_pool_color_array_write_access *",
- "arguments": [
- ["godot_pool_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_color_array_set",
+ "name": "godot_packed_color_array_set",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array *", "p_self"],
+ ["godot_packed_color_array *", "p_self"],
["const godot_int", "p_idx"],
["const godot_color *", "p_data"]
]
},
{
- "name": "godot_pool_color_array_get",
+ "name": "godot_packed_color_array_get",
"return_type": "godot_color",
"arguments": [
- ["const godot_pool_color_array *", "p_self"],
+ ["const godot_packed_color_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_pool_color_array_size",
+ "name": "godot_packed_color_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_pool_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_color_array_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array *", "p_self"]
- ]
- },
- {
- "name": "godot_pool_byte_array_read_access_copy",
- "return_type": "godot_pool_byte_array_read_access *",
- "arguments": [
- ["const godot_pool_byte_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_byte_array_read_access_ptr",
- "return_type": "const uint8_t *",
- "arguments": [
- ["const godot_pool_byte_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_byte_array_read_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array_read_access *", "p_read"],
- ["godot_pool_byte_array_read_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_byte_array_read_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_int_array_read_access_copy",
- "return_type": "godot_pool_int_array_read_access *",
- "arguments": [
- ["const godot_pool_int_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_int_array_read_access_ptr",
- "return_type": "const godot_int *",
- "arguments": [
- ["const godot_pool_int_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_int_array_read_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array_read_access *", "p_read"],
- ["godot_pool_int_array_read_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_int_array_read_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_real_array_read_access_copy",
- "return_type": "godot_pool_real_array_read_access *",
- "arguments": [
- ["const godot_pool_real_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_real_array_read_access_ptr",
- "return_type": "const godot_real *",
- "arguments": [
- ["const godot_pool_real_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_real_array_read_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array_read_access *", "p_read"],
- ["godot_pool_real_array_read_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_real_array_read_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_string_array_read_access_copy",
- "return_type": "godot_pool_string_array_read_access *",
- "arguments": [
- ["const godot_pool_string_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_string_array_read_access_ptr",
- "return_type": "const godot_string *",
- "arguments": [
- ["const godot_pool_string_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_string_array_read_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array_read_access *", "p_read"],
- ["godot_pool_string_array_read_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_string_array_read_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_read_access_copy",
- "return_type": "godot_pool_vector2_array_read_access *",
- "arguments": [
- ["const godot_pool_vector2_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_read_access_ptr",
- "return_type": "const godot_vector2 *",
- "arguments": [
- ["const godot_pool_vector2_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_read_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array_read_access *", "p_read"],
- ["godot_pool_vector2_array_read_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_read_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_read_access_copy",
- "return_type": "godot_pool_vector3_array_read_access *",
- "arguments": [
- ["const godot_pool_vector3_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_read_access_ptr",
- "return_type": "const godot_vector3 *",
- "arguments": [
- ["const godot_pool_vector3_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_read_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array_read_access *", "p_read"],
- ["godot_pool_vector3_array_read_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_read_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_color_array_read_access_copy",
- "return_type": "godot_pool_color_array_read_access *",
- "arguments": [
- ["const godot_pool_color_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_color_array_read_access_ptr",
- "return_type": "const godot_color *",
- "arguments": [
- ["const godot_pool_color_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_color_array_read_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array_read_access *", "p_read"],
- ["godot_pool_color_array_read_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_color_array_read_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array_read_access *", "p_read"]
- ]
- },
- {
- "name": "godot_pool_byte_array_write_access_copy",
- "return_type": "godot_pool_byte_array_write_access *",
- "arguments": [
- ["const godot_pool_byte_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_byte_array_write_access_ptr",
- "return_type": "uint8_t *",
- "arguments": [
- ["const godot_pool_byte_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_byte_array_write_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array_write_access *", "p_write"],
- ["godot_pool_byte_array_write_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_byte_array_write_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_byte_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_int_array_write_access_copy",
- "return_type": "godot_pool_int_array_write_access *",
- "arguments": [
- ["const godot_pool_int_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_int_array_write_access_ptr",
- "return_type": "godot_int *",
- "arguments": [
- ["const godot_pool_int_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_int_array_write_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array_write_access *", "p_write"],
- ["godot_pool_int_array_write_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_int_array_write_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_int_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_real_array_write_access_copy",
- "return_type": "godot_pool_real_array_write_access *",
- "arguments": [
- ["const godot_pool_real_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_real_array_write_access_ptr",
- "return_type": "godot_real *",
- "arguments": [
- ["const godot_pool_real_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_real_array_write_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array_write_access *", "p_write"],
- ["godot_pool_real_array_write_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_real_array_write_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_real_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_string_array_write_access_copy",
- "return_type": "godot_pool_string_array_write_access *",
- "arguments": [
- ["const godot_pool_string_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_string_array_write_access_ptr",
- "return_type": "godot_string *",
- "arguments": [
- ["const godot_pool_string_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_string_array_write_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array_write_access *", "p_write"],
- ["godot_pool_string_array_write_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_string_array_write_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_string_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_write_access_copy",
- "return_type": "godot_pool_vector2_array_write_access *",
- "arguments": [
- ["const godot_pool_vector2_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_write_access_ptr",
- "return_type": "godot_vector2 *",
- "arguments": [
- ["const godot_pool_vector2_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_write_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array_write_access *", "p_write"],
- ["godot_pool_vector2_array_write_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_vector2_array_write_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector2_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_write_access_copy",
- "return_type": "godot_pool_vector3_array_write_access *",
- "arguments": [
- ["const godot_pool_vector3_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_write_access_ptr",
- "return_type": "godot_vector3 *",
- "arguments": [
- ["const godot_pool_vector3_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_write_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array_write_access *", "p_write"],
- ["godot_pool_vector3_array_write_access *", "p_other"]
- ]
- },
- {
- "name": "godot_pool_vector3_array_write_access_destroy",
- "return_type": "void",
- "arguments": [
- ["godot_pool_vector3_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_color_array_write_access_copy",
- "return_type": "godot_pool_color_array_write_access *",
- "arguments": [
- ["const godot_pool_color_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_color_array_write_access_ptr",
- "return_type": "godot_color *",
- "arguments": [
- ["const godot_pool_color_array_write_access *", "p_write"]
- ]
- },
- {
- "name": "godot_pool_color_array_write_access_operator_assign",
- "return_type": "void",
- "arguments": [
- ["godot_pool_color_array_write_access *", "p_write"],
- ["godot_pool_color_array_write_access *", "p_other"]
+ ["const godot_packed_color_array *", "p_self"]
]
},
{
- "name": "godot_pool_color_array_write_access_destroy",
+ "name": "godot_packed_color_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_pool_color_array_write_access *", "p_write"]
+ ["godot_packed_color_array *", "p_self"]
]
},
{
@@ -2960,59 +2442,59 @@
]
},
{
- "name": "godot_array_new_pool_color_array",
+ "name": "godot_array_new_packed_color_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_pool_color_array *", "p_pca"]
+ ["const godot_packed_color_array *", "p_pca"]
]
},
{
- "name": "godot_array_new_pool_vector3_array",
+ "name": "godot_array_new_packed_vector3_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_pool_vector3_array *", "p_pv3a"]
+ ["const godot_packed_vector3_array *", "p_pv3a"]
]
},
{
- "name": "godot_array_new_pool_vector2_array",
+ "name": "godot_array_new_packed_vector2_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_pool_vector2_array *", "p_pv2a"]
+ ["const godot_packed_vector2_array *", "p_pv2a"]
]
},
{
- "name": "godot_array_new_pool_string_array",
+ "name": "godot_array_new_packed_string_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_pool_string_array *", "p_psa"]
+ ["const godot_packed_string_array *", "p_psa"]
]
},
{
- "name": "godot_array_new_pool_real_array",
+ "name": "godot_array_new_packed_real_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_pool_real_array *", "p_pra"]
+ ["const godot_packed_real_array *", "p_pra"]
]
},
{
- "name": "godot_array_new_pool_int_array",
+ "name": "godot_array_new_packed_int_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_pool_int_array *", "p_pia"]
+ ["const godot_packed_int_array *", "p_pia"]
]
},
{
- "name": "godot_array_new_pool_byte_array",
+ "name": "godot_array_new_packed_byte_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_pool_byte_array *", "p_pba"]
+ ["const godot_packed_byte_array *", "p_pba"]
]
},
{
@@ -4569,59 +4051,59 @@
]
},
{
- "name": "godot_variant_new_pool_byte_array",
+ "name": "godot_variant_new_packed_byte_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_pool_byte_array *", "p_pba"]
+ ["const godot_packed_byte_array *", "p_pba"]
]
},
{
- "name": "godot_variant_new_pool_int_array",
+ "name": "godot_variant_new_packed_int_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_pool_int_array *", "p_pia"]
+ ["const godot_packed_int_array *", "p_pia"]
]
},
{
- "name": "godot_variant_new_pool_real_array",
+ "name": "godot_variant_new_packed_real_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_pool_real_array *", "p_pra"]
+ ["const godot_packed_real_array *", "p_pra"]
]
},
{
- "name": "godot_variant_new_pool_string_array",
+ "name": "godot_variant_new_packed_string_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_pool_string_array *", "p_psa"]
+ ["const godot_packed_string_array *", "p_psa"]
]
},
{
- "name": "godot_variant_new_pool_vector2_array",
+ "name": "godot_variant_new_packed_vector2_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_pool_vector2_array *", "p_pv2a"]
+ ["const godot_packed_vector2_array *", "p_pv2a"]
]
},
{
- "name": "godot_variant_new_pool_vector3_array",
+ "name": "godot_variant_new_packed_vector3_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_pool_vector3_array *", "p_pv3a"]
+ ["const godot_packed_vector3_array *", "p_pv3a"]
]
},
{
- "name": "godot_variant_new_pool_color_array",
+ "name": "godot_variant_new_packed_color_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_pool_color_array *", "p_pca"]
+ ["const godot_packed_color_array *", "p_pca"]
]
},
{
@@ -4765,50 +4247,50 @@
]
},
{
- "name": "godot_variant_as_pool_byte_array",
- "return_type": "godot_pool_byte_array",
+ "name": "godot_variant_as_packed_byte_array",
+ "return_type": "godot_packed_byte_array",
"arguments": [
["const godot_variant *", "p_self"]
]
},
{
- "name": "godot_variant_as_pool_int_array",
- "return_type": "godot_pool_int_array",
+ "name": "godot_variant_as_packed_int_array",
+ "return_type": "godot_packed_int_array",
"arguments": [
["const godot_variant *", "p_self"]
]
},
{
- "name": "godot_variant_as_pool_real_array",
- "return_type": "godot_pool_real_array",
+ "name": "godot_variant_as_packed_real_array",
+ "return_type": "godot_packed_real_array",
"arguments": [
["const godot_variant *", "p_self"]
]
},
{
- "name": "godot_variant_as_pool_string_array",
- "return_type": "godot_pool_string_array",
+ "name": "godot_variant_as_packed_string_array",
+ "return_type": "godot_packed_string_array",
"arguments": [
["const godot_variant *", "p_self"]
]
},
{
- "name": "godot_variant_as_pool_vector2_array",
- "return_type": "godot_pool_vector2_array",
+ "name": "godot_variant_as_packed_vector2_array",
+ "return_type": "godot_packed_vector2_array",
"arguments": [
["const godot_variant *", "p_self"]
]
},
{
- "name": "godot_variant_as_pool_vector3_array",
- "return_type": "godot_pool_vector3_array",
+ "name": "godot_variant_as_packed_vector3_array",
+ "return_type": "godot_packed_vector3_array",
"arguments": [
["const godot_variant *", "p_self"]
]
},
{
- "name": "godot_variant_as_pool_color_array",
- "return_type": "godot_pool_color_array",
+ "name": "godot_variant_as_packed_color_array",
+ "return_type": "godot_packed_color_array",
"arguments": [
["const godot_variant *", "p_self"]
]
@@ -5796,7 +5278,7 @@
},
{
"name": "godot_string_md5_buffer",
- "return_type": "godot_pool_byte_array",
+ "return_type": "godot_packed_byte_array",
"arguments": [
["const godot_string *", "p_self"]
]
@@ -5810,7 +5292,7 @@
},
{
"name": "godot_string_sha256_buffer",
- "return_type": "godot_pool_byte_array",
+ "return_type": "godot_packed_byte_array",
"arguments": [
["const godot_string *", "p_self"]
]
@@ -6453,8 +5935,8 @@
]
},
{
- "name": "arvr",
- "type": "ARVR",
+ "name": "xr",
+ "type": "XR",
"version": {
"major": 1,
"minor": 1
@@ -6462,40 +5944,40 @@
"next": null,
"api": [
{
- "name": "godot_arvr_register_interface",
+ "name": "godot_xr_register_interface",
"return_type": "void",
"arguments": [
- ["const godot_arvr_interface_gdnative *", "p_interface"]
+ ["const godot_xr_interface_gdnative *", "p_interface"]
]
},
{
- "name": "godot_arvr_get_worldscale",
+ "name": "godot_xr_get_worldscale",
"return_type": "godot_real",
"arguments": []
},
{
- "name": "godot_arvr_get_reference_frame",
+ "name": "godot_xr_get_reference_frame",
"return_type": "godot_transform",
"arguments": []
},
{
- "name": "godot_arvr_blit",
+ "name": "godot_xr_blit",
"return_type": "void",
"arguments": [
- ["int", "p_eye"],
+ ["godot_int", "p_eye"],
["godot_rid *", "p_render_target"],
["godot_rect2 *", "p_screen_rect"]
]
},
{
- "name": "godot_arvr_get_texid",
+ "name": "godot_xr_get_texid",
"return_type": "godot_int",
"arguments": [
["godot_rid *", "p_render_target"]
]
},
{
- "name": "godot_arvr_add_controller",
+ "name": "godot_xr_add_controller",
"return_type": "godot_int",
"arguments": [
["char *", "p_device_name"],
@@ -6505,14 +5987,14 @@
]
},
{
- "name": "godot_arvr_remove_controller",
+ "name": "godot_xr_remove_controller",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"]
]
},
{
- "name": "godot_arvr_set_controller_transform",
+ "name": "godot_xr_set_controller_transform",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"],
@@ -6522,7 +6004,7 @@
]
},
{
- "name": "godot_arvr_set_controller_button",
+ "name": "godot_xr_set_controller_button",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"],
@@ -6531,7 +6013,7 @@
]
},
{
- "name": "godot_arvr_set_controller_axis",
+ "name": "godot_xr_set_controller_axis",
"return_type": "void",
"arguments": [
["godot_int", "p_controller_id"],
@@ -6541,7 +6023,7 @@
]
},
{
- "name": "godot_arvr_get_controller_rumble",
+ "name": "godot_xr_get_controller_rumble",
"return_type": "godot_real",
"arguments": [
["godot_int", "p_controller_id"]
diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py
index 0d95a65b7e..620935795f 100644
--- a/modules/gdnative/gdnative_builders.py
+++ b/modules/gdnative/gdnative_builders.py
@@ -8,209 +8,249 @@ from platform_methods import subprocess_main
def _spaced(e):
- return e if e[-1] == '*' else e + ' '
+ return e if e[-1] == "*" else e + " "
def _build_gdnative_api_struct_header(api):
out = [
- '/* THIS FILE IS GENERATED DO NOT EDIT */',
- '#ifndef GODOT_GDNATIVE_API_STRUCT_H',
- '#define GODOT_GDNATIVE_API_STRUCT_H',
- '',
- '#include <gdnative/gdnative.h>',
- '#include <android/godot_android.h>',
- '#include <arvr/godot_arvr.h>',
- '#include <nativescript/godot_nativescript.h>',
- '#include <net/godot_net.h>',
- '#include <pluginscript/godot_pluginscript.h>',
- '#include <videodecoder/godot_videodecoder.h>',
- '',
- '#ifdef __cplusplus',
+ "/* THIS FILE IS GENERATED DO NOT EDIT */",
+ "#ifndef GODOT_GDNATIVE_API_STRUCT_H",
+ "#define GODOT_GDNATIVE_API_STRUCT_H",
+ "",
+ "#include <gdnative/gdnative.h>",
+ "#include <android/godot_android.h>",
+ "#include <xr/godot_xr.h>",
+ "#include <nativescript/godot_nativescript.h>",
+ "#include <net/godot_net.h>",
+ "#include <pluginscript/godot_pluginscript.h>",
+ "#include <videodecoder/godot_videodecoder.h>",
+ "",
+ "#ifdef __cplusplus",
'extern "C" {',
- '#endif',
- '',
- 'enum GDNATIVE_API_TYPES {',
- '\tGDNATIVE_' + api['core']['type'] + ','
+ "#endif",
+ "",
+ "enum GDNATIVE_API_TYPES {",
+ "\tGDNATIVE_" + api["core"]["type"] + ",",
]
- for ext in api['extensions']:
- out += ['\tGDNATIVE_EXT_' + ext['type'] + ',']
+ for ext in api["extensions"]:
+ out += ["\tGDNATIVE_EXT_" + ext["type"] + ","]
- out += ['};', '']
+ out += ["};", ""]
def generate_extension_struct(name, ext, include_version=True):
ret_val = []
- if ext['next']:
- ret_val += generate_extension_struct(name, ext['next'])
+ if ext["next"]:
+ ret_val += generate_extension_struct(name, ext["next"])
ret_val += [
- 'typedef struct godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct {',
- '\tunsigned int type;',
- '\tgodot_gdnative_api_version version;',
- '\tconst godot_gdnative_api_struct *next;'
+ "typedef struct godot_gdnative_ext_"
+ + name
+ + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
+ + "_api_struct {",
+ "\tunsigned int type;",
+ "\tgodot_gdnative_api_version version;",
+ "\tconst godot_gdnative_api_struct *next;",
]
- for funcdef in ext['api']:
- args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
- ret_val.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))
+ for funcdef in ext["api"]:
+ args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
+ ret_val.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
- ret_val += ['} godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct;', '']
+ ret_val += [
+ "} godot_gdnative_ext_"
+ + name
+ + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
+ + "_api_struct;",
+ "",
+ ]
return ret_val
-
def generate_core_extension_struct(core):
ret_val = []
- if core['next']:
- ret_val += generate_core_extension_struct(core['next'])
+ if core["next"]:
+ ret_val += generate_core_extension_struct(core["next"])
ret_val += [
- 'typedef struct godot_gdnative_core_' + ('{0}_{1}'.format(core['version']['major'], core['version']['minor'])) + '_api_struct {',
- '\tunsigned int type;',
- '\tgodot_gdnative_api_version version;',
- '\tconst godot_gdnative_api_struct *next;',
+ "typedef struct godot_gdnative_core_"
+ + ("{0}_{1}".format(core["version"]["major"], core["version"]["minor"]))
+ + "_api_struct {",
+ "\tunsigned int type;",
+ "\tgodot_gdnative_api_version version;",
+ "\tconst godot_gdnative_api_struct *next;",
]
- for funcdef in core['api']:
- args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
- ret_val.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))
+ for funcdef in core["api"]:
+ args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
+ ret_val.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
- ret_val += ['} godot_gdnative_core_' + '{0}_{1}'.format(core['version']['major'], core['version']['minor']) + '_api_struct;', '']
+ ret_val += [
+ "} godot_gdnative_core_"
+ + "{0}_{1}".format(core["version"]["major"], core["version"]["minor"])
+ + "_api_struct;",
+ "",
+ ]
return ret_val
-
- for ext in api['extensions']:
- name = ext['name']
+ for ext in api["extensions"]:
+ name = ext["name"]
out += generate_extension_struct(name, ext, False)
- if api['core']['next']:
- out += generate_core_extension_struct(api['core']['next'])
+ if api["core"]["next"]:
+ out += generate_core_extension_struct(api["core"]["next"])
out += [
- 'typedef struct godot_gdnative_core_api_struct {',
- '\tunsigned int type;',
- '\tgodot_gdnative_api_version version;',
- '\tconst godot_gdnative_api_struct *next;',
- '\tunsigned int num_extensions;',
- '\tconst godot_gdnative_api_struct **extensions;',
+ "typedef struct godot_gdnative_core_api_struct {",
+ "\tunsigned int type;",
+ "\tgodot_gdnative_api_version version;",
+ "\tconst godot_gdnative_api_struct *next;",
+ "\tunsigned int num_extensions;",
+ "\tconst godot_gdnative_api_struct **extensions;",
]
- for funcdef in api['core']['api']:
- args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
- out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))
+ for funcdef in api["core"]["api"]:
+ args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
+ out.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
out += [
- '} godot_gdnative_core_api_struct;',
- '',
- '#ifdef __cplusplus',
- '}',
- '#endif',
- '',
- '#endif // GODOT_GDNATIVE_API_STRUCT_H',
- ''
+ "} godot_gdnative_core_api_struct;",
+ "",
+ "#ifdef __cplusplus",
+ "}",
+ "#endif",
+ "",
+ "#endif // GODOT_GDNATIVE_API_STRUCT_H",
+ "",
]
- return '\n'.join(out)
+ return "\n".join(out)
def _build_gdnative_api_struct_source(api):
- out = [
- '/* THIS FILE IS GENERATED DO NOT EDIT */',
- '',
- '#include <gdnative_api_struct.gen.h>',
- ''
- ]
+ out = ["/* THIS FILE IS GENERATED DO NOT EDIT */", "", "#include <gdnative_api_struct.gen.h>", ""]
def get_extension_struct_name(name, ext, include_version=True):
- return 'godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct'
+ return (
+ "godot_gdnative_ext_"
+ + name
+ + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
+ + "_api_struct"
+ )
def get_extension_struct_instance_name(name, ext, include_version=True):
- return 'api_extension_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_struct'
+ return (
+ "api_extension_"
+ + name
+ + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
+ + "_struct"
+ )
def get_extension_struct_definition(name, ext, include_version=True):
ret_val = []
- if ext['next']:
- ret_val += get_extension_struct_definition(name, ext['next'])
+ if ext["next"]:
+ ret_val += get_extension_struct_definition(name, ext["next"])
ret_val += [
- 'extern const ' + get_extension_struct_name(name, ext, include_version) + ' ' + get_extension_struct_instance_name(name, ext, include_version) + ' = {',
- '\tGDNATIVE_EXT_' + ext['type'] + ',',
- '\t{' + str(ext['version']['major']) + ', ' + str(ext['version']['minor']) + '},',
- '\t' + ('NULL' if not ext['next'] else ('(const godot_gdnative_api_struct *)&' + get_extension_struct_instance_name(name, ext['next']))) + ','
+ "extern const "
+ + get_extension_struct_name(name, ext, include_version)
+ + " "
+ + get_extension_struct_instance_name(name, ext, include_version)
+ + " = {",
+ "\tGDNATIVE_EXT_" + ext["type"] + ",",
+ "\t{" + str(ext["version"]["major"]) + ", " + str(ext["version"]["minor"]) + "},",
+ "\t"
+ + (
+ "nullptr"
+ if not ext["next"]
+ else ("(const godot_gdnative_api_struct *)&" + get_extension_struct_instance_name(name, ext["next"]))
+ )
+ + ",",
]
- for funcdef in ext['api']:
- ret_val.append('\t%s,' % funcdef['name'])
+ for funcdef in ext["api"]:
+ ret_val.append("\t%s," % funcdef["name"])
- ret_val += ['};\n']
+ ret_val += ["};\n"]
return ret_val
-
def get_core_struct_definition(core):
ret_val = []
- if core['next']:
- ret_val += get_core_struct_definition(core['next'])
+ if core["next"]:
+ ret_val += get_core_struct_definition(core["next"])
ret_val += [
- 'extern const godot_gdnative_core_' + ('{0}_{1}_api_struct api_{0}_{1}'.format(core['version']['major'], core['version']['minor'])) + ' = {',
- '\tGDNATIVE_' + core['type'] + ',',
- '\t{' + str(core['version']['major']) + ', ' + str(core['version']['minor']) + '},',
- '\t' + ('NULL' if not core['next'] else ('(const godot_gdnative_api_struct *)& api_{0}_{1}'.format(core['next']['version']['major'], core['next']['version']['minor']))) + ','
+ "extern const godot_gdnative_core_"
+ + ("{0}_{1}_api_struct api_{0}_{1}".format(core["version"]["major"], core["version"]["minor"]))
+ + " = {",
+ "\tGDNATIVE_" + core["type"] + ",",
+ "\t{" + str(core["version"]["major"]) + ", " + str(core["version"]["minor"]) + "},",
+ "\t"
+ + (
+ "nullptr"
+ if not core["next"]
+ else (
+ "(const godot_gdnative_api_struct *)& api_{0}_{1}".format(
+ core["next"]["version"]["major"], core["next"]["version"]["minor"]
+ )
+ )
+ )
+ + ",",
]
- for funcdef in core['api']:
- ret_val.append('\t%s,' % funcdef['name'])
+ for funcdef in core["api"]:
+ ret_val.append("\t%s," % funcdef["name"])
- ret_val += ['};\n']
+ ret_val += ["};\n"]
return ret_val
- for ext in api['extensions']:
- name = ext['name']
+ for ext in api["extensions"]:
+ name = ext["name"]
out += get_extension_struct_definition(name, ext, False)
- out += ['', 'const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {']
+ out += ["", "const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {"]
- for ext in api['extensions']:
- name = ext['name']
- out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,']
+ for ext in api["extensions"]:
+ name = ext["name"]
+ out += ["\t(godot_gdnative_api_struct *)&api_extension_" + name + "_struct,"]
- out += ['};\n']
+ out += ["};\n"]
- if api['core']['next']:
- out += get_core_struct_definition(api['core']['next'])
+ if api["core"]["next"]:
+ out += get_core_struct_definition(api["core"]["next"])
out += [
- 'extern const godot_gdnative_core_api_struct api_struct = {',
- '\tGDNATIVE_' + api['core']['type'] + ',',
- '\t{' + str(api['core']['version']['major']) + ', ' + str(api['core']['version']['minor']) + '},',
- '\t(const godot_gdnative_api_struct *)&api_1_1,',
- '\t' + str(len(api['extensions'])) + ',',
- '\tgdnative_extensions_pointers,',
+ "extern const godot_gdnative_core_api_struct api_struct = {",
+ "\tGDNATIVE_" + api["core"]["type"] + ",",
+ "\t{" + str(api["core"]["version"]["major"]) + ", " + str(api["core"]["version"]["minor"]) + "},",
+ "\t(const godot_gdnative_api_struct *)&api_1_1,",
+ "\t" + str(len(api["extensions"])) + ",",
+ "\tgdnative_extensions_pointers,",
]
- for funcdef in api['core']['api']:
- out.append('\t%s,' % funcdef['name'])
- out.append('};\n')
+ for funcdef in api["core"]["api"]:
+ out.append("\t%s," % funcdef["name"])
+ out.append("};\n")
- return '\n'.join(out)
+ return "\n".join(out)
def build_gdnative_api_struct(target, source, env):
- with open(source[0], 'r') as fd:
+ with open(source[0], "r") as fd:
api = json.load(fd)
header, source = target
- with open(header, 'w') as fd:
+ with open(header, "w") as fd:
fd.write(_build_gdnative_api_struct_header(api))
- with open(source, 'w') as fd:
+ with open(source, "w") as fd:
fd.write(_build_gdnative_api_struct_source(api))
-if __name__ == '__main__':
+if __name__ == "__main__":
subprocess_main(globals())
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index 5ffab0f80e..10ddd79d3a 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -53,14 +53,6 @@ void GDNativeLibraryEditor::edit(Ref<GDNativeLibrary> p_library) {
}
void GDNativeLibraryEditor::_bind_methods() {
-
- ClassDB::bind_method("_on_item_button", &GDNativeLibraryEditor::_on_item_button);
- ClassDB::bind_method("_on_library_selected", &GDNativeLibraryEditor::_on_library_selected);
- ClassDB::bind_method("_on_dependencies_selected", &GDNativeLibraryEditor::_on_dependencies_selected);
- ClassDB::bind_method("_on_filter_selected", &GDNativeLibraryEditor::_on_filter_selected);
- ClassDB::bind_method("_on_item_collapsed", &GDNativeLibraryEditor::_on_item_collapsed);
- ClassDB::bind_method("_on_item_activated", &GDNativeLibraryEditor::_on_item_activated);
- ClassDB::bind_method("_on_create_new_entry", &GDNativeLibraryEditor::_on_create_new_entry);
}
void GDNativeLibraryEditor::_update_tree() {
@@ -85,9 +77,9 @@ void GDNativeLibraryEditor::_update_tree() {
platform->set_text(0, E->get().name);
platform->set_metadata(0, E->get().library_extension);
- platform->set_custom_bg_color(0, get_color("prop_category", "Editor"));
- platform->set_custom_bg_color(1, get_color("prop_category", "Editor"));
- platform->set_custom_bg_color(2, get_color("prop_category", "Editor"));
+ platform->set_custom_bg_color(0, get_theme_color("prop_category", "Editor"));
+ platform->set_custom_bg_color(1, get_theme_color("prop_category", "Editor"));
+ platform->set_custom_bg_color(2, get_theme_color("prop_category", "Editor"));
platform->set_selectable(0, false);
platform->set_expand_right(0, true);
@@ -99,35 +91,35 @@ void GDNativeLibraryEditor::_update_tree() {
bit->set_text(0, it->get());
bit->set_metadata(0, target);
bit->set_selectable(0, false);
- bit->set_custom_bg_color(0, get_color("prop_subsection", "Editor"));
+ bit->set_custom_bg_color(0, get_theme_color("prop_subsection", "Editor"));
- bit->add_button(1, get_icon("Folder", "EditorIcons"), BUTTON_SELECT_LIBRARY, false, TTR("Select the dynamic library for this entry"));
+ bit->add_button(1, get_theme_icon("Folder", "EditorIcons"), BUTTON_SELECT_LIBRARY, false, TTR("Select the dynamic library for this entry"));
String file = entry_configs[target].library;
if (!file.empty()) {
- bit->add_button(1, get_icon("Clear", "EditorIcons"), BUTTON_CLEAR_LIBRARY, false, TTR("Clear"));
+ bit->add_button(1, get_theme_icon("Clear", "EditorIcons"), BUTTON_CLEAR_LIBRARY, false, TTR("Clear"));
}
bit->set_text(1, file);
- bit->add_button(2, get_icon("Folder", "EditorIcons"), BUTTON_SELECT_DEPENDENCES, false, TTR("Select dependencies of the library for this entry"));
+ bit->add_button(2, get_theme_icon("Folder", "EditorIcons"), BUTTON_SELECT_DEPENDENCES, false, TTR("Select dependencies of the library for this entry"));
Array files = entry_configs[target].dependencies;
if (files.size()) {
- bit->add_button(2, get_icon("Clear", "EditorIcons"), BUTTON_CLEAR_DEPENDENCES, false, TTR("Clear"));
+ bit->add_button(2, get_theme_icon("Clear", "EditorIcons"), BUTTON_CLEAR_DEPENDENCES, false, TTR("Clear"));
}
bit->set_text(2, Variant(files));
- bit->add_button(3, get_icon("MoveUp", "EditorIcons"), BUTTON_MOVE_UP, false, TTR("Move Up"));
- bit->add_button(3, get_icon("MoveDown", "EditorIcons"), BUTTON_MOVE_DOWN, false, TTR("Move Down"));
- bit->add_button(3, get_icon("Remove", "EditorIcons"), BUTTON_ERASE_ENTRY, false, TTR("Remove current entry"));
+ bit->add_button(3, get_theme_icon("MoveUp", "EditorIcons"), BUTTON_MOVE_UP, false, TTR("Move Up"));
+ bit->add_button(3, get_theme_icon("MoveDown", "EditorIcons"), BUTTON_MOVE_DOWN, false, TTR("Move Down"));
+ bit->add_button(3, get_theme_icon("Remove", "EditorIcons"), BUTTON_ERASE_ENTRY, false, TTR("Remove current entry"));
}
TreeItem *new_arch = tree->create_item(platform);
new_arch->set_text(0, TTR("Double click to create a new entry"));
new_arch->set_text_align(0, TreeItem::ALIGN_CENTER);
- new_arch->set_custom_color(0, get_color("accent_color", "Editor"));
+ new_arch->set_custom_color(0, get_theme_color("accent_color", "Editor"));
new_arch->set_expand_right(0, true);
new_arch->set_metadata(1, E->key());
- platform->set_collapsed(collapsed_items.find(E->get().name) != NULL);
+ platform->set_collapsed(collapsed_items.find(E->get().name) != nullptr);
}
filter->set_text(text);
}
@@ -141,15 +133,15 @@ void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
if (id == BUTTON_SELECT_LIBRARY || id == BUTTON_SELECT_DEPENDENCES) {
- EditorFileDialog::Mode mode = EditorFileDialog::MODE_OPEN_FILE;
+ EditorFileDialog::FileMode mode = EditorFileDialog::FILE_MODE_OPEN_FILE;
if (id == BUTTON_SELECT_DEPENDENCES)
- mode = EditorFileDialog::MODE_OPEN_FILES;
+ mode = EditorFileDialog::FILE_MODE_OPEN_FILES;
file_dialog->set_meta("target", target);
file_dialog->set_meta("section", section);
file_dialog->clear_filters();
file_dialog->add_filter(Object::cast_to<TreeItem>(item)->get_parent()->get_metadata(0));
- file_dialog->set_mode(mode);
+ file_dialog->set_file_mode(mode);
file_dialog->popup_centered_ratio();
} else if (id == BUTTON_CLEAR_LIBRARY) {
@@ -168,7 +160,7 @@ void GDNativeLibraryEditor::_on_library_selected(const String &file) {
_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), file);
}
-void GDNativeLibraryEditor::_on_dependencies_selected(const PoolStringArray &files) {
+void GDNativeLibraryEditor::_on_dependencies_selected(const PackedStringArray &files) {
_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), files);
}
@@ -359,7 +351,7 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
filter_list->set_item_checked(idx, true);
idx += 1;
}
- filter_list->connect("index_pressed", this, "_on_filter_selected");
+ filter_list->connect("index_pressed", callable_mp(this, &GDNativeLibraryEditor::_on_filter_selected));
tree = memnew(Tree);
container->add_child(tree);
@@ -374,25 +366,25 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
tree->set_column_title(2, TTR("Dependencies"));
tree->set_column_expand(3, false);
tree->set_column_min_width(3, int(110 * EDSCALE));
- tree->connect("button_pressed", this, "_on_item_button");
- tree->connect("item_collapsed", this, "_on_item_collapsed");
- tree->connect("item_activated", this, "_on_item_activated");
+ tree->connect("button_pressed", callable_mp(this, &GDNativeLibraryEditor::_on_item_button));
+ tree->connect("item_collapsed", callable_mp(this, &GDNativeLibraryEditor::_on_item_collapsed));
+ tree->connect("item_activated", callable_mp(this, &GDNativeLibraryEditor::_on_item_activated));
file_dialog = memnew(EditorFileDialog);
file_dialog->set_access(EditorFileDialog::ACCESS_RESOURCES);
- file_dialog->set_resizable(true);
+ //file_dialog->set_resizable(true);
add_child(file_dialog);
- file_dialog->connect("file_selected", this, "_on_library_selected");
- file_dialog->connect("files_selected", this, "_on_dependencies_selected");
+ file_dialog->connect("file_selected", callable_mp(this, &GDNativeLibraryEditor::_on_library_selected));
+ file_dialog->connect("files_selected", callable_mp(this, &GDNativeLibraryEditor::_on_dependencies_selected));
new_architecture_dialog = memnew(ConfirmationDialog);
add_child(new_architecture_dialog);
new_architecture_dialog->set_title(TTR("Add an architecture entry"));
new_architecture_input = memnew(LineEdit);
new_architecture_dialog->add_child(new_architecture_input);
- new_architecture_dialog->set_custom_minimum_size(Vector2(300, 80) * EDSCALE);
+ // new_architecture_dialog->set_custom_minimum_size(Vector2(300, 80) * EDSCALE);
new_architecture_input->set_anchors_and_margins_preset(PRESET_HCENTER_WIDE, PRESET_MODE_MINSIZE, 5 * EDSCALE);
- new_architecture_dialog->get_ok()->connect("pressed", this, "_on_create_new_entry");
+ new_architecture_dialog->get_ok()->connect("pressed", callable_mp(this, &GDNativeLibraryEditor::_on_create_new_entry));
}
void GDNativeLibraryEditorPlugin::edit(Object *p_node) {
diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h
index 7b59aaac38..b1274d08b3 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.h
+++ b/modules/gdnative/gdnative_library_editor_plugin.h
@@ -77,7 +77,7 @@ protected:
void _update_tree();
void _on_item_button(Object *item, int column, int id);
void _on_library_selected(const String &file);
- void _on_dependencies_selected(const PoolStringArray &files);
+ void _on_dependencies_selected(const PackedStringArray &files);
void _on_filter_selected(int id);
void _on_item_collapsed(Object *p_item);
void _on_item_activated();
diff --git a/modules/gdnative/gdnative_library_singleton_editor.cpp b/modules/gdnative/gdnative_library_singleton_editor.cpp
index 17a7d5492a..378339ecea 100644
--- a/modules/gdnative/gdnative_library_singleton_editor.cpp
+++ b/modules/gdnative/gdnative_library_singleton_editor.cpp
@@ -192,8 +192,6 @@ void GDNativeLibrarySingletonEditor::_notification(int p_what) {
void GDNativeLibrarySingletonEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_item_edited"), &GDNativeLibrarySingletonEditor::_item_edited);
- ClassDB::bind_method(D_METHOD("_discover_singletons"), &GDNativeLibrarySingletonEditor::_discover_singletons);
ClassDB::bind_method(D_METHOD("_update_libraries"), &GDNativeLibrarySingletonEditor::_update_libraries);
}
@@ -207,8 +205,8 @@ GDNativeLibrarySingletonEditor::GDNativeLibrarySingletonEditor() {
libraries->set_hide_root(true);
add_margin_child(TTR("Libraries: "), libraries, true);
updating = false;
- libraries->connect("item_edited", this, "_item_edited");
- EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_discover_singletons");
+ libraries->connect("item_edited", callable_mp(this, &GDNativeLibrarySingletonEditor::_item_edited));
+ EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &GDNativeLibrarySingletonEditor::_discover_singletons));
}
#endif // TOOLS_ENABLED
diff --git a/modules/gdnative/icons/icon_g_d_native_library.svg b/modules/gdnative/icons/GDNativeLibrary.svg
index b494c7af6e..b494c7af6e 100644
--- a/modules/gdnative/icons/icon_g_d_native_library.svg
+++ b/modules/gdnative/icons/GDNativeLibrary.svg
diff --git a/modules/gdnative/icons/icon_native_script.svg b/modules/gdnative/icons/NativeScript.svg
index fb9e135627..fb9e135627 100644
--- a/modules/gdnative/icons/icon_native_script.svg
+++ b/modules/gdnative/icons/NativeScript.svg
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index 36b5c77875..e3114e9348 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -62,13 +62,13 @@ extern "C" {
void GDAPI godot_array_new(godot_array *r_dest);
void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src);
-void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_pool_color_array *p_pca);
-void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_pool_vector3_array *p_pv3a);
-void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_pool_vector2_array *p_pv2a);
-void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_pool_string_array *p_psa);
-void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool_real_array *p_pra);
-void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_int_array *p_pia);
-void GDAPI godot_array_new_pool_byte_array(godot_array *r_dest, const godot_pool_byte_array *p_pba);
+void GDAPI godot_array_new_packed_color_array(godot_array *r_dest, const godot_packed_color_array *p_pca);
+void GDAPI godot_array_new_packed_vector3_array(godot_array *r_dest, const godot_packed_vector3_array *p_pv3a);
+void GDAPI godot_array_new_packed_vector2_array(godot_array *r_dest, const godot_packed_vector2_array *p_pv2a);
+void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_packed_string_array *p_psa);
+void GDAPI godot_array_new_packed_real_array(godot_array *r_dest, const godot_packed_real_array *p_pra);
+void GDAPI godot_array_new_packed_int_array(godot_array *r_dest, const godot_packed_int_array *p_pia);
+void GDAPI godot_array_new_packed_byte_array(godot_array *r_dest, const godot_packed_byte_array *p_pba);
void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value);
diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h
index 3f046b7f08..47c01dbb20 100644
--- a/modules/gdnative/include/gdnative/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -91,8 +91,6 @@ godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self);
godot_int GDAPI godot_color_to_argb32(const godot_color *p_self);
-godot_real GDAPI godot_color_gray(const godot_color *p_self);
-
godot_color GDAPI godot_color_inverted(const godot_color *p_self);
godot_color GDAPI godot_color_contrasted(const godot_color *p_self);
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index e19a2ec149..6fdca30122 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -127,7 +127,7 @@ typedef bool godot_bool;
/////// int
-typedef int godot_int;
+typedef int64_t godot_int;
/////// real
@@ -282,9 +282,7 @@ void GDAPI godot_print_error(const char *p_description, const char *p_function,
void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line);
void GDAPI godot_print(const godot_string *p_message);
-// GDNATIVE CORE 1.0.1
-
-bool GDAPI godot_is_instance_valid(const godot_object *p_object);
+// GDNATIVE CORE 1.0.2?
//tags used for safe dynamic casting
void GDAPI *godot_get_class_tag(const godot_string_name *p_class);
diff --git a/modules/gdnative/include/gdnative/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h
index 7d51b3cd5c..c610377f54 100644
--- a/modules/gdnative/include/gdnative/pool_arrays.h
+++ b/modules/gdnative/include/gdnative/pool_arrays.h
@@ -37,113 +37,81 @@ extern "C" {
#include <stdint.h>
-/////// Read Access
+/////// PackedByteArray
-#define GODOT_POOL_ARRAY_READ_ACCESS_SIZE 1
+#define GODOT_PACKED_BYTE_ARRAY_SIZE sizeof(void *)
+#ifndef GODOT_CORE_API_GODOT_PACKED_BYTE_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_BYTE_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_ARRAY_READ_ACCESS_SIZE];
-} godot_pool_array_read_access;
-
-typedef godot_pool_array_read_access godot_pool_byte_array_read_access;
-typedef godot_pool_array_read_access godot_pool_int_array_read_access;
-typedef godot_pool_array_read_access godot_pool_real_array_read_access;
-typedef godot_pool_array_read_access godot_pool_string_array_read_access;
-typedef godot_pool_array_read_access godot_pool_vector2_array_read_access;
-typedef godot_pool_array_read_access godot_pool_vector3_array_read_access;
-typedef godot_pool_array_read_access godot_pool_color_array_read_access;
-
-/////// Write Access
-
-#define GODOT_POOL_ARRAY_WRITE_ACCESS_SIZE 1
-
-typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_ARRAY_WRITE_ACCESS_SIZE];
-} godot_pool_array_write_access;
-
-typedef godot_pool_array_write_access godot_pool_byte_array_write_access;
-typedef godot_pool_array_write_access godot_pool_int_array_write_access;
-typedef godot_pool_array_write_access godot_pool_real_array_write_access;
-typedef godot_pool_array_write_access godot_pool_string_array_write_access;
-typedef godot_pool_array_write_access godot_pool_vector2_array_write_access;
-typedef godot_pool_array_write_access godot_pool_vector3_array_write_access;
-typedef godot_pool_array_write_access godot_pool_color_array_write_access;
-
-/////// PoolByteArray
-
-#define GODOT_POOL_BYTE_ARRAY_SIZE sizeof(void *)
-
-#ifndef GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED
-typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_BYTE_ARRAY_SIZE];
-} godot_pool_byte_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_BYTE_ARRAY_SIZE];
+} godot_packed_byte_array;
#endif
-/////// PoolIntArray
+/////// PackedInt32Array
-#define GODOT_POOL_INT_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_INT_ARRAY_SIZE sizeof(void *)
-#ifndef GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_PACKED_INT_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_INT_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_INT_ARRAY_SIZE];
-} godot_pool_int_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_INT_ARRAY_SIZE];
+} godot_packed_int_array;
#endif
-/////// PoolRealArray
+/////// PackedFloat32Array
-#define GODOT_POOL_REAL_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_REAL_ARRAY_SIZE sizeof(void *)
-#ifndef GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_PACKED_REAL_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_REAL_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_REAL_ARRAY_SIZE];
-} godot_pool_real_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_REAL_ARRAY_SIZE];
+} godot_packed_real_array;
#endif
-/////// PoolStringArray
+/////// PackedStringArray
-#define GODOT_POOL_STRING_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_STRING_ARRAY_SIZE sizeof(void *)
-#ifndef GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_PACKED_STRING_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_STRING_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_STRING_ARRAY_SIZE];
-} godot_pool_string_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_STRING_ARRAY_SIZE];
+} godot_packed_string_array;
#endif
-/////// PoolVector2Array
+/////// PackedVector2Array
-#define GODOT_POOL_VECTOR2_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_VECTOR2_ARRAY_SIZE sizeof(void *)
-#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_PACKED_VECTOR2_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_VECTOR2_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_VECTOR2_ARRAY_SIZE];
-} godot_pool_vector2_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_VECTOR2_ARRAY_SIZE];
+} godot_packed_vector2_array;
#endif
-/////// PoolVector3Array
+/////// PackedVector3Array
-#define GODOT_POOL_VECTOR3_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_VECTOR3_ARRAY_SIZE sizeof(void *)
-#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_PACKED_VECTOR3_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_VECTOR3_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_VECTOR3_ARRAY_SIZE];
-} godot_pool_vector3_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_VECTOR3_ARRAY_SIZE];
+} godot_packed_vector3_array;
#endif
-/////// PoolColorArray
+/////// PackedColorArray
-#define GODOT_POOL_COLOR_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_COLOR_ARRAY_SIZE sizeof(void *)
-#ifndef GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_PACKED_COLOR_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_COLOR_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_POOL_COLOR_ARRAY_SIZE];
-} godot_pool_color_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_COLOR_ARRAY_SIZE];
+} godot_packed_color_array;
#endif
// reduce extern "C" nesting for VS2013
@@ -164,312 +132,206 @@ extern "C" {
// byte
-void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *r_dest);
-void GDAPI godot_pool_byte_array_new_copy(godot_pool_byte_array *r_dest, const godot_pool_byte_array *p_src);
-void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *r_dest, const godot_array *p_a);
+void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *r_dest);
+void GDAPI godot_packed_byte_array_new_copy(godot_packed_byte_array *r_dest, const godot_packed_byte_array *p_src);
+void GDAPI godot_packed_byte_array_new_with_array(godot_packed_byte_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_self, const uint8_t p_data);
+void GDAPI godot_packed_byte_array_append(godot_packed_byte_array *p_self, const uint8_t p_data);
-void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_self, const godot_pool_byte_array *p_array);
+void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self, const godot_packed_byte_array *p_array);
-godot_error GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
+godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
-void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_self);
+void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self);
-void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_self, const uint8_t p_data);
+void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data);
-void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_byte_array_remove(godot_packed_byte_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_byte_array_resize(godot_packed_byte_array *p_self, const godot_int p_size);
-godot_pool_byte_array_read_access GDAPI *godot_pool_byte_array_read(const godot_pool_byte_array *p_self);
+void GDAPI godot_packed_byte_array_set(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
+uint8_t GDAPI godot_packed_byte_array_get(const godot_packed_byte_array *p_self, const godot_int p_idx);
-godot_pool_byte_array_write_access GDAPI *godot_pool_byte_array_write(godot_pool_byte_array *p_self);
+godot_int GDAPI godot_packed_byte_array_size(const godot_packed_byte_array *p_self);
-void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
-uint8_t GDAPI godot_pool_byte_array_get(const godot_pool_byte_array *p_self, const godot_int p_idx);
+godot_bool GDAPI godot_packed_byte_array_empty(const godot_packed_byte_array *p_self);
-godot_int GDAPI godot_pool_byte_array_size(const godot_pool_byte_array *p_self);
-
-godot_bool GDAPI godot_pool_byte_array_empty(const godot_pool_byte_array *p_self);
-
-void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_self);
+void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self);
// int
-void GDAPI godot_pool_int_array_new(godot_pool_int_array *r_dest);
-void GDAPI godot_pool_int_array_new_copy(godot_pool_int_array *r_dest, const godot_pool_int_array *p_src);
-void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *r_dest, const godot_array *p_a);
-
-void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_self, const godot_int p_data);
+void GDAPI godot_packed_int_array_new(godot_packed_int_array *r_dest);
+void GDAPI godot_packed_int_array_new_copy(godot_packed_int_array *r_dest, const godot_packed_int_array *p_src);
+void GDAPI godot_packed_int_array_new_with_array(godot_packed_int_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_self, const godot_pool_int_array *p_array);
+void GDAPI godot_packed_int_array_append(godot_packed_int_array *p_self, const godot_int p_data);
-godot_error GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data);
+void GDAPI godot_packed_int_array_append_array(godot_packed_int_array *p_self, const godot_packed_int_array *p_array);
-void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_self);
+godot_error GDAPI godot_packed_int_array_insert(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data);
-void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_self, const godot_int p_data);
+void GDAPI godot_packed_int_array_invert(godot_packed_int_array *p_self);
-void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_int_array_push_back(godot_packed_int_array *p_self, const godot_int p_data);
-void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_int_array_remove(godot_packed_int_array *p_self, const godot_int p_idx);
-godot_pool_int_array_read_access GDAPI *godot_pool_int_array_read(const godot_pool_int_array *p_self);
+void GDAPI godot_packed_int_array_resize(godot_packed_int_array *p_self, const godot_int p_size);
-godot_pool_int_array_write_access GDAPI *godot_pool_int_array_write(godot_pool_int_array *p_self);
+void GDAPI godot_packed_int_array_set(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data);
+godot_int GDAPI godot_packed_int_array_get(const godot_packed_int_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data);
-godot_int GDAPI godot_pool_int_array_get(const godot_pool_int_array *p_self, const godot_int p_idx);
+godot_int GDAPI godot_packed_int_array_size(const godot_packed_int_array *p_self);
-godot_int GDAPI godot_pool_int_array_size(const godot_pool_int_array *p_self);
+godot_bool GDAPI godot_packed_int_array_empty(const godot_packed_int_array *p_self);
-godot_bool GDAPI godot_pool_int_array_empty(const godot_pool_int_array *p_self);
-
-void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_self);
+void GDAPI godot_packed_int_array_destroy(godot_packed_int_array *p_self);
// real
-void GDAPI godot_pool_real_array_new(godot_pool_real_array *r_dest);
-void GDAPI godot_pool_real_array_new_copy(godot_pool_real_array *r_dest, const godot_pool_real_array *p_src);
-void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *r_dest, const godot_array *p_a);
-
-void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_self, const godot_real p_data);
+void GDAPI godot_packed_real_array_new(godot_packed_real_array *r_dest);
+void GDAPI godot_packed_real_array_new_copy(godot_packed_real_array *r_dest, const godot_packed_real_array *p_src);
+void GDAPI godot_packed_real_array_new_with_array(godot_packed_real_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_self, const godot_pool_real_array *p_array);
+void GDAPI godot_packed_real_array_append(godot_packed_real_array *p_self, const godot_real p_data);
-godot_error GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data);
+void GDAPI godot_packed_real_array_append_array(godot_packed_real_array *p_self, const godot_packed_real_array *p_array);
-void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_self);
+godot_error GDAPI godot_packed_real_array_insert(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data);
-void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_self, const godot_real p_data);
+void GDAPI godot_packed_real_array_invert(godot_packed_real_array *p_self);
-void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_real_array_push_back(godot_packed_real_array *p_self, const godot_real p_data);
-void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_real_array_remove(godot_packed_real_array *p_self, const godot_int p_idx);
-godot_pool_real_array_read_access GDAPI *godot_pool_real_array_read(const godot_pool_real_array *p_self);
+void GDAPI godot_packed_real_array_resize(godot_packed_real_array *p_self, const godot_int p_size);
-godot_pool_real_array_write_access GDAPI *godot_pool_real_array_write(godot_pool_real_array *p_self);
+void GDAPI godot_packed_real_array_set(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data);
+godot_real GDAPI godot_packed_real_array_get(const godot_packed_real_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data);
-godot_real GDAPI godot_pool_real_array_get(const godot_pool_real_array *p_self, const godot_int p_idx);
+godot_int GDAPI godot_packed_real_array_size(const godot_packed_real_array *p_self);
-godot_int GDAPI godot_pool_real_array_size(const godot_pool_real_array *p_self);
+godot_bool GDAPI godot_packed_real_array_empty(const godot_packed_real_array *p_self);
-godot_bool GDAPI godot_pool_real_array_empty(const godot_pool_real_array *p_self);
-
-void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_self);
+void GDAPI godot_packed_real_array_destroy(godot_packed_real_array *p_self);
// string
-void GDAPI godot_pool_string_array_new(godot_pool_string_array *r_dest);
-void GDAPI godot_pool_string_array_new_copy(godot_pool_string_array *r_dest, const godot_pool_string_array *p_src);
-void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *r_dest, const godot_array *p_a);
-
-void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_self, const godot_string *p_data);
-
-void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_self, const godot_pool_string_array *p_array);
+void GDAPI godot_packed_string_array_new(godot_packed_string_array *r_dest);
+void GDAPI godot_packed_string_array_new_copy(godot_packed_string_array *r_dest, const godot_packed_string_array *p_src);
+void GDAPI godot_packed_string_array_new_with_array(godot_packed_string_array *r_dest, const godot_array *p_a);
-godot_error GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
+void GDAPI godot_packed_string_array_append(godot_packed_string_array *p_self, const godot_string *p_data);
-void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_self);
+void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_self, const godot_packed_string_array *p_array);
-void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_self, const godot_string *p_data);
+godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
-void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self);
-void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data);
-godot_pool_string_array_read_access GDAPI *godot_pool_string_array_read(const godot_pool_string_array *p_self);
+void GDAPI godot_packed_string_array_remove(godot_packed_string_array *p_self, const godot_int p_idx);
-godot_pool_string_array_write_access GDAPI *godot_pool_string_array_write(godot_pool_string_array *p_self);
+void GDAPI godot_packed_string_array_resize(godot_packed_string_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
-godot_string GDAPI godot_pool_string_array_get(const godot_pool_string_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_string_array_set(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
+godot_string GDAPI godot_packed_string_array_get(const godot_packed_string_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_string_array_size(const godot_pool_string_array *p_self);
+godot_int GDAPI godot_packed_string_array_size(const godot_packed_string_array *p_self);
-godot_bool GDAPI godot_pool_string_array_empty(const godot_pool_string_array *p_self);
+godot_bool GDAPI godot_packed_string_array_empty(const godot_packed_string_array *p_self);
-void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_self);
+void GDAPI godot_packed_string_array_destroy(godot_packed_string_array *p_self);
// vector2
-void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *r_dest);
-void GDAPI godot_pool_vector2_array_new_copy(godot_pool_vector2_array *r_dest, const godot_pool_vector2_array *p_src);
-void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *r_dest, const godot_array *p_a);
-
-void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_self, const godot_vector2 *p_data);
-
-void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_self, const godot_pool_vector2_array *p_array);
+void GDAPI godot_packed_vector2_array_new(godot_packed_vector2_array *r_dest);
+void GDAPI godot_packed_vector2_array_new_copy(godot_packed_vector2_array *r_dest, const godot_packed_vector2_array *p_src);
+void GDAPI godot_packed_vector2_array_new_with_array(godot_packed_vector2_array *r_dest, const godot_array *p_a);
-godot_error GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
+void GDAPI godot_packed_vector2_array_append(godot_packed_vector2_array *p_self, const godot_vector2 *p_data);
-void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_self);
+void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p_self, const godot_packed_vector2_array *p_array);
-void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_self, const godot_vector2 *p_data);
+godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
-void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self);
-void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data);
-godot_pool_vector2_array_read_access GDAPI *godot_pool_vector2_array_read(const godot_pool_vector2_array *p_self);
+void GDAPI godot_packed_vector2_array_remove(godot_packed_vector2_array *p_self, const godot_int p_idx);
-godot_pool_vector2_array_write_access GDAPI *godot_pool_vector2_array_write(godot_pool_vector2_array *p_self);
+void GDAPI godot_packed_vector2_array_resize(godot_packed_vector2_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
-godot_vector2 GDAPI godot_pool_vector2_array_get(const godot_pool_vector2_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_vector2_array_set(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
+godot_vector2 GDAPI godot_packed_vector2_array_get(const godot_packed_vector2_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_vector2_array_size(const godot_pool_vector2_array *p_self);
+godot_int GDAPI godot_packed_vector2_array_size(const godot_packed_vector2_array *p_self);
-godot_bool GDAPI godot_pool_vector2_array_empty(const godot_pool_vector2_array *p_self);
+godot_bool GDAPI godot_packed_vector2_array_empty(const godot_packed_vector2_array *p_self);
-void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_self);
+void GDAPI godot_packed_vector2_array_destroy(godot_packed_vector2_array *p_self);
// vector3
-void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *r_dest);
-void GDAPI godot_pool_vector3_array_new_copy(godot_pool_vector3_array *r_dest, const godot_pool_vector3_array *p_src);
-void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *r_dest, const godot_array *p_a);
+void GDAPI godot_packed_vector3_array_new(godot_packed_vector3_array *r_dest);
+void GDAPI godot_packed_vector3_array_new_copy(godot_packed_vector3_array *r_dest, const godot_packed_vector3_array *p_src);
+void GDAPI godot_packed_vector3_array_new_with_array(godot_packed_vector3_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_self, const godot_vector3 *p_data);
+void GDAPI godot_packed_vector3_array_append(godot_packed_vector3_array *p_self, const godot_vector3 *p_data);
-void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_self, const godot_pool_vector3_array *p_array);
+void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p_self, const godot_packed_vector3_array *p_array);
-godot_error GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
+godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
-void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_self);
+void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self);
-void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_self, const godot_vector3 *p_data);
+void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data);
-void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_vector3_array_remove(godot_packed_vector3_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_vector3_array_resize(godot_packed_vector3_array *p_self, const godot_int p_size);
-godot_pool_vector3_array_read_access GDAPI *godot_pool_vector3_array_read(const godot_pool_vector3_array *p_self);
+void GDAPI godot_packed_vector3_array_set(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
+godot_vector3 GDAPI godot_packed_vector3_array_get(const godot_packed_vector3_array *p_self, const godot_int p_idx);
-godot_pool_vector3_array_write_access GDAPI *godot_pool_vector3_array_write(godot_pool_vector3_array *p_self);
+godot_int GDAPI godot_packed_vector3_array_size(const godot_packed_vector3_array *p_self);
-void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
-godot_vector3 GDAPI godot_pool_vector3_array_get(const godot_pool_vector3_array *p_self, const godot_int p_idx);
+godot_bool GDAPI godot_packed_vector3_array_empty(const godot_packed_vector3_array *p_self);
-godot_int GDAPI godot_pool_vector3_array_size(const godot_pool_vector3_array *p_self);
-
-godot_bool GDAPI godot_pool_vector3_array_empty(const godot_pool_vector3_array *p_self);
-
-void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_self);
+void GDAPI godot_packed_vector3_array_destroy(godot_packed_vector3_array *p_self);
// color
-void GDAPI godot_pool_color_array_new(godot_pool_color_array *r_dest);
-void GDAPI godot_pool_color_array_new_copy(godot_pool_color_array *r_dest, const godot_pool_color_array *p_src);
-void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *r_dest, const godot_array *p_a);
-
-void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_self, const godot_color *p_data);
-
-void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_self, const godot_pool_color_array *p_array);
-
-godot_error GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
-
-void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_self);
-
-void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_self, const godot_color *p_data);
-
-void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_self, const godot_int p_idx);
-
-void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_self, const godot_int p_size);
-
-godot_pool_color_array_read_access GDAPI *godot_pool_color_array_read(const godot_pool_color_array *p_self);
-
-godot_pool_color_array_write_access GDAPI *godot_pool_color_array_write(godot_pool_color_array *p_self);
-
-void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
-godot_color GDAPI godot_pool_color_array_get(const godot_pool_color_array *p_self, const godot_int p_idx);
-
-godot_int GDAPI godot_pool_color_array_size(const godot_pool_color_array *p_self);
-
-godot_bool GDAPI godot_pool_color_array_empty(const godot_pool_color_array *p_self);
-
-void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self);
-
-//
-// read accessor functions
-//
-
-godot_pool_byte_array_read_access GDAPI *godot_pool_byte_array_read_access_copy(const godot_pool_byte_array_read_access *p_other);
-const uint8_t GDAPI *godot_pool_byte_array_read_access_ptr(const godot_pool_byte_array_read_access *p_read);
-void GDAPI godot_pool_byte_array_read_access_operator_assign(godot_pool_byte_array_read_access *p_read, godot_pool_byte_array_read_access *p_other);
-void GDAPI godot_pool_byte_array_read_access_destroy(godot_pool_byte_array_read_access *p_read);
-
-godot_pool_int_array_read_access GDAPI *godot_pool_int_array_read_access_copy(const godot_pool_int_array_read_access *p_other);
-const godot_int GDAPI *godot_pool_int_array_read_access_ptr(const godot_pool_int_array_read_access *p_read);
-void GDAPI godot_pool_int_array_read_access_operator_assign(godot_pool_int_array_read_access *p_read, godot_pool_int_array_read_access *p_other);
-void GDAPI godot_pool_int_array_read_access_destroy(godot_pool_int_array_read_access *p_read);
-
-godot_pool_real_array_read_access GDAPI *godot_pool_real_array_read_access_copy(const godot_pool_real_array_read_access *p_other);
-const godot_real GDAPI *godot_pool_real_array_read_access_ptr(const godot_pool_real_array_read_access *p_read);
-void GDAPI godot_pool_real_array_read_access_operator_assign(godot_pool_real_array_read_access *p_read, godot_pool_real_array_read_access *p_other);
-void GDAPI godot_pool_real_array_read_access_destroy(godot_pool_real_array_read_access *p_read);
-
-godot_pool_string_array_read_access GDAPI *godot_pool_string_array_read_access_copy(const godot_pool_string_array_read_access *p_other);
-const godot_string GDAPI *godot_pool_string_array_read_access_ptr(const godot_pool_string_array_read_access *p_read);
-void GDAPI godot_pool_string_array_read_access_operator_assign(godot_pool_string_array_read_access *p_read, godot_pool_string_array_read_access *p_other);
-void GDAPI godot_pool_string_array_read_access_destroy(godot_pool_string_array_read_access *p_read);
+void GDAPI godot_packed_color_array_new(godot_packed_color_array *r_dest);
+void GDAPI godot_packed_color_array_new_copy(godot_packed_color_array *r_dest, const godot_packed_color_array *p_src);
+void GDAPI godot_packed_color_array_new_with_array(godot_packed_color_array *r_dest, const godot_array *p_a);
-godot_pool_vector2_array_read_access GDAPI *godot_pool_vector2_array_read_access_copy(const godot_pool_vector2_array_read_access *p_other);
-const godot_vector2 GDAPI *godot_pool_vector2_array_read_access_ptr(const godot_pool_vector2_array_read_access *p_read);
-void GDAPI godot_pool_vector2_array_read_access_operator_assign(godot_pool_vector2_array_read_access *p_read, godot_pool_vector2_array_read_access *p_other);
-void GDAPI godot_pool_vector2_array_read_access_destroy(godot_pool_vector2_array_read_access *p_read);
+void GDAPI godot_packed_color_array_append(godot_packed_color_array *p_self, const godot_color *p_data);
-godot_pool_vector3_array_read_access GDAPI *godot_pool_vector3_array_read_access_copy(const godot_pool_vector3_array_read_access *p_other);
-const godot_vector3 GDAPI *godot_pool_vector3_array_read_access_ptr(const godot_pool_vector3_array_read_access *p_read);
-void GDAPI godot_pool_vector3_array_read_access_operator_assign(godot_pool_vector3_array_read_access *p_read, godot_pool_vector3_array_read_access *p_other);
-void GDAPI godot_pool_vector3_array_read_access_destroy(godot_pool_vector3_array_read_access *p_read);
+void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_self, const godot_packed_color_array *p_array);
-godot_pool_color_array_read_access GDAPI *godot_pool_color_array_read_access_copy(const godot_pool_color_array_read_access *p_other);
-const godot_color GDAPI *godot_pool_color_array_read_access_ptr(const godot_pool_color_array_read_access *p_read);
-void GDAPI godot_pool_color_array_read_access_operator_assign(godot_pool_color_array_read_access *p_read, godot_pool_color_array_read_access *p_other);
-void GDAPI godot_pool_color_array_read_access_destroy(godot_pool_color_array_read_access *p_read);
+godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
-//
-// write accessor functions
-//
+void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self);
-godot_pool_byte_array_write_access GDAPI *godot_pool_byte_array_write_access_copy(const godot_pool_byte_array_write_access *p_other);
-uint8_t GDAPI *godot_pool_byte_array_write_access_ptr(const godot_pool_byte_array_write_access *p_write);
-void GDAPI godot_pool_byte_array_write_access_operator_assign(godot_pool_byte_array_write_access *p_write, godot_pool_byte_array_write_access *p_other);
-void GDAPI godot_pool_byte_array_write_access_destroy(godot_pool_byte_array_write_access *p_write);
+void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data);
-godot_pool_int_array_write_access GDAPI *godot_pool_int_array_write_access_copy(const godot_pool_int_array_write_access *p_other);
-godot_int GDAPI *godot_pool_int_array_write_access_ptr(const godot_pool_int_array_write_access *p_write);
-void GDAPI godot_pool_int_array_write_access_operator_assign(godot_pool_int_array_write_access *p_write, godot_pool_int_array_write_access *p_other);
-void GDAPI godot_pool_int_array_write_access_destroy(godot_pool_int_array_write_access *p_write);
+void GDAPI godot_packed_color_array_remove(godot_packed_color_array *p_self, const godot_int p_idx);
-godot_pool_real_array_write_access GDAPI *godot_pool_real_array_write_access_copy(const godot_pool_real_array_write_access *p_other);
-godot_real GDAPI *godot_pool_real_array_write_access_ptr(const godot_pool_real_array_write_access *p_write);
-void GDAPI godot_pool_real_array_write_access_operator_assign(godot_pool_real_array_write_access *p_write, godot_pool_real_array_write_access *p_other);
-void GDAPI godot_pool_real_array_write_access_destroy(godot_pool_real_array_write_access *p_write);
+void GDAPI godot_packed_color_array_resize(godot_packed_color_array *p_self, const godot_int p_size);
-godot_pool_string_array_write_access GDAPI *godot_pool_string_array_write_access_copy(const godot_pool_string_array_write_access *p_other);
-godot_string GDAPI *godot_pool_string_array_write_access_ptr(const godot_pool_string_array_write_access *p_write);
-void GDAPI godot_pool_string_array_write_access_operator_assign(godot_pool_string_array_write_access *p_write, godot_pool_string_array_write_access *p_other);
-void GDAPI godot_pool_string_array_write_access_destroy(godot_pool_string_array_write_access *p_write);
+void GDAPI godot_packed_color_array_set(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
+godot_color GDAPI godot_packed_color_array_get(const godot_packed_color_array *p_self, const godot_int p_idx);
-godot_pool_vector2_array_write_access GDAPI *godot_pool_vector2_array_write_access_copy(const godot_pool_vector2_array_write_access *p_other);
-godot_vector2 GDAPI *godot_pool_vector2_array_write_access_ptr(const godot_pool_vector2_array_write_access *p_write);
-void GDAPI godot_pool_vector2_array_write_access_operator_assign(godot_pool_vector2_array_write_access *p_write, godot_pool_vector2_array_write_access *p_other);
-void GDAPI godot_pool_vector2_array_write_access_destroy(godot_pool_vector2_array_write_access *p_write);
+godot_int GDAPI godot_packed_color_array_size(const godot_packed_color_array *p_self);
-godot_pool_vector3_array_write_access GDAPI *godot_pool_vector3_array_write_access_copy(const godot_pool_vector3_array_write_access *p_other);
-godot_vector3 GDAPI *godot_pool_vector3_array_write_access_ptr(const godot_pool_vector3_array_write_access *p_write);
-void GDAPI godot_pool_vector3_array_write_access_operator_assign(godot_pool_vector3_array_write_access *p_write, godot_pool_vector3_array_write_access *p_other);
-void GDAPI godot_pool_vector3_array_write_access_destroy(godot_pool_vector3_array_write_access *p_write);
+godot_bool GDAPI godot_packed_color_array_empty(const godot_packed_color_array *p_self);
-godot_pool_color_array_write_access GDAPI *godot_pool_color_array_write_access_copy(const godot_pool_color_array_write_access *p_other);
-godot_color GDAPI *godot_pool_color_array_write_access_ptr(const godot_pool_color_array_write_access *p_write);
-void GDAPI godot_pool_color_array_write_access_operator_assign(godot_pool_color_array_write_access *p_write, godot_pool_color_array_write_access *p_other);
-void GDAPI godot_pool_color_array_write_access_destroy(godot_pool_color_array_write_access *p_write);
+void GDAPI godot_packed_color_array_destroy(godot_packed_color_array *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index b676d21fb2..608978db76 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -209,9 +209,9 @@ uint32_t GDAPI godot_string_hash_chars(const char *p_cstr);
uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len);
uint32_t GDAPI godot_string_hash_utf8_chars(const wchar_t *p_str);
uint32_t GDAPI godot_string_hash_utf8_chars_with_len(const wchar_t *p_str, godot_int p_len);
-godot_pool_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self);
+godot_packed_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self);
godot_string GDAPI godot_string_md5_text(const godot_string *p_self);
-godot_pool_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self);
+godot_packed_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self);
godot_string GDAPI godot_string_sha256_text(const godot_string *p_self);
godot_bool godot_string_empty(const godot_string *p_self);
@@ -252,7 +252,7 @@ godot_string GDAPI godot_string_dedent(const godot_string *p_self);
godot_string GDAPI godot_string_trim_prefix(const godot_string *p_self, const godot_string *p_prefix);
godot_string GDAPI godot_string_trim_suffix(const godot_string *p_self, const godot_string *p_suffix);
godot_string GDAPI godot_string_rstrip(const godot_string *p_self, const godot_string *p_chars);
-godot_pool_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor, const godot_bool p_allow_empty, const godot_int p_maxsplit);
+godot_packed_string_array GDAPI godot_string_rsplit(const godot_string *p_self, const godot_string *p_divisor, const godot_bool p_allow_empty, const godot_int p_maxsplit);
void GDAPI godot_string_destroy(godot_string *p_self);
diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h
index c65f7a28d2..934e856fbf 100644
--- a/modules/gdnative/include/gdnative/variant.h
+++ b/modules/gdnative/include/gdnative/variant.h
@@ -56,33 +56,35 @@ typedef enum godot_variant_type {
GODOT_VARIANT_TYPE_STRING,
// math types
-
- GODOT_VARIANT_TYPE_VECTOR2, // 5
+ GODOT_VARIANT_TYPE_VECTOR2,
+ GODOT_VARIANT_TYPE_VECTOR2I,
GODOT_VARIANT_TYPE_RECT2,
+ GODOT_VARIANT_TYPE_RECT2I,
GODOT_VARIANT_TYPE_VECTOR3,
+ GODOT_VARIANT_TYPE_VECTOR3I,
GODOT_VARIANT_TYPE_TRANSFORM2D,
GODOT_VARIANT_TYPE_PLANE,
- GODOT_VARIANT_TYPE_QUAT, // 10
+ GODOT_VARIANT_TYPE_QUAT,
GODOT_VARIANT_TYPE_AABB,
GODOT_VARIANT_TYPE_BASIS,
GODOT_VARIANT_TYPE_TRANSFORM,
// misc types
GODOT_VARIANT_TYPE_COLOR,
- GODOT_VARIANT_TYPE_NODE_PATH, // 15
+ GODOT_VARIANT_TYPE_NODE_PATH,
GODOT_VARIANT_TYPE_RID,
GODOT_VARIANT_TYPE_OBJECT,
GODOT_VARIANT_TYPE_DICTIONARY,
- GODOT_VARIANT_TYPE_ARRAY, // 20
+ GODOT_VARIANT_TYPE_ARRAY,
// arrays
- GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY,
- GODOT_VARIANT_TYPE_POOL_INT_ARRAY,
- GODOT_VARIANT_TYPE_POOL_REAL_ARRAY,
- GODOT_VARIANT_TYPE_POOL_STRING_ARRAY,
- GODOT_VARIANT_TYPE_POOL_VECTOR2_ARRAY, // 25
- GODOT_VARIANT_TYPE_POOL_VECTOR3_ARRAY,
- GODOT_VARIANT_TYPE_POOL_COLOR_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_BYTE_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_INT_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_REAL_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_STRING_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_VECTOR2_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_VECTOR3_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_COLOR_ARRAY,
} godot_variant_type;
typedef enum godot_variant_call_error_error {
@@ -194,13 +196,13 @@ void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid);
void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj);
void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict);
void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr);
-void GDAPI godot_variant_new_pool_byte_array(godot_variant *r_dest, const godot_pool_byte_array *p_pba);
-void GDAPI godot_variant_new_pool_int_array(godot_variant *r_dest, const godot_pool_int_array *p_pia);
-void GDAPI godot_variant_new_pool_real_array(godot_variant *r_dest, const godot_pool_real_array *p_pra);
-void GDAPI godot_variant_new_pool_string_array(godot_variant *r_dest, const godot_pool_string_array *p_psa);
-void GDAPI godot_variant_new_pool_vector2_array(godot_variant *r_dest, const godot_pool_vector2_array *p_pv2a);
-void GDAPI godot_variant_new_pool_vector3_array(godot_variant *r_dest, const godot_pool_vector3_array *p_pv3a);
-void GDAPI godot_variant_new_pool_color_array(godot_variant *r_dest, const godot_pool_color_array *p_pca);
+void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba);
+void GDAPI godot_variant_new_packed_int_array(godot_variant *r_dest, const godot_packed_int_array *p_pia);
+void GDAPI godot_variant_new_packed_real_array(godot_variant *r_dest, const godot_packed_real_array *p_pra);
+void GDAPI godot_variant_new_packed_string_array(godot_variant *r_dest, const godot_packed_string_array *p_psa);
+void GDAPI godot_variant_new_packed_vector2_array(godot_variant *r_dest, const godot_packed_vector2_array *p_pv2a);
+void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const godot_packed_vector3_array *p_pv3a);
+void GDAPI godot_variant_new_packed_color_array(godot_variant *r_dest, const godot_packed_color_array *p_pca);
godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self);
uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self);
@@ -222,13 +224,13 @@ godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_self);
godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self);
godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_self);
godot_array GDAPI godot_variant_as_array(const godot_variant *p_self);
-godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_self);
-godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_self);
-godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_self);
-godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_self);
-godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_self);
-godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_self);
-godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_self);
+godot_packed_byte_array GDAPI godot_variant_as_packed_byte_array(const godot_variant *p_self);
+godot_packed_int_array GDAPI godot_variant_as_packed_int_array(const godot_variant *p_self);
+godot_packed_real_array GDAPI godot_variant_as_packed_real_array(const godot_variant *p_self);
+godot_packed_string_array GDAPI godot_variant_as_packed_string_array(const godot_variant *p_self);
+godot_packed_vector2_array GDAPI godot_variant_as_packed_vector2_array(const godot_variant *p_self);
+godot_packed_vector3_array GDAPI godot_variant_as_packed_vector3_array(const godot_variant *p_self);
+godot_packed_color_array GDAPI godot_variant_as_packed_color_array(const godot_variant *p_self);
godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant_call_error *r_error);
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index d2ed4fb3e5..0fb5180103 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -42,9 +42,7 @@ typedef enum {
GODOT_METHOD_RPC_MODE_REMOTE,
GODOT_METHOD_RPC_MODE_MASTER,
GODOT_METHOD_RPC_MODE_PUPPET,
- GODOT_METHOD_RPC_MODE_SLAVE = GODOT_METHOD_RPC_MODE_PUPPET,
GODOT_METHOD_RPC_MODE_REMOTESYNC,
- GODOT_METHOD_RPC_MODE_SYNC = GODOT_METHOD_RPC_MODE_REMOTESYNC,
GODOT_METHOD_RPC_MODE_MASTERSYNC,
GODOT_METHOD_RPC_MODE_PUPPETSYNC,
} godot_method_rpc_mode;
@@ -56,7 +54,6 @@ typedef enum {
GODOT_PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
GODOT_PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease)
GODOT_PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
- GODOT_PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat
GODOT_PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
GODOT_PROPERTY_HINT_LAYERS_2D_RENDER,
@@ -98,8 +95,7 @@ typedef enum {
GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
GODOT_PROPERTY_USAGE_CATEGORY = 256,
- GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, // FIXME: Obsolete: drop whenever we can break compat
- GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, // FIXME: Obsolete: drop whenever we can break compat
+ GODOT_PROPERTY_USAGE_SUBGROUP = 512,
GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h
index e8822fc1ec..406c3ba663 100644
--- a/modules/gdnative/include/pluginscript/godot_pluginscript.h
+++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h
@@ -44,13 +44,12 @@ typedef void godot_pluginscript_language_data;
// --- Instance ---
-// TODO: use godot_string_name for faster lookup ?
typedef struct {
godot_pluginscript_instance_data *(*init)(godot_pluginscript_script_data *p_data, godot_object *p_owner);
void (*finish)(godot_pluginscript_instance_data *p_data);
- godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, const godot_variant *p_value);
- godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, godot_variant *r_ret);
+ godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string_name *p_name, const godot_variant *p_value);
+ godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string_name *p_name, godot_variant *r_ret);
godot_variant (*call_method)(godot_pluginscript_instance_data *p_data,
const godot_string_name *p_method, const godot_variant **p_args,
@@ -61,7 +60,7 @@ typedef struct {
//this is used by script languages that keep a reference counter of their own
//you can make make Ref<> not die when it reaches zero, so deleting the reference
//depends entirely from the script.
- // Note: You can set those function pointer to NULL if not needed.
+ // Note: You can set those function pointer to nullptr if not needed.
void (*refcount_incremented)(godot_pluginscript_instance_data *p_data);
bool (*refcount_decremented)(godot_pluginscript_instance_data *p_data); // return true if it can die
} godot_pluginscript_instance_desc;
@@ -120,31 +119,31 @@ typedef struct {
const char *name;
const char *type;
const char *extension;
- const char **recognized_extensions; // NULL terminated array
+ const char **recognized_extensions; // nullptr terminated array
godot_pluginscript_language_data *(*init)();
void (*finish)(godot_pluginscript_language_data *p_data);
- const char **reserved_words; // NULL terminated array
- const char **comment_delimiters; // NULL terminated array
- const char **string_delimiters; // NULL terminated array
+ const char **reserved_words; // nullptr terminated array
+ const char **comment_delimiters; // nullptr terminated array
+ const char **string_delimiters; // nullptr terminated array
godot_bool has_named_classes;
godot_bool supports_builtin_mode;
godot_string (*get_template_source_code)(godot_pluginscript_language_data *p_data, const godot_string *p_class_name, const godot_string *p_base_class_name);
- godot_bool (*validate)(godot_pluginscript_language_data *p_data, const godot_string *p_script, int *r_line_error, int *r_col_error, godot_string *r_test_error, const godot_string *p_path, godot_pool_string_array *r_functions);
- int (*find_function)(godot_pluginscript_language_data *p_data, const godot_string *p_function, const godot_string *p_code); // Can be NULL
- godot_string (*make_function)(godot_pluginscript_language_data *p_data, const godot_string *p_class, const godot_string *p_name, const godot_pool_string_array *p_args);
+ godot_bool (*validate)(godot_pluginscript_language_data *p_data, const godot_string *p_script, int *r_line_error, int *r_col_error, godot_string *r_test_error, const godot_string *p_path, godot_packed_string_array *r_functions);
+ int (*find_function)(godot_pluginscript_language_data *p_data, const godot_string *p_function, const godot_string *p_code); // Can be nullptr
+ godot_string (*make_function)(godot_pluginscript_language_data *p_data, const godot_string *p_class, const godot_string *p_name, const godot_packed_string_array *p_args);
godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
void (*auto_indent_code)(godot_pluginscript_language_data *p_data, godot_string *p_code, int p_from_line, int p_to_line);
- void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string *p_variable, const godot_variant *p_value);
+ void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string_name *p_variable, const godot_variant *p_value);
godot_string (*debug_get_error)(godot_pluginscript_language_data *p_data);
int (*debug_get_stack_level_count)(godot_pluginscript_language_data *p_data);
int (*debug_get_stack_level_line)(godot_pluginscript_language_data *p_data, int p_level);
godot_string (*debug_get_stack_level_function)(godot_pluginscript_language_data *p_data, int p_level);
godot_string (*debug_get_stack_level_source)(godot_pluginscript_language_data *p_data, int p_level);
- void (*debug_get_stack_level_locals)(godot_pluginscript_language_data *p_data, int p_level, godot_pool_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
- void (*debug_get_stack_level_members)(godot_pluginscript_language_data *p_data, int p_level, godot_pool_string_array *p_members, godot_array *p_values, int p_max_subitems, int p_max_depth);
- void (*debug_get_globals)(godot_pluginscript_language_data *p_data, godot_pool_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ void (*debug_get_stack_level_locals)(godot_pluginscript_language_data *p_data, int p_level, godot_packed_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ void (*debug_get_stack_level_members)(godot_pluginscript_language_data *p_data, int p_level, godot_packed_string_array *p_members, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ void (*debug_get_globals)(godot_pluginscript_language_data *p_data, godot_packed_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
godot_string (*debug_parse_stack_level_expression)(godot_pluginscript_language_data *p_data, int p_level, const godot_string *p_expression, int p_max_subitems, int p_max_depth);
// TODO: could this stuff be moved to the godot_pluginscript_language_desc ?
diff --git a/modules/gdnative/include/videodecoder/godot_videodecoder.h b/modules/gdnative/include/videodecoder/godot_videodecoder.h
index 714991ca72..3e91a2e9ac 100644
--- a/modules/gdnative/include/videodecoder/godot_videodecoder.h
+++ b/modules/gdnative/include/videodecoder/godot_videodecoder.h
@@ -54,7 +54,7 @@ typedef struct
void (*seek)(void *, godot_real);
void (*set_audio_track)(void *, godot_int);
void (*update)(void *, godot_real);
- godot_pool_byte_array *(*get_videoframe)(void *);
+ godot_packed_byte_array *(*get_videoframe)(void *);
godot_int (*get_audioframe)(void *, float *, int);
godot_int (*get_channels)(const void *);
godot_int (*get_mix_rate)(const void *);
diff --git a/modules/gdnative/include/arvr/godot_arvr.h b/modules/gdnative/include/xr/godot_xr.h
index aaef31a855..22f7f021c4 100644
--- a/modules/gdnative/include/arvr/godot_arvr.h
+++ b/modules/gdnative/include/xr/godot_xr.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_arvr.h */
+/* godot_xr.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_NATIVEARVR_H
-#define GODOT_NATIVEARVR_H
+#ifndef GODOT_NATIVEXR_H
+#define GODOT_NATIVEXR_H
#include <gdnative/gdnative.h>
@@ -61,32 +61,31 @@ typedef struct {
void (*fill_projection_for_eye)(void *, godot_real *, godot_int, godot_real, godot_real, godot_real);
void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *);
void (*process)(void *);
- // only in 1.1 onwards
godot_int (*get_external_texture_for_eye)(void *, godot_int);
void (*notification)(void *, godot_int);
godot_int (*get_camera_feed_id)(void *);
-} godot_arvr_interface_gdnative;
+} godot_xr_interface_gdnative;
-void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface);
+void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface);
-// helper functions to access ARVRServer data
-godot_real GDAPI godot_arvr_get_worldscale();
-godot_transform GDAPI godot_arvr_get_reference_frame();
+// helper functions to access XRServer data
+godot_real GDAPI godot_xr_get_worldscale();
+godot_transform GDAPI godot_xr_get_reference_frame();
// helper functions for rendering
-void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect);
-godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target);
+void GDAPI godot_xr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect);
+godot_int GDAPI godot_xr_get_texid(godot_rid *p_render_target);
-// helper functions for updating ARVR controllers
-godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
-void GDAPI godot_arvr_remove_controller(godot_int p_controller_id);
-void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
-void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed);
-void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
-godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id);
+// helper functions for updating XR controllers
+godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
+void GDAPI godot_xr_remove_controller(godot_int p_controller_id);
+void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
+void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed);
+void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
+godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id);
#ifdef __cplusplus
}
#endif
-#endif /* !GODOT_NATIVEARVR_H */
+#endif /* !GODOT_NATIVEXR_H */
diff --git a/modules/gdnative/nativescript/SCsub b/modules/gdnative/nativescript/SCsub
index 92c9d6630d..4212e87a87 100644
--- a/modules/gdnative/nativescript/SCsub
+++ b/modules/gdnative/nativescript/SCsub
@@ -1,9 +1,9 @@
#!/usr/bin/env python
-Import('env')
-Import('env_gdnative')
+Import("env")
+Import("env_gdnative")
-env_gdnative.add_source_files(env.modules_sources, '*.cpp')
+env_gdnative.add_source_files(env.modules_sources, "*.cpp")
-if "platform" in env and env["platform"] in ["x11", "iphone"]:
+if "platform" in env and env["platform"] in ["linuxbsd", "iphone"]:
env.Append(LINKFLAGS=["-rdynamic"])
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 850871579b..3c0cfd0484 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -46,7 +46,7 @@ static Error save_file(const String &p_path, const List<String> &p_content) {
ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
- for (const List<String>::Element *e = p_content.front(); e != NULL; e = e->next()) {
+ for (const List<String>::Element *e = p_content.front(); e != nullptr; e = e->next()) {
file->store_string(e->get());
}
@@ -98,7 +98,7 @@ struct SignalAPI {
struct EnumAPI {
String name;
- List<Pair<int, String> > values;
+ List<Pair<int, String>> values;
};
struct ClassAPI {
@@ -197,7 +197,7 @@ List<ClassAPI> generate_c_api_classes() {
api.push_back(global_constants_api);
}
- for (List<StringName>::Element *e = classes.front(); e != NULL; e = e->next()) {
+ for (List<StringName>::Element *e = classes.front(); e != nullptr; e = e->next()) {
StringName class_name = e->get();
ClassAPI class_api;
@@ -229,7 +229,7 @@ List<ClassAPI> generate_c_api_classes() {
List<String> constant;
ClassDB::get_integer_constant_list(class_name, &constant, true);
constant.sort_custom<NoCaseComparator>();
- for (List<String>::Element *c = constant.front(); c != NULL; c = c->next()) {
+ for (List<String>::Element *c = constant.front(); c != nullptr; c = c->next()) {
ConstantAPI constant_api;
constant_api.constant_name = c->get();
constant_api.constant_value = ClassDB::get_integer_constant(class_name, c->get());
@@ -284,7 +284,7 @@ List<ClassAPI> generate_c_api_classes() {
ClassDB::get_property_list(class_name, &properties, true);
properties.sort_custom<PropertyInfoComparator>();
- for (List<PropertyInfo>::Element *p = properties.front(); p != NULL; p = p->next()) {
+ for (List<PropertyInfo>::Element *p = properties.front(); p != nullptr; p = p->next()) {
PropertyAPI property_api;
property_api.name = p->get().name;
@@ -312,7 +312,7 @@ List<ClassAPI> generate_c_api_classes() {
ClassDB::get_method_list(class_name, &methods, true);
methods.sort_custom<MethodInfoComparator>();
- for (List<MethodInfo>::Element *m = methods.front(); m != NULL; m = m->next()) {
+ for (List<MethodInfo>::Element *m = methods.front(); m != nullptr; m = m->next()) {
MethodAPI method_api;
MethodBind *method_bind = ClassDB::get_method(class_name, m->get().name);
MethodInfo &method_info = m->get();
@@ -392,10 +392,10 @@ List<ClassAPI> generate_c_api_classes() {
enum_api.name = E->get();
ClassDB::get_enum_constants(class_name, E->get(), &value_names, true);
for (List<StringName>::Element *val_e = value_names.front(); val_e; val_e = val_e->next()) {
- int int_val = ClassDB::get_integer_constant(class_name, val_e->get(), NULL);
+ int int_val = ClassDB::get_integer_constant(class_name, val_e->get(), nullptr);
enum_api.values.push_back(Pair<int, String>(int_val, val_e->get()));
}
- enum_api.values.sort_custom<PairSort<int, String> >();
+ enum_api.values.sort_custom<PairSort<int, String>>();
class_api.enums.push_back(enum_api);
}
}
@@ -417,7 +417,7 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
source.push_back("[\n");
- for (const List<ClassAPI>::Element *c = p_api.front(); c != NULL; c = c->next()) {
+ for (const List<ClassAPI>::Element *c = p_api.front(); c != nullptr; c = c->next()) {
ClassAPI api = c->get();
source.push_back("\t{\n");
@@ -497,7 +497,7 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
source.push_back("\t\t\t{\n");
source.push_back("\t\t\t\t\"name\": \"" + e->get().name + "\",\n");
source.push_back("\t\t\t\t\"values\": {\n");
- for (List<Pair<int, String> >::Element *val_e = e->get().values.front(); val_e; val_e = val_e->next()) {
+ for (List<Pair<int, String>>::Element *val_e = e->get().values.front(); val_e; val_e = val_e->next()) {
source.push_back("\t\t\t\t\t\"" + val_e->get().second + "\": " + itos(val_e->get().first));
source.push_back(String((val_e->next() ? "," : "")) + "\n");
}
diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index e19e675344..0502458b4f 100644
--- a/modules/gdnative/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -36,6 +36,7 @@
#include "core/project_settings.h"
#include "core/variant.h"
#include "gdnative/gdnative.h"
+#include <stdint.h>
#include "nativescript.h"
@@ -67,8 +68,16 @@ void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char
if (classes->has(p_base)) {
desc.base_data = &(*classes)[p_base];
desc.base_native_type = desc.base_data->base_native_type;
+
+ const NativeScriptDesc *b = desc.base_data;
+ while (b) {
+ desc.rpc_count += b->rpc_count;
+ desc.rset_count += b->rset_count;
+ b = b->base_data;
+ }
+
} else {
- desc.base_data = NULL;
+ desc.base_data = nullptr;
desc.base_native_type = p_base;
}
@@ -87,12 +96,22 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const
desc.destroy_func = p_destroy_func;
desc.is_tool = true;
desc.base = p_base;
+ desc.rpc_count = 0;
+ desc.rset_count = 0;
if (classes->has(p_base)) {
desc.base_data = &(*classes)[p_base];
desc.base_native_type = desc.base_data->base_native_type;
+
+ const NativeScriptDesc *b = desc.base_data;
+ while (b) {
+ desc.rpc_count += b->rpc_count;
+ desc.rset_count += b->rset_count;
+ b = b->base_data;
+ }
+
} else {
- desc.base_data = NULL;
+ desc.base_data = nullptr;
desc.base_native_type = p_base;
}
@@ -109,6 +128,11 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha
NativeScriptDesc::Method method;
method.method = p_method;
method.rpc_mode = p_attr.rpc_type;
+ method.rpc_method_id = UINT16_MAX;
+ if (p_attr.rpc_type != GODOT_METHOD_RPC_MODE_DISABLED) {
+ method.rpc_method_id = E->get().rpc_count;
+ E->get().rpc_count += 1;
+ }
method.info = MethodInfo(p_function_name);
E->get().methods.insert(p_function_name, method);
@@ -125,6 +149,10 @@ void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const c
property.default_value = *(Variant *)&p_attr->default_value;
property.getter = p_get_func;
property.rset_mode = p_attr->rset_type;
+ if (p_attr->rset_type != GODOT_METHOD_RPC_MODE_DISABLED) {
+ property.rset_property_id = E->get().rset_count;
+ E->get().rset_count += 1;
+ }
property.setter = p_set_func;
property.info = PropertyInfo((Variant::Type)p_attr->type,
p_path,
@@ -182,11 +210,11 @@ void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const cha
void GDAPI *godot_nativescript_get_userdata(godot_object *p_instance) {
Object *instance = (Object *)p_instance;
if (!instance)
- return NULL;
+ return nullptr;
if (instance->get_script_instance() && instance->get_script_instance()->get_language() == NativeScriptLanguage::get_singleton()) {
return ((NativeScriptInstance *)instance->get_script_instance())->userdata;
}
- return NULL;
+ return nullptr;
}
/*
@@ -291,18 +319,18 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object)
const Object *o = (Object *)p_object;
if (!o->get_script_instance()) {
- return NULL;
+ return nullptr;
} else {
NativeScript *script = Object::cast_to<NativeScript>(o->get_script_instance()->get_script().ptr());
if (!script) {
- return NULL;
+ return nullptr;
}
if (script->get_script_desc())
return script->get_script_desc()->type_tag;
}
- return NULL;
+ return nullptr;
}
int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_instance_binding_functions p_binding_functions) {
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 8b06af6c7b..ed3ec44bf7 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -30,6 +30,8 @@
#include "nativescript.h"
+#include <stdint.h>
+
#include "gdnative/gdnative.h"
#include "core/core_string_names.h"
@@ -109,6 +111,13 @@ void NativeScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder)
#endif
+bool NativeScript::inherits_script(const Ref<Script> &p_script) const {
+#ifndef _MSC_VER
+#warning inheritance needs to be implemented in NativeScript
+#endif
+ return false;
+}
+
void NativeScript::set_class_name(String p_class_name) {
class_name = p_class_name;
}
@@ -202,7 +211,7 @@ ScriptInstance *NativeScript::instance_create(Object *p_this) {
NativeScriptDesc *script_data = get_script_desc();
if (!script_data) {
- return NULL;
+ return nullptr;
}
NativeScriptInstance *nsi = memnew(NativeScriptInstance);
@@ -212,7 +221,7 @@ ScriptInstance *NativeScript::instance_create(Object *p_this) {
#ifndef TOOLS_ENABLED
if (!ScriptServer::is_scripting_enabled()) {
- nsi->userdata = NULL;
+ nsi->userdata = nullptr;
} else {
nsi->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
}
@@ -220,15 +229,11 @@ ScriptInstance *NativeScript::instance_create(Object *p_this) {
nsi->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
#endif
-#ifndef NO_THREADS
- owners_lock->lock();
-#endif
-
- instance_owners.insert(p_this);
+ {
+ MutexLock lock(owners_lock);
-#ifndef NO_THREADS
- owners_lock->unlock();
-#endif
+ instance_owners.insert(p_this);
+ }
return nsi;
}
@@ -242,7 +247,7 @@ PlaceHolderScriptInstance *NativeScript::placeholder_instance_create(Object *p_t
return sins;
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -402,6 +407,262 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const {
}
}
+Vector<ScriptNetData> NativeScript::get_rpc_methods() const {
+
+ Vector<ScriptNetData> v;
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
+ if (E->get().rpc_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = MultiplayerAPI::RPCMode(E->get().rpc_mode);
+ v.push_back(nd);
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return v;
+}
+
+uint16_t NativeScript::get_rpc_method_id(const StringName &p_method) const {
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
+ if (E) {
+ return E->get().rpc_method_id;
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return UINT16_MAX;
+}
+
+StringName NativeScript::get_rpc_method(uint16_t p_id) const {
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName());
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
+ if (E->get().rpc_method_id == p_id) {
+ return E->key();
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rpc_mode_by_id(uint16_t p_id) const {
+
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
+ if (E->get().rpc_method_id == p_id) {
+ switch (E->get().rpc_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rpc_mode(const StringName &p_method) const {
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
+ if (E) {
+ switch (E->get().rpc_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+Vector<ScriptNetData> NativeScript::get_rset_properties() const {
+ Vector<ScriptNetData> v;
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
+ if (E.get().rset_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E.key();
+ nd.mode = MultiplayerAPI::RPCMode(E.get().rset_mode);
+ v.push_back(nd);
+ }
+ }
+ script_data = script_data->base_data;
+ }
+
+ return v;
+}
+
+uint16_t NativeScript::get_rset_property_id(const StringName &p_variable) const {
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
+ if (E) {
+ return E.get().rset_property_id;
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return UINT16_MAX;
+}
+
+StringName NativeScript::get_rset_property(uint16_t p_id) const {
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName());
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
+ if (E.get().rset_property_id == p_id) {
+ return E.key();
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rset_mode_by_id(uint16_t p_id) const {
+
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
+ if (E.get().rset_property_id == p_id) {
+ switch (E.get().rset_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rset_mode(const StringName &p_variable) const {
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
+ if (E) {
+ switch (E.get().rset_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
String NativeScript::get_class_documentation() const {
NativeScriptDesc *script_data = get_script_desc();
@@ -467,24 +728,24 @@ String NativeScript::get_property_documentation(const StringName &p_path) const
ERR_FAIL_V_MSG("", "Attempt to get property documentation for non-existent signal.");
}
-Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant NativeScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (lib_path.empty() || class_name.empty() || library.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
NativeScriptDesc *script_data = get_script_desc();
if (!script_data) {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
REF ref;
- Object *owner = NULL;
+ Object *owner = nullptr;
if (!(script_data->base_native_type == "")) {
owner = ClassDB::instance(script_data->base_native_type);
@@ -493,7 +754,7 @@ Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::Call
}
if (!owner) {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
@@ -524,17 +785,10 @@ NativeScript::NativeScript() {
library = Ref<GDNative>();
lib_path = "";
class_name = "";
-#ifndef NO_THREADS
- owners_lock = Mutex::create();
-#endif
}
NativeScript::~NativeScript() {
NSL->unregister_script(this);
-
-#ifndef NO_THREADS
- memdelete(owners_lock);
-#endif
}
#define GET_SCRIPT_DESC() script->get_script_desc()
@@ -639,7 +893,7 @@ void NativeScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c
E->get().method.method_data,
userdata,
0,
- NULL);
+ nullptr);
Variant res = *(Variant *)&result;
godot_variant_destroy(&result);
@@ -706,7 +960,7 @@ bool NativeScriptInstance::has_method(const StringName &p_method) const {
return script->has_method(p_method);
}
-Variant NativeScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant NativeScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
@@ -731,14 +985,14 @@ Variant NativeScriptInstance::call(const StringName &p_method, const Variant **p
Variant res = *(Variant *)&result;
godot_variant_destroy(&result);
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
return res;
}
script_data = script_data->base_data;
}
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
@@ -759,9 +1013,9 @@ void NativeScriptInstance::notification(int p_notification) {
String NativeScriptInstance::to_string(bool *r_valid) {
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
- Variant::CallError ce;
- Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
- if (ce.error == Variant::CallError::CALL_OK) {
+ Callable::CallError ce;
+ Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
+ if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;
@@ -778,21 +1032,21 @@ String NativeScriptInstance::to_string(bool *r_valid) {
}
void NativeScriptInstance::refcount_incremented() {
- Variant::CallError err;
- call("_refcount_incremented", NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK && err.error != Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ Callable::CallError err;
+ call("_refcount_incremented", nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK && err.error != Callable::CallError::CALL_ERROR_INVALID_METHOD) {
ERR_PRINT("Failed to invoke _refcount_incremented - should not happen");
}
}
bool NativeScriptInstance::refcount_decremented() {
- Variant::CallError err;
- Variant ret = call("_refcount_decremented", NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK && err.error != Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ Callable::CallError err;
+ Variant ret = call("_refcount_decremented", nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK && err.error != Callable::CallError::CALL_ERROR_INVALID_METHOD) {
ERR_PRINT("Failed to invoke _refcount_decremented - should not happen");
return true; // assume we can destroy the object
}
- if (err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ if (err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
// the method does not exist, default is true
return true;
}
@@ -803,72 +1057,44 @@ Ref<Script> NativeScriptInstance::get_script() const {
return script;
}
-MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
-
- NativeScriptDesc *script_data = GET_SCRIPT_DESC();
-
- while (script_data) {
+Vector<ScriptNetData> NativeScriptInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
- if (E) {
- switch (E->get().rpc_mode) {
- case GODOT_METHOD_RPC_MODE_DISABLED:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- case GODOT_METHOD_RPC_MODE_REMOTE:
- return MultiplayerAPI::RPC_MODE_REMOTE;
- case GODOT_METHOD_RPC_MODE_MASTER:
- return MultiplayerAPI::RPC_MODE_MASTER;
- case GODOT_METHOD_RPC_MODE_PUPPET:
- return MultiplayerAPI::RPC_MODE_PUPPET;
- case GODOT_METHOD_RPC_MODE_REMOTESYNC:
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- case GODOT_METHOD_RPC_MODE_MASTERSYNC:
- return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
- return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
- default:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
- }
+uint16_t NativeScriptInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
+}
- script_data = script_data->base_data;
- }
+StringName NativeScriptInstance::get_rpc_method(uint16_t p_id) const {
+ return script->get_rpc_method(p_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const {
+ return script->get_rpc_mode_by_id(p_id);
}
-MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
+}
- NativeScriptDesc *script_data = GET_SCRIPT_DESC();
+Vector<ScriptNetData> NativeScriptInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- while (script_data) {
+uint16_t NativeScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
+}
- OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
- if (E) {
- switch (E.get().rset_mode) {
- case GODOT_METHOD_RPC_MODE_DISABLED:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- case GODOT_METHOD_RPC_MODE_REMOTE:
- return MultiplayerAPI::RPC_MODE_REMOTE;
- case GODOT_METHOD_RPC_MODE_MASTER:
- return MultiplayerAPI::RPC_MODE_MASTER;
- case GODOT_METHOD_RPC_MODE_PUPPET:
- return MultiplayerAPI::RPC_MODE_PUPPET;
- case GODOT_METHOD_RPC_MODE_REMOTESYNC:
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- case GODOT_METHOD_RPC_MODE_MASTERSYNC:
- return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
- return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
- default:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
- }
+StringName NativeScriptInstance::get_rset_property(uint16_t p_id) const {
+ return script->get_rset_property(p_id);
+}
- script_data = script_data->base_data;
- }
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode_by_id(uint16_t p_id) const {
+ return script->get_rset_mode_by_id(p_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return script->get_rset_mode(p_variable);
}
ScriptLanguage *NativeScriptInstance::get_language() {
@@ -910,16 +1136,9 @@ NativeScriptInstance::~NativeScriptInstance() {
script_data->destroy_func.destroy_func((godot_object *)owner, script_data->destroy_func.method_data, userdata);
if (owner) {
-
-#ifndef NO_THREADS
- script->owners_lock->lock();
-#endif
+ MutexLock lock(script->owners_lock);
script->instance_owners.erase(owner);
-
-#ifndef NO_THREADS
- script->owners_lock->unlock();
-#endif
}
}
@@ -927,16 +1146,16 @@ NativeScriptLanguage *NativeScriptLanguage::singleton;
void NativeScriptLanguage::_unload_stuff(bool p_reload) {
- Map<String, Ref<GDNative> > erase_and_unload;
+ Map<String, Ref<GDNative>> erase_and_unload;
- for (Map<String, Map<StringName, NativeScriptDesc> >::Element *L = library_classes.front(); L; L = L->next()) {
+ for (Map<String, Map<StringName, NativeScriptDesc>>::Element *L = library_classes.front(); L; L = L->next()) {
String lib_path = L->key();
Map<StringName, NativeScriptDesc> classes = L->get();
if (p_reload) {
- Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path);
+ Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path);
Ref<GDNative> gdn;
if (E) {
@@ -957,7 +1176,7 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) {
}
}
- Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path);
+ Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path);
Ref<GDNative> gdn;
if (E) {
@@ -992,7 +1211,7 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) {
erase_and_unload.insert(lib_path, gdn);
}
- for (Map<String, Ref<GDNative> >::Element *E = erase_and_unload.front(); E; E = E->next()) {
+ for (Map<String, Ref<GDNative>>::Element *E = erase_and_unload.front(); E; E = E->next()) {
String lib_path = E->key();
Ref<GDNative> gdn = E->get();
@@ -1016,7 +1235,6 @@ NativeScriptLanguage::NativeScriptLanguage() {
NativeScriptLanguage::singleton = this;
#ifndef NO_THREADS
has_objects_to_register = false;
- mutex = Mutex::create();
#endif
#ifdef DEBUG_ENABLED
@@ -1036,7 +1254,7 @@ NativeScriptLanguage::NativeScriptLanguage() {
NativeScriptLanguage::~NativeScriptLanguage() {
- for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
+ for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
Ref<GDNative> lib = L->get();
// only shut down valid libs, duh!
@@ -1053,10 +1271,6 @@ NativeScriptLanguage::~NativeScriptLanguage() {
NSL->library_classes.clear();
NSL->library_gdnatives.clear();
NSL->library_script_users.clear();
-
-#ifndef NO_THREADS
- memdelete(mutex);
-#endif
}
String NativeScriptLanguage::get_name() const {
@@ -1131,7 +1345,7 @@ bool NativeScriptLanguage::supports_builtin_mode() const {
int NativeScriptLanguage::find_function(const String &p_function, const String &p_code) const {
return -1;
}
-String NativeScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+String NativeScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
return "";
}
void NativeScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
@@ -1178,14 +1392,12 @@ void NativeScriptLanguage::get_recognized_extensions(List<String> *p_extensions)
void NativeScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
}
-void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
+void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const {
}
void NativeScriptLanguage::profiling_start() {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
profile_data.clear();
profiling = true;
@@ -1194,9 +1406,7 @@ void NativeScriptLanguage::profiling_start() {
void NativeScriptLanguage::profiling_stop() {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
profiling = false;
#endif
@@ -1204,9 +1414,8 @@ void NativeScriptLanguage::profiling_stop() {
int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
@@ -1228,9 +1437,8 @@ int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_a
int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
@@ -1254,9 +1462,7 @@ int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, in
void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p_time) {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
Map<StringName, ProfileData>::Element *d = profile_data.find(p_signature);
if (d) {
@@ -1326,14 +1532,14 @@ void NativeScriptLanguage::unregister_binding_functions(int p_idx) {
}
void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_object) {
- ERR_FAIL_INDEX_V(p_idx, binding_functions.size(), NULL);
+ ERR_FAIL_INDEX_V(p_idx, binding_functions.size(), nullptr);
- ERR_FAIL_COND_V_MSG(!binding_functions[p_idx].first, NULL, "Tried to get binding data for a nativescript binding that does not exist.");
+ ERR_FAIL_COND_V_MSG(!binding_functions[p_idx].first, nullptr, "Tried to get binding data for a nativescript binding that does not exist.");
Vector<void *> *binding_data = (Vector<void *> *)p_object->get_script_instance_binding(lang_idx);
if (!binding_data)
- return NULL; // should never happen.
+ return nullptr; // should never happen.
if (binding_data->size() <= p_idx) {
// okay, add new elements here.
@@ -1342,7 +1548,7 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec
binding_data->resize(p_idx + 1);
for (int i = old_size; i <= p_idx; i++) {
- (*binding_data).write[i] = NULL;
+ (*binding_data).write[i] = nullptr;
}
}
@@ -1364,7 +1570,7 @@ void *NativeScriptLanguage::alloc_instance_binding_data(Object *p_object) {
binding_data->resize(binding_functions.size());
for (int i = 0; i < binding_functions.size(); i++) {
- (*binding_data).write[i] = NULL;
+ (*binding_data).write[i] = nullptr;
}
binding_instances.insert(binding_data);
@@ -1453,12 +1659,12 @@ void NativeScriptLanguage::set_global_type_tag(int p_idx, StringName p_class_nam
const void *NativeScriptLanguage::get_global_type_tag(int p_idx, StringName p_class_name) const {
if (!global_type_tags.has(p_idx))
- return NULL;
+ return nullptr;
const HashMap<StringName, const void *> &tags = global_type_tags[p_idx];
if (!tags.has(p_class_name))
- return NULL;
+ return nullptr;
const void *tag = tags.get(p_class_name);
@@ -1475,13 +1681,12 @@ void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeSc
#endif
void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
// See if this library was "registered" already.
const String &lib_path = lib->get_current_library_path();
ERR_FAIL_COND_MSG(lib_path.length() == 0, lib->get_name() + " does not have a library for the current platform.");
- Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path);
+ Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path);
if (!E) {
Ref<GDNative> gdn;
@@ -1513,17 +1718,15 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
}
void NativeScriptLanguage::register_script(NativeScript *script) {
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
library_script_users[script->lib_path].insert(script);
}
void NativeScriptLanguage::unregister_script(NativeScript *script) {
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
- Map<String, Set<NativeScript *> >::Element *S = library_script_users.find(script->lib_path);
+
+ Map<String, Set<NativeScript *>>::Element *S = library_script_users.find(script->lib_path);
if (S) {
S->get().erase(script);
if (S->get().size() == 0) {
@@ -1537,7 +1740,7 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) {
void NativeScriptLanguage::call_libraries_cb(const StringName &name) {
// library_gdnatives is modified only from the main thread, so it's safe not to use mutex here
- for (Map<String, Ref<GDNative> >::Element *L = library_gdnatives.front(); L; L = L->next()) {
+ for (Map<String, Ref<GDNative>>::Element *L = library_gdnatives.front(); L; L = L->next()) {
if (L->get().is_null()) {
continue;
@@ -1559,7 +1762,7 @@ void NativeScriptLanguage::frame() {
#ifndef NO_THREADS
if (has_objects_to_register) {
MutexLock lock(mutex);
- for (Set<Ref<GDNativeLibrary> >::Element *L = libs_to_init.front(); L; L = L->next()) {
+ for (Set<Ref<GDNativeLibrary>>::Element *L = libs_to_init.front(); L; L = L->next()) {
init_library(L->get());
}
libs_to_init.clear();
@@ -1573,9 +1776,7 @@ void NativeScriptLanguage::frame() {
#ifdef DEBUG_ENABLED
{
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
d->get().last_frame_call_count = d->get().frame_call_count;
@@ -1633,16 +1834,14 @@ void NativeReloadNode::_notification(int p_what) {
#ifdef TOOLS_ENABLED
switch (p_what) {
- case MainLoop::NOTIFICATION_WM_FOCUS_OUT: {
+ case NOTIFICATION_WM_FOCUS_OUT: {
if (unloaded)
break;
-#ifndef NO_THREADS
MutexLock lock(NSL->mutex);
-#endif
NSL->_unload_stuff(true);
- for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
+ for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
Ref<GDNative> gdn = L->get();
@@ -1670,15 +1869,14 @@ void NativeReloadNode::_notification(int p_what) {
} break;
- case MainLoop::NOTIFICATION_WM_FOCUS_IN: {
+ case NOTIFICATION_WM_FOCUS_IN: {
if (!unloaded)
break;
-#ifndef NO_THREADS
MutexLock lock(NSL->mutex);
-#endif
+
Set<StringName> libs_to_remove;
- for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
+ for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
Ref<GDNative> gdn = L->get();
@@ -1713,7 +1911,7 @@ void NativeReloadNode::_notification(int p_what) {
((void (*)(void *))proc_ptr)((void *)&L->key());
}
- for (Map<String, Set<NativeScript *> >::Element *U = NSL->library_script_users.front(); U; U = U->next()) {
+ for (Map<String, Set<NativeScript *>>::Element *U = NSL->library_script_users.front(); U; U = U->next()) {
for (Set<NativeScript *>::Element *S = U->get().front(); S; S = S->next()) {
NativeScript *script = S->get();
@@ -1740,7 +1938,7 @@ void NativeReloadNode::_notification(int p_what) {
#endif
}
-RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error);
}
@@ -1765,7 +1963,7 @@ Error ResourceFormatSaverNativeScript::save(const String &p_path, const RES &p_r
}
bool ResourceFormatSaverNativeScript::recognize(const RES &p_resource) const {
- return Object::cast_to<NativeScript>(*p_resource) != NULL;
+ return Object::cast_to<NativeScript>(*p_resource) != nullptr;
}
void ResourceFormatSaverNativeScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index cf787e1f6a..7e7598e06c 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -35,6 +35,7 @@
#include "core/io/resource_saver.h"
#include "core/oa_hash_map.h"
#include "core/ordered_hash_map.h"
+#include "core/os/mutex.h"
#include "core/os/thread_safe.h"
#include "core/resource.h"
#include "core/script_language.h"
@@ -44,16 +45,13 @@
#include "modules/gdnative/gdnative.h"
#include <nativescript/godot_nativescript.h>
-#ifndef NO_THREADS
-#include "core/os/mutex.h"
-#endif
-
struct NativeScriptDesc {
struct Method {
godot_instance_method method;
MethodInfo info;
int rpc_mode;
+ uint16_t rpc_method_id;
String documentation;
};
struct Property {
@@ -62,6 +60,7 @@ struct NativeScriptDesc {
PropertyInfo info;
Variant default_value;
int rset_mode;
+ uint16_t rset_property_id;
String documentation;
};
@@ -70,7 +69,9 @@ struct NativeScriptDesc {
String documentation;
};
+ uint16_t rpc_count;
Map<StringName, Method> methods;
+ uint16_t rset_count;
OrderedHashMap<StringName, Property> properties;
Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals
StringName base;
@@ -86,13 +87,15 @@ struct NativeScriptDesc {
bool is_tool;
inline NativeScriptDesc() :
+ rpc_count(0),
methods(),
+ rset_count(0),
properties(),
signals_(),
base(),
base_native_type(),
documentation(),
- type_tag(NULL) {
+ type_tag(nullptr) {
zeromem(&create_func, sizeof(godot_instance_create_func));
zeromem(&destroy_func, sizeof(godot_instance_destroy_func));
}
@@ -121,9 +124,7 @@ class NativeScript : public Script {
String script_class_name;
String script_class_icon_path;
-#ifndef NO_THREADS
- Mutex *owners_lock;
-#endif
+ Mutex owners_lock;
Set<Object *> instance_owners;
protected:
@@ -132,6 +133,8 @@ protected:
public:
inline NativeScriptDesc *get_script_desc() const;
+ bool inherits_script(const Ref<Script> &p_script) const;
+
void set_class_name(String p_class_name);
String get_class_name() const;
@@ -174,12 +177,24 @@ public:
virtual void get_script_method_list(List<MethodInfo> *p_list) const;
virtual void get_script_property_list(List<PropertyInfo> *p_list) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
String get_class_documentation() const;
String get_method_documentation(const StringName &p_method) const;
String get_signal_documentation(const StringName &p_signal_name) const;
String get_property_documentation(const StringName &p_path) const;
- Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
NativeScript();
~NativeScript();
@@ -206,12 +221,23 @@ public:
virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const;
virtual void get_method_list(List<MethodInfo> *p_list) const;
virtual bool has_method(const StringName &p_method) const;
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual void notification(int p_notification);
String to_string(bool *r_valid);
virtual Ref<Script> get_script() const;
+
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
virtual ScriptLanguage *get_language();
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
@@ -237,10 +263,9 @@ private:
void _unload_stuff(bool p_reload = false);
+ Mutex mutex;
#ifndef NO_THREADS
- Mutex *mutex;
-
- Set<Ref<GDNativeLibrary> > libs_to_init;
+ Set<Ref<GDNativeLibrary>> libs_to_init;
Set<NativeScript *> scripts_to_register;
volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed
void defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script);
@@ -252,10 +277,10 @@ private:
void call_libraries_cb(const StringName &name);
- Vector<Pair<bool, godot_instance_binding_functions> > binding_functions;
+ Vector<Pair<bool, godot_instance_binding_functions>> binding_functions;
Set<Vector<void *> *> binding_instances;
- Map<int, HashMap<StringName, const void *> > global_type_tags;
+ Map<int, HashMap<StringName, const void *>> global_type_tags;
struct ProfileData {
StringName signature;
@@ -275,10 +300,10 @@ private:
public:
// These two maps must only be touched on the main thread
- Map<String, Map<StringName, NativeScriptDesc> > library_classes;
- Map<String, Ref<GDNative> > library_gdnatives;
+ Map<String, Map<StringName, NativeScriptDesc>> library_classes;
+ Map<String, Ref<GDNative>> library_gdnatives;
- Map<String, Set<NativeScript *> > library_script_users;
+ Map<String, Set<NativeScript *>> library_script_users;
StringName _init_call_type;
StringName _init_call_name;
@@ -318,12 +343,12 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
virtual void get_string_delimiters(List<String> *p_delimiters) const;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
- virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = NULL, Set<int> *r_safe_lines = NULL) const;
+ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
virtual bool supports_builtin_mode() const;
virtual int find_function(const String &p_function, const String &p_code) const;
- virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const;
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
virtual String debug_get_error() const;
@@ -339,7 +364,7 @@ public:
virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_public_functions(List<MethodInfo> *p_functions) const;
- virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
+ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const;
virtual void profiling_start();
virtual void profiling_stop();
virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max);
@@ -366,7 +391,7 @@ public:
inline NativeScriptDesc *NativeScript::get_script_desc() const {
Map<StringName, NativeScriptDesc>::Element *E = NativeScriptLanguage::singleton->library_classes[lib_path].find(class_name);
- return E ? &E->get() : NULL;
+ return E ? &E->get() : nullptr;
}
class NativeReloadNode : public Node {
@@ -383,7 +408,7 @@ public:
class ResourceFormatLoaderNativeScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/nativescript/register_types.h b/modules/gdnative/nativescript/register_types.h
index 8fcecb9836..088bf38dd5 100644
--- a/modules/gdnative/nativescript/register_types.h
+++ b/modules/gdnative/nativescript/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef NATIVESCRIPT_REGISTER_TYPES_H
+#define NATIVESCRIPT_REGISTER_TYPES_H
+
void register_nativescript_types();
void unregister_nativescript_types();
+
+#endif // NATIVESCRIPT_REGISTER_TYPES_H
diff --git a/modules/gdnative/net/SCsub b/modules/gdnative/net/SCsub
index 18ab9986b0..b76500c003 100644
--- a/modules/gdnative/net/SCsub
+++ b/modules/gdnative/net/SCsub
@@ -1,13 +1,12 @@
#!/usr/bin/env python
-Import('env')
-Import('env_gdnative')
+Import("env")
+Import("env_gdnative")
env_net = env_gdnative.Clone()
has_webrtc = env_net["module_webrtc_enabled"]
if has_webrtc:
- env_net.Append(CPPDEFINES=['WEBRTC_GDNATIVE_ENABLED'])
-
-env_net.add_source_files(env.modules_sources, '*.cpp')
+ env_net.Append(CPPDEFINES=["WEBRTC_GDNATIVE_ENABLED"])
+env_net.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.cpp b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
index 8c43a79cc5..a95697ea65 100644
--- a/modules/gdnative/net/multiplayer_peer_gdnative.cpp
+++ b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
@@ -31,7 +31,7 @@
#include "multiplayer_peer_gdnative.h"
MultiplayerPeerGDNative::MultiplayerPeerGDNative() {
- interface = NULL;
+ interface = nullptr;
}
MultiplayerPeerGDNative::~MultiplayerPeerGDNative() {
@@ -42,73 +42,73 @@ void MultiplayerPeerGDNative::set_native_multiplayer_peer(const godot_net_multip
}
Error MultiplayerPeerGDNative::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->get_packet(interface->data, r_buffer, &r_buffer_size);
}
Error MultiplayerPeerGDNative::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->put_packet(interface->data, p_buffer, p_buffer_size);
}
int MultiplayerPeerGDNative::get_max_packet_size() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_max_packet_size(interface->data);
}
int MultiplayerPeerGDNative::get_available_packet_count() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_available_packet_count(interface->data);
}
/* NetworkedMultiplayerPeer */
void MultiplayerPeerGDNative::set_transfer_mode(TransferMode p_mode) {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->set_transfer_mode(interface->data, (godot_int)p_mode);
}
NetworkedMultiplayerPeer::TransferMode MultiplayerPeerGDNative::get_transfer_mode() const {
- ERR_FAIL_COND_V(interface == NULL, TRANSFER_MODE_UNRELIABLE);
+ ERR_FAIL_COND_V(interface == nullptr, TRANSFER_MODE_UNRELIABLE);
return (TransferMode)interface->get_transfer_mode(interface->data);
}
void MultiplayerPeerGDNative::set_target_peer(int p_peer_id) {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->set_target_peer(interface->data, p_peer_id);
}
int MultiplayerPeerGDNative::get_packet_peer() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_packet_peer(interface->data);
}
bool MultiplayerPeerGDNative::is_server() const {
- ERR_FAIL_COND_V(interface == NULL, false);
+ ERR_FAIL_COND_V(interface == nullptr, false);
return interface->is_server(interface->data);
}
void MultiplayerPeerGDNative::poll() {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->poll(interface->data);
}
int MultiplayerPeerGDNative::get_unique_id() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_unique_id(interface->data);
}
void MultiplayerPeerGDNative::set_refuse_new_connections(bool p_enable) {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->set_refuse_new_connections(interface->data, p_enable);
}
bool MultiplayerPeerGDNative::is_refusing_new_connections() const {
- ERR_FAIL_COND_V(interface == NULL, true);
+ ERR_FAIL_COND_V(interface == nullptr, true);
return interface->is_refusing_new_connections(interface->data);
}
NetworkedMultiplayerPeer::ConnectionStatus MultiplayerPeerGDNative::get_connection_status() const {
- ERR_FAIL_COND_V(interface == NULL, CONNECTION_DISCONNECTED);
+ ERR_FAIL_COND_V(interface == nullptr, CONNECTION_DISCONNECTED);
return (ConnectionStatus)interface->get_connection_status(interface->data);
}
diff --git a/modules/gdnative/net/packet_peer_gdnative.cpp b/modules/gdnative/net/packet_peer_gdnative.cpp
index 75e1e0b824..28135df3b6 100644
--- a/modules/gdnative/net/packet_peer_gdnative.cpp
+++ b/modules/gdnative/net/packet_peer_gdnative.cpp
@@ -31,7 +31,7 @@
#include "packet_peer_gdnative.h"
PacketPeerGDNative::PacketPeerGDNative() {
- interface = NULL;
+ interface = nullptr;
}
PacketPeerGDNative::~PacketPeerGDNative() {
@@ -45,22 +45,22 @@ void PacketPeerGDNative::_bind_methods() {
}
Error PacketPeerGDNative::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->get_packet(interface->data, r_buffer, &r_buffer_size);
}
Error PacketPeerGDNative::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->put_packet(interface->data, p_buffer, p_buffer_size);
}
int PacketPeerGDNative::get_max_packet_size() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_max_packet_size(interface->data);
}
int PacketPeerGDNative::get_available_packet_count() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_available_packet_count(interface->data);
}
diff --git a/modules/gdnative/net/register_types.h b/modules/gdnative/net/register_types.h
index 526bc49deb..70b266f9b9 100644
--- a/modules/gdnative/net/register_types.h
+++ b/modules/gdnative/net/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef NET_REGISTER_TYPES_H
+#define NET_REGISTER_TYPES_H
+
void register_net_types();
void unregister_net_types();
+
+#endif // NET_REGISTER_TYPES_H
diff --git a/modules/gdnative/net/stream_peer_gdnative.cpp b/modules/gdnative/net/stream_peer_gdnative.cpp
index 22634daf5f..9dcb184115 100644
--- a/modules/gdnative/net/stream_peer_gdnative.cpp
+++ b/modules/gdnative/net/stream_peer_gdnative.cpp
@@ -31,7 +31,7 @@
#include "stream_peer_gdnative.h"
StreamPeerGDNative::StreamPeerGDNative() {
- interface = NULL;
+ interface = nullptr;
}
StreamPeerGDNative::~StreamPeerGDNative() {
@@ -45,27 +45,27 @@ void StreamPeerGDNative::_bind_methods() {
}
Error StreamPeerGDNative::put_data(const uint8_t *p_data, int p_bytes) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)(interface->put_data(interface->data, p_data, p_bytes));
}
Error StreamPeerGDNative::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)(interface->put_partial_data(interface->data, p_data, p_bytes, &r_sent));
}
Error StreamPeerGDNative::get_data(uint8_t *p_buffer, int p_bytes) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)(interface->get_data(interface->data, p_buffer, p_bytes));
}
Error StreamPeerGDNative::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)(interface->get_partial_data(interface->data, p_buffer, p_bytes, &r_received));
}
int StreamPeerGDNative::get_available_bytes() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_available_bytes(interface->data);
}
diff --git a/modules/gdnative/pluginscript/SCsub b/modules/gdnative/pluginscript/SCsub
index 20eaa99592..0b2db3b504 100644
--- a/modules/gdnative/pluginscript/SCsub
+++ b/modules/gdnative/pluginscript/SCsub
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-Import('env')
-Import('env_gdnative')
+Import("env")
+Import("env_gdnative")
-env_gdnative.add_source_files(env.modules_sources, '*.cpp')
+env_gdnative.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp
index c64a00a4d9..7d17a7d5ab 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp
@@ -39,13 +39,11 @@
#include "pluginscript_script.h"
bool PluginScriptInstance::set(const StringName &p_name, const Variant &p_value) {
- String name = String(p_name);
- return _desc->set_prop(_data, (const godot_string *)&name, (const godot_variant *)&p_value);
+ return _desc->set_prop(_data, (const godot_string_name *)&p_name, (const godot_variant *)&p_value);
}
bool PluginScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
- String name = String(p_name);
- return _desc->get_prop(_data, (const godot_string *)&name, (godot_variant *)&r_ret);
+ return _desc->get_prop(_data, (const godot_string_name *)&p_name, (godot_variant *)&r_ret);
}
Ref<Script> PluginScriptInstance::get_script() const {
@@ -81,7 +79,7 @@ bool PluginScriptInstance::has_method(const StringName &p_method) const {
return _script->has_method(p_method);
}
-Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
// TODO: optimize when calling a Godot method from Godot to avoid param conversion ?
godot_variant ret = _desc->call_method(
_data, (godot_string_name *)&p_method, (const godot_variant **)p_args,
@@ -95,10 +93,42 @@ void PluginScriptInstance::notification(int p_notification) {
_desc->notification(_data, p_notification);
}
+Vector<ScriptNetData> PluginScriptInstance::get_rpc_methods() const {
+ return _script->get_rpc_methods();
+}
+
+uint16_t PluginScriptInstance::get_rpc_method_id(const StringName &p_variable) const {
+ return _script->get_rpc_method_id(p_variable);
+}
+
+StringName PluginScriptInstance::get_rpc_method(uint16_t p_id) const {
+ return _script->get_rpc_method(p_id);
+}
+
+MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const {
+ return _script->get_rpc_mode_by_id(p_id);
+}
+
MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const {
return _script->get_rpc_mode(p_method);
}
+Vector<ScriptNetData> PluginScriptInstance::get_rset_properties() const {
+ return _script->get_rset_properties();
+}
+
+uint16_t PluginScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return _script->get_rset_property_id(p_variable);
+}
+
+StringName PluginScriptInstance::get_rset_property(uint16_t p_id) const {
+ return _script->get_rset_property(p_id);
+}
+
+MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode_by_id(uint16_t p_id) const {
+ return _script->get_rset_mode_by_id(p_id);
+}
+
MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const {
return _script->get_rset_mode(p_variable);
}
@@ -126,7 +156,7 @@ bool PluginScriptInstance::init(PluginScript *p_script, Object *p_owner) {
_script = Ref<PluginScript>(p_script);
_desc = &p_script->_desc->instance_desc;
_data = _desc->init(p_script->_data, (godot_object *)p_owner);
- ERR_FAIL_COND_V(_data == NULL, false);
+ ERR_FAIL_COND_V(_data == nullptr, false);
p_owner->set_script_instance(this);
return true;
}
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h
index dc1229a44d..6309b6fde3 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.h
+++ b/modules/gdnative/pluginscript/pluginscript_instance.h
@@ -55,12 +55,12 @@ public:
virtual bool set(const StringName &p_name, const Variant &p_value);
virtual bool get(const StringName &p_name, Variant &r_ret) const;
virtual void get_property_list(List<PropertyInfo> *p_properties) const;
- virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const;
virtual void get_method_list(List<MethodInfo> *p_list) const;
virtual bool has_method(const StringName &p_method) const;
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
// Rely on default implementations provided by ScriptInstance for the moment.
// Note that multilevel call could be removed in 3.0 release, so stay tuned
@@ -76,7 +76,16 @@ public:
void set_path(const String &p_path);
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
virtual void refcount_incremented();
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
index 41f0e34243..bccbe95033 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -109,7 +109,7 @@ Ref<Script> PluginScriptLanguage::get_template(const String &p_class_name, const
}
bool PluginScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
- PoolStringArray functions;
+ PackedStringArray functions;
if (_desc.validate) {
bool ret = _desc.validate(
_data,
@@ -118,7 +118,7 @@ bool PluginScriptLanguage::validate(const String &p_script, int &r_line_error, i
&r_col_error,
(godot_string *)&r_test_error,
(godot_string *)&p_path,
- (godot_pool_string_array *)&functions);
+ (godot_packed_string_array *)&functions);
for (int i = 0; i < functions.size(); i++) {
r_functions->push_back(functions[i]);
}
@@ -149,9 +149,9 @@ int PluginScriptLanguage::find_function(const String &p_function, const String &
return -1;
}
-String PluginScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+String PluginScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
if (_desc.make_function) {
- godot_string tmp = _desc.make_function(_data, (godot_string *)&p_class, (godot_string *)&p_name, (godot_pool_string_array *)&p_args);
+ godot_string tmp = _desc.make_function(_data, (godot_string *)&p_class, (godot_string *)&p_name, (godot_packed_string_array *)&p_args);
String ret = *(String *)&tmp;
godot_string_destroy(&tmp);
return ret;
@@ -187,8 +187,7 @@ void PluginScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int
}
void PluginScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
- const String variable = String(p_variable);
- _desc.add_global_constant(_data, (godot_string *)&variable, (godot_variant *)&p_value);
+ _desc.add_global_constant(_data, (godot_string_name *)&p_variable, (godot_variant *)&p_value);
}
/* LOADER FUNCTIONS */
@@ -211,7 +210,7 @@ void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) c
}
}
-void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
+void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const {
// TODO: provide this statically in `godot_pluginscript_language_desc` ?
if (_desc.get_public_constants) {
Dictionary constants;
@@ -337,9 +336,9 @@ String PluginScriptLanguage::debug_get_stack_level_source(int p_level) const {
void PluginScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
if (_desc.debug_get_stack_level_locals) {
- PoolStringArray locals;
+ PackedStringArray locals;
Array values;
- _desc.debug_get_stack_level_locals(_data, p_level, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
+ _desc.debug_get_stack_level_locals(_data, p_level, (godot_packed_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
for (int i = 0; i < locals.size(); i++) {
p_locals->push_back(locals[i]);
}
@@ -351,9 +350,9 @@ void PluginScriptLanguage::debug_get_stack_level_locals(int p_level, List<String
void PluginScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
if (_desc.debug_get_stack_level_members) {
- PoolStringArray members;
+ PackedStringArray members;
Array values;
- _desc.debug_get_stack_level_members(_data, p_level, (godot_pool_string_array *)&members, (godot_array *)&values, p_max_subitems, p_max_depth);
+ _desc.debug_get_stack_level_members(_data, p_level, (godot_packed_string_array *)&members, (godot_array *)&values, p_max_subitems, p_max_depth);
for (int i = 0; i < members.size(); i++) {
p_members->push_back(members[i]);
}
@@ -365,9 +364,9 @@ void PluginScriptLanguage::debug_get_stack_level_members(int p_level, List<Strin
void PluginScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
if (_desc.debug_get_globals) {
- PoolStringArray locals;
+ PackedStringArray locals;
Array values;
- _desc.debug_get_globals(_data, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
+ _desc.debug_get_globals(_data, (godot_packed_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
for (int i = 0; i < locals.size(); i++) {
p_locals->push_back(locals[i]);
}
@@ -400,39 +399,18 @@ void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool
}
void PluginScriptLanguage::lock() {
-#ifndef NO_THREADS
- if (_lock) {
- _lock->lock();
- }
-#endif
+ _lock.lock();
}
void PluginScriptLanguage::unlock() {
-#ifndef NO_THREADS
- if (_lock) {
- _lock->unlock();
- }
-#endif
+ _lock.unlock();
}
PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc) :
_desc(*desc) {
_resource_loader = Ref<ResourceFormatLoaderPluginScript>(memnew(ResourceFormatLoaderPluginScript(this)));
_resource_saver = Ref<ResourceFormatSaverPluginScript>(memnew(ResourceFormatSaverPluginScript(this)));
-
-// TODO: totally remove _lock attribute if NO_THREADS is set
-#ifdef NO_THREADS
- _lock = NULL;
-#else
- _lock = Mutex::create();
-#endif
}
PluginScriptLanguage::~PluginScriptLanguage() {
-#ifndef NO_THREADS
- if (_lock) {
- memdelete(_lock);
- _lock = NULL;
- }
-#endif
}
diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h
index 145ab5599c..dd6758713f 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.h
+++ b/modules/gdnative/pluginscript/pluginscript_language.h
@@ -53,7 +53,7 @@ class PluginScriptLanguage : public ScriptLanguage {
const godot_pluginscript_language_desc _desc;
godot_pluginscript_language_data *_data;
- Mutex *_lock;
+ Mutex _lock;
SelfList<PluginScript>::List _script_list;
public:
@@ -74,13 +74,13 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
virtual void get_string_delimiters(List<String> *p_delimiters) const;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
- virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL, List<ScriptLanguage::Warning> *r_warnings = NULL, Set<int> *r_safe_lines = NULL) const;
+ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
virtual bool supports_builtin_mode() const;
virtual bool can_inherit_from_file() { return true; }
virtual int find_function(const String &p_function, const String &p_code) const;
- virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const;
virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint);
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
@@ -112,7 +112,7 @@ public:
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_public_functions(List<MethodInfo> *p_functions) const;
- virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
+ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const;
virtual void profiling_start();
virtual void profiling_stop();
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp
index fe1cc83c69..64582cc517 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp
@@ -39,7 +39,7 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL
_language = language;
}
-RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
@@ -109,5 +109,5 @@ void ResourceFormatSaverPluginScript::get_recognized_extensions(const RES &p_res
bool ResourceFormatSaverPluginScript::recognize(const RES &p_resource) const {
- return Object::cast_to<PluginScript>(*p_resource) != NULL;
+ return Object::cast_to<PluginScript>(*p_resource) != nullptr;
}
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h
index ede31c027e..e47754490a 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.h
+++ b/modules/gdnative/pluginscript/pluginscript_loader.h
@@ -44,7 +44,7 @@ class ResourceFormatLoaderPluginScript : public ResourceFormatLoader {
public:
ResourceFormatLoaderPluginScript(PluginScriptLanguage *language);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index cc5bdee0a1..6b303c8716 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -34,6 +34,8 @@
#include "pluginscript_instance.h"
#include "pluginscript_script.h"
+#include <stdint.h>
+
#ifdef DEBUG_ENABLED
#define __ASSERT_SCRIPT_REASON "Cannot retrieve PluginScript class for this script, is your code correct?"
#define ASSERT_SCRIPT_VALID() \
@@ -53,9 +55,9 @@ void PluginScript::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &PluginScript::_new, MethodInfo("new"));
}
-PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Variant::CallError &r_error) {
+PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
// Create instance
PluginScriptInstance *instance = memnew(PluginScriptInstance());
@@ -65,9 +67,9 @@ PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int
_instances.insert(instance->get_owner());
_language->unlock();
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
memdelete(instance);
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
// Construct
@@ -81,17 +83,17 @@ PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int
return instance;
}
-Variant PluginScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant PluginScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
if (!_valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
REF ref;
- Object *owner = NULL;
+ Object *owner = nullptr;
if (get_instance_base_type() == "") {
owner = memnew(Reference);
@@ -100,7 +102,7 @@ Variant PluginScript::_new(const Variant **p_args, int p_argcount, Variant::Call
}
if (!owner) {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
@@ -138,6 +140,13 @@ bool PluginScript::can_instance() const {
return can;
}
+bool PluginScript::inherits_script(const Ref<Script> &p_script) const {
+#ifndef _MSC_VER
+#warning inheritance needs to be implemented in PluginScript
+#endif
+ return false;
+}
+
Ref<Script> PluginScript::get_base_script() const {
if (_ref_base_parent.is_valid()) {
return Ref<PluginScript>(_ref_base_parent);
@@ -173,7 +182,7 @@ void PluginScript::update_exports() {
// TODO: rename p_this "p_owner" ?
ScriptInstance *PluginScript::instance_create(Object *p_this) {
- ASSERT_SCRIPT_VALID_V(NULL);
+ ASSERT_SCRIPT_VALID_V(nullptr);
// TODO check script validity ?
if (!_tool && !ScriptServer::is_scripting_enabled()) {
#ifdef TOOLS_ENABLED
@@ -183,7 +192,7 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) {
update_exports();
return si;
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -192,15 +201,15 @@ ScriptInstance *PluginScript::instance_create(Object *p_this) {
if (!ClassDB::is_parent_class(p_this->get_class_name(), base_type)) {
String msg = "Script inherits from native type '" + String(base_type) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'";
// TODO: implement PluginscriptLanguage::debug_break_parse
- // if (ScriptDebugger::get_singleton()) {
+ // if (EngineDebugger::is_active()) {
// _language->debug_break_parse(get_path(), 0, msg);
// }
- ERR_FAIL_V_MSG(NULL, msg);
+ ERR_FAIL_V_MSG(nullptr, msg);
}
}
- Variant::CallError unchecked_error;
- return _create_instance(NULL, 0, p_this, unchecked_error);
+ Callable::CallError unchecked_error;
+ return _create_instance(nullptr, 0, p_this, unchecked_error);
}
bool PluginScript::instance_has(const Object *p_this) const {
@@ -294,22 +303,35 @@ Error PluginScript::reload(bool p_keep_state) {
_tool = manifest.is_tool;
Dictionary *members = (Dictionary *)&manifest.member_lines;
- for (const Variant *key = members->next(); key != NULL; key = members->next(key)) {
+ for (const Variant *key = members->next(); key != nullptr; key = members->next(key)) {
_member_lines[*key] = (*members)[*key];
}
Array *methods = (Array *)&manifest.methods;
+ _rpc_methods.clear();
+ _rpc_variables.clear();
+ if (_ref_base_parent.is_valid()) {
+ _rpc_methods = _ref_base_parent->get_rpc_methods();
+ _rpc_variables = _ref_base_parent->get_rset_properties();
+ }
for (int i = 0; i < methods->size(); ++i) {
Dictionary v = (*methods)[i];
MethodInfo mi = MethodInfo::from_dict(v);
_methods_info[mi.name] = mi;
// rpc_mode is passed as an optional field and is not part of MethodInfo
Variant var = v["rpc_mode"];
- if (var == Variant()) {
- _methods_rpc_mode[mi.name] = MultiplayerAPI::RPC_MODE_DISABLED;
- } else {
- _methods_rpc_mode[mi.name] = MultiplayerAPI::RPCMode(int(var));
+ if (var != Variant()) {
+ ScriptNetData nd;
+ nd.name = mi.name;
+ nd.mode = MultiplayerAPI::RPCMode(int(var));
+ if (_rpc_methods.find(nd) == -1) {
+ _rpc_methods.push_back(nd);
+ }
}
}
+
+ // Sort so we are 100% that they are always the same.
+ _rpc_methods.sort_custom<SortNetData>();
+
Array *signals = (Array *)&manifest.signals;
for (int i = 0; i < signals->size(); ++i) {
Variant v = (*signals)[i];
@@ -324,13 +346,19 @@ Error PluginScript::reload(bool p_keep_state) {
_properties_default_values[pi.name] = v["default_value"];
// rset_mode is passed as an optional field and is not part of PropertyInfo
Variant var = v["rset_mode"];
- if (var == Variant()) {
- _methods_rpc_mode[pi.name] = MultiplayerAPI::RPC_MODE_DISABLED;
- } else {
- _methods_rpc_mode[pi.name] = MultiplayerAPI::RPCMode(int(var));
+ if (var != Variant()) {
+ ScriptNetData nd;
+ nd.name = pi.name;
+ nd.mode = MultiplayerAPI::RPCMode(int(var));
+ if (_rpc_variables.find(nd) == -1) {
+ _rpc_variables.push_back(nd);
+ }
}
}
+ // Sort so we are 100% that they are always the same.
+ _rpc_variables.sort_custom<SortNetData>();
+
#ifdef TOOLS_ENABLED
/*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
@@ -345,14 +373,14 @@ Error PluginScript::reload(bool p_keep_state) {
void PluginScript::get_script_method_list(List<MethodInfo> *r_methods) const {
ASSERT_SCRIPT_VALID();
- for (Map<StringName, MethodInfo>::Element *e = _methods_info.front(); e != NULL; e = e->next()) {
+ for (Map<StringName, MethodInfo>::Element *e = _methods_info.front(); e != nullptr; e = e->next()) {
r_methods->push_back(e->get());
}
}
void PluginScript::get_script_property_list(List<PropertyInfo> *r_properties) const {
ASSERT_SCRIPT_VALID();
- for (Map<StringName, PropertyInfo>::Element *e = _properties_info.front(); e != NULL; e = e->next()) {
+ for (Map<StringName, PropertyInfo>::Element *e = _properties_info.front(); e != nullptr; e = e->next()) {
r_properties->push_back(e->get());
}
}
@@ -365,7 +393,7 @@ bool PluginScript::has_method(const StringName &p_method) const {
MethodInfo PluginScript::get_method_info(const StringName &p_method) const {
ASSERT_SCRIPT_VALID_V(MethodInfo());
const Map<StringName, MethodInfo>::Element *e = _methods_info.find(p_method);
- if (e != NULL) {
+ if (e != nullptr) {
return e->get();
} else {
return MethodInfo();
@@ -380,7 +408,7 @@ bool PluginScript::has_property(const StringName &p_method) const {
PropertyInfo PluginScript::get_property_info(const StringName &p_property) const {
ASSERT_SCRIPT_VALID_V(PropertyInfo());
const Map<StringName, PropertyInfo>::Element *e = _properties_info.find(p_property);
- if (e != NULL) {
+ if (e != nullptr) {
return e->get();
} else {
return PropertyInfo();
@@ -391,7 +419,7 @@ bool PluginScript::get_property_default_value(const StringName &p_property, Vari
ASSERT_SCRIPT_VALID_V(false);
#ifdef TOOLS_ENABLED
const Map<StringName, Variant>::Element *e = _properties_default_values.find(p_property);
- if (e != NULL) {
+ if (e != nullptr) {
r_value = e->get();
return true;
} else {
@@ -407,22 +435,22 @@ ScriptLanguage *PluginScript::get_language() const {
Error PluginScript::load_source_code(const String &p_path) {
- PoolVector<uint8_t> sourcef;
+ Vector<uint8_t> sourcef;
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + p_path + "'.");
int len = f->get_len();
sourcef.resize(len + 1);
- PoolVector<uint8_t>::Write w = sourcef.write();
- int r = f->get_buffer(w.ptr(), len);
+ uint8_t *w = sourcef.ptrw();
+ int r = f->get_buffer(w, len);
f->close();
memdelete(f);
ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
w[len] = 0;
String s;
- if (s.parse_utf8((const char *)w.ptr())) {
+ if (s.parse_utf8((const char *)w)) {
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
@@ -441,7 +469,7 @@ bool PluginScript::has_script_signal(const StringName &p_signal) const {
void PluginScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
ASSERT_SCRIPT_VALID();
- for (Map<StringName, MethodInfo>::Element *e = _signals_info.front(); e != NULL; e = e->next()) {
+ for (Map<StringName, MethodInfo>::Element *e = _signals_info.front(); e != nullptr; e = e->next()) {
r_signals->push_back(e->get());
}
}
@@ -455,30 +483,76 @@ int PluginScript::get_member_line(const StringName &p_member) const {
return -1;
}
-MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
+Vector<ScriptNetData> PluginScript::get_rpc_methods() const {
+ return _rpc_methods;
+}
+
+uint16_t PluginScript::get_rpc_method_id(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(UINT16_MAX);
+ for (int i = 0; i < _rpc_methods.size(); i++) {
+ if (_rpc_methods[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName PluginScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ASSERT_SCRIPT_VALID_V(StringName());
+ if (p_rpc_method_id >= _rpc_methods.size())
+ return StringName();
+ return _rpc_methods[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _methods_rpc_mode.find(p_method);
- if (e != NULL) {
- return e->get();
- } else {
+ if (p_rpc_method_id >= _rpc_methods.size())
return MultiplayerAPI::RPC_MODE_DISABLED;
+ return _rpc_methods[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> PluginScript::get_rset_properties() const {
+ return _rpc_variables;
+}
+
+uint16_t PluginScript::get_rset_property_id(const StringName &p_property) const {
+ ASSERT_SCRIPT_VALID_V(UINT16_MAX);
+ for (int i = 0; i < _rpc_variables.size(); i++) {
+ if (_rpc_variables[i].name == p_property) {
+ return i;
+ }
}
+ return UINT16_MAX;
}
-MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
+StringName PluginScript::get_rset_property(const uint16_t p_rset_property_id) const {
+ ASSERT_SCRIPT_VALID_V(StringName());
+ if (p_rset_property_id >= _rpc_variables.size())
+ return StringName();
+ return _rpc_variables[p_rset_property_id].name;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rset_mode_by_id(const uint16_t p_rset_property_id) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _variables_rset_mode.find(p_variable);
- if (e != NULL) {
- return e->get();
- } else {
+ if (p_rset_property_id >= _rpc_variables.size())
return MultiplayerAPI::RPC_MODE_DISABLED;
- }
+ return _rpc_variables[p_rset_property_id].mode;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
+ ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
}
PluginScript::PluginScript() :
- _data(NULL),
- _desc(NULL),
- _language(NULL),
+ _data(nullptr),
+ _desc(nullptr),
+ _language(nullptr),
_tool(false),
_valid(false),
_script_list(this) {
diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h
index f67c88c794..70b9ca980b 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.h
+++ b/modules/gdnative/pluginscript/pluginscript_script.h
@@ -60,8 +60,8 @@ private:
Map<StringName, PropertyInfo> _properties_info;
Map<StringName, MethodInfo> _signals_info;
Map<StringName, MethodInfo> _methods_info;
- Map<StringName, MultiplayerAPI::RPCMode> _variables_rset_mode;
- Map<StringName, MultiplayerAPI::RPCMode> _methods_rpc_mode;
+ Vector<ScriptNetData> _rpc_methods;
+ Vector<ScriptNetData> _rpc_variables;
Set<Object *> _instances;
//exported members
@@ -72,8 +72,10 @@ private:
protected:
static void _bind_methods();
- PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Variant::CallError &r_error);
- Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ bool inherits_script(const Ref<Script> &p_script) const;
+
+ PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error);
+ Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
#ifdef TOOLS_ENABLED
Set<PlaceHolderScriptInstance *> placeholders;
@@ -118,8 +120,17 @@ public:
virtual int get_member_line(const StringName &p_member) const;
- MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
- MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_property) const;
+ virtual StringName get_rset_property(const uint16_t p_rset_property_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
PluginScript();
void init(PluginScriptLanguage *language);
diff --git a/modules/gdnative/pluginscript/register_types.h b/modules/gdnative/pluginscript/register_types.h
index a4f7284b54..c6a64b4f40 100644
--- a/modules/gdnative/pluginscript/register_types.h
+++ b/modules/gdnative/pluginscript/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef PLUGINSCRIPT_REGISTER_TYPES_H
+#define PLUGINSCRIPT_REGISTER_TYPES_H
+
void register_pluginscript_types();
void unregister_pluginscript_types();
+
+#endif // PLUGINSCRIPT_REGISTER_TYPES_H
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 4142f60ba6..67a286ee2e 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -34,11 +34,11 @@
#include "gdnative.h"
-#include "arvr/register_types.h"
#include "nativescript/register_types.h"
#include "net/register_types.h"
#include "pluginscript/register_types.h"
#include "videodecoder/register_types.h"
+#include "xr/register_types.h"
#include "core/engine.h"
#include "core/io/resource_loader.h"
@@ -214,7 +214,7 @@ static godot_variant cb_standard_varcall(void *p_procedure_handle, godot_array *
GDNativeCallRegistry *GDNativeCallRegistry::singleton;
-Vector<Ref<GDNative> > singleton_gdnatives;
+Vector<Ref<GDNative>> singleton_gdnatives;
Ref<GDNativeLibraryResourceLoader> resource_loader_gdnlib;
Ref<GDNativeLibraryResourceSaver> resource_saver_gdnlib;
@@ -240,7 +240,7 @@ void register_gdnative_types() {
GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall);
register_net_types();
- register_arvr_types();
+ register_xr_types();
register_nativescript_types();
register_pluginscript_types();
register_videodecoder_types();
@@ -305,7 +305,7 @@ void unregister_gdnative_types() {
unregister_videodecoder_types();
unregister_pluginscript_types();
unregister_nativescript_types();
- unregister_arvr_types();
+ unregister_xr_types();
unregister_net_types();
memdelete(GDNativeCallRegistry::singleton);
@@ -325,7 +325,7 @@ void unregister_gdnative_types() {
print_line(String("dict:\t" ) + itos(sizeof(Dictionary)));
print_line(String("node_path:\t") + itos(sizeof(NodePath)));
print_line(String("plane:\t") + itos(sizeof(Plane)));
- print_line(String("poolarray:\t") + itos(sizeof(PoolByteArray)));
+ print_line(String("poolarray:\t") + itos(sizeof(PackedByteArray)));
print_line(String("quat:\t") + itos(sizeof(Quat)));
print_line(String("rect2:\t") + itos(sizeof(Rect2)));
print_line(String("aabb:\t") + itos(sizeof(AABB)));
diff --git a/modules/gdnative/register_types.h b/modules/gdnative/register_types.h
index 0091ef3f96..b5c182f8b7 100644
--- a/modules/gdnative/register_types.h
+++ b/modules/gdnative/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef GDNATIVE_REGISTER_TYPES_H
+#define GDNATIVE_REGISTER_TYPES_H
+
void register_gdnative_types();
void unregister_gdnative_types();
+
+#endif // GDNATIVE_REGISTER_TYPES_H
diff --git a/modules/gdnative/videodecoder/SCsub b/modules/gdnative/videodecoder/SCsub
index 04cc8ed604..5948b9a3dd 100644
--- a/modules/gdnative/videodecoder/SCsub
+++ b/modules/gdnative/videodecoder/SCsub
@@ -1,9 +1,9 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_vsdecoder_gdnative = env_modules.Clone()
-env_vsdecoder_gdnative.Prepend(CPPPATH=['#modules/gdnative/include/'])
-env_vsdecoder_gdnative.add_source_files(env.modules_sources, '*.cpp')
+env_vsdecoder_gdnative.Prepend(CPPPATH=["#modules/gdnative/include/"])
+env_vsdecoder_gdnative.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/gdnative/videodecoder/register_types.h b/modules/gdnative/videodecoder/register_types.h
index d81d5c497b..b1a83d4071 100644
--- a/modules/gdnative/videodecoder/register_types.h
+++ b/modules/gdnative/videodecoder/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef VIDEODECODER_REGISTER_TYPES_H
+#define VIDEODECODER_REGISTER_TYPES_H
+
void register_videodecoder_types();
void unregister_videodecoder_types();
+
+#endif // VIDEODECODER_REGISTER_TYPES_H
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
index dbe00cdf71..f7d87595af 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
@@ -33,7 +33,7 @@
#include "core/project_settings.h"
#include "servers/audio_server.h"
-VideoDecoderServer *VideoDecoderServer::instance = NULL;
+VideoDecoderServer *VideoDecoderServer::instance = nullptr;
static VideoDecoderServer decoder_server;
@@ -113,7 +113,7 @@ void GDAPI godot_videodecoder_register_decoder(const godot_videodecoder_interfac
// VideoStreamPlaybackGDNative starts here.
bool VideoStreamPlaybackGDNative::open_file(const String &p_file) {
- ERR_FAIL_COND_V(interface == NULL, false);
+ ERR_FAIL_COND_V(interface == nullptr, false);
file = FileAccess::open(p_file, FileAccess::READ);
bool file_opened = interface->open_file(data_struct, file);
@@ -132,7 +132,11 @@ bool VideoStreamPlaybackGDNative::open_file(const String &p_file) {
pcm_write_idx = -1;
samples_decoded = 0;
- texture->create((int)texture_size.width, (int)texture_size.height, Image::FORMAT_RGBA8, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE);
+ Ref<Image> img;
+ img.instance();
+ img->create((int)texture_size.width, false, (int)texture_size.height, Image::FORMAT_RGBA8);
+
+ texture->create_from_image(img);
}
return file_opened;
@@ -146,7 +150,7 @@ void VideoStreamPlaybackGDNative::update(float p_delta) {
return;
}
time += p_delta;
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->update(data_struct, p_delta);
// Don't mix if there's no audio (num_channels == 0).
@@ -183,16 +187,16 @@ void VideoStreamPlaybackGDNative::update(float p_delta) {
}
void VideoStreamPlaybackGDNative::update_texture() {
- PoolByteArray *pba = (PoolByteArray *)interface->get_videoframe(data_struct);
+ PackedByteArray *pba = (PackedByteArray *)interface->get_videoframe(data_struct);
- if (pba == NULL) {
+ if (pba == nullptr) {
playing = false;
return;
}
Ref<Image> img = memnew(Image(texture_size.width, texture_size.height, 0, Image::FORMAT_RGBA8, *pba));
- texture->set_data(img);
+ texture->update(img, true);
}
// ctor and dtor
@@ -201,19 +205,19 @@ VideoStreamPlaybackGDNative::VideoStreamPlaybackGDNative() :
texture(Ref<ImageTexture>(memnew(ImageTexture))),
playing(false),
paused(false),
- mix_udata(NULL),
- mix_callback(NULL),
+ mix_udata(nullptr),
+ mix_callback(nullptr),
num_channels(-1),
time(0),
seek_backward(false),
mix_rate(0),
delay_compensation(0),
- pcm(NULL),
+ pcm(nullptr),
pcm_write_idx(0),
samples_decoded(0),
- file(NULL),
- interface(NULL),
- data_struct(NULL) {}
+ file(nullptr),
+ interface(nullptr),
+ data_struct(nullptr) {}
VideoStreamPlaybackGDNative::~VideoStreamPlaybackGDNative() {
cleanup();
@@ -224,16 +228,16 @@ void VideoStreamPlaybackGDNative::cleanup() {
interface->destructor(data_struct);
if (pcm)
memfree(pcm);
- pcm = NULL;
+ pcm = nullptr;
time = 0;
num_channels = -1;
- interface = NULL;
- data_struct = NULL;
+ interface = nullptr;
+ data_struct = nullptr;
}
void VideoStreamPlaybackGDNative::set_interface(const godot_videodecoder_interface_gdnative *p_interface) {
- ERR_FAIL_COND(p_interface == NULL);
- if (interface != NULL) {
+ ERR_FAIL_COND(p_interface == nullptr);
+ if (interface != nullptr) {
cleanup();
}
interface = p_interface;
@@ -268,7 +272,7 @@ void VideoStreamPlaybackGDNative::stop() {
}
void VideoStreamPlaybackGDNative::seek(float p_time) {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->seek(data_struct, p_time);
if (p_time < time)
seek_backward = true;
@@ -283,18 +287,18 @@ void VideoStreamPlaybackGDNative::set_paused(bool p_paused) {
paused = p_paused;
}
-Ref<Texture> VideoStreamPlaybackGDNative::get_texture() const {
+Ref<Texture2D> VideoStreamPlaybackGDNative::get_texture() const {
return texture;
}
float VideoStreamPlaybackGDNative::get_length() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_length(data_struct);
}
float VideoStreamPlaybackGDNative::get_playback_position() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_playback_position(data_struct);
}
@@ -308,7 +312,7 @@ void VideoStreamPlaybackGDNative::set_loop(bool p_enable) {
}
void VideoStreamPlaybackGDNative::set_audio_track(int p_idx) {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->set_audio_track(data_struct, p_idx);
}
@@ -319,13 +323,13 @@ void VideoStreamPlaybackGDNative::set_mix_callback(AudioMixCallback p_callback,
}
int VideoStreamPlaybackGDNative::get_channels() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return (num_channels > 0) ? num_channels : 0;
}
int VideoStreamPlaybackGDNative::get_mix_rate() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return mix_rate;
}
@@ -335,13 +339,13 @@ int VideoStreamPlaybackGDNative::get_mix_rate() const {
Ref<VideoStreamPlayback> VideoStreamGDNative::instance_playback() {
Ref<VideoStreamPlaybackGDNative> pb = memnew(VideoStreamPlaybackGDNative);
VideoDecoderGDNative *decoder = decoder_server.get_decoder(file.get_extension().to_lower());
- if (decoder == NULL)
- return NULL;
+ if (decoder == nullptr)
+ return nullptr;
pb->set_interface(decoder->interface);
pb->set_audio_track(audio_track);
if (pb->open_file(file))
return pb;
- return NULL;
+ return nullptr;
}
void VideoStreamGDNative::set_file(const String &p_file) {
@@ -369,7 +373,7 @@ void VideoStreamGDNative::set_audio_track(int p_track) {
/* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */
-RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h
index bb0346efb4..092e10a0f5 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.h
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.h
@@ -42,7 +42,7 @@ struct VideoDecoderGDNative {
Vector<String> supported_extensions;
VideoDecoderGDNative() :
- interface(NULL),
+ interface(nullptr),
plugin_name("none") {}
VideoDecoderGDNative(const godot_videodecoder_interface_gdnative *p_interface) :
@@ -89,7 +89,7 @@ public:
VideoDecoderGDNative *get_decoder(const String &extension) {
if (extensions.size() == 0 || !extensions.has(extension))
- return NULL;
+ return nullptr;
return decoders[extensions[extension]];
}
@@ -102,7 +102,7 @@ public:
memdelete(decoders[i]);
}
decoders.clear();
- instance = NULL;
+ instance = nullptr;
}
};
@@ -168,7 +168,7 @@ public:
//virtual int mix(int16_t* p_buffer,int p_frames)=0;
- virtual Ref<Texture> get_texture() const;
+ virtual Ref<Texture2D> get_texture() const;
virtual void update(float p_delta);
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata);
@@ -194,12 +194,12 @@ public:
virtual void set_audio_track(int p_track);
virtual Ref<VideoStreamPlayback> instance_playback();
- VideoStreamGDNative() {}
+ VideoStreamGDNative() { audio_track = 0; }
};
class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/xr/SCsub b/modules/gdnative/xr/SCsub
new file mode 100644
index 0000000000..0b2db3b504
--- /dev/null
+++ b/modules/gdnative/xr/SCsub
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_gdnative")
+
+env_gdnative.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/gdnative/arvr/config.py b/modules/gdnative/xr/config.py
index 53bc827027..d22f9454ed 100644
--- a/modules/gdnative/arvr/config.py
+++ b/modules/gdnative/xr/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return True
+ return True
+
def configure(env):
- pass
+ pass
diff --git a/modules/gdnative/arvr/register_types.cpp b/modules/gdnative/xr/register_types.cpp
index 0f6e2bca1a..da3a7dc4b8 100644
--- a/modules/gdnative/arvr/register_types.cpp
+++ b/modules/gdnative/xr/register_types.cpp
@@ -29,11 +29,12 @@
/*************************************************************************/
#include "register_types.h"
-#include "arvr_interface_gdnative.h"
+#include "xr_interface_gdnative.h"
-void register_arvr_types() {
- ClassDB::register_class<ARVRInterfaceGDNative>();
+void register_xr_types() {
+ ClassDB::register_class<XRInterfaceGDNative>();
+ ClassDB::add_compatibility_class("ARVRInterfaceGDNative", "XRInterfaceGDNative");
}
-void unregister_arvr_types() {
+void unregister_xr_types() {
}
diff --git a/modules/gdnative/arvr/register_types.h b/modules/gdnative/xr/register_types.h
index 815f112fbf..2501d28651 100644
--- a/modules/gdnative/arvr/register_types.h
+++ b/modules/gdnative/xr/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_arvr_types();
-void unregister_arvr_types();
+#ifndef XR_REGISTER_TYPES_H
+#define XR_REGISTER_TYPES_H
+
+void register_xr_types();
+void unregister_xr_types();
+
+#endif // XR_REGISTER_TYPES_H
diff --git a/modules/gdnative/xr/xr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp
new file mode 100644
index 0000000000..0451945139
--- /dev/null
+++ b/modules/gdnative/xr/xr_interface_gdnative.cpp
@@ -0,0 +1,428 @@
+/*************************************************************************/
+/* xr_interface_gdnative.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "xr_interface_gdnative.h"
+#include "core/input/input_filter.h"
+#include "servers/rendering/rendering_server_globals.h"
+#include "servers/xr/xr_positional_tracker.h"
+
+void XRInterfaceGDNative::_bind_methods() {
+ ADD_PROPERTY_DEFAULT("interface_is_initialized", false);
+ ADD_PROPERTY_DEFAULT("ar_is_anchor_detection_enabled", false);
+}
+
+XRInterfaceGDNative::XRInterfaceGDNative() {
+ print_verbose("Construct gdnative interface\n");
+
+ // we won't have our data pointer until our library gets set
+ data = nullptr;
+
+ interface = nullptr;
+}
+
+XRInterfaceGDNative::~XRInterfaceGDNative() {
+ print_verbose("Destruct gdnative interface\n");
+
+ if (interface != nullptr && is_initialized()) {
+ uninitialize();
+ };
+
+ // cleanup after ourselves
+ cleanup();
+}
+
+void XRInterfaceGDNative::cleanup() {
+ if (interface != nullptr) {
+ interface->destructor(data);
+ data = nullptr;
+ interface = nullptr;
+ }
+}
+
+void XRInterfaceGDNative::set_interface(const godot_xr_interface_gdnative *p_interface) {
+ // this should only be called once, just being paranoid..
+ if (interface) {
+ cleanup();
+ }
+
+ // bind to our interface
+ interface = p_interface;
+
+ // Now we do our constructing...
+ data = interface->constructor((godot_object *)this);
+}
+
+StringName XRInterfaceGDNative::get_name() const {
+
+ ERR_FAIL_COND_V(interface == nullptr, StringName());
+
+ godot_string result = interface->get_name(data);
+
+ StringName name = *(String *)&result;
+
+ godot_string_destroy(&result);
+
+ return name;
+}
+
+int XRInterfaceGDNative::get_capabilities() const {
+ int capabilities;
+
+ ERR_FAIL_COND_V(interface == nullptr, 0); // 0 = None
+
+ capabilities = interface->get_capabilities(data);
+
+ return capabilities;
+}
+
+bool XRInterfaceGDNative::get_anchor_detection_is_enabled() const {
+
+ ERR_FAIL_COND_V(interface == nullptr, false);
+
+ return interface->get_anchor_detection_is_enabled(data);
+}
+
+void XRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) {
+
+ ERR_FAIL_COND(interface == nullptr);
+
+ interface->set_anchor_detection_is_enabled(data, p_enable);
+}
+
+int XRInterfaceGDNative::get_camera_feed_id() {
+
+ ERR_FAIL_COND_V(interface == nullptr, 0);
+
+ return (unsigned int)interface->get_camera_feed_id(data);
+}
+
+bool XRInterfaceGDNative::is_stereo() {
+ bool stereo;
+
+ ERR_FAIL_COND_V(interface == nullptr, false);
+
+ stereo = interface->is_stereo(data);
+
+ return stereo;
+}
+
+bool XRInterfaceGDNative::is_initialized() const {
+
+ ERR_FAIL_COND_V(interface == nullptr, false);
+
+ return interface->is_initialized(data);
+}
+
+bool XRInterfaceGDNative::initialize() {
+ ERR_FAIL_COND_V(interface == nullptr, false);
+
+ bool initialized = interface->initialize(data);
+
+ if (initialized) {
+ // if we successfully initialize our interface and we don't have a primary interface yet, this becomes our primary interface
+
+ XRServer *xr_server = XRServer::get_singleton();
+ if ((xr_server != nullptr) && (xr_server->get_primary_interface() == nullptr)) {
+ xr_server->set_primary_interface(this);
+ };
+ };
+
+ return initialized;
+}
+
+void XRInterfaceGDNative::uninitialize() {
+ ERR_FAIL_COND(interface == nullptr);
+
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
+ // Whatever happens, make sure this is no longer our primary interface
+ xr_server->clear_primary_interface_if(this);
+ }
+
+ interface->uninitialize(data);
+}
+
+Size2 XRInterfaceGDNative::get_render_targetsize() {
+
+ ERR_FAIL_COND_V(interface == nullptr, Size2());
+
+ godot_vector2 result = interface->get_render_targetsize(data);
+ Vector2 *vec = (Vector2 *)&result;
+
+ return *vec;
+}
+
+Transform XRInterfaceGDNative::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+ Transform *ret;
+
+ ERR_FAIL_COND_V(interface == nullptr, Transform());
+
+ godot_transform t = interface->get_transform_for_eye(data, (int)p_eye, (godot_transform *)&p_cam_transform);
+
+ ret = (Transform *)&t;
+
+ return *ret;
+}
+
+CameraMatrix XRInterfaceGDNative::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+ CameraMatrix cm;
+
+ ERR_FAIL_COND_V(interface == nullptr, CameraMatrix());
+
+ interface->fill_projection_for_eye(data, (godot_real *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far);
+
+ return cm;
+}
+
+unsigned int XRInterfaceGDNative::get_external_texture_for_eye(XRInterface::Eyes p_eye) {
+
+ ERR_FAIL_COND_V(interface == nullptr, 0);
+
+ return (unsigned int)interface->get_external_texture_for_eye(data, (godot_int)p_eye);
+}
+
+void XRInterfaceGDNative::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+
+ ERR_FAIL_COND(interface == nullptr);
+
+ interface->commit_for_eye(data, (godot_int)p_eye, (godot_rid *)&p_render_target, (godot_rect2 *)&p_screen_rect);
+}
+
+void XRInterfaceGDNative::process() {
+ ERR_FAIL_COND(interface == nullptr);
+
+ interface->process(data);
+}
+
+void XRInterfaceGDNative::notification(int p_what) {
+ ERR_FAIL_COND(interface == nullptr);
+
+ interface->notification(data, p_what);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// some helper callbacks
+
+extern "C" {
+
+void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface) {
+ // Must be on a version 4 plugin
+ ERR_FAIL_COND_MSG(p_interface->version.major < 4, "GDNative XR interfaces build for Godot 3.x are not supported.");
+
+ Ref<XRInterfaceGDNative> new_interface;
+ new_interface.instance();
+ new_interface->set_interface((const godot_xr_interface_gdnative *)p_interface);
+ XRServer::get_singleton()->add_interface(new_interface);
+}
+
+godot_real GDAPI godot_xr_get_worldscale() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 1.0);
+
+ return xr_server->get_world_scale();
+}
+
+godot_transform GDAPI godot_xr_get_reference_frame() {
+ godot_transform reference_frame;
+ Transform *reference_frame_ptr = (Transform *)&reference_frame;
+
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
+ *reference_frame_ptr = xr_server->get_reference_frame();
+ } else {
+ godot_transform_new_identity(&reference_frame);
+ }
+
+ return reference_frame;
+}
+
+void GDAPI godot_xr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) {
+ // blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD
+ XRInterface::Eyes eye = (XRInterface::Eyes)p_eye;
+#if 0
+ RID *render_target = (RID *)p_render_target;
+#endif
+ Rect2 screen_rect = *(Rect2 *)p_rect;
+
+ if (eye == XRInterface::EYE_LEFT) {
+ screen_rect.size.x /= 2.0;
+ } else if (p_eye == XRInterface::EYE_RIGHT) {
+ screen_rect.size.x /= 2.0;
+ screen_rect.position.x += screen_rect.size.x;
+ }
+#ifndef _MSC_VER
+#warning this needs to be redone
+#endif
+#if 0
+ RSG::rasterizer->blit_render_target_to_screen(*render_target, screen_rect, 0);
+#endif
+}
+
+godot_int GDAPI godot_xr_get_texid(godot_rid *p_render_target) {
+ // In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID
+ // This is a handy function to expose that.
+#if 0
+ RID *render_target = (RID *)p_render_target;
+
+ RID eye_texture = RSG::storage->render_target_get_texture(*render_target);
+#endif
+
+#ifndef _MSC_VER
+#warning need to obtain this ID again
+#endif
+ uint32_t texid = 0; //RS::get_singleton()->texture_get_texid(eye_texture);
+
+ return texid;
+}
+
+godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 0);
+
+ InputFilter *input = InputFilter::get_singleton();
+ ERR_FAIL_NULL_V(input, 0);
+
+ XRPositionalTracker *new_tracker = memnew(XRPositionalTracker);
+ new_tracker->set_name(p_device_name);
+ new_tracker->set_type(XRServer::TRACKER_CONTROLLER);
+ if (p_hand == 1) {
+ new_tracker->set_hand(XRPositionalTracker::TRACKER_LEFT_HAND);
+ } else if (p_hand == 2) {
+ new_tracker->set_hand(XRPositionalTracker::TRACKER_RIGHT_HAND);
+ }
+
+ // also register as joystick...
+ int joyid = input->get_unused_joy_id();
+ if (joyid != -1) {
+ new_tracker->set_joy_id(joyid);
+ input->joy_connection_changed(joyid, true, p_device_name, "");
+ }
+
+ if (p_tracks_orientation) {
+ Basis orientation;
+ new_tracker->set_orientation(orientation);
+ }
+ if (p_tracks_position) {
+ Vector3 position;
+ new_tracker->set_position(position);
+ }
+
+ // add our tracker to our server and remember its pointer
+ xr_server->add_tracker(new_tracker);
+
+ // note, this ID is only unique within controllers!
+ return new_tracker->get_tracker_id();
+}
+
+void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ InputFilter *input = InputFilter::get_singleton();
+ ERR_FAIL_NULL(input);
+
+ XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (remove_tracker != nullptr) {
+ // unset our joystick if applicable
+ int joyid = remove_tracker->get_joy_id();
+ if (joyid != -1) {
+ input->joy_connection_changed(joyid, false, "", "");
+ remove_tracker->set_joy_id(-1);
+ }
+
+ // remove our tracker from our server
+ xr_server->remove_tracker(remove_tracker);
+ memdelete(remove_tracker);
+ }
+}
+
+void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != nullptr) {
+ Transform *transform = (Transform *)p_transform;
+ if (p_tracks_orientation) {
+ tracker->set_orientation(transform->basis);
+ }
+ if (p_tracks_position) {
+ tracker->set_rw_position(transform->origin);
+ }
+ }
+}
+
+void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ InputFilter *input = InputFilter::get_singleton();
+ ERR_FAIL_NULL(input);
+
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != nullptr) {
+ int joyid = tracker->get_joy_id();
+ if (joyid != -1) {
+ input->joy_button(joyid, p_button, p_is_pressed);
+ }
+ }
+}
+
+void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ InputFilter *input = InputFilter::get_singleton();
+ ERR_FAIL_NULL(input);
+
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != nullptr) {
+ int joyid = tracker->get_joy_id();
+ if (joyid != -1) {
+ InputFilter::JoyAxis jx;
+ jx.min = p_can_be_negative ? -1 : 0;
+ jx.value = p_value;
+ input->joy_axis(joyid, p_axis, jx);
+ }
+ }
+}
+
+godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, 0.0);
+
+ XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != nullptr) {
+ return tracker->get_rumble();
+ }
+
+ return 0.0;
+}
+}
diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.h b/modules/gdnative/xr/xr_interface_gdnative.h
index 1077bef994..64f1282a7e 100644
--- a/modules/gdnative/arvr/arvr_interface_gdnative.h
+++ b/modules/gdnative/xr/xr_interface_gdnative.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* arvr_interface_gdnative.h */
+/* xr_interface_gdnative.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ARVR_INTERFACE_GDNATIVE_H
-#define ARVR_INTERFACE_GDNATIVE_H
+#ifndef XR_INTERFACE_GDNATIVE_H
+#define XR_INTERFACE_GDNATIVE_H
#include "modules/gdnative/gdnative.h"
-#include "servers/arvr/arvr_interface.h"
+#include "servers/xr/xr_interface.h"
/**
@authors Hinsbart & Karroffel & Mux213
@@ -40,23 +40,23 @@
This subclass of our AR/VR interface forms a bridge to GDNative.
*/
-class ARVRInterfaceGDNative : public ARVRInterface {
- GDCLASS(ARVRInterfaceGDNative, ARVRInterface);
+class XRInterfaceGDNative : public XRInterface {
+ GDCLASS(XRInterfaceGDNative, XRInterface);
void cleanup();
protected:
- const godot_arvr_interface_gdnative *interface;
+ const godot_xr_interface_gdnative *interface;
void *data;
static void _bind_methods();
public:
/** general interface information **/
- ARVRInterfaceGDNative();
- ~ARVRInterfaceGDNative();
+ XRInterfaceGDNative();
+ ~XRInterfaceGDNative();
- void set_interface(const godot_arvr_interface_gdnative *p_interface);
+ void set_interface(const godot_xr_interface_gdnative *p_interface);
virtual StringName get_name() const;
virtual int get_capabilities() const;
@@ -73,19 +73,19 @@ public:
/** rendering and internal **/
virtual Size2 get_render_targetsize();
virtual bool is_stereo();
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
+ virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform);
- // we expose a PoolVector<float> version of this function to GDNative
- PoolVector<float> _get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ // we expose a Vector<float> version of this function to GDNative
+ Vector<float> _get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- // and a CameraMatrix version to ARVRServer
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ // and a CameraMatrix version to XRServer
+ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- virtual unsigned int get_external_texture_for_eye(ARVRInterface::Eyes p_eye);
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+ virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye);
+ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
virtual void process();
virtual void notification(int p_what);
};
-#endif // ARVR_INTERFACE_GDNATIVE_H
+#endif // XR_INTERFACE_GDNATIVE_H
diff --git a/modules/gdnavigation/SCsub b/modules/gdnavigation/SCsub
new file mode 100644
index 0000000000..877d601c6a
--- /dev/null
+++ b/modules/gdnavigation/SCsub
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_modules")
+
+env_navigation = env_modules.Clone()
+
+# Recast Thirdparty source files
+if env["builtin_recast"]:
+ thirdparty_dir = "#thirdparty/recastnavigation/Recast/"
+ thirdparty_sources = [
+ "Source/Recast.cpp",
+ "Source/RecastAlloc.cpp",
+ "Source/RecastArea.cpp",
+ "Source/RecastAssert.cpp",
+ "Source/RecastContour.cpp",
+ "Source/RecastFilter.cpp",
+ "Source/RecastLayers.cpp",
+ "Source/RecastMesh.cpp",
+ "Source/RecastMeshDetail.cpp",
+ "Source/RecastRasterization.cpp",
+ "Source/RecastRegion.cpp",
+ ]
+ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+
+ env_navigation.Prepend(CPPPATH=[thirdparty_dir + "/Include"])
+
+ env_thirdparty = env_navigation.Clone()
+ env_thirdparty.disable_warnings()
+ env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
+
+
+# RVO Thirdparty source files
+if env["builtin_rvo2"]:
+ thirdparty_dir = "#thirdparty/rvo2"
+ thirdparty_sources = [
+ "/src/Agent.cpp",
+ "/src/KdTree.cpp",
+ ]
+ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+
+ env_navigation.Prepend(CPPPATH=[thirdparty_dir + "/src"])
+
+ env_thirdparty = env_navigation.Clone()
+ env_thirdparty.disable_warnings()
+ env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
+
+
+# Godot source files
+env_navigation.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/gdnavigation/config.py b/modules/gdnavigation/config.py
new file mode 100644
index 0000000000..d22f9454ed
--- /dev/null
+++ b/modules/gdnavigation/config.py
@@ -0,0 +1,6 @@
+def can_build(env, platform):
+ return True
+
+
+def configure(env):
+ pass
diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp
new file mode 100644
index 0000000000..278c27ae22
--- /dev/null
+++ b/modules/gdnavigation/gd_navigation_server.cpp
@@ -0,0 +1,502 @@
+/*************************************************************************/
+/* gd_navigation_server.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "gd_navigation_server.h"
+
+#include "core/os/mutex.h"
+
+#ifndef _3D_DISABLED
+#include "navigation_mesh_generator.h"
+#endif
+
+/**
+ @author AndreaCatania
+*/
+
+/// Creates a struct for each function and a function that once called creates
+/// an instance of that struct with the submitted parameters.
+/// Then, that struct is stored in an array; the `sync` function consume that array.
+
+#define COMMAND_1(F_NAME, T_0, D_0) \
+ struct MERGE(F_NAME, _command) : public SetCommand { \
+ T_0 d_0; \
+ MERGE(F_NAME, _command) \
+ (T_0 p_d_0) : \
+ d_0(p_d_0) {} \
+ virtual void exec(GdNavigationServer *server) { \
+ server->MERGE(_cmd_, F_NAME)(d_0); \
+ } \
+ }; \
+ void GdNavigationServer::F_NAME(T_0 D_0) const { \
+ auto cmd = memnew(MERGE(F_NAME, _command)( \
+ D_0)); \
+ add_command(cmd); \
+ } \
+ void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0)
+
+#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \
+ struct MERGE(F_NAME, _command) : public SetCommand { \
+ T_0 d_0; \
+ T_1 d_1; \
+ MERGE(F_NAME, _command) \
+ ( \
+ T_0 p_d_0, \
+ T_1 p_d_1) : \
+ d_0(p_d_0), \
+ d_1(p_d_1) {} \
+ virtual void exec(GdNavigationServer *server) { \
+ server->MERGE(_cmd_, F_NAME)(d_0, d_1); \
+ } \
+ }; \
+ void GdNavigationServer::F_NAME(T_0 D_0, T_1 D_1) const { \
+ auto cmd = memnew(MERGE(F_NAME, _command)( \
+ D_0, \
+ D_1)); \
+ add_command(cmd); \
+ } \
+ void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1)
+
+#define COMMAND_4(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3) \
+ struct MERGE(F_NAME, _command) : public SetCommand { \
+ T_0 d_0; \
+ T_1 d_1; \
+ T_2 d_2; \
+ T_3 d_3; \
+ MERGE(F_NAME, _command) \
+ ( \
+ T_0 p_d_0, \
+ T_1 p_d_1, \
+ T_2 p_d_2, \
+ T_3 p_d_3) : \
+ d_0(p_d_0), \
+ d_1(p_d_1), \
+ d_2(p_d_2), \
+ d_3(p_d_3) {} \
+ virtual void exec(GdNavigationServer *server) { \
+ server->MERGE(_cmd_, F_NAME)(d_0, d_1, d_2, d_3); \
+ } \
+ }; \
+ void GdNavigationServer::F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) const { \
+ auto cmd = memnew(MERGE(F_NAME, _command)( \
+ D_0, \
+ D_1, \
+ D_2, \
+ D_3)); \
+ add_command(cmd); \
+ } \
+ void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
+
+GdNavigationServer::GdNavigationServer() :
+ NavigationServer3D(),
+ active(true) {
+}
+
+GdNavigationServer::~GdNavigationServer() {
+ flush_queries();
+}
+
+void GdNavigationServer::add_command(SetCommand *command) const {
+ auto mut_this = const_cast<GdNavigationServer *>(this);
+ {
+ MutexLock lock(commands_mutex);
+ mut_this->commands.push_back(command);
+ }
+}
+
+RID GdNavigationServer::map_create() const {
+ auto mut_this = const_cast<GdNavigationServer *>(this);
+ MutexLock lock(mut_this->operations_mutex);
+ NavMap *space = memnew(NavMap);
+ RID rid = map_owner.make_rid(space);
+ space->set_self(rid);
+ return rid;
+}
+
+COMMAND_2(map_set_active, RID, p_map, bool, p_active) {
+ NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND(map == nullptr);
+
+ if (p_active) {
+ if (!map_is_active(p_map)) {
+ active_maps.push_back(map);
+ }
+ } else {
+ active_maps.erase(map);
+ }
+}
+
+bool GdNavigationServer::map_is_active(RID p_map) const {
+ NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, false);
+
+ return active_maps.find(map) >= 0;
+}
+
+COMMAND_2(map_set_up, RID, p_map, Vector3, p_up) {
+ NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND(map == nullptr);
+
+ map->set_up(p_up);
+}
+
+Vector3 GdNavigationServer::map_get_up(RID p_map) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, Vector3());
+
+ return map->get_up();
+}
+
+COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size) {
+ NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND(map == nullptr);
+
+ map->set_cell_size(p_cell_size);
+}
+
+real_t GdNavigationServer::map_get_cell_size(RID p_map) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, 0);
+
+ return map->get_cell_size();
+}
+
+COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin) {
+ NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND(map == nullptr);
+
+ map->set_edge_connection_margin(p_connection_margin);
+}
+
+real_t GdNavigationServer::map_get_edge_connection_margin(RID p_map) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, 0);
+
+ return map->get_edge_connection_margin();
+}
+
+Vector<Vector3> GdNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>());
+
+ return map->get_path(p_origin, p_destination, p_optimize);
+}
+
+Vector3 GdNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, Vector3());
+
+ return map->get_closest_point_to_segment(p_from, p_to, p_use_collision);
+}
+
+Vector3 GdNavigationServer::map_get_closest_point(RID p_map, const Vector3 &p_point) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, Vector3());
+
+ return map->get_closest_point(p_point);
+}
+
+Vector3 GdNavigationServer::map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, Vector3());
+
+ return map->get_closest_point_normal(p_point);
+}
+
+RID GdNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const {
+ const NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND_V(map == nullptr, RID());
+
+ return map->get_closest_point_owner(p_point);
+}
+
+RID GdNavigationServer::region_create() const {
+ auto mut_this = const_cast<GdNavigationServer *>(this);
+ MutexLock lock(mut_this->operations_mutex);
+ NavRegion *reg = memnew(NavRegion);
+ RID rid = region_owner.make_rid(reg);
+ reg->set_self(rid);
+ return rid;
+}
+
+COMMAND_2(region_set_map, RID, p_region, RID, p_map) {
+ NavRegion *region = region_owner.getornull(p_region);
+ ERR_FAIL_COND(region == nullptr);
+
+ if (region->get_map() != nullptr) {
+
+ if (region->get_map()->get_self() == p_map)
+ return; // Pointless
+
+ region->get_map()->remove_region(region);
+ region->set_map(nullptr);
+ }
+
+ if (p_map.is_valid()) {
+ NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND(map == nullptr);
+
+ map->add_region(region);
+ region->set_map(map);
+ }
+}
+
+COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform) {
+ NavRegion *region = region_owner.getornull(p_region);
+ ERR_FAIL_COND(region == nullptr);
+
+ region->set_transform(p_transform);
+}
+
+COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh) {
+ NavRegion *region = region_owner.getornull(p_region);
+ ERR_FAIL_COND(region == nullptr);
+
+ region->set_mesh(p_nav_mesh);
+}
+
+void GdNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const {
+ ERR_FAIL_COND(r_mesh.is_null());
+ ERR_FAIL_COND(p_node == nullptr);
+
+#ifndef _3D_DISABLED
+ NavigationMeshGenerator::get_singleton()->clear(r_mesh);
+ NavigationMeshGenerator::get_singleton()->bake(r_mesh, p_node);
+#endif
+}
+
+RID GdNavigationServer::agent_create() const {
+ auto mut_this = const_cast<GdNavigationServer *>(this);
+ MutexLock lock(mut_this->operations_mutex);
+ RvoAgent *agent = memnew(RvoAgent());
+ RID rid = agent_owner.make_rid(agent);
+ agent->set_self(rid);
+ return rid;
+}
+
+COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ if (agent->get_map()) {
+ if (agent->get_map()->get_self() == p_map)
+ return; // Pointless
+
+ agent->get_map()->remove_agent(agent);
+ }
+
+ agent->set_map(nullptr);
+
+ if (p_map.is_valid()) {
+ NavMap *map = map_owner.getornull(p_map);
+ ERR_FAIL_COND(map == nullptr);
+
+ agent->set_map(map);
+ map->add_agent(agent);
+
+ if (agent->has_callback()) {
+ map->set_agent_as_controlled(agent);
+ }
+ }
+}
+
+COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->neighborDist_ = p_dist;
+}
+
+COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->maxNeighbors_ = p_count;
+}
+
+COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->timeHorizon_ = p_time;
+}
+
+COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->radius_ = p_radius;
+}
+
+COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->maxSpeed_ = p_max_speed;
+}
+
+COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->velocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z);
+}
+
+COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->prefVelocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z);
+}
+
+COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->position_ = RVO::Vector3(p_position.x, p_position.y, p_position.z);
+}
+
+COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->get_agent()->ignore_y_ = p_ignore;
+}
+
+bool GdNavigationServer::agent_is_map_changed(RID p_agent) const {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND_V(agent == nullptr, false);
+
+ return agent->is_map_changed();
+}
+
+COMMAND_4(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata) {
+ RvoAgent *agent = agent_owner.getornull(p_agent);
+ ERR_FAIL_COND(agent == nullptr);
+
+ agent->set_callback(p_receiver == nullptr ? ObjectID() : p_receiver->get_instance_id(), p_method, p_udata);
+
+ if (agent->get_map()) {
+ if (p_receiver == nullptr) {
+ agent->get_map()->remove_agent_as_controlled(agent);
+ } else {
+ agent->get_map()->set_agent_as_controlled(agent);
+ }
+ }
+}
+
+COMMAND_1(free, RID, p_object) {
+ if (map_owner.owns(p_object)) {
+ NavMap *map = map_owner.getornull(p_object);
+
+ // Removes any assigned region
+ std::vector<NavRegion *> regions = map->get_regions();
+ for (size_t i(0); i < regions.size(); i++) {
+ map->remove_region(regions[i]);
+ regions[i]->set_map(nullptr);
+ }
+
+ // Remove any assigned agent
+ std::vector<RvoAgent *> agents = map->get_agents();
+ for (size_t i(0); i < agents.size(); i++) {
+ map->remove_agent(agents[i]);
+ agents[i]->set_map(nullptr);
+ }
+
+ active_maps.erase(map);
+ map_owner.free(p_object);
+ memdelete(map);
+
+ } else if (region_owner.owns(p_object)) {
+ NavRegion *region = region_owner.getornull(p_object);
+
+ // Removes this region from the map if assigned
+ if (region->get_map() != nullptr) {
+ region->get_map()->remove_region(region);
+ region->set_map(nullptr);
+ }
+
+ region_owner.free(p_object);
+ memdelete(region);
+
+ } else if (agent_owner.owns(p_object)) {
+ RvoAgent *agent = agent_owner.getornull(p_object);
+
+ // Removes this agent from the map if assigned
+ if (agent->get_map() != nullptr) {
+ agent->get_map()->remove_agent(agent);
+ agent->set_map(nullptr);
+ }
+
+ agent_owner.free(p_object);
+ memdelete(agent);
+
+ } else {
+ ERR_FAIL_COND("Invalid ID.");
+ }
+}
+
+void GdNavigationServer::set_active(bool p_active) const {
+ auto mut_this = const_cast<GdNavigationServer *>(this);
+ MutexLock lock(mut_this->operations_mutex);
+ mut_this->active = p_active;
+}
+
+void GdNavigationServer::flush_queries() {
+ // In c++ we can't be sure that this is performed in the main thread
+ // even with mutable functions.
+ MutexLock lock(commands_mutex);
+ MutexLock lock2(operations_mutex);
+ for (size_t i(0); i < commands.size(); i++) {
+ commands[i]->exec(this);
+ memdelete(commands[i]);
+ }
+ commands.clear();
+}
+
+void GdNavigationServer::process(real_t p_delta_time) {
+ flush_queries();
+
+ if (!active) {
+ return;
+ }
+
+ // In c++ we can't be sure that this is performed in the main thread
+ // even with mutable functions.
+ MutexLock lock(operations_mutex);
+ for (int i(0); i < active_maps.size(); i++) {
+ active_maps[i]->sync();
+ active_maps[i]->step(p_delta_time);
+ active_maps[i]->dispatch_callbacks();
+ }
+}
+
+#undef COMMAND_1
+#undef COMMAND_2
+#undef COMMAND_4
diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h
new file mode 100644
index 0000000000..01d1a4fba9
--- /dev/null
+++ b/modules/gdnavigation/gd_navigation_server.h
@@ -0,0 +1,142 @@
+/*************************************************************************/
+/* gd_navigation_server.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 GD_NAVIGATION_SERVER_H
+#define GD_NAVIGATION_SERVER_H
+
+#include "core/rid.h"
+#include "core/rid_owner.h"
+#include "servers/navigation_server_3d.h"
+
+#include "nav_map.h"
+#include "nav_region.h"
+#include "rvo_agent.h"
+
+/**
+ @author AndreaCatania
+*/
+
+/// The commands are functions executed during the `sync` phase.
+
+#define MERGE_INTERNAL(A, B) A##B
+#define MERGE(A, B) MERGE_INTERNAL(A, B)
+
+#define COMMAND_1(F_NAME, T_0, D_0) \
+ virtual void F_NAME(T_0 D_0) const; \
+ void MERGE(_cmd_, F_NAME)(T_0 D_0)
+
+#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \
+ virtual void F_NAME(T_0 D_0, T_1 D_1) const; \
+ void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1)
+
+#define COMMAND_4_DEF(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, D_3_DEF) \
+ virtual void F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3 = D_3_DEF) const; \
+ void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
+
+class GdNavigationServer;
+
+struct SetCommand {
+ virtual ~SetCommand() {}
+ virtual void exec(GdNavigationServer *server) = 0;
+};
+
+class GdNavigationServer : public NavigationServer3D {
+ Mutex commands_mutex;
+ /// Mutex used to make any operation threadsafe.
+ Mutex operations_mutex;
+
+ std::vector<SetCommand *> commands;
+
+ mutable RID_PtrOwner<NavMap> map_owner;
+ mutable RID_PtrOwner<NavRegion> region_owner;
+ mutable RID_PtrOwner<RvoAgent> agent_owner;
+
+ bool active;
+ Vector<NavMap *> active_maps;
+
+public:
+ GdNavigationServer();
+ virtual ~GdNavigationServer();
+
+ void add_command(SetCommand *command) const;
+
+ virtual RID map_create() const;
+ COMMAND_2(map_set_active, RID, p_map, bool, p_active);
+ virtual bool map_is_active(RID p_map) const;
+
+ COMMAND_2(map_set_up, RID, p_map, Vector3, p_up);
+ virtual Vector3 map_get_up(RID p_map) const;
+
+ COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size);
+ virtual real_t map_get_cell_size(RID p_map) const;
+
+ COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin);
+ virtual real_t map_get_edge_connection_margin(RID p_map) const;
+
+ virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const;
+
+ virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const;
+ virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const;
+ virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const;
+ virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const;
+
+ virtual RID region_create() const;
+ COMMAND_2(region_set_map, RID, p_region, RID, p_map);
+ COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform);
+ COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh);
+ virtual void region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const;
+
+ virtual RID agent_create() const;
+ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map);
+ COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist);
+ COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count);
+ COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time);
+ COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius);
+ COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed);
+ COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity);
+ COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity);
+ COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position);
+ COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore);
+ virtual bool agent_is_map_changed(RID p_agent) const;
+ COMMAND_4_DEF(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata, Variant());
+
+ COMMAND_1(free, RID, p_object);
+
+ virtual void set_active(bool p_active) const;
+
+ void flush_queries();
+ virtual void process(real_t p_delta_time);
+};
+
+#undef COMMAND_1
+#undef COMMAND_2
+#undef COMMAND_4_DEF
+
+#endif // GD_NAVIGATION_SERVER_H
diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp
new file mode 100644
index 0000000000..7e6a3f7a26
--- /dev/null
+++ b/modules/gdnavigation/nav_map.cpp
@@ -0,0 +1,807 @@
+/*************************************************************************/
+/* nav_map.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "nav_map.h"
+
+#include "core/os/threaded_array_processor.h"
+#include "nav_region.h"
+#include "rvo_agent.h"
+#include <algorithm>
+
+/**
+ @author AndreaCatania
+*/
+
+#define USE_ENTRY_POINT
+
+NavMap::NavMap() :
+ up(0, 1, 0),
+ cell_size(0.3),
+ edge_connection_margin(5.0),
+ regenerate_polygons(true),
+ regenerate_links(true),
+ agents_dirty(false),
+ deltatime(0.0),
+ map_update_id(0) {}
+
+void NavMap::set_up(Vector3 p_up) {
+ up = p_up;
+ regenerate_polygons = true;
+}
+
+void NavMap::set_cell_size(float p_cell_size) {
+ cell_size = p_cell_size;
+ regenerate_polygons = true;
+}
+
+void NavMap::set_edge_connection_margin(float p_edge_connection_margin) {
+ edge_connection_margin = p_edge_connection_margin;
+ regenerate_links = true;
+}
+
+gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
+ const int x = int(Math::floor(p_pos.x / cell_size));
+ const int y = int(Math::floor(p_pos.y / cell_size));
+ const int z = int(Math::floor(p_pos.z / cell_size));
+
+ gd::PointKey p;
+ p.key = 0;
+ p.x = x;
+ p.y = y;
+ p.z = z;
+ return p;
+}
+
+Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const {
+
+ const gd::Polygon *begin_poly = nullptr;
+ const gd::Polygon *end_poly = nullptr;
+ Vector3 begin_point;
+ Vector3 end_point;
+ float begin_d = 1e20;
+ float end_d = 1e20;
+
+ // Find the initial poly and the end poly on this map.
+ for (size_t i(0); i < polygons.size(); i++) {
+ const gd::Polygon &p = polygons[i];
+
+ // For each point cast a face and check the distance between the origin/destination
+ for (size_t point_id = 2; point_id < p.points.size(); point_id++) {
+
+ Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
+ Vector3 spoint = f.get_closest_point_to(p_origin);
+ float dpoint = spoint.distance_to(p_origin);
+ if (dpoint < begin_d) {
+ begin_d = dpoint;
+ begin_poly = &p;
+ begin_point = spoint;
+ }
+
+ spoint = f.get_closest_point_to(p_destination);
+ dpoint = spoint.distance_to(p_destination);
+ if (dpoint < end_d) {
+ end_d = dpoint;
+ end_poly = &p;
+ end_point = spoint;
+ }
+ }
+ }
+
+ if (!begin_poly || !end_poly) {
+ // No path
+ return Vector<Vector3>();
+ }
+
+ if (begin_poly == end_poly) {
+
+ Vector<Vector3> path;
+ path.resize(2);
+ path.write[0] = begin_point;
+ path.write[1] = end_point;
+ return path;
+ }
+
+ std::vector<gd::NavigationPoly> navigation_polys;
+ navigation_polys.reserve(polygons.size() * 0.75);
+
+ // The elements indices in the `navigation_polys`.
+ int least_cost_id(-1);
+ List<uint32_t> open_list;
+ bool found_route = false;
+
+ navigation_polys.push_back(gd::NavigationPoly(begin_poly));
+ {
+ least_cost_id = 0;
+ gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id];
+ least_cost_poly->self_id = least_cost_id;
+ least_cost_poly->entry = begin_point;
+ }
+
+ open_list.push_back(0);
+
+ const gd::Polygon *reachable_end = nullptr;
+ float reachable_d = 1e30;
+ bool is_reachable = true;
+
+ while (found_route == false) {
+
+ {
+ // Takes the current least_cost_poly neighbors and compute the traveled_distance of each
+ for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) {
+ gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id];
+
+ const gd::Edge &edge = least_cost_poly->poly->edges[i];
+ if (!edge.other_polygon)
+ continue;
+
+#ifdef USE_ENTRY_POINT
+ Vector3 edge_line[2] = {
+ least_cost_poly->poly->points[i].pos,
+ least_cost_poly->poly->points[(i + 1) % least_cost_poly->poly->points.size()].pos
+ };
+
+ const Vector3 new_entry = Geometry::get_closest_point_to_segment(least_cost_poly->entry, edge_line);
+ const float new_distance = least_cost_poly->entry.distance_to(new_entry) + least_cost_poly->traveled_distance;
+#else
+ const float new_distance = least_cost_poly->poly->center.distance_to(edge.other_polygon->center) + least_cost_poly->traveled_distance;
+#endif
+
+ auto it = std::find(
+ navigation_polys.begin(),
+ navigation_polys.end(),
+ gd::NavigationPoly(edge.other_polygon));
+
+ if (it != navigation_polys.end()) {
+ // Oh this was visited already, can we win the cost?
+ if (it->traveled_distance > new_distance) {
+
+ it->prev_navigation_poly_id = least_cost_id;
+ it->back_navigation_edge = edge.other_edge;
+ it->traveled_distance = new_distance;
+#ifdef USE_ENTRY_POINT
+ it->entry = new_entry;
+#endif
+ }
+ } else {
+ // Add to open neighbours
+
+ navigation_polys.push_back(gd::NavigationPoly(edge.other_polygon));
+ gd::NavigationPoly *np = &navigation_polys[navigation_polys.size() - 1];
+
+ np->self_id = navigation_polys.size() - 1;
+ np->prev_navigation_poly_id = least_cost_id;
+ np->back_navigation_edge = edge.other_edge;
+ np->traveled_distance = new_distance;
+#ifdef USE_ENTRY_POINT
+ np->entry = new_entry;
+#endif
+ open_list.push_back(navigation_polys.size() - 1);
+ }
+ }
+ }
+
+ // Removes the least cost polygon from the open list so we can advance.
+ open_list.erase(least_cost_id);
+
+ if (open_list.size() == 0) {
+ // When the open list is empty at this point the End Polygon is not reachable
+ // so use the further reachable polygon
+ ERR_BREAK_MSG(is_reachable == false, "It's not expect to not find the most reachable polygons");
+ is_reachable = false;
+ if (reachable_end == nullptr) {
+ // The path is not found and there is not a way out.
+ break;
+ }
+
+ // Set as end point the furthest reachable point.
+ end_poly = reachable_end;
+ end_d = 1e20;
+ for (size_t point_id = 2; point_id < end_poly->points.size(); point_id++) {
+ Face3 f(end_poly->points[point_id - 2].pos, end_poly->points[point_id - 1].pos, end_poly->points[point_id].pos);
+ Vector3 spoint = f.get_closest_point_to(p_destination);
+ float dpoint = spoint.distance_to(p_destination);
+ if (dpoint < end_d) {
+ end_point = spoint;
+ end_d = dpoint;
+ }
+ }
+
+ // Reset open and navigation_polys
+ gd::NavigationPoly np = navigation_polys[0];
+ navigation_polys.clear();
+ navigation_polys.push_back(np);
+ open_list.clear();
+ open_list.push_back(0);
+
+ reachable_end = nullptr;
+
+ continue;
+ }
+
+ // Now take the new least_cost_poly from the open list.
+ least_cost_id = -1;
+ float least_cost = 1e30;
+
+ for (auto element = open_list.front(); element != nullptr; element = element->next()) {
+ gd::NavigationPoly *np = &navigation_polys[element->get()];
+ float cost = np->traveled_distance;
+#ifdef USE_ENTRY_POINT
+ cost += np->entry.distance_to(end_point);
+#else
+ cost += np->poly->center.distance_to(end_point);
+#endif
+ if (cost < least_cost) {
+ least_cost_id = np->self_id;
+ least_cost = cost;
+ }
+ }
+
+ // Stores the further reachable end polygon, in case our goal is not reachable.
+ if (is_reachable) {
+ float 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;
+ }
+ }
+
+ ERR_BREAK(least_cost_id == -1);
+
+ // Check if we reached the end
+ if (navigation_polys[least_cost_id].poly == end_poly) {
+ // Yep, done!!
+ found_route = true;
+ break;
+ }
+ }
+
+ if (found_route) {
+
+ Vector<Vector3> path;
+ if (p_optimize) {
+
+ // String pulling
+
+ gd::NavigationPoly *apex_poly = &navigation_polys[least_cost_id];
+ Vector3 apex_point = end_point;
+ Vector3 portal_left = apex_point;
+ Vector3 portal_right = apex_point;
+ gd::NavigationPoly *left_poly = apex_poly;
+ gd::NavigationPoly *right_poly = apex_poly;
+ gd::NavigationPoly *p = apex_poly;
+
+ path.push_back(end_point);
+
+ while (p) {
+
+ Vector3 left;
+ Vector3 right;
+
+#define CLOCK_TANGENT(m_a, m_b, m_c) (((m_a) - (m_c)).cross((m_a) - (m_b)))
+
+ if (p->poly == begin_poly) {
+ left = begin_point;
+ right = begin_point;
+ } else {
+ int prev = p->back_navigation_edge;
+ int prev_n = (p->back_navigation_edge + 1) % p->poly->points.size();
+ left = p->poly->points[prev].pos;
+ right = p->poly->points[prev_n].pos;
+
+ //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){
+ if (p->poly->clockwise) {
+ SWAP(left, right);
+ }
+ }
+
+ bool skip = false;
+
+ if (CLOCK_TANGENT(apex_point, portal_left, left).dot(up) >= 0) {
+ //process
+ if (portal_left == apex_point || CLOCK_TANGENT(apex_point, left, portal_right).dot(up) > 0) {
+ left_poly = p;
+ portal_left = left;
+ } else {
+
+ clip_path(navigation_polys, path, apex_poly, portal_right, right_poly);
+
+ apex_point = portal_right;
+ p = right_poly;
+ left_poly = p;
+ apex_poly = p;
+ portal_left = apex_point;
+ portal_right = apex_point;
+ path.push_back(apex_point);
+ skip = true;
+ }
+ }
+
+ if (!skip && CLOCK_TANGENT(apex_point, portal_right, right).dot(up) <= 0) {
+ //process
+ if (portal_right == apex_point || CLOCK_TANGENT(apex_point, right, portal_left).dot(up) < 0) {
+ right_poly = p;
+ portal_right = right;
+ } else {
+
+ clip_path(navigation_polys, path, apex_poly, portal_left, left_poly);
+
+ apex_point = portal_left;
+ p = left_poly;
+ right_poly = p;
+ apex_poly = p;
+ portal_right = apex_point;
+ portal_left = apex_point;
+ path.push_back(apex_point);
+ }
+ }
+
+ if (p->prev_navigation_poly_id != -1)
+ p = &navigation_polys[p->prev_navigation_poly_id];
+ else
+ // The end
+ p = nullptr;
+ }
+
+ if (path[path.size() - 1] != begin_point)
+ path.push_back(begin_point);
+
+ path.invert();
+
+ } else {
+ path.push_back(end_point);
+
+ // Add mid points
+ int np_id = least_cost_id;
+ while (np_id != -1) {
+
+#ifdef USE_ENTRY_POINT
+ Vector3 point = navigation_polys[np_id].entry;
+#else
+ int prev = navigation_polys[np_id].back_navigation_edge;
+ int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size();
+ Vector3 point = (navigation_polys[np_id].poly->points[prev].pos + navigation_polys[np_id].poly->points[prev_n].pos) * 0.5;
+#endif
+
+ path.push_back(point);
+ np_id = navigation_polys[np_id].prev_navigation_poly_id;
+ }
+
+ path.invert();
+ }
+
+ return path;
+ }
+ return Vector<Vector3>();
+}
+
+Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
+
+ bool use_collision = p_use_collision;
+ Vector3 closest_point;
+ real_t closest_point_d = 1e20;
+
+ // Find the initial poly and the end poly on this map.
+ for (size_t i(0); i < polygons.size(); i++) {
+ const gd::Polygon &p = polygons[i];
+
+ // For each point cast a face and check the distance to the segment
+ for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
+
+ const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
+ Vector3 inters;
+ if (f.intersects_segment(p_from, p_to, &inters)) {
+ const real_t d = closest_point_d = p_from.distance_to(inters);
+ if (use_collision == false) {
+ closest_point = inters;
+ use_collision = true;
+ closest_point_d = d;
+ } else if (closest_point_d > d) {
+
+ closest_point = inters;
+ closest_point_d = d;
+ }
+ }
+ }
+
+ if (use_collision == false) {
+
+ for (size_t point_id = 0; point_id < p.points.size(); point_id += 1) {
+
+ Vector3 a, b;
+
+ Geometry::get_closest_points_between_segments(
+ p_from,
+ p_to,
+ p.points[point_id].pos,
+ p.points[(point_id + 1) % p.points.size()].pos,
+ a,
+ b);
+
+ const real_t d = a.distance_to(b);
+ if (d < closest_point_d) {
+
+ closest_point_d = d;
+ closest_point = b;
+ }
+ }
+ }
+ }
+
+ return closest_point;
+}
+
+Vector3 NavMap::get_closest_point(const Vector3 &p_point) const {
+ // TODO this is really not optimal, please redesign the API to directly return all this data
+
+ Vector3 closest_point;
+ real_t closest_point_d = 1e20;
+
+ // Find the initial poly and the end poly on this map.
+ for (size_t i(0); i < polygons.size(); i++) {
+ const gd::Polygon &p = polygons[i];
+
+ // For each point cast a face and check the distance to the point
+ for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
+
+ const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
+ const Vector3 inters = f.get_closest_point_to(p_point);
+ const real_t d = inters.distance_to(p_point);
+ if (d < closest_point_d) {
+ closest_point = inters;
+ closest_point_d = d;
+ }
+ }
+ }
+
+ return closest_point;
+}
+
+Vector3 NavMap::get_closest_point_normal(const Vector3 &p_point) const {
+ // TODO this is really not optimal, please redesign the API to directly return all this data
+
+ Vector3 closest_point;
+ Vector3 closest_point_normal;
+ real_t closest_point_d = 1e20;
+
+ // Find the initial poly and the end poly on this map.
+ for (size_t i(0); i < polygons.size(); i++) {
+ const gd::Polygon &p = polygons[i];
+
+ // For each point cast a face and check the distance to the point
+ for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
+
+ const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
+ const Vector3 inters = f.get_closest_point_to(p_point);
+ const real_t d = inters.distance_to(p_point);
+ if (d < closest_point_d) {
+ closest_point = inters;
+ closest_point_normal = f.get_plane().normal;
+ closest_point_d = d;
+ }
+ }
+ }
+
+ return closest_point_normal;
+}
+
+RID NavMap::get_closest_point_owner(const Vector3 &p_point) const {
+ // TODO this is really not optimal, please redesign the API to directly return all this data
+
+ Vector3 closest_point;
+ RID closest_point_owner;
+ real_t closest_point_d = 1e20;
+
+ // Find the initial poly and the end poly on this map.
+ for (size_t i(0); i < polygons.size(); i++) {
+ const gd::Polygon &p = polygons[i];
+
+ // For each point cast a face and check the distance to the point
+ for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
+
+ const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
+ const Vector3 inters = f.get_closest_point_to(p_point);
+ const real_t d = inters.distance_to(p_point);
+ if (d < closest_point_d) {
+ closest_point = inters;
+ closest_point_owner = p.owner->get_self();
+ closest_point_d = d;
+ }
+ }
+ }
+
+ return closest_point_owner;
+}
+
+void NavMap::add_region(NavRegion *p_region) {
+ regions.push_back(p_region);
+ regenerate_links = true;
+}
+
+void NavMap::remove_region(NavRegion *p_region) {
+ std::vector<NavRegion *>::iterator it = std::find(regions.begin(), regions.end(), p_region);
+ if (it != regions.end()) {
+ regions.erase(it);
+ regenerate_links = true;
+ }
+}
+
+bool NavMap::has_agent(RvoAgent *agent) const {
+ return std::find(agents.begin(), agents.end(), agent) != agents.end();
+}
+
+void NavMap::add_agent(RvoAgent *agent) {
+ if (!has_agent(agent)) {
+ agents.push_back(agent);
+ agents_dirty = true;
+ }
+}
+
+void NavMap::remove_agent(RvoAgent *agent) {
+ remove_agent_as_controlled(agent);
+ auto it = std::find(agents.begin(), agents.end(), agent);
+ if (it != agents.end()) {
+ agents.erase(it);
+ agents_dirty = true;
+ }
+}
+
+void NavMap::set_agent_as_controlled(RvoAgent *agent) {
+ const bool exist = std::find(controlled_agents.begin(), controlled_agents.end(), agent) != controlled_agents.end();
+ if (!exist) {
+ ERR_FAIL_COND(!has_agent(agent));
+ controlled_agents.push_back(agent);
+ }
+}
+
+void NavMap::remove_agent_as_controlled(RvoAgent *agent) {
+ auto it = std::find(controlled_agents.begin(), controlled_agents.end(), agent);
+ if (it != controlled_agents.end()) {
+ controlled_agents.erase(it);
+ }
+}
+
+void NavMap::sync() {
+
+ if (regenerate_polygons) {
+ for (size_t r(0); r < regions.size(); r++) {
+ regions[r]->scratch_polygons();
+ }
+ regenerate_links = true;
+ }
+
+ for (size_t r(0); r < regions.size(); r++) {
+ if (regions[r]->sync()) {
+ regenerate_links = true;
+ }
+ }
+
+ if (regenerate_links) {
+ // Copy all region polygons in the map.
+ int count = 0;
+ for (size_t r(0); r < regions.size(); r++) {
+ count += regions[r]->get_polygons().size();
+ }
+
+ polygons.resize(count);
+ count = 0;
+
+ for (size_t r(0); r < regions.size(); r++) {
+ std::copy(
+ regions[r]->get_polygons().data(),
+ regions[r]->get_polygons().data() + regions[r]->get_polygons().size(),
+ polygons.begin() + count);
+
+ count += regions[r]->get_polygons().size();
+ }
+
+ // Connects the `Edges` of all the `Polygons` of all `Regions` each other.
+ Map<gd::EdgeKey, gd::Connection> connections;
+
+ for (size_t poly_id(0); poly_id < polygons.size(); poly_id++) {
+ gd::Polygon &poly(polygons[poly_id]);
+
+ for (size_t p(0); p < poly.points.size(); p++) {
+ int next_point = (p + 1) % poly.points.size();
+ gd::EdgeKey ek(poly.points[p].key, poly.points[next_point].key);
+
+ Map<gd::EdgeKey, gd::Connection>::Element *connection = connections.find(ek);
+ if (!connection) {
+ // Nothing yet
+ gd::Connection c;
+ c.A = &poly;
+ c.A_edge = p;
+ c.B = nullptr;
+ c.B_edge = -1;
+ connections[ek] = c;
+
+ } else if (connection->get().B == nullptr) {
+ CRASH_COND(connection->get().A == nullptr); // Unreachable
+
+ // Connect the two Polygons by this edge
+ connection->get().B = &poly;
+ connection->get().B_edge = p;
+
+ connection->get().A->edges[connection->get().A_edge].this_edge = connection->get().A_edge;
+ connection->get().A->edges[connection->get().A_edge].other_polygon = connection->get().B;
+ connection->get().A->edges[connection->get().A_edge].other_edge = connection->get().B_edge;
+
+ connection->get().B->edges[connection->get().B_edge].this_edge = connection->get().B_edge;
+ connection->get().B->edges[connection->get().B_edge].other_polygon = connection->get().A;
+ connection->get().B->edges[connection->get().B_edge].other_edge = connection->get().A_edge;
+ } else {
+ // The edge is already connected with another edge, skip.
+ ERR_PRINT("Attempted to merge a navigation mesh triangle edge with another already-merged edge. This happens when the Navigation3D's `cell_size` is different from the one used to generate the navigation mesh. This will cause navigation problem.");
+ }
+ }
+ }
+
+ // Takes all the free edges.
+ std::vector<gd::FreeEdge> free_edges;
+ free_edges.reserve(connections.size());
+
+ for (auto connection_element = connections.front(); connection_element; connection_element = connection_element->next()) {
+ if (connection_element->get().B == nullptr) {
+ CRASH_COND(connection_element->get().A == nullptr); // Unreachable
+ CRASH_COND(connection_element->get().A_edge < 0); // Unreachable
+
+ // This is a free edge
+ uint32_t id(free_edges.size());
+ free_edges.push_back(gd::FreeEdge());
+ free_edges[id].is_free = true;
+ free_edges[id].poly = connection_element->get().A;
+ free_edges[id].edge_id = connection_element->get().A_edge;
+ uint32_t point_0(free_edges[id].edge_id);
+ uint32_t point_1((free_edges[id].edge_id + 1) % free_edges[id].poly->points.size());
+ Vector3 pos_0 = free_edges[id].poly->points[point_0].pos;
+ Vector3 pos_1 = free_edges[id].poly->points[point_1].pos;
+ Vector3 relative = pos_1 - pos_0;
+ free_edges[id].edge_center = (pos_0 + pos_1) / 2.0;
+ free_edges[id].edge_dir = relative.normalized();
+ free_edges[id].edge_len_squared = relative.length_squared();
+ }
+ }
+
+ const float ecm_squared(edge_connection_margin * edge_connection_margin);
+#define LEN_TOLLERANCE 0.1
+#define DIR_TOLLERANCE 0.9
+ // In front of tolerance
+#define IFO_TOLLERANCE 0.5
+
+ // Find the compatible near edges.
+ //
+ // Note:
+ // Considering that the edges must be compatible (for obvious reasons)
+ // to be connected, create new polygons to remove that small gap is
+ // not really useful and would result in wasteful computation during
+ // connection, integration and path finding.
+ for (size_t i(0); i < free_edges.size(); i++) {
+ if (!free_edges[i].is_free) {
+ continue;
+ }
+ gd::FreeEdge &edge = free_edges[i];
+ for (size_t y(0); y < free_edges.size(); y++) {
+ gd::FreeEdge &other_edge = free_edges[y];
+ if (i == y || !other_edge.is_free || edge.poly->owner == other_edge.poly->owner) {
+ continue;
+ }
+
+ Vector3 rel_centers = other_edge.edge_center - edge.edge_center;
+ if (ecm_squared > rel_centers.length_squared() // Are enough closer?
+ && ABS(edge.edge_len_squared - other_edge.edge_len_squared) < LEN_TOLLERANCE // Are the same length?
+ && ABS(edge.edge_dir.dot(other_edge.edge_dir)) > DIR_TOLLERANCE // Are aligned?
+ && ABS(rel_centers.normalized().dot(edge.edge_dir)) < IFO_TOLLERANCE // Are one in front the other?
+ ) {
+ // The edges can be connected
+ edge.is_free = false;
+ other_edge.is_free = false;
+
+ edge.poly->edges[edge.edge_id].this_edge = edge.edge_id;
+ edge.poly->edges[edge.edge_id].other_edge = other_edge.edge_id;
+ edge.poly->edges[edge.edge_id].other_polygon = other_edge.poly;
+
+ other_edge.poly->edges[other_edge.edge_id].this_edge = other_edge.edge_id;
+ other_edge.poly->edges[other_edge.edge_id].other_edge = edge.edge_id;
+ other_edge.poly->edges[other_edge.edge_id].other_polygon = edge.poly;
+ }
+ }
+ }
+ }
+
+ if (regenerate_links) {
+ map_update_id = map_update_id + 1 % 9999999;
+ }
+
+ if (agents_dirty) {
+ std::vector<RVO::Agent *> raw_agents;
+ raw_agents.reserve(agents.size());
+ for (size_t i(0); i < agents.size(); i++)
+ raw_agents.push_back(agents[i]->get_agent());
+ rvo.buildAgentTree(raw_agents);
+ }
+
+ regenerate_polygons = false;
+ regenerate_links = false;
+ agents_dirty = false;
+}
+
+void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) {
+ (*(agent + index))->get_agent()->computeNeighbors(&rvo);
+ (*(agent + index))->get_agent()->computeNewVelocity(deltatime);
+}
+
+void NavMap::step(real_t p_deltatime) {
+ deltatime = p_deltatime;
+ if (controlled_agents.size() > 0) {
+ thread_process_array(
+ controlled_agents.size(),
+ this,
+ &NavMap::compute_single_step,
+ controlled_agents.data());
+ }
+}
+
+void NavMap::dispatch_callbacks() {
+ for (int i(0); i < static_cast<int>(controlled_agents.size()); i++) {
+ controlled_agents[i]->dispatch_callback();
+ }
+}
+
+void NavMap::clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const {
+ Vector3 from = path[path.size() - 1];
+
+ if (from.distance_to(p_to_point) < CMP_EPSILON)
+ return;
+ Plane cut_plane;
+ cut_plane.normal = (from - p_to_point).cross(up);
+ if (cut_plane.normal == Vector3())
+ return;
+ cut_plane.normal.normalize();
+ cut_plane.d = cut_plane.normal.dot(from);
+
+ while (from_poly != p_to_poly) {
+
+ int back_nav_edge = from_poly->back_navigation_edge;
+ Vector3 a = from_poly->poly->points[back_nav_edge].pos;
+ Vector3 b = from_poly->poly->points[(back_nav_edge + 1) % from_poly->poly->points.size()].pos;
+
+ ERR_FAIL_COND(from_poly->prev_navigation_poly_id == -1);
+ from_poly = &p_navigation_polys[from_poly->prev_navigation_poly_id];
+
+ if (a.distance_to(b) > CMP_EPSILON) {
+
+ Vector3 inters;
+ if (cut_plane.intersects_segment(a, b, &inters)) {
+ if (inters.distance_to(p_to_point) > CMP_EPSILON && inters.distance_to(path[path.size() - 1]) > CMP_EPSILON) {
+ path.push_back(inters);
+ }
+ }
+ }
+ }
+}
diff --git a/modules/gdnavigation/nav_map.h b/modules/gdnavigation/nav_map.h
new file mode 100644
index 0000000000..4543f00926
--- /dev/null
+++ b/modules/gdnavigation/nav_map.h
@@ -0,0 +1,141 @@
+/*************************************************************************/
+/* nav_map.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 RVO_SPACE_H
+#define RVO_SPACE_H
+
+#include "nav_rid.h"
+
+#include "core/math/math_defs.h"
+#include "nav_utils.h"
+#include <KdTree.h>
+
+/**
+ @author AndreaCatania
+*/
+
+class NavRegion;
+class RvoAgent;
+class NavRegion;
+
+class NavMap : public NavRid {
+
+ /// Map Up
+ Vector3 up;
+
+ /// To find the polygons edges the vertices are displaced in a grid where
+ /// each cell has the following cell_size.
+ real_t cell_size;
+
+ /// This value is used to detect the near edges to connect.
+ real_t edge_connection_margin;
+
+ bool regenerate_polygons;
+ bool regenerate_links;
+
+ std::vector<NavRegion *> regions;
+
+ /// Map polygons
+ std::vector<gd::Polygon> polygons;
+
+ /// Rvo world
+ RVO::KdTree rvo;
+
+ /// Is agent array modified?
+ bool agents_dirty;
+
+ /// All the Agents (even the controlled one)
+ std::vector<RvoAgent *> agents;
+
+ /// Controlled agents
+ std::vector<RvoAgent *> controlled_agents;
+
+ /// Physics delta time
+ real_t deltatime;
+
+ /// Change the id each time the map is updated.
+ uint32_t map_update_id;
+
+public:
+ NavMap();
+
+ void set_up(Vector3 p_up);
+ Vector3 get_up() const {
+ return up;
+ }
+
+ void set_cell_size(float p_cell_size);
+ float get_cell_size() const {
+ return cell_size;
+ }
+
+ void set_edge_connection_margin(float p_edge_connection_margin);
+ float get_edge_connection_margin() const {
+ return edge_connection_margin;
+ }
+
+ gd::PointKey get_point_key(const Vector3 &p_pos) const;
+
+ Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const;
+ Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const;
+ Vector3 get_closest_point(const Vector3 &p_point) const;
+ Vector3 get_closest_point_normal(const Vector3 &p_point) const;
+ RID get_closest_point_owner(const Vector3 &p_point) const;
+
+ void add_region(NavRegion *p_region);
+ void remove_region(NavRegion *p_region);
+ const std::vector<NavRegion *> &get_regions() const {
+ return regions;
+ }
+
+ bool has_agent(RvoAgent *agent) const;
+ void add_agent(RvoAgent *agent);
+ void remove_agent(RvoAgent *agent);
+ const std::vector<RvoAgent *> &get_agents() const {
+ return agents;
+ }
+
+ void set_agent_as_controlled(RvoAgent *agent);
+ void remove_agent_as_controlled(RvoAgent *agent);
+
+ uint32_t get_map_update_id() const {
+ return map_update_id;
+ }
+
+ void sync();
+ void step(real_t p_deltatime);
+ void dispatch_callbacks();
+
+private:
+ void compute_single_step(uint32_t index, RvoAgent **agent);
+ void clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const;
+};
+
+#endif // RVO_SPACE_H
diff --git a/modules/gdnavigation/nav_region.cpp b/modules/gdnavigation/nav_region.cpp
new file mode 100644
index 0000000000..b91376f761
--- /dev/null
+++ b/modules/gdnavigation/nav_region.cpp
@@ -0,0 +1,136 @@
+/*************************************************************************/
+/* nav_region.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "nav_region.h"
+
+#include "nav_map.h"
+
+/**
+ @author AndreaCatania
+*/
+
+NavRegion::NavRegion() :
+ map(nullptr),
+ polygons_dirty(true) {
+}
+
+void NavRegion::set_map(NavMap *p_map) {
+ map = p_map;
+ polygons_dirty = true;
+}
+
+void NavRegion::set_transform(Transform p_transform) {
+ transform = p_transform;
+ polygons_dirty = true;
+}
+
+void NavRegion::set_mesh(Ref<NavigationMesh> p_mesh) {
+ mesh = p_mesh;
+ polygons_dirty = true;
+}
+
+bool NavRegion::sync() {
+ bool something_changed = polygons_dirty /* || something_dirty? */;
+
+ update_polygons();
+
+ return something_changed;
+}
+
+void NavRegion::update_polygons() {
+ if (!polygons_dirty) {
+ return;
+ }
+ polygons.clear();
+ polygons_dirty = false;
+
+ if (map == nullptr) {
+ return;
+ }
+
+ if (mesh.is_null())
+ return;
+
+ Vector<Vector3> vertices = mesh->get_vertices();
+ int len = vertices.size();
+ if (len == 0)
+ return;
+
+ const Vector3 *vertices_r = vertices.ptr();
+
+ polygons.resize(mesh->get_polygon_count());
+
+ // Build
+ for (size_t i(0); i < polygons.size(); i++) {
+
+ gd::Polygon &p = polygons[i];
+ p.owner = this;
+
+ Vector<int> mesh_poly = mesh->get_polygon(i);
+ const int *indices = mesh_poly.ptr();
+ bool valid(true);
+ p.points.resize(mesh_poly.size());
+ p.edges.resize(mesh_poly.size());
+
+ Vector3 center;
+ float sum(0);
+
+ for (int j(0); j < mesh_poly.size(); j++) {
+
+ int idx = indices[j];
+ if (idx < 0 || idx >= len) {
+ valid = false;
+ break;
+ }
+
+ Vector3 point_position = transform.xform(vertices_r[idx]);
+ p.points[j].pos = point_position;
+ p.points[j].key = map->get_point_key(point_position);
+
+ center += point_position; // Composing the center of the polygon
+
+ if (j >= 2) {
+ Vector3 epa = transform.xform(vertices_r[indices[j - 2]]);
+ Vector3 epb = transform.xform(vertices_r[indices[j - 1]]);
+
+ sum += map->get_up().dot((epb - epa).cross(point_position - epa));
+ }
+ }
+
+ if (!valid) {
+ ERR_BREAK_MSG(!valid, "The navigation mesh set in this region is not valid!");
+ }
+
+ p.clockwise = sum > 0;
+ if (mesh_poly.size() != 0) {
+ p.center = center / float(mesh_poly.size());
+ }
+ }
+}
diff --git a/modules/gdnavigation/nav_region.h b/modules/gdnavigation/nav_region.h
new file mode 100644
index 0000000000..f35ee4bea0
--- /dev/null
+++ b/modules/gdnavigation/nav_region.h
@@ -0,0 +1,89 @@
+/*************************************************************************/
+/* nav_region.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 NAV_REGION_H
+#define NAV_REGION_H
+
+#include "nav_rid.h"
+
+#include "nav_utils.h"
+#include "scene/3d/navigation_3d.h"
+#include <vector>
+
+/**
+ @author AndreaCatania
+*/
+
+class NavMap;
+class NavRegion;
+
+class NavRegion : public NavRid {
+ NavMap *map;
+ Transform transform;
+ Ref<NavigationMesh> mesh;
+
+ bool polygons_dirty;
+
+ /// Cache
+ std::vector<gd::Polygon> polygons;
+
+public:
+ NavRegion();
+
+ void scratch_polygons() {
+ polygons_dirty = true;
+ }
+
+ void set_map(NavMap *p_map);
+ NavMap *get_map() const {
+ return map;
+ }
+
+ void set_transform(Transform transform);
+ const Transform &get_transform() const {
+ return transform;
+ }
+
+ void set_mesh(Ref<NavigationMesh> p_mesh);
+ const Ref<NavigationMesh> get_mesh() const {
+ return mesh;
+ }
+
+ std::vector<gd::Polygon> const &get_polygons() const {
+ return polygons;
+ }
+
+ bool sync();
+
+private:
+ void update_polygons();
+};
+
+#endif // NAV_REGION_H
diff --git a/modules/vorbis/stub/register_types.cpp b/modules/gdnavigation/nav_rid.h
index 8874b3887b..c119ecc5e0 100644
--- a/modules/vorbis/stub/register_types.cpp
+++ b/modules/gdnavigation/nav_rid.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* register_types.cpp */
+/* nav_rid.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,10 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "register_types.h"
+#ifndef NAV_RID_H
+#define NAV_RID_H
-// Dummy module as libvorbis is needed by other modules (theora ...)
+#include "core/rid.h"
-void register_vorbis_types() {}
+/**
+ @author AndreaCatania
+*/
-void unregister_vorbis_types() {}
+class NavRid {
+ RID self;
+
+public:
+ _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; }
+ _FORCE_INLINE_ RID get_self() const { return self; }
+};
+
+#endif // NAV_RID_H
diff --git a/modules/gdnavigation/nav_utils.h b/modules/gdnavigation/nav_utils.h
new file mode 100644
index 0000000000..3401284c31
--- /dev/null
+++ b/modules/gdnavigation/nav_utils.h
@@ -0,0 +1,169 @@
+/*************************************************************************/
+/* nav_utils.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 NAV_UTILS_H
+#define NAV_UTILS_H
+
+#include "core/math/vector3.h"
+#include <vector>
+
+/**
+ @author AndreaCatania
+*/
+
+class NavRegion;
+
+namespace gd {
+struct Polygon;
+
+union PointKey {
+
+ struct {
+ int64_t x : 21;
+ int64_t y : 22;
+ int64_t z : 21;
+ };
+
+ uint64_t key;
+ bool operator<(const PointKey &p_key) const { return key < p_key.key; }
+};
+
+struct EdgeKey {
+
+ PointKey a;
+ PointKey b;
+
+ bool operator<(const EdgeKey &p_key) const {
+ return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
+ }
+
+ EdgeKey(const PointKey &p_a = PointKey(), const PointKey &p_b = PointKey()) :
+ a(p_a),
+ b(p_b) {
+ if (a.key > b.key) {
+ SWAP(a, b);
+ }
+ }
+};
+
+struct Point {
+ Vector3 pos;
+ PointKey key;
+};
+
+struct Edge {
+ /// This edge ID
+ int this_edge;
+
+ /// Other Polygon
+ Polygon *other_polygon;
+
+ /// The other `Polygon` at this edge id has this `Polygon`.
+ int other_edge;
+
+ Edge() {
+ this_edge = -1;
+ other_polygon = nullptr;
+ other_edge = -1;
+ }
+};
+
+struct Polygon {
+ NavRegion *owner;
+
+ /// The points of this `Polygon`
+ std::vector<Point> points;
+
+ /// Are the points clockwise ?
+ bool clockwise;
+
+ /// The edges of this `Polygon`
+ std::vector<Edge> edges;
+
+ /// The center of this `Polygon`
+ Vector3 center;
+};
+
+struct Connection {
+
+ Polygon *A;
+ int A_edge;
+ Polygon *B;
+ int B_edge;
+
+ Connection() {
+ A = nullptr;
+ B = nullptr;
+ A_edge = -1;
+ B_edge = -1;
+ }
+};
+
+struct NavigationPoly {
+ uint32_t self_id;
+ /// This poly.
+ const Polygon *poly;
+ /// The previous navigation poly (id in the `navigation_poly` array).
+ int prev_navigation_poly_id;
+ /// The edge id in this `Poly` to reach the `prev_navigation_poly_id`.
+ uint32_t back_navigation_edge;
+ /// The entry location of this poly.
+ Vector3 entry;
+ /// The distance to the destination.
+ float traveled_distance;
+
+ NavigationPoly(const Polygon *p_poly) :
+ self_id(0),
+ poly(p_poly),
+ prev_navigation_poly_id(-1),
+ back_navigation_edge(0),
+ traveled_distance(0.0) {
+ }
+
+ bool operator==(const NavigationPoly &other) const {
+ return this->poly == other.poly;
+ }
+
+ bool operator!=(const NavigationPoly &other) const {
+ return !operator==(other);
+ }
+};
+
+struct FreeEdge {
+ bool is_free;
+ Polygon *poly;
+ uint32_t edge_id;
+ Vector3 edge_center;
+ Vector3 edge_dir;
+ float edge_len_squared;
+};
+} // namespace gd
+
+#endif // NAV_UTILS_H
diff --git a/modules/recast/navigation_mesh_editor_plugin.cpp b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
index 6e68dba8ee..abaf73ba6a 100644
--- a/modules/recast/navigation_mesh_editor_plugin.cpp
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
@@ -28,17 +28,19 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifdef TOOLS_ENABLED
#include "navigation_mesh_editor_plugin.h"
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
-#include "scene/3d/mesh_instance.h"
+#include "navigation_mesh_generator.h"
+#include "scene/3d/mesh_instance_3d.h"
#include "scene/gui/box_container.h"
void NavigationMeshEditor::_node_removed(Node *p_node) {
if (p_node == node) {
- node = NULL;
+ node = nullptr;
hide();
}
@@ -48,8 +50,8 @@ void NavigationMeshEditor::_notification(int p_option) {
if (p_option == NOTIFICATION_ENTER_TREE) {
- button_bake->set_icon(get_icon("Bake", "EditorIcons"));
- button_reset->set_icon(get_icon("Reload", "EditorIcons"));
+ button_bake->set_icon(get_theme_icon("Bake", "EditorIcons"));
+ button_reset->set_icon(get_theme_icon("Reload", "EditorIcons"));
}
}
@@ -57,15 +59,14 @@ void NavigationMeshEditor::_bake_pressed() {
button_bake->set_pressed(false);
ERR_FAIL_COND(!node);
- const String conf_warning = node->get_configuration_warning();
- if (!conf_warning.empty()) {
- err_dialog->set_text(conf_warning);
- err_dialog->popup_centered_minsize();
+ if (!node->get_navigation_mesh().is_valid()) {
+ err_dialog->set_text(TTR("A NavigationMesh resource must be set or created for this node to work."));
+ err_dialog->popup_centered();
return;
}
- EditorNavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
- EditorNavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node);
+ NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
+ NavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node);
node->update_gizmo();
}
@@ -73,7 +74,7 @@ void NavigationMeshEditor::_bake_pressed() {
void NavigationMeshEditor::_clear_pressed() {
if (node)
- EditorNavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
+ NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
button_bake->set_pressed(false);
bake_info->set_text("");
@@ -83,19 +84,16 @@ void NavigationMeshEditor::_clear_pressed() {
}
}
-void NavigationMeshEditor::edit(NavigationMeshInstance *p_nav_mesh_instance) {
+void NavigationMeshEditor::edit(NavigationRegion3D *p_nav_region) {
- if (p_nav_mesh_instance == NULL || node == p_nav_mesh_instance) {
+ if (p_nav_region == nullptr || node == p_nav_region) {
return;
}
- node = p_nav_mesh_instance;
+ node = p_nav_region;
}
void NavigationMeshEditor::_bind_methods() {
-
- ClassDB::bind_method("_bake_pressed", &NavigationMeshEditor::_bake_pressed);
- ClassDB::bind_method("_clear_pressed", &NavigationMeshEditor::_clear_pressed);
}
NavigationMeshEditor::NavigationMeshEditor() {
@@ -106,20 +104,20 @@ NavigationMeshEditor::NavigationMeshEditor() {
bake_hbox->add_child(button_bake);
button_bake->set_toggle_mode(true);
button_bake->set_text(TTR("Bake NavMesh"));
- button_bake->connect("pressed", this, "_bake_pressed");
+ button_bake->connect("pressed", callable_mp(this, &NavigationMeshEditor::_bake_pressed));
button_reset = memnew(ToolButton);
bake_hbox->add_child(button_reset);
// No button text, we only use a revert icon which is set when entering the tree.
button_reset->set_tooltip(TTR("Clear the navigation mesh."));
- button_reset->connect("pressed", this, "_clear_pressed");
+ button_reset->connect("pressed", callable_mp(this, &NavigationMeshEditor::_clear_pressed));
bake_info = memnew(Label);
bake_hbox->add_child(bake_info);
err_dialog = memnew(AcceptDialog);
add_child(err_dialog);
- node = NULL;
+ node = nullptr;
}
NavigationMeshEditor::~NavigationMeshEditor() {
@@ -127,12 +125,12 @@ NavigationMeshEditor::~NavigationMeshEditor() {
void NavigationMeshEditorPlugin::edit(Object *p_object) {
- navigation_mesh_editor->edit(Object::cast_to<NavigationMeshInstance>(p_object));
+ navigation_mesh_editor->edit(Object::cast_to<NavigationRegion3D>(p_object));
}
bool NavigationMeshEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("NavigationMeshInstance");
+ return p_object->is_class("NavigationRegion3D");
}
void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
@@ -144,7 +142,7 @@ void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
navigation_mesh_editor->hide();
navigation_mesh_editor->bake_hbox->hide();
- navigation_mesh_editor->edit(NULL);
+ navigation_mesh_editor->edit(nullptr);
}
}
@@ -160,3 +158,5 @@ NavigationMeshEditorPlugin::NavigationMeshEditorPlugin(EditorNode *p_node) {
NavigationMeshEditorPlugin::~NavigationMeshEditorPlugin() {
}
+
+#endif
diff --git a/modules/recast/navigation_mesh_editor_plugin.h b/modules/gdnavigation/navigation_mesh_editor_plugin.h
index 09c8673b43..434981c9e0 100644
--- a/modules/recast/navigation_mesh_editor_plugin.h
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.h
@@ -28,12 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef NAVIGATION_MESH_GENERATOR_PLUGIN_H
-#define NAVIGATION_MESH_GENERATOR_PLUGIN_H
+#ifndef NAVIGATION_MESH_EDITOR_PLUGIN_H
+#define NAVIGATION_MESH_EDITOR_PLUGIN_H
+
+#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
-#include "navigation_mesh_generator.h"
+
+class NavigationRegion3D;
class NavigationMeshEditor : public Control {
friend class NavigationMeshEditorPlugin;
@@ -47,7 +50,7 @@ class NavigationMeshEditor : public Control {
ToolButton *button_reset;
Label *bake_info;
- NavigationMeshInstance *node;
+ NavigationRegion3D *node;
void _bake_pressed();
void _clear_pressed();
@@ -58,7 +61,7 @@ protected:
void _notification(int p_option);
public:
- void edit(NavigationMeshInstance *p_nav_mesh_instance);
+ void edit(NavigationRegion3D *p_nav_region);
NavigationMeshEditor();
~NavigationMeshEditor();
};
@@ -81,4 +84,6 @@ public:
~NavigationMeshEditorPlugin();
};
-#endif // NAVIGATION_MESH_GENERATOR_PLUGIN_H
+#endif
+
+#endif
diff --git a/modules/recast/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp
index b6f5b38038..acb4f0461f 100644
--- a/modules/recast/navigation_mesh_generator.cpp
+++ b/modules/gdnavigation/navigation_mesh_generator.cpp
@@ -28,25 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef _3D_DISABLED
+
#include "navigation_mesh_generator.h"
#include "core/math/quick_hull.h"
#include "core/os/thread.h"
-#include "editor/editor_settings.h"
-#include "scene/3d/collision_shape.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/3d/physics_body.h"
-#include "scene/resources/box_shape.h"
-#include "scene/resources/capsule_shape.h"
-#include "scene/resources/concave_polygon_shape.h"
-#include "scene/resources/convex_polygon_shape.h"
-#include "scene/resources/cylinder_shape.h"
-#include "scene/resources/plane_shape.h"
+#include "scene/3d/collision_shape_3d.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/physics_body_3d.h"
+#include "scene/resources/box_shape_3d.h"
+#include "scene/resources/capsule_shape_3d.h"
+#include "scene/resources/concave_polygon_shape_3d.h"
+#include "scene/resources/convex_polygon_shape_3d.h"
+#include "scene/resources/cylinder_shape_3d.h"
#include "scene/resources/primitive_meshes.h"
-#include "scene/resources/shape.h"
-#include "scene/resources/sphere_shape.h"
+#include "scene/resources/shape_3d.h"
+#include "scene/resources/sphere_shape_3d.h"
+#include "scene/resources/world_margin_shape_3d.h"
#include "modules/modules_enabled.gen.h"
+#ifdef TOOLS_ENABLED
+#include "editor/editor_node.h"
+#include "editor/editor_settings.h"
+#endif
+
#ifdef MODULE_CSG_ENABLED
#include "modules/csg/csg_shape.h"
#endif
@@ -54,15 +60,15 @@
#include "modules/gridmap/grid_map.h"
#endif
-EditorNavigationMeshGenerator *EditorNavigationMeshGenerator::singleton = NULL;
+NavigationMeshGenerator *NavigationMeshGenerator::singleton = nullptr;
-void EditorNavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
+void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
p_verticies.push_back(p_vec3.x);
p_verticies.push_back(p_vec3.y);
p_verticies.push_back(p_vec3.z);
}
-void EditorNavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
int current_vertex_count;
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
@@ -84,13 +90,13 @@ void EditorNavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Tra
Array a = p_mesh->surface_get_arrays(i);
- PoolVector<Vector3> mesh_vertices = a[Mesh::ARRAY_VERTEX];
- PoolVector<Vector3>::Read vr = mesh_vertices.read();
+ Vector<Vector3> mesh_vertices = a[Mesh::ARRAY_VERTEX];
+ const Vector3 *vr = mesh_vertices.ptr();
if (p_mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
- PoolVector<int> mesh_indices = a[Mesh::ARRAY_INDEX];
- PoolVector<int>::Read ir = mesh_indices.read();
+ Vector<int> mesh_indices = a[Mesh::ARRAY_INDEX];
+ const int *ir = mesh_indices.ptr();
for (int j = 0; j < mesh_vertices.size(); j++) {
_add_vertex(p_xform.xform(vr[j]), p_verticies);
@@ -117,7 +123,7 @@ void EditorNavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Tra
}
}
-void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
int face_count = p_faces.size() / 3;
int current_vertex_count = p_verticies.size() / 3;
@@ -132,11 +138,11 @@ void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces,
}
}
-void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
+void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
- if (Object::cast_to<MeshInstance>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
+ if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
- MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mesh_instance->get_mesh();
if (mesh.is_valid()) {
_add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_verticies, p_indices);
@@ -144,9 +150,9 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
}
#ifdef MODULE_CSG_ENABLED
- if (Object::cast_to<CSGShape>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
+ if (Object::cast_to<CSGShape3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
- CSGShape *csg_shape = Object::cast_to<CSGShape>(p_node);
+ CSGShape3D *csg_shape = Object::cast_to<CSGShape3D>(p_node);
Array meshes = csg_shape->get_meshes();
if (!meshes.empty()) {
Ref<Mesh> mesh = meshes[1];
@@ -157,22 +163,22 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
}
#endif
- if (Object::cast_to<StaticBody>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_MESH_INSTANCES) {
- StaticBody *static_body = Object::cast_to<StaticBody>(p_node);
+ if (Object::cast_to<StaticBody3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_MESH_INSTANCES) {
+ StaticBody3D *static_body = Object::cast_to<StaticBody3D>(p_node);
if (static_body->get_collision_layer() & p_collision_mask) {
for (int i = 0; i < p_node->get_child_count(); ++i) {
Node *child = p_node->get_child(i);
- if (Object::cast_to<CollisionShape>(child)) {
- CollisionShape *col_shape = Object::cast_to<CollisionShape>(child);
+ if (Object::cast_to<CollisionShape3D>(child)) {
+ CollisionShape3D *col_shape = Object::cast_to<CollisionShape3D>(child);
Transform transform = p_accumulated_transform * static_body->get_transform() * col_shape->get_transform();
Ref<Mesh> mesh;
- Ref<Shape> s = col_shape->get_shape();
+ Ref<Shape3D> s = col_shape->get_shape();
- BoxShape *box = Object::cast_to<BoxShape>(*s);
+ BoxShape3D *box = Object::cast_to<BoxShape3D>(*s);
if (box) {
Ref<CubeMesh> cube_mesh;
cube_mesh.instance();
@@ -180,7 +186,7 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
mesh = cube_mesh;
}
- CapsuleShape *capsule = Object::cast_to<CapsuleShape>(*s);
+ CapsuleShape3D *capsule = Object::cast_to<CapsuleShape3D>(*s);
if (capsule) {
Ref<CapsuleMesh> capsule_mesh;
capsule_mesh.instance();
@@ -189,7 +195,7 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
mesh = capsule_mesh;
}
- CylinderShape *cylinder = Object::cast_to<CylinderShape>(*s);
+ CylinderShape3D *cylinder = Object::cast_to<CylinderShape3D>(*s);
if (cylinder) {
Ref<CylinderMesh> cylinder_mesh;
cylinder_mesh.instance();
@@ -199,7 +205,7 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
mesh = cylinder_mesh;
}
- SphereShape *sphere = Object::cast_to<SphereShape>(*s);
+ SphereShape3D *sphere = Object::cast_to<SphereShape3D>(*s);
if (sphere) {
Ref<SphereMesh> sphere_mesh;
sphere_mesh.instance();
@@ -208,12 +214,12 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
mesh = sphere_mesh;
}
- ConcavePolygonShape *concave_polygon = Object::cast_to<ConcavePolygonShape>(*s);
+ ConcavePolygonShape3D *concave_polygon = Object::cast_to<ConcavePolygonShape3D>(*s);
if (concave_polygon) {
_add_faces(concave_polygon->get_faces(), transform, p_verticies, p_indices);
}
- ConvexPolygonShape *convex_polygon = Object::cast_to<ConvexPolygonShape>(*s);
+ ConvexPolygonShape3D *convex_polygon = Object::cast_to<ConvexPolygonShape3D>(*s);
if (convex_polygon) {
Vector<Vector3> varr = Variant(convex_polygon->get_points());
Geometry::MeshData md;
@@ -221,7 +227,7 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
Error err = QuickHull::build(varr, md);
if (err == OK) {
- PoolVector3Array faces;
+ PackedVector3Array faces;
for (int j = 0; j < md.faces.size(); ++j) {
Geometry::MeshData::Face face = md.faces[j];
@@ -259,8 +265,8 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
}
#endif
- if (Object::cast_to<Spatial>(p_node)) {
- Spatial *spatial = Object::cast_to<Spatial>(p_node);
+ if (Object::cast_to<Node3D>(p_node)) {
+ Node3D *spatial = Object::cast_to<Node3D>(p_node);
p_accumulated_transform = p_accumulated_transform * spatial->get_transform();
}
@@ -271,13 +277,13 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
}
}
-void EditorNavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) {
+void NavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) {
- PoolVector<Vector3> nav_vertices;
+ Vector<Vector3> nav_vertices;
for (int i = 0; i < p_detail_mesh->nverts; i++) {
const float *v = &p_detail_mesh->verts[i * 3];
- nav_vertices.append(Vector3(v[0], v[1], v[2]));
+ nav_vertices.push_back(Vector3(v[0], v[1], v[2]));
}
p_nav_mesh->set_vertices(nav_vertices);
@@ -299,11 +305,24 @@ void EditorNavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_me
}
}
-void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
- rcHeightfield *hf, rcCompactHeightfield *chf, rcContourSet *cset, rcPolyMesh *poly_mesh, rcPolyMeshDetail *detail_mesh,
- Vector<float> &vertices, Vector<int> &indices) {
+void NavigationMeshGenerator::_build_recast_navigation_mesh(
+ Ref<NavigationMesh> p_nav_mesh,
+#ifdef TOOLS_ENABLED
+ EditorProgress *ep,
+#endif
+ rcHeightfield *hf,
+ rcCompactHeightfield *chf,
+ rcContourSet *cset,
+ rcPolyMesh *poly_mesh,
+ rcPolyMeshDetail *detail_mesh,
+ Vector<float> &vertices,
+ Vector<int> &indices) {
rcContext ctx;
- ep->step(TTR("Setting up Configuration..."), 1);
+
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Setting up Configuration..."), 1);
+#endif
const float *verts = vertices.ptr();
const int nverts = vertices.size() / 3;
@@ -337,16 +356,25 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation
cfg.bmax[1] = bmax[1];
cfg.bmax[2] = bmax[2];
- ep->step(TTR("Calculating grid size..."), 2);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Calculating grid size..."), 2);
+#endif
rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height);
- ep->step(TTR("Creating heightfield..."), 3);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Creating heightfield..."), 3);
+#endif
hf = rcAllocHeightfield();
ERR_FAIL_COND(!hf);
ERR_FAIL_COND(!rcCreateHeightfield(&ctx, *hf, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch));
- ep->step(TTR("Marking walkable triangles..."), 4);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Marking walkable triangles..."), 4);
+#endif
{
Vector<unsigned char> tri_areas;
tri_areas.resize(ntris);
@@ -366,7 +394,10 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation
if (p_nav_mesh->get_filter_walkable_low_height_spans())
rcFilterWalkableLowHeightSpans(&ctx, cfg.walkableHeight, *hf);
- ep->step(TTR("Constructing compact heightfield..."), 5);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Constructing compact heightfield..."), 5);
+#endif
chf = rcAllocCompactHeightfield();
@@ -374,12 +405,20 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation
ERR_FAIL_COND(!rcBuildCompactHeightfield(&ctx, cfg.walkableHeight, cfg.walkableClimb, *hf, *chf));
rcFreeHeightField(hf);
- hf = 0;
+ hf = nullptr;
+
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Eroding walkable area..."), 6);
+#endif
- ep->step(TTR("Eroding walkable area..."), 6);
ERR_FAIL_COND(!rcErodeWalkableArea(&ctx, cfg.walkableRadius, *chf));
- ep->step(TTR("Partitioning..."), 7);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Partitioning..."), 7);
+#endif
+
if (p_nav_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_WATERSHED) {
ERR_FAIL_COND(!rcBuildDistanceField(&ctx, *chf));
ERR_FAIL_COND(!rcBuildRegions(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea));
@@ -389,14 +428,20 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation
ERR_FAIL_COND(!rcBuildLayerRegions(&ctx, *chf, 0, cfg.minRegionArea));
}
- ep->step(TTR("Creating contours..."), 8);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Creating contours..."), 8);
+#endif
cset = rcAllocContourSet();
ERR_FAIL_COND(!cset);
ERR_FAIL_COND(!rcBuildContours(&ctx, *chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset));
- ep->step(TTR("Creating polymesh..."), 9);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Creating polymesh..."), 9);
+#endif
poly_mesh = rcAllocPolyMesh();
ERR_FAIL_COND(!poly_mesh);
@@ -407,37 +452,47 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation
ERR_FAIL_COND(!rcBuildPolyMeshDetail(&ctx, *poly_mesh, *chf, cfg.detailSampleDist, cfg.detailSampleMaxError, *detail_mesh));
rcFreeCompactHeightfield(chf);
- chf = 0;
+ chf = nullptr;
rcFreeContourSet(cset);
- cset = 0;
+ cset = nullptr;
- ep->step(TTR("Converting to native navigation mesh..."), 10);
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Converting to native navigation mesh..."), 10);
+#endif
_convert_detail_mesh_to_native_navigation_mesh(detail_mesh, p_nav_mesh);
rcFreePolyMesh(poly_mesh);
- poly_mesh = 0;
+ poly_mesh = nullptr;
rcFreePolyMeshDetail(detail_mesh);
- detail_mesh = 0;
+ detail_mesh = nullptr;
}
-EditorNavigationMeshGenerator *EditorNavigationMeshGenerator::get_singleton() {
+NavigationMeshGenerator *NavigationMeshGenerator::get_singleton() {
return singleton;
}
-EditorNavigationMeshGenerator::EditorNavigationMeshGenerator() {
+NavigationMeshGenerator::NavigationMeshGenerator() {
singleton = this;
}
-EditorNavigationMeshGenerator::~EditorNavigationMeshGenerator() {
+NavigationMeshGenerator::~NavigationMeshGenerator() {
}
-void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) {
+void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) {
ERR_FAIL_COND(!p_nav_mesh.is_valid());
- EditorProgress ep("bake", TTR("Navigation Mesh Generator Setup:"), 11);
- ep.step(TTR("Parsing Geometry..."), 0);
+#ifdef TOOLS_ENABLED
+ EditorProgress *ep(nullptr);
+ if (Engine::get_singleton()->is_editor_hint()) {
+ ep = memnew(EditorProgress("bake", TTR("Navigation Mesh Generator Setup:"), 11));
+ }
+
+ if (ep)
+ ep->step(TTR("Parsing Geometry..."), 0);
+#endif
Vector<float> vertices;
Vector<int> indices;
@@ -450,7 +505,7 @@ void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p
p_node->get_tree()->get_nodes_in_group(p_nav_mesh->get_source_group_name(), &parse_nodes);
}
- Transform navmesh_xform = Object::cast_to<Spatial>(p_node)->get_transform().affine_inverse();
+ Transform navmesh_xform = Object::cast_to<Node3D>(p_node)->get_transform().affine_inverse();
for (const List<Node *>::Element *E = parse_nodes.front(); E; E = E->next()) {
int geometry_type = p_nav_mesh->get_parsed_geometry_type();
uint32_t collision_mask = p_nav_mesh->get_collision_mask();
@@ -460,40 +515,60 @@ void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p
if (vertices.size() > 0 && indices.size() > 0) {
- rcHeightfield *hf = NULL;
- rcCompactHeightfield *chf = NULL;
- rcContourSet *cset = NULL;
- rcPolyMesh *poly_mesh = NULL;
- rcPolyMeshDetail *detail_mesh = NULL;
+ rcHeightfield *hf = nullptr;
+ rcCompactHeightfield *chf = nullptr;
+ rcContourSet *cset = nullptr;
+ rcPolyMesh *poly_mesh = nullptr;
+ rcPolyMeshDetail *detail_mesh = nullptr;
- _build_recast_navigation_mesh(p_nav_mesh, &ep, hf, chf, cset, poly_mesh, detail_mesh, vertices, indices);
+ _build_recast_navigation_mesh(
+ p_nav_mesh,
+#ifdef TOOLS_ENABLED
+ ep,
+#endif
+ hf,
+ chf,
+ cset,
+ poly_mesh,
+ detail_mesh,
+ vertices,
+ indices);
rcFreeHeightField(hf);
- hf = 0;
+ hf = nullptr;
rcFreeCompactHeightfield(chf);
- chf = 0;
+ chf = nullptr;
rcFreeContourSet(cset);
- cset = 0;
+ cset = nullptr;
rcFreePolyMesh(poly_mesh);
- poly_mesh = 0;
+ poly_mesh = nullptr;
rcFreePolyMeshDetail(detail_mesh);
- detail_mesh = 0;
+ detail_mesh = nullptr;
}
- ep.step(TTR("Done!"), 11);
+
+#ifdef TOOLS_ENABLED
+ if (ep)
+ ep->step(TTR("Done!"), 11);
+
+ if (ep)
+ memdelete(ep);
+#endif
}
-void EditorNavigationMeshGenerator::clear(Ref<NavigationMesh> p_nav_mesh) {
+void NavigationMeshGenerator::clear(Ref<NavigationMesh> p_nav_mesh) {
if (p_nav_mesh.is_valid()) {
p_nav_mesh->clear_polygons();
- p_nav_mesh->set_vertices(PoolVector<Vector3>());
+ p_nav_mesh->set_vertices(Vector<Vector3>());
}
}
-void EditorNavigationMeshGenerator::_bind_methods() {
- ClassDB::bind_method(D_METHOD("bake", "nav_mesh", "root_node"), &EditorNavigationMeshGenerator::bake);
- ClassDB::bind_method(D_METHOD("clear", "nav_mesh"), &EditorNavigationMeshGenerator::clear);
+void NavigationMeshGenerator::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("bake", "nav_mesh", "root_node"), &NavigationMeshGenerator::bake);
+ ClassDB::bind_method(D_METHOD("clear", "nav_mesh"), &NavigationMeshGenerator::clear);
}
+
+#endif
diff --git a/modules/recast/navigation_mesh_generator.h b/modules/gdnavigation/navigation_mesh_generator.h
index 8c7ca8b62c..c5f7b2ab81 100644
--- a/modules/recast/navigation_mesh_generator.h
+++ b/modules/gdnavigation/navigation_mesh_generator.h
@@ -31,37 +31,53 @@
#ifndef NAVIGATION_MESH_GENERATOR_H
#define NAVIGATION_MESH_GENERATOR_H
-#include "editor/editor_node.h"
-#include "scene/3d/navigation_mesh.h"
+#ifndef _3D_DISABLED
+
+#include "scene/3d/navigation_region_3d.h"
#include <Recast.h>
-class EditorNavigationMeshGenerator : public Object {
- GDCLASS(EditorNavigationMeshGenerator, Object);
+#ifdef TOOLS_ENABLED
+struct EditorProgress;
+#endif
+
+class NavigationMeshGenerator : public Object {
+ GDCLASS(NavigationMeshGenerator, Object);
- static EditorNavigationMeshGenerator *singleton;
+ static NavigationMeshGenerator *singleton;
protected:
static void _bind_methods();
static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
+ static void _add_faces(const PackedVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
- static void _build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
- rcHeightfield *hf, rcCompactHeightfield *chf, rcContourSet *cset, rcPolyMesh *poly_mesh,
- rcPolyMeshDetail *detail_mesh, Vector<float> &vertices, Vector<int> &indices);
+ static void _build_recast_navigation_mesh(
+ Ref<NavigationMesh> p_nav_mesh,
+#ifdef TOOLS_ENABLED
+ EditorProgress *ep,
+#endif
+ rcHeightfield *hf,
+ rcCompactHeightfield *chf,
+ rcContourSet *cset,
+ rcPolyMesh *poly_mesh,
+ rcPolyMeshDetail *detail_mesh,
+ Vector<float> &vertices,
+ Vector<int> &indices);
public:
- static EditorNavigationMeshGenerator *get_singleton();
+ static NavigationMeshGenerator *get_singleton();
- EditorNavigationMeshGenerator();
- ~EditorNavigationMeshGenerator();
+ NavigationMeshGenerator();
+ ~NavigationMeshGenerator();
void bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node);
void clear(Ref<NavigationMesh> p_nav_mesh);
};
+#endif
+
#endif // NAVIGATION_MESH_GENERATOR_H
diff --git a/modules/recast/register_types.cpp b/modules/gdnavigation/register_types.cpp
index ea0ab00771..088b26bf17 100644
--- a/modules/recast/register_types.cpp
+++ b/modules/gdnavigation/register_types.cpp
@@ -30,30 +30,51 @@
#include "register_types.h"
-#include "navigation_mesh_editor_plugin.h"
+#include "core/engine.h"
+#include "gd_navigation_server.h"
+#include "servers/navigation_server_3d.h"
-#ifdef TOOLS_ENABLED
-EditorNavigationMeshGenerator *_nav_mesh_generator = NULL;
+#ifndef _3D_DISABLED
+#include "navigation_mesh_generator.h"
#endif
-void register_recast_types() {
#ifdef TOOLS_ENABLED
- ClassDB::APIType prev_api = ClassDB::get_current_api();
- ClassDB::set_current_api(ClassDB::API_EDITOR);
+#include "navigation_mesh_editor_plugin.h"
+#endif
- EditorPlugins::add_by_type<NavigationMeshEditorPlugin>();
- _nav_mesh_generator = memnew(EditorNavigationMeshGenerator);
+/**
+ @author AndreaCatania
+*/
- ClassDB::register_class<EditorNavigationMeshGenerator>();
+#ifndef _3D_DISABLED
+NavigationMeshGenerator *_nav_mesh_generator = nullptr;
+#endif
+
+NavigationServer3D *new_server() {
+ return memnew(GdNavigationServer);
+}
- Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", EditorNavigationMeshGenerator::get_singleton()));
+void register_gdnavigation_types() {
+ NavigationServer3DManager::set_default_server(new_server);
+
+#ifndef _3D_DISABLED
+ _nav_mesh_generator = memnew(NavigationMeshGenerator);
+ ClassDB::register_class<NavigationMeshGenerator>();
+ Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", NavigationMeshGenerator::get_singleton()));
+#endif
+
+#ifdef TOOLS_ENABLED
+ EditorPlugins::add_by_type<NavigationMeshEditorPlugin>();
+
+ ClassDB::APIType prev_api = ClassDB::get_current_api();
+ ClassDB::set_current_api(ClassDB::API_EDITOR);
ClassDB::set_current_api(prev_api);
#endif
}
-void unregister_recast_types() {
-#ifdef TOOLS_ENABLED
+void unregister_gdnavigation_types() {
+#ifndef _3D_DISABLED
if (_nav_mesh_generator) {
memdelete(_nav_mesh_generator);
}
diff --git a/modules/opus/stub/register_types.h b/modules/gdnavigation/register_types.h
index 445be4e166..cdbff1b937 100644
--- a/modules/opus/stub/register_types.h
+++ b/modules/gdnavigation/register_types.h
@@ -28,5 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_opus_types();
-void unregister_opus_types();
+/**
+ @author AndreaCatania
+*/
+
+#ifndef GDNAVIGATION_REGISTER_TYPES_H
+#define GDNAVIGATION_REGISTER_TYPES_H
+
+void register_gdnavigation_types();
+void unregister_gdnavigation_types();
+
+#endif // GDNAVIGATION_REGISTER_TYPES_H
diff --git a/modules/gdnavigation/rvo_agent.cpp b/modules/gdnavigation/rvo_agent.cpp
new file mode 100644
index 0000000000..3c39f02c26
--- /dev/null
+++ b/modules/gdnavigation/rvo_agent.cpp
@@ -0,0 +1,84 @@
+/*************************************************************************/
+/* rvo_agent.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "rvo_agent.h"
+
+#include "nav_map.h"
+
+/**
+ @author AndreaCatania
+*/
+
+RvoAgent::RvoAgent() :
+ map(nullptr) {
+ callback.id = ObjectID();
+}
+
+void RvoAgent::set_map(NavMap *p_map) {
+ map = p_map;
+}
+
+bool RvoAgent::is_map_changed() {
+ if (map) {
+ bool is_changed = map->get_map_update_id() != map_update_id;
+ map_update_id = map->get_map_update_id();
+ return is_changed;
+ } else {
+ return false;
+ }
+}
+
+void RvoAgent::set_callback(ObjectID p_id, const StringName p_method, const Variant p_udata) {
+ callback.id = p_id;
+ callback.method = p_method;
+ callback.udata = p_udata;
+}
+
+bool RvoAgent::has_callback() const {
+ return callback.id.is_valid();
+}
+
+void RvoAgent::dispatch_callback() {
+ if (callback.id.is_null()) {
+ return;
+ }
+ Object *obj = ObjectDB::get_instance(callback.id);
+ if (obj == nullptr) {
+ callback.id = ObjectID();
+ }
+
+ Callable::CallError responseCallError;
+
+ callback.new_velocity = Vector3(agent.newVelocity_.x(), agent.newVelocity_.y(), agent.newVelocity_.z());
+
+ const Variant *vp[2] = { &callback.new_velocity, &callback.udata };
+ int argc = (callback.udata.get_type() == Variant::NIL) ? 1 : 2;
+ obj->call(callback.method, vp, argc, responseCallError);
+}
diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h
new file mode 100644
index 0000000000..914cbaa7d9
--- /dev/null
+++ b/modules/gdnavigation/rvo_agent.h
@@ -0,0 +1,77 @@
+/*************************************************************************/
+/* rvo_agent.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 RVO_AGENT_H
+#define RVO_AGENT_H
+
+#include "core/object.h"
+#include "nav_rid.h"
+#include <Agent.h>
+
+/**
+ @author AndreaCatania
+*/
+
+class NavMap;
+
+class RvoAgent : public NavRid {
+ struct AvoidanceComputedCallback {
+ ObjectID id;
+ StringName method;
+ Variant udata;
+ Variant new_velocity;
+ };
+
+ NavMap *map;
+ RVO::Agent agent;
+ AvoidanceComputedCallback callback;
+ uint32_t map_update_id;
+
+public:
+ RvoAgent();
+
+ void set_map(NavMap *p_map);
+ NavMap *get_map() {
+ return map;
+ }
+
+ RVO::Agent *get_agent() {
+ return &agent;
+ }
+
+ bool is_map_changed();
+
+ void set_callback(ObjectID p_id, const StringName p_method, const Variant p_udata = Variant());
+ bool has_callback() const;
+
+ void dispatch_callback();
+};
+
+#endif // RVO_AGENT_H
diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub
index 74e653ce43..e58a1d8edc 100644
--- a/modules/gdscript/SCsub
+++ b/modules/gdscript/SCsub
@@ -1,19 +1,19 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_gdscript = env_modules.Clone()
env_gdscript.add_source_files(env.modules_sources, "*.cpp")
-if env['tools']:
+if env["tools"]:
env_gdscript.add_source_files(env.modules_sources, "./editor/*.cpp")
# Those two modules are required for the language server protocol
- if env['module_jsonrpc_enabled'] and env['module_websocket_enabled']:
+ if env["module_jsonrpc_enabled"] and env["module_websocket_enabled"]:
env_gdscript.add_source_files(env.modules_sources, "./language_server/*.cpp")
else:
# Using a define in the disabled case, to avoid having an extra define
# in regular builds where all modules are enabled.
- env_gdscript.Append(CPPDEFINES=['GDSCRIPT_NO_LSP'])
+ env_gdscript.Append(CPPDEFINES=["GDSCRIPT_NO_LSP"])
diff --git a/modules/gdscript/config.py b/modules/gdscript/config.py
index a525eedaaa..6fc227e7f5 100644
--- a/modules/gdscript/config.py
+++ b/modules/gdscript/config.py
@@ -1,16 +1,18 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"@GDScript",
"GDScript",
"GDScriptFunctionState",
- "GDScriptNativeClass",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index b947d95fac..9324691df5 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -90,14 +90,18 @@
</return>
<argument index="0" name="condition" type="bool">
</argument>
+ <argument index="1" name="message" type="String" default="&quot;&quot;">
+ </argument>
<description>
- Asserts that the [code]condition[/code] is [code]true[/code] . If the [code]condition[/code] is [code]false[/code], an error is generated and the program is halted until you resume it. Only executes in debug builds, or when running the game from the editor. Use it for debugging purposes, to make sure a statement is [code]true[/code] during development.
+ Asserts that the [code]condition[/code] is [code]true[/code]. If the [code]condition[/code] is [code]false[/code], an error is generated and the program is halted until you resume it. Only executes in debug builds, or when running the game from the editor. Use it for debugging purposes, to make sure a statement is [code]true[/code] during development.
+ The optional [code]message[/code] argument, if given, is shown in addition to the generic "Assertion failed" message. You can use this to provide additional details about why the assertion failed.
[codeblock]
# Imagine we always want speed to be between 0 and 20
speed = -10
assert(speed &lt; 20) # True, the program will continue
assert(speed &gt;= 0) # False, the program will stop
assert(speed &gt;= 0 &amp;&amp; speed &lt; 20) # You can also combine the two conditional statements in one check
+ assert(speed &lt; 20, "speed = %f, but the speed limit is 20" % speed) # Show a message with clarifying details
[/codeblock]
</description>
</method>
@@ -131,7 +135,7 @@
<method name="bytes2var">
<return type="Variant">
</return>
- <argument index="0" name="bytes" type="PoolByteArray">
+ <argument index="0" name="bytes" type="PackedByteArray">
</argument>
<argument index="1" name="allow_objects" type="bool" default="false">
</argument>
@@ -256,15 +260,6 @@
Converts from decibels to linear energy (audio).
</description>
</method>
- <method name="decimals">
- <return type="int">
- </return>
- <argument index="0" name="step" type="float">
- </argument>
- <description>
- Deprecated alias for [method step_decimals].
- </description>
- </method>
<method name="dectime">
<return type="float">
</return>
@@ -490,9 +485,13 @@
<argument index="2" name="weight" type="float">
</argument>
<description>
- Returns a normalized value considering the given range.
+ Returns a normalized value considering the given range. This is the opposite of [method lerp].
[codeblock]
- inverse_lerp(3, 5, 4) # Returns 0.5
+ var middle = lerp(20, 30, 0.75)
+ # `middle` is now 27.5.
+ # Now, we pretend to have forgotten the original ratio and want to get it back.
+ var ratio = inverse_lerp(20, 30, 27.5)
+ # `ratio` is now 0.75.
[/codeblock]
</description>
</method>
@@ -567,7 +566,7 @@
<argument index="2" name="weight" type="float">
</argument>
<description>
- Linearly interpolates between two values by a normalized value.
+ Linearly interpolates between two values by a normalized value. This is the opposite of [method inverse_lerp].
If the [code]from[/code] and [code]to[/code] arguments are of type [int] or [float], the return value is a [float].
If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]linear_interpolate[/code] method).
[codeblock]
@@ -587,7 +586,7 @@
</argument>
<description>
Linearly interpolates between two angles (in radians) by a normalized value.
- Similar to [method lerp] but interpolate correctly when the angles wrap around [constant @GDScript.TAU].
+ Similar to [method lerp], but interpolates correctly when the angles wrap around [constant @GDScript.TAU].
[codeblock]
extends Sprite
var elapsed = 0.0
@@ -605,7 +604,13 @@
<argument index="0" name="nrg" type="float">
</argument>
<description>
- Converts from linear energy to decibels (audio).
+ Converts from linear energy to decibels (audio). This can be used to implement volume sliders that behave as expected (since volume isn't linear). Example:
+ [codeblock]
+ # "Slider" refers to a node that inherits Range such as HSlider or VSlider.
+ # Its range must be configured to go from 0 to 1.
+ # Change the bus name if you'd like to change the volume of a specific bus only.
+ AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db($Slider.value))
+ [/codeblock]
</description>
</method>
<method name="load">
@@ -1215,7 +1220,7 @@
<description>
Returns whether the given class exists in [ClassDB].
[codeblock]
- type_exists("Sprite") # Returns true
+ type_exists("Sprite2D") # Returns true
type_exists("Variant") # Returns false
[/codeblock]
</description>
@@ -1254,7 +1259,7 @@
</description>
</method>
<method name="var2bytes">
- <return type="PoolByteArray">
+ <return type="PackedByteArray">
</return>
<argument index="0" name="var" type="Variant">
</argument>
diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml
index 5d0e93e117..62ccb93901 100644
--- a/modules/gdscript/doc_classes/GDScript.xml
+++ b/modules/gdscript/doc_classes/GDScript.xml
@@ -12,7 +12,7 @@
</tutorials>
<methods>
<method name="get_as_byte_code" qualifiers="const">
- <return type="PoolByteArray">
+ <return type="PackedByteArray">
</return>
<description>
Returns byte code for the script source code.
diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml
deleted file mode 100644
index 0a8982de8e..0000000000
--- a/modules/gdscript/doc_classes/GDScriptNativeClass.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GDScriptNativeClass" inherits="Reference" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- <method name="new">
- <return type="Variant">
- </return>
- <description>
- </description>
- </method>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 687e1785be..0aca4dbc5e 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -358,11 +358,11 @@ List<String> GDScriptSyntaxHighlighter::get_supported_languages() {
}
void GDScriptSyntaxHighlighter::_update_cache() {
- font_color = text_editor->get_color("font_color");
- symbol_color = text_editor->get_color("symbol_color");
- function_color = text_editor->get_color("function_color");
- number_color = text_editor->get_color("number_color");
- member_color = text_editor->get_color("member_variable_color");
+ font_color = text_editor->get_theme_color("font_color");
+ symbol_color = text_editor->get_theme_color("symbol_color");
+ function_color = text_editor->get_theme_color("function_color");
+ number_color = text_editor->get_theme_color("number_color");
+ member_color = text_editor->get_theme_color("member_variable_color");
const String text_editor_color_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme");
const bool default_theme = text_editor_color_theme == "Default";
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index a255b92257..98366f7957 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -30,6 +30,8 @@
#include "gdscript.h"
+#include <stdint.h>
+
#include "core/core_string_names.h"
#include "core/engine.h"
#include "core/global_constants.h"
@@ -82,7 +84,7 @@ Object *GDScriptNativeClass::instance() {
return ClassDB::instance(name);
}
-GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) {
+GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
/* STEP 1, CREATE */
@@ -91,6 +93,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
instance->members.resize(member_indices.size());
instance->script = Ref<GDScript>(this);
instance->owner = p_owner;
+ instance->owner_id = p_owner->get_instance_id();
#ifdef DEBUG_ENABLED
//needed for hot reloading
for (Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) {
@@ -101,48 +104,41 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
/* STEP 2, INITIALIZE AND CONSTRUCT */
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
-
- instances.insert(instance->owner);
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
+ instances.insert(instance->owner);
+ }
initializer->call(instance, p_args, p_argcount, r_error);
- if (r_error.error != Variant::CallError::CALL_OK) {
+ if (r_error.error != Callable::CallError::CALL_OK) {
instance->script = Ref<GDScript>();
- instance->owner->set_script_instance(NULL);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
- instances.erase(p_owner);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
+ instance->owner->set_script_instance(nullptr);
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
+ instances.erase(p_owner);
+ }
- ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
+ ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, nullptr); //error constructing
}
//@TODO make thread safe
return instance;
}
-Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
/* STEP 1, CREATE */
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
REF ref;
- Object *owner = NULL;
+ Object *owner = nullptr;
GDScript *_baseptr = this;
while (_baseptr->_base) {
@@ -162,7 +158,7 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallErro
ref = REF(r);
}
- GDScriptInstance *instance = _create_instance(p_args, p_argcount, owner, r != NULL, r_error);
+ GDScriptInstance *instance = _create_instance(p_args, p_argcount, owner, r != nullptr, r_error);
if (!instance) {
if (ref.is_null()) {
memdelete(owner); //no owner, sorry
@@ -319,15 +315,15 @@ ScriptInstance *GDScript::instance_create(Object *p_this) {
if (top->native.is_valid()) {
if (!ClassDB::is_parent_class(p_this->get_class_name(), top->native->get_name())) {
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), 1, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
}
- ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type '" + p_this->get_class() + "'" + ".");
+ ERR_FAIL_V_MSG(nullptr, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type '" + p_this->get_class() + "'" + ".");
}
}
- Variant::CallError unchecked_error;
- return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error);
+ Callable::CallError unchecked_error;
+ return _create_instance(nullptr, 0, p_this, Object::cast_to<Reference>(p_this) != nullptr, unchecked_error);
}
PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) {
@@ -337,22 +333,15 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this)
_update_exports();
return si;
#else
- return NULL;
+ return nullptr;
#endif
}
bool GDScript::instance_has(const Object *p_this) const {
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
- bool hasit = instances.has((Object *)p_this);
+ MutexLock lock(GDScriptLanguage::singleton->lock);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
-
- return hasit;
+ return instances.has((Object *)p_this);
}
bool GDScript::has_source_code() const {
@@ -533,7 +522,7 @@ void GDScript::update_exports() {
void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
p_sc->path = p_path;
- for (Map<StringName, Ref<GDScript> >::Element *E = p_sc->subclasses.front(); E; E = E->next()) {
+ for (Map<StringName, Ref<GDScript>>::Element *E = p_sc->subclasses.front(); E; E = E->next()) {
_set_subclass_path(E->get(), p_path);
}
@@ -541,14 +530,12 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
Error GDScript::reload(bool p_keep_state) {
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
- bool has_instances = instances.size();
+ bool has_instances;
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
+ has_instances = instances.size();
+ }
ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE);
@@ -569,7 +556,7 @@ Error GDScript::reload(bool p_keep_state) {
GDScriptParser parser;
Error err = parser.parse(source, basedir, false, path);
if (err) {
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), parser.get_error_line(), "Parser Error: " + parser.get_error());
}
_err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_error_line(), ("Parse Error: " + parser.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
@@ -584,7 +571,7 @@ Error GDScript::reload(bool p_keep_state) {
if (err) {
if (can_run) {
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error());
}
_err_print_error("GDScript::reload", path.empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), ERR_HANDLER_SCRIPT);
@@ -596,20 +583,22 @@ Error GDScript::reload(bool p_keep_state) {
#ifdef DEBUG_ENABLED
for (const List<GDScriptWarning>::Element *E = parser.get_warnings().front(); E; E = E->next()) {
const GDScriptWarning &warning = E->get();
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
Vector<ScriptLanguage::StackInfo> si;
- ScriptDebugger::get_singleton()->send_error("", get_path(), warning.line, warning.get_name(), warning.get_message(), ERR_HANDLER_WARNING, si);
+ EngineDebugger::get_script_debugger()->send_error("", get_path(), warning.line, warning.get_name(), warning.get_message(), ERR_HANDLER_WARNING, si);
}
}
#endif
valid = true;
- for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) {
+ for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) {
_set_subclass_path(E->get(), path);
}
+ _init_rpc_methods_properties();
+
return OK;
}
@@ -635,7 +624,61 @@ void GDScript::get_members(Set<StringName> *p_members) {
}
}
-Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Vector<ScriptNetData> GDScript::get_rpc_methods() const {
+ return rpc_functions;
+}
+
+uint16_t GDScript::get_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < rpc_functions.size(); i++) {
+ if (rpc_functions[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName GDScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName());
+ return rpc_functions[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rpc_mode(const StringName &p_method) const {
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> GDScript::get_rset_properties() const {
+ return rpc_variables;
+}
+
+uint16_t GDScript::get_rset_property_id(const StringName &p_variable) const {
+ for (int i = 0; i < rpc_variables.size(); i++) {
+ if (rpc_variables[i].name == p_variable) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName());
+ return rpc_variables[p_rset_member_id].name;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_variables[p_rset_member_id].mode;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) const {
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
+}
+
+Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *top = this;
while (top) {
@@ -645,7 +688,7 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p
ERR_FAIL_COND_V_MSG(!E->get()->is_static(), Variant(), "Can't call non-static function '" + String(p_method) + "' in script.");
- return E->get()->call(NULL, p_args, p_argcount, r_error);
+ return E->get()->call(nullptr, p_args, p_argcount, r_error);
}
top = top->_base;
}
@@ -672,7 +715,7 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
}
{
- const Map<StringName, Ref<GDScript> >::Element *E = subclasses.find(p_name);
+ const Map<StringName, Ref<GDScript>>::Element *E = subclasses.find(p_name);
if (E) {
r_ret = E->get();
@@ -788,17 +831,19 @@ Error GDScript::load_byte_code(const String &p_path) {
valid = true;
- for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) {
+ for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) {
_set_subclass_path(E->get(), path);
}
+ _init_rpc_methods_properties();
+
return OK;
}
Error GDScript::load_source_code(const String &p_path) {
- PoolVector<uint8_t> sourcef;
+ Vector<uint8_t> sourcef;
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
@@ -808,15 +853,15 @@ Error GDScript::load_source_code(const String &p_path) {
int len = f->get_len();
sourcef.resize(len + 1);
- PoolVector<uint8_t>::Write w = sourcef.write();
- int r = f->get_buffer(w.ptr(), len);
+ uint8_t *w = sourcef.ptrw();
+ int r = f->get_buffer(w, len);
f->close();
memdelete(f);
ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
w[len] = 0;
String s;
- if (s.parse_utf8((const char *)w.ptr())) {
+ if (s.parse_utf8((const char *)w)) {
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
@@ -850,6 +895,24 @@ Ref<GDScript> GDScript::get_base() const {
return base;
}
+bool GDScript::inherits_script(const Ref<Script> &p_script) const {
+ Ref<GDScript> gd = p_script;
+ if (gd.is_null()) {
+ return false;
+ }
+
+ const GDScript *s = this;
+
+ while (s) {
+ if (s == p_script.ptr()) {
+ return true;
+ }
+ s = s->_base;
+ }
+
+ return false;
+}
+
bool GDScript::has_script_signal(const StringName &p_signal) const {
if (_signals.has(p_signal))
return true;
@@ -865,7 +928,7 @@ bool GDScript::has_script_signal(const StringName &p_signal) const {
}
void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
- for (const Map<StringName, Vector<StringName> >::Element *E = _signals.front(); E; E = E->next()) {
+ for (const Map<StringName, Vector<StringName>>::Element *E = _signals.front(); E; E = E->next()) {
MethodInfo mi;
mi.name = E->key();
@@ -891,12 +954,11 @@ void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
GDScript::GDScript() :
script_list(this) {
- _static_ref = this;
valid = false;
subclass_count = 0;
- initializer = NULL;
- _base = NULL;
- _owner = NULL;
+ initializer = nullptr;
+ _base = nullptr;
+ _owner = nullptr;
tool = false;
#ifdef TOOLS_ENABLED
source_changed_cache = false;
@@ -904,13 +966,10 @@ GDScript::GDScript() :
#endif
#ifdef DEBUG_ENABLED
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->script_list.add(&script_list);
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
+ GDScriptLanguage::get_singleton()->script_list.add(&script_list);
}
#endif
}
@@ -922,8 +981,8 @@ void GDScript::_save_orphaned_subclasses() {
};
Vector<ClassRefWithName> weak_subclasses;
// collect subclasses ObjectID and name
- for (Map<StringName, Ref<GDScript> >::Element *E = subclasses.front(); E; E = E->next()) {
- E->get()->_owner = NULL; //bye, you are no longer owned cause I died
+ for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) {
+ E->get()->_owner = nullptr; //bye, you are no longer owned cause I died
ClassRefWithName subclass;
subclass.id = E->get()->get_instance_id();
subclass.fully_qualified_name = E->get()->fully_qualified_name;
@@ -946,6 +1005,55 @@ void GDScript::_save_orphaned_subclasses() {
}
}
+void GDScript::_init_rpc_methods_properties() {
+ // Copy the base rpc methods so we don't mask their IDs.
+ rpc_functions.clear();
+ rpc_variables.clear();
+ if (base.is_valid()) {
+ rpc_functions = base->rpc_functions;
+ rpc_variables = base->rpc_variables;
+ }
+
+ GDScript *cscript = this;
+ Map<StringName, Ref<GDScript>>::Element *sub_E = subclasses.front();
+ while (cscript) {
+ // RPC Methods
+ for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) {
+ if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = E->get()->get_rpc_mode();
+ if (-1 == rpc_functions.find(nd)) {
+ rpc_functions.push_back(nd);
+ }
+ }
+ }
+ // RSet
+ for (Map<StringName, MemberInfo>::Element *E = cscript->member_indices.front(); E; E = E->next()) {
+ if (E->get().rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = E->get().rpc_mode;
+ if (-1 == rpc_variables.find(nd)) {
+ rpc_variables.push_back(nd);
+ }
+ }
+ }
+
+ if (cscript != this)
+ sub_E = sub_E->next();
+
+ if (sub_E)
+ cscript = sub_E->get().ptr();
+ else
+ cscript = nullptr;
+ }
+
+ // Sort so we are 100% that they are always the same.
+ rpc_functions.sort_custom<SortNetData>();
+ rpc_variables.sort_custom<SortNetData>();
+}
+
GDScript::~GDScript() {
for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) {
memdelete(E->get());
@@ -954,13 +1062,10 @@ GDScript::~GDScript() {
_save_orphaned_subclasses();
#ifdef DEBUG_ENABLED
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
+ GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
}
#endif
}
@@ -978,18 +1083,18 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
const GDScript::MemberInfo *member = &E->get();
if (member->setter) {
const Variant *val = &p_value;
- Variant::CallError err;
+ Callable::CallError err;
call(member->setter, &val, 1, err);
- if (err.error == Variant::CallError::CALL_OK) {
+ if (err.error == Callable::CallError::CALL_OK) {
return true; //function exists, call was successful
}
} else {
if (!member->data_type.is_type(p_value)) {
// Try conversion
- Variant::CallError ce;
+ Callable::CallError ce;
const Variant *value = &p_value;
Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce);
- if (ce.error == Variant::CallError::CALL_OK) {
+ if (ce.error == Callable::CallError::CALL_OK) {
members.write[member->index] = converted;
return true;
} else {
@@ -1012,9 +1117,9 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
Variant name = p_name;
const Variant *args[2] = { &name, &p_value };
- Variant::CallError err;
+ Callable::CallError err;
Variant ret = E->get()->call(this, (const Variant **)args, 2, err);
- if (err.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool())
+ if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool())
return true;
}
sptr = sptr->_base;
@@ -1032,9 +1137,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
if (E) {
if (E->get().getter) {
- Variant::CallError err;
- r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, NULL, 0, err);
- if (err.error == Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, nullptr, 0, err);
+ if (err.error == Callable::CallError::CALL_OK) {
return true;
}
}
@@ -1063,9 +1168,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
Variant name = p_name;
const Variant *args[1] = { &name };
- Variant::CallError err;
+ Callable::CallError err;
Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), (const Variant **)args, 1, err);
- if (err.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
+ if (err.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
r_ret = ret;
return true;
}
@@ -1106,9 +1211,9 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list);
if (E) {
- Variant::CallError err;
- Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), NULL, 0, err);
- if (err.error == Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), nullptr, 0, err);
+ if (err.error == Callable::CallError::CALL_OK) {
ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries.");
@@ -1193,7 +1298,7 @@ bool GDScriptInstance::has_method(const StringName &p_method) const {
return false;
}
-Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *sptr = script.ptr();
while (sptr) {
@@ -1203,14 +1308,14 @@ Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_arg
}
sptr = sptr->_base;
}
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
GDScript *sptr = script.ptr();
- Variant::CallError ce;
+ Callable::CallError ce;
while (sptr) {
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
@@ -1226,7 +1331,7 @@ void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_met
if (sptr->_base)
_ml_call_reversed(sptr->_base, p_method, p_args, p_argcount);
- Variant::CallError ce;
+ Callable::CallError ce;
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
if (E) {
@@ -1251,9 +1356,9 @@ void GDScriptInstance::notification(int p_notification) {
while (sptr) {
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._notification);
if (E) {
- Variant::CallError err;
+ Callable::CallError err;
E->get()->call(this, args, 1, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ if (err.error != Callable::CallError::CALL_OK) {
//print error about notification call
}
}
@@ -1263,9 +1368,9 @@ void GDScriptInstance::notification(int p_notification) {
String GDScriptInstance::to_string(bool *r_valid) {
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
- Variant::CallError ce;
- Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
- if (ce.error == Variant::CallError::CALL_OK) {
+ Callable::CallError ce;
+ Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
+ if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;
@@ -1291,40 +1396,44 @@ ScriptLanguage *GDScriptInstance::get_language() {
return GDScriptLanguage::get_singleton();
}
-MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
+Vector<ScriptNetData> GDScriptInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- const GDScript *cscript = script.ptr();
+uint16_t GDScriptInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
+}
- while (cscript) {
- const Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.find(p_method);
- if (E) {
+StringName GDScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_method(p_rpc_method_id);
+}
- if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
- return E->get()->get_rpc_mode();
- }
- }
- cscript = cscript->_base;
- }
+MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_mode_by_id(p_rpc_method_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
}
-MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
+Vector<ScriptNetData> GDScriptInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- const GDScript *cscript = script.ptr();
+uint16_t GDScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
+}
- while (cscript) {
- const Map<StringName, GDScript::MemberInfo>::Element *E = cscript->member_indices.find(p_variable);
- if (E) {
+StringName GDScriptInstance::get_rset_property(const uint16_t p_rset_member_id) const {
+ return script->get_rset_property(p_rset_member_id);
+}
- if (E->get().rpc_mode) {
- return E->get().rpc_mode;
- }
- }
- cscript = cscript->_base;
- }
+MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ return script->get_rset_mode_by_id(p_rset_member_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return script->get_rset_mode(p_variable);
}
void GDScriptInstance::reload_members() {
@@ -1359,26 +1468,21 @@ void GDScriptInstance::reload_members() {
}
GDScriptInstance::GDScriptInstance() {
- owner = NULL;
+ owner = nullptr;
base_ref = false;
}
GDScriptInstance::~GDScriptInstance() {
if (script.is_valid() && owner) {
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
+ MutexLock lock(GDScriptLanguage::singleton->lock);
script->instances.erase(owner);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
}
}
/************* SCRIPT LANGUAGE **************/
-GDScriptLanguage *GDScriptLanguage::singleton = NULL;
+GDScriptLanguage *GDScriptLanguage::singleton = nullptr;
String GDScriptLanguage::get_name() const {
@@ -1473,9 +1577,7 @@ void GDScriptLanguage::finish() {
void GDScriptLanguage::profiling_start() {
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1492,25 +1594,15 @@ void GDScriptLanguage::profiling_start() {
}
profiling = true;
- if (lock) {
- lock->unlock();
- }
-
#endif
}
void GDScriptLanguage::profiling_stop() {
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
profiling = false;
- if (lock) {
- lock->unlock();
- }
-
#endif
}
@@ -1518,9 +1610,8 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
int current = 0;
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1533,11 +1624,6 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
elem = elem->next();
current++;
}
-
- if (lock) {
- lock->unlock();
- }
-
#endif
return current;
@@ -1548,9 +1634,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
int current = 0;
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1565,11 +1649,6 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
}
elem = elem->next();
}
-
- if (lock) {
- lock->unlock();
- }
-
#endif
return current;
@@ -1600,30 +1679,25 @@ void GDScriptLanguage::reload_all_scripts() {
#ifdef DEBUG_ENABLED
print_verbose("GDScript: Reloading all scripts");
- if (lock) {
- lock->lock();
- }
-
- List<Ref<GDScript> > scripts;
+ List<Ref<GDScript>> scripts;
+ {
+ MutexLock lock(this->lock);
- SelfList<GDScript> *elem = script_list.first();
- while (elem) {
- if (elem->self()->get_path().is_resource_file()) {
- print_verbose("GDScript: Found: " + elem->self()->get_path());
- scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ SelfList<GDScript> *elem = script_list.first();
+ while (elem) {
+ if (elem->self()->get_path().is_resource_file()) {
+ print_verbose("GDScript: Found: " + elem->self()->get_path());
+ scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ }
+ elem = elem->next();
}
- elem = elem->next();
- }
-
- if (lock) {
- lock->unlock();
}
//as scripts are going to be reloaded, must proceed without locking here
scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order
- for (List<Ref<GDScript> >::Element *E = scripts.front(); E; E = E->next()) {
+ for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) {
print_verbose("GDScript: Reloading: " + E->get()->get_path());
E->get()->load_source_code(E->get()->get_path());
@@ -1636,56 +1710,51 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
-
- List<Ref<GDScript> > scripts;
+ List<Ref<GDScript>> scripts;
+ {
+ MutexLock lock(this->lock);
- SelfList<GDScript> *elem = script_list.first();
- while (elem) {
- if (elem->self()->get_path().is_resource_file()) {
+ SelfList<GDScript> *elem = script_list.first();
+ while (elem) {
+ if (elem->self()->get_path().is_resource_file()) {
- scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ }
+ elem = elem->next();
}
- elem = elem->next();
- }
-
- if (lock) {
- lock->unlock();
}
//when someone asks you why dynamically typed languages are easier to write....
- Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant> > > > to_reload;
+ Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>> to_reload;
//as scripts are going to be reloaded, must proceed without locking here
scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order
- for (List<Ref<GDScript> >::Element *E = scripts.front(); E; E = E->next()) {
+ for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) {
bool reload = E->get() == p_script || to_reload.has(E->get()->get_base());
if (!reload)
continue;
- to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant> > >());
+ to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant>>>());
if (!p_soft_reload) {
//save state and remove script from instances
- Map<ObjectID, List<Pair<StringName, Variant> > > &map = to_reload[E->get()];
+ Map<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[E->get()];
while (E->get()->instances.front()) {
Object *obj = E->get()->instances.front()->get();
//save instance info
- List<Pair<StringName, Variant> > state;
+ List<Pair<StringName, Variant>> state;
if (obj->get_script_instance()) {
obj->get_script_instance()->get_property_state(state);
map[obj->get_instance_id()] = state;
- obj->set_script(RefPtr());
+ obj->set_script(Variant());
}
}
@@ -1698,10 +1767,10 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
//save instance info
if (obj->get_script_instance()) {
- map.insert(obj->get_instance_id(), List<Pair<StringName, Variant> >());
- List<Pair<StringName, Variant> > &state = map[obj->get_instance_id()];
+ map.insert(obj->get_instance_id(), List<Pair<StringName, Variant>>());
+ List<Pair<StringName, Variant>> &state = map[obj->get_instance_id()];
obj->get_script_instance()->get_property_state(state);
- obj->set_script(RefPtr());
+ obj->set_script(Variant());
} else {
// no instance found. Let's remove it so we don't loop forever
E->get()->placeholders.erase(E->get()->placeholders.front()->get());
@@ -1710,21 +1779,21 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
#endif
- for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) {
+ for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get()->pending_reload_state.front(); F; F = F->next()) {
map[F->key()] = F->get(); //pending to reload, use this one instead
}
}
}
- for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant> > > >::Element *E = to_reload.front(); E; E = E->next()) {
+ for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>>::Element *E = to_reload.front(); E; E = E->next()) {
Ref<GDScript> scr = E->key();
scr->reload(p_soft_reload);
//restore state if saved
- for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get().front(); F; F = F->next()) {
+ for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get().front(); F; F = F->next()) {
- List<Pair<StringName, Variant> > &saved_state = F->get();
+ List<Pair<StringName, Variant>> &saved_state = F->get();
Object *obj = ObjectDB::get_instance(F->key());
if (!obj)
@@ -1732,9 +1801,9 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
if (!p_soft_reload) {
//clear it just in case (may be a pending reload state)
- obj->set_script(RefPtr());
+ obj->set_script(Variant());
}
- obj->set_script(scr.get_ref_ptr());
+ obj->set_script(scr);
ScriptInstance *script_instance = obj->get_script_instance();
@@ -1748,11 +1817,11 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
if (script_instance->is_placeholder() && scr->is_placeholder_fallback_enabled()) {
PlaceHolderScriptInstance *placeholder = static_cast<PlaceHolderScriptInstance *>(script_instance);
- for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) {
+ for (List<Pair<StringName, Variant>>::Element *G = saved_state.front(); G; G = G->next()) {
placeholder->property_set_fallback(G->get().first, G->get().second);
}
} else {
- for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) {
+ for (List<Pair<StringName, Variant>>::Element *G = saved_state.front(); G; G = G->next()) {
script_instance->set(G->get().first, G->get().second);
}
}
@@ -1772,9 +1841,7 @@ void GDScriptLanguage::frame() {
#ifdef DEBUG_ENABLED
if (profiling) {
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1786,10 +1853,6 @@ void GDScriptLanguage::frame() {
elem->self()->profile.frame_total_time = 0;
elem = elem->next();
}
-
- if (lock) {
- lock->unlock();
- }
}
#endif
@@ -1850,14 +1913,12 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"match",
"while",
"remote",
- "sync",
"master",
"puppet",
- "slave",
"remotesync",
"mastersync",
"puppetsync",
- 0
+ nullptr
};
const char **w = _reserved_words;
@@ -1880,7 +1941,7 @@ bool GDScriptLanguage::handles_global_class_type(const String &p_type) const {
String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
- PoolVector<uint8_t> sourcef;
+ Vector<uint8_t> sourcef;
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
@@ -1890,7 +1951,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
String source = f->get_as_utf8_string();
GDScriptParser parser;
- parser.parse(source, p_path.get_base_dir(), true, p_path, false, NULL, true);
+ parser.parse(source, p_path.get_base_dir(), true, p_path, false, nullptr, true);
if (parser.get_parse_tree() && parser.get_parse_tree()->type == GDScriptParser::Node::TYPE_CLASS) {
@@ -1911,7 +1972,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
if (subclass->extends_file) {
if (subclass->extends_class.size() == 0) {
get_global_class_name(subclass->extends_file, r_base_type);
- subclass = NULL;
+ subclass = nullptr;
break;
} else {
Vector<StringName> extend_classes = subclass->extends_class;
@@ -1930,7 +1991,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
subpath = path.get_base_dir().plus_file(subpath).simplify_path();
}
- if (OK != subparser.parse(subsource, subpath.get_base_dir(), true, subpath, false, NULL, true)) {
+ if (OK != subparser.parse(subsource, subpath.get_base_dir(), true, subpath, false, nullptr, true)) {
break;
}
path = subpath;
@@ -1951,20 +2012,20 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
}
}
if (!found) {
- subclass = NULL;
+ subclass = nullptr;
break;
}
}
}
} else if (subclass->extends_class.size() == 1) {
*r_base_type = subclass->extends_class[0];
- subclass = NULL;
+ subclass = nullptr;
} else {
break;
}
} else {
*r_base_type = "Reference";
- subclass = NULL;
+ subclass = nullptr;
}
}
}
@@ -2125,7 +2186,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
"UNSAFE_CALL_ARGUMENT",
"DEPRECATED_KEYWORD",
"STANDALONE_TERNARY",
- NULL
+ nullptr
};
return names[(int)p_code];
@@ -2157,11 +2218,6 @@ GDScriptLanguage::GDScriptLanguage() {
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
-#ifdef NO_THREADS
- lock = NULL;
-#else
- lock = Mutex::create();
-#endif
profiling = false;
script_frame_time = 0;
@@ -2169,7 +2225,7 @@ GDScriptLanguage::GDScriptLanguage() {
int dmcs = GLOBAL_DEF("debug/settings/gdscript/max_call_stack", 1024);
ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/gdscript/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/gdscript/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
//debugging enabled!
_debug_max_call_stack = dmcs;
@@ -2177,7 +2233,7 @@ GDScriptLanguage::GDScriptLanguage() {
} else {
_debug_max_call_stack = 0;
- _call_stack = NULL;
+ _call_stack = nullptr;
}
#ifdef DEBUG_ENABLED
@@ -2195,14 +2251,10 @@ GDScriptLanguage::GDScriptLanguage() {
GDScriptLanguage::~GDScriptLanguage() {
- if (lock) {
- memdelete(lock);
- lock = NULL;
- }
if (_call_stack) {
memdelete_arr(_call_stack);
}
- singleton = NULL;
+ singleton = nullptr;
}
void GDScriptLanguage::add_orphan_subclass(const String &p_qualified_name, const ObjectID &p_subclass) {
@@ -2223,7 +2275,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
@@ -2285,7 +2337,7 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S
}
GDScriptParser parser;
- if (OK != parser.parse(source, p_path.get_base_dir(), true, p_path, false, NULL, true)) {
+ if (OK != parser.parse(source, p_path.get_base_dir(), true, p_path, false, nullptr, true)) {
return;
}
@@ -2329,5 +2381,5 @@ void ResourceFormatSaverGDScript::get_recognized_extensions(const RES &p_resourc
}
bool ResourceFormatSaverGDScript::recognize(const RES &p_resource) const {
- return Object::cast_to<GDScript>(*p_resource) != NULL;
+ return Object::cast_to<GDScript>(*p_resource) != nullptr;
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 4ae52238ce..5fdc25669f 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -31,6 +31,8 @@
#ifndef GDSCRIPT_H
#define GDSCRIPT_H
+#include "core/debugger/engine_debugger.h"
+#include "core/debugger/script_debugger.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/script_language.h"
@@ -73,7 +75,6 @@ class GDScript : public Script {
friend class GDScriptFunctions;
friend class GDScriptLanguage;
- Variant _static_ref; //used for static call
Ref<GDScriptNativeClass> native;
Ref<GDScript> base;
GDScript *_base; //fast pointer access
@@ -83,8 +84,10 @@ class GDScript : public Script {
Map<StringName, Variant> constants;
Map<StringName, GDScriptFunction *> member_functions;
Map<StringName, MemberInfo> member_indices; //members are just indices to the instanced script.
- Map<StringName, Ref<GDScript> > subclasses;
- Map<StringName, Vector<StringName> > _signals;
+ Map<StringName, Ref<GDScript>> subclasses;
+ Map<StringName, Vector<StringName>> _signals;
+ Vector<ScriptNetData> rpc_functions;
+ Vector<ScriptNetData> rpc_variables;
#ifdef TOOLS_ENABLED
@@ -114,7 +117,7 @@ class GDScript : public Script {
String fully_qualified_name;
SelfList<GDScript> script_list;
- GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error);
+ GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error);
void _set_subclass_path(Ref<GDScript> &p_sc, const String &p_path);
@@ -126,20 +129,21 @@ class GDScript : public Script {
#ifdef DEBUG_ENABLED
- Map<ObjectID, List<Pair<StringName, Variant> > > pending_reload_state;
+ Map<ObjectID, List<Pair<StringName, Variant>>> pending_reload_state;
#endif
bool _update_exports();
void _save_orphaned_subclasses();
+ void _init_rpc_methods_properties();
protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
bool _set(const StringName &p_name, const Variant &p_value);
void _get_property_list(List<PropertyInfo> *p_properties) const;
- Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
//void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount);
static void _bind_methods();
@@ -147,7 +151,9 @@ protected:
public:
virtual bool is_valid() const { return valid; }
- const Map<StringName, Ref<GDScript> > &get_subclasses() const { return subclasses; }
+ bool inherits_script(const Ref<Script> &p_script) const;
+
+ const Map<StringName, Ref<GDScript>> &get_subclasses() const { return subclasses; }
const Map<StringName, Variant> &get_constants() const { return constants; }
const Set<StringName> &get_members() const { return members; }
const GDScriptDataType &get_member_type(const StringName &p_member) const {
@@ -168,7 +174,7 @@ public:
const Map<StringName, GDScriptFunction *> &debug_get_member_functions() const; //this is debug only
StringName debug_get_member_by_index(int p_idx) const;
- Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual bool can_instance() const;
virtual Ref<Script> get_base_script() const;
@@ -213,6 +219,18 @@ public:
virtual void get_constants(Map<StringName, Variant> *p_constants);
virtual void get_members(Set<StringName> *p_members);
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
#ifdef TOOLS_ENABLED
virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; }
#endif
@@ -227,6 +245,7 @@ class GDScriptInstance : public ScriptInstance {
friend class GDScriptFunctions;
friend class GDScriptCompiler;
+ ObjectID owner_id;
Object *owner;
Ref<GDScript> script;
#ifdef DEBUG_ENABLED
@@ -243,11 +262,11 @@ public:
virtual bool set(const StringName &p_name, const Variant &p_value);
virtual bool get(const StringName &p_name, Variant &r_ret) const;
virtual void get_property_list(List<PropertyInfo> *p_properties) const;
- virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const;
virtual void get_method_list(List<MethodInfo> *p_list) const;
virtual bool has_method(const StringName &p_method) const;
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
@@ -264,7 +283,16 @@ public:
void reload_members();
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
GDScriptInstance();
@@ -346,7 +374,7 @@ class GDScriptLanguage : public ScriptLanguage {
friend class GDScriptInstance;
- Mutex *lock;
+ Mutex lock;
friend class GDScript;
@@ -370,13 +398,13 @@ public:
if (Thread::get_main_id() != Thread::get_caller_id())
return; //no support for other threads than main for now
- if (ScriptDebugger::get_singleton()->get_lines_left() > 0 && ScriptDebugger::get_singleton()->get_depth() >= 0)
- ScriptDebugger::get_singleton()->set_depth(ScriptDebugger::get_singleton()->get_depth() + 1);
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() + 1);
if (_debug_call_stack_pos >= _debug_max_call_stack) {
//stack overflow
_debug_error = "Stack Overflow (Stack Size: " + itos(_debug_max_call_stack) + ")";
- ScriptDebugger::get_singleton()->debug(this);
+ EngineDebugger::get_script_debugger()->debug(this);
return;
}
@@ -393,13 +421,13 @@ public:
if (Thread::get_main_id() != Thread::get_caller_id())
return; //no support for other threads than main for now
- if (ScriptDebugger::get_singleton()->get_lines_left() > 0 && ScriptDebugger::get_singleton()->get_depth() >= 0)
- ScriptDebugger::get_singleton()->set_depth(ScriptDebugger::get_singleton()->get_depth() - 1);
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() - 1);
if (_debug_call_stack_pos == 0) {
_debug_error = "Stack Underflow (Engine Bug)";
- ScriptDebugger::get_singleton()->debug(this);
+ EngineDebugger::get_script_debugger()->debug(this);
return;
}
@@ -457,13 +485,13 @@ public:
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
virtual bool is_using_templates();
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
- virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL, List<ScriptLanguage::Warning> *r_warnings = NULL, Set<int> *r_safe_lines = NULL) const;
+ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
virtual bool supports_builtin_mode() const;
virtual bool can_inherit_from_file() { return true; }
virtual int find_function(const String &p_function, const String &p_code) const;
- virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const;
virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint);
#ifdef TOOLS_ENABLED
virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result);
@@ -493,7 +521,7 @@ public:
virtual void frame();
virtual void get_public_functions(List<MethodInfo> *p_functions) const;
- virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
+ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const;
virtual void profiling_start();
virtual void profiling_stop();
@@ -508,7 +536,7 @@ public:
/* GLOBAL CLASSES */
virtual bool handles_global_class_type(const String &p_type) const;
- virtual String get_global_class_name(const String &p_path, String *r_base_type = NULL, String *r_icon_path = NULL) const;
+ virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const;
void add_orphan_subclass(const String &p_qualified_name, const ObjectID &p_subclass);
Ref<GDScript> get_orphan_subclass(const String &p_qualified_name);
@@ -519,7 +547,7 @@ public:
class ResourceFormatLoaderGDScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index fba1b992ec..2bbec29043 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -46,7 +46,7 @@ bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringN
bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringName &p_name) {
GDScript *scr = owner;
- GDScriptNativeClass *nc = NULL;
+ GDScriptNativeClass *nc = nullptr;
while (scr) {
if (scr->native.is_valid())
@@ -265,7 +265,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
while (owner) {
GDScript *scr = owner;
- GDScriptNativeClass *nc = NULL;
+ GDScriptNativeClass *nc = nullptr;
while (scr) {
if (scr->constants.has(identifier)) {
@@ -1579,7 +1579,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
codegen.stack_max = 0;
codegen.current_line = 0;
codegen.call_max = 0;
- codegen.debug_stack = ScriptDebugger::get_singleton() != NULL;
+ codegen.debug_stack = EngineDebugger::is_active();
Vector<StringName> argnames;
int stack_level = 0;
@@ -1700,14 +1700,14 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->_constant_count = codegen.constant_map.size();
gdfunc->constants.resize(codegen.constant_map.size());
gdfunc->_constants_ptr = gdfunc->constants.ptrw();
- const Variant *K = NULL;
+ const Variant *K = nullptr;
while ((K = codegen.constant_map.next(K))) {
int idx = codegen.constant_map[*K];
gdfunc->constants.write[idx] = *K;
}
} else {
- gdfunc->_constants_ptr = NULL;
+ gdfunc->_constants_ptr = nullptr;
gdfunc->_constant_count = 0;
}
//global names
@@ -1722,7 +1722,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->_global_names_count = gdfunc->global_names.size();
} else {
- gdfunc->_global_names_ptr = NULL;
+ gdfunc->_global_names_ptr = nullptr;
gdfunc->_global_names_count = 0;
}
@@ -1746,7 +1746,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
} else {
- gdfunc->_code_ptr = NULL;
+ gdfunc->_code_ptr = nullptr;
gdfunc->_code_size = 0;
}
@@ -1757,7 +1757,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->_default_arg_ptr = &gdfunc->default_arguments[0];
} else {
gdfunc->_default_arg_count = 0;
- gdfunc->_default_arg_ptr = NULL;
+ gdfunc->_default_arg_ptr = nullptr;
}
gdfunc->_argument_count = p_func ? p_func->arguments.size() : 0;
@@ -1765,7 +1765,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->_call_size = codegen.call_max;
gdfunc->name = func_name;
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
String signature;
//path
if (p_script->get_path() != String())
@@ -1838,7 +1838,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
p_script->native = Ref<GDScriptNativeClass>();
p_script->base = Ref<GDScript>();
- p_script->_base = NULL;
+ p_script->_base = nullptr;
p_script->members.clear();
p_script->constants.clear();
for (Map<StringName, GDScriptFunction *>::Element *E = p_script->member_functions.front(); E; E = E->next()) {
@@ -1848,7 +1848,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
p_script->member_indices.clear();
p_script->member_info.clear();
p_script->_signals.clear();
- p_script->initializer = NULL;
+ p_script->initializer = nullptr;
p_script->tool = p_class->tool;
p_script->name = p_class->name;
@@ -1962,7 +1962,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
if (c->base.is_valid()) {
c = c->base.ptr();
} else {
- c = NULL;
+ c = nullptr;
}
}
@@ -2032,14 +2032,14 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
if (!has_initializer) {
//create a constructor
- Error err = _parse_function(p_script, p_class, NULL);
+ Error err = _parse_function(p_script, p_class, nullptr);
if (err)
return err;
}
if (!has_ready && p_class->ready->statements.size()) {
//create a constructor
- Error err = _parse_function(p_script, p_class, NULL, true);
+ Error err = _parse_function(p_script, p_class, nullptr, true);
if (err)
return err;
}
@@ -2076,10 +2076,10 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
/* STEP 2, INITIALIZE AND CONSTRUCT */
- Variant::CallError ce;
- p_script->initializer->call(instance, NULL, 0, ce);
+ Callable::CallError ce;
+ p_script->initializer->call(instance, nullptr, 0, ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
//well, tough luck, not goinna do anything here
}
}
@@ -2111,7 +2111,7 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
- Map<StringName, Ref<GDScript> > old_subclasses;
+ Map<StringName, Ref<GDScript>> old_subclasses;
if (p_keep_state) {
old_subclasses = p_script->subclasses;
@@ -2162,7 +2162,7 @@ Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_scri
// Create scripts for subclasses beforehand so they can be referenced
_make_scripts(p_script, static_cast<const GDScriptParser::ClassNode *>(root), p_keep_state);
- p_script->_owner = NULL;
+ p_script->_owner = nullptr;
Error err = _parse_class_level(p_script, static_cast<const GDScriptParser::ClassNode *>(root), p_keep_state);
if (err)
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 7d5234a023..34b066b5c7 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -48,11 +48,11 @@ class GDScriptCompiler {
const GDScriptParser::FunctionNode *function_node;
bool debug_stack;
- List<Map<StringName, int> > stack_id_stack;
+ List<Map<StringName, int>> stack_id_stack;
Map<StringName, int> stack_identifiers;
List<GDScriptFunction::StackDebug> stack_debug;
- List<Map<StringName, int> > block_identifier_stack;
+ List<Map<StringName, int>> block_identifier_stack;
Map<StringName, int> block_identifiers;
void add_stack_identifier(const StringName &p_id, int p_stackpos) {
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 65c61cb57c..7ad0682637 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -221,12 +221,12 @@ Script *GDScriptLanguage::create_script() const {
bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const String &p_error) {
//break because of parse error
- if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
+ if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_line = p_line;
_debug_parse_err_file = p_file;
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, false, true);
+ EngineDebugger::get_script_debugger()->debug(this, false, true);
return true;
} else {
return false;
@@ -235,13 +235,13 @@ bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const
bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) {
- if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
+ if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
_debug_error = p_error;
bool is_error_breakpoint = p_error != "Breakpoint";
- ScriptDebugger::get_singleton()->debug(this, p_allow_continue, is_error_breakpoint);
+ EngineDebugger::get_script_debugger()->debug(this, p_allow_continue, is_error_breakpoint);
return true;
} else {
return false;
@@ -299,10 +299,10 @@ void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p
GDScriptFunction *f = _call_stack[l].function;
- List<Pair<StringName, int> > locals;
+ List<Pair<StringName, int>> locals;
f->debug_get_stack_member_state(*_call_stack[l].line, &locals);
- for (List<Pair<StringName, int> >::Element *E = locals.front(); E; E = E->next()) {
+ for (List<Pair<StringName, int>>::Element *E = locals.front(); E; E = E->next()) {
p_locals->push_back(E->get().first);
p_values->push_back(_call_stack[l].stack[E->get().second]);
@@ -336,9 +336,9 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *
ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) {
if (_debug_parse_err_line >= 0)
- return NULL;
+ return nullptr;
- ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, NULL);
+ ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, nullptr);
int l = _debug_call_stack_pos - p_level - 1;
ScriptInstance *instance = _call_stack[l].instance;
@@ -351,7 +351,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
const Map<StringName, int> &name_idx = GDScriptLanguage::get_singleton()->get_global_map();
const Variant *globals = GDScriptLanguage::get_singleton()->get_global_array();
- List<Pair<String, Variant> > cinfo;
+ List<Pair<String, Variant>> cinfo;
get_public_constants(&cinfo);
for (const Map<StringName, int>::Element *E = name_idx.front(); E; E = E->next()) {
@@ -360,7 +360,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
continue;
bool is_script_constant = false;
- for (List<Pair<String, Variant> >::Element *CE = cinfo.front(); CE; CE = CE->next()) {
+ for (List<Pair<String, Variant>>::Element *CE = cinfo.front(); CE; CE = CE->next()) {
if (CE->get().first == E->key()) {
is_script_constant = true;
break;
@@ -430,11 +430,13 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const
mi.name = "assert";
mi.return_val.type = Variant::NIL;
mi.arguments.push_back(PropertyInfo(Variant::BOOL, "condition"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING, "message"));
+ mi.default_arguments.push_back(String());
p_functions->push_back(mi);
}
}
-void GDScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
+void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const {
Pair<String, Variant> pi;
pi.first = "PI";
@@ -457,7 +459,7 @@ void GDScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_cons
p_constants->push_back(nan);
}
-String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
#ifdef TOOLS_ENABLED
bool th = EditorSettings::get_singleton()->get_setting("text_editor/completion/add_type_hints");
@@ -499,10 +501,10 @@ struct GDScriptCompletionContext {
uint32_t depth;
GDScriptCompletionContext() :
- _class(NULL),
- function(NULL),
- block(NULL),
- base(NULL),
+ _class(nullptr),
+ function(nullptr),
+ block(nullptr),
+ base(nullptr),
line(0),
depth(0) {}
};
@@ -514,7 +516,7 @@ struct GDScriptCompletionIdentifier {
const GDScriptParser::Node *assigned_expression;
GDScriptCompletionIdentifier() :
- assigned_expression(NULL) {}
+ assigned_expression(nullptr) {}
};
static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list) {
@@ -905,11 +907,11 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
argptr.push_back(&args[i]);
}
- Variant::CallError ce;
+ Callable::CallError ce;
Variant ret = mb->call(baseptr, (const Variant **)argptr.ptr(), argptr.size(), ce);
- if (ce.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
- if (ret.get_type() != Variant::OBJECT || ret.operator Object *() != NULL) {
+ if (ce.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
+ if (ret.get_type() != Variant::OBJECT || ret.operator Object *() != nullptr) {
r_type = _type_from_variant(ret);
found = true;
}
@@ -963,7 +965,7 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
break;
}
- const GDScriptParser::DictionaryNode *dn = NULL;
+ const GDScriptParser::DictionaryNode *dn = nullptr;
if (op->arguments[0]->type == GDScriptParser::Node::TYPE_DICTIONARY) {
dn = static_cast<const GDScriptParser::DictionaryNode *>(op->arguments[0]);
} else if (base.assigned_expression && base.assigned_expression->type == GDScriptParser::Node::TYPE_DICTIONARY) {
@@ -1017,7 +1019,7 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
}
// Look if it is a dictionary node
- const GDScriptParser::DictionaryNode *dn = NULL;
+ const GDScriptParser::DictionaryNode *dn = nullptr;
if (op->arguments[0]->type == GDScriptParser::Node::TYPE_DICTIONARY) {
dn = static_cast<const GDScriptParser::DictionaryNode *>(op->arguments[0]);
} else if (base.assigned_expression && base.assigned_expression->type == GDScriptParser::Node::TYPE_DICTIONARY) {
@@ -1041,7 +1043,7 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
// Look if it is an array node
if (!found && index.value.is_num()) {
int idx = index.value;
- const GDScriptParser::ArrayNode *an = NULL;
+ const GDScriptParser::ArrayNode *an = nullptr;
if (op->arguments[0]->type == GDScriptParser::Node::TYPE_ARRAY) {
an = static_cast<const GDScriptParser::ArrayNode *>(op->arguments[0]);
} else if (base.assigned_expression && base.assigned_expression->type == GDScriptParser::Node::TYPE_ARRAY) {
@@ -1060,8 +1062,8 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
StringName id = index.value;
found = _guess_identifier_type_from_base(c, base, id, r_type);
} else if (!found && index.type.kind == GDScriptParser::DataType::BUILTIN) {
- Variant::CallError err;
- Variant base_val = Variant::construct(base.type.builtin_type, NULL, 0, err);
+ Callable::CallError err;
+ Variant base_val = Variant::construct(base.type.builtin_type, nullptr, 0, err);
bool valid = false;
Variant res = base_val.get(index.value, &valid);
if (valid) {
@@ -1114,17 +1116,17 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
break;
}
- Variant::CallError ce;
+ Callable::CallError ce;
bool v1_use_value = p1.value.get_type() != Variant::NIL && p1.value.get_type() != Variant::OBJECT;
- Variant v1 = (v1_use_value) ? p1.value : Variant::construct(p1.type.builtin_type, NULL, 0, ce);
+ Variant v1 = (v1_use_value) ? p1.value : Variant::construct(p1.type.builtin_type, nullptr, 0, ce);
bool v2_use_value = p2.value.get_type() != Variant::NIL && p2.value.get_type() != Variant::OBJECT;
- Variant v2 = (v2_use_value) ? p2.value : Variant::construct(p2.type.builtin_type, NULL, 0, ce);
+ Variant v2 = (v2_use_value) ? p2.value : Variant::construct(p2.type.builtin_type, nullptr, 0, ce);
// avoid potential invalid ops
if ((vop == Variant::OP_DIVIDE || vop == Variant::OP_MODULE) && v2.get_type() == Variant::INT) {
v2 = 1;
v2_use_value = false;
}
- if (vop == Variant::OP_DIVIDE && v2.get_type() == Variant::REAL) {
+ if (vop == Variant::OP_DIVIDE && v2.get_type() == Variant::FLOAT) {
v2 = 1.0;
v2_use_value = false;
}
@@ -1173,7 +1175,7 @@ static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const S
// Look in blocks first
const GDScriptParser::BlockNode *blk = p_context.block;
int last_assign_line = -1;
- const GDScriptParser::Node *last_assigned_expression = NULL;
+ const GDScriptParser::Node *last_assigned_expression = nullptr;
GDScriptParser::DataType var_type;
while (blk) {
if (blk->variables.has(p_identifier)) {
@@ -1227,7 +1229,7 @@ static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const S
r_type.type.is_meta_type = false; // Right-hand of `is` will be a meta type, but the left-hand value is not
// Not an assignment, it shouldn't carry any value
r_type.value = Variant();
- r_type.assigned_expression = NULL;
+ r_type.assigned_expression = nullptr;
return true;
}
@@ -1271,8 +1273,8 @@ static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const S
return false;
}
GDScriptCompletionContext c = p_context;
- c.function = NULL;
- c.block = NULL;
+ c.function = nullptr;
+ c.block = nullptr;
return _guess_expression_type(c, op->arguments[1], r_type);
}
}
@@ -1533,10 +1535,10 @@ static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_contex
return false;
} break;
case GDScriptParser::DataType::BUILTIN: {
- Variant::CallError err;
- Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
+ Callable::CallError err;
+ Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ if (err.error != Callable::CallError::CALL_OK) {
return false;
}
bool valid = false;
@@ -1612,7 +1614,7 @@ static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_con
for (int i = 0; i < base_type.class_type->static_functions.size(); i++) {
if (base_type.class_type->static_functions[i]->name == p_method) {
int last_return_line = -1;
- const GDScriptParser::Node *last_returned_value = NULL;
+ const GDScriptParser::Node *last_returned_value = nullptr;
GDScriptCompletionContext c = p_context;
c._class = base_type.class_type;
c.function = base_type.class_type->static_functions[i];
@@ -1629,7 +1631,7 @@ static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_con
for (int i = 0; i < base_type.class_type->functions.size(); i++) {
if (base_type.class_type->functions[i]->name == p_method) {
int last_return_line = -1;
- const GDScriptParser::Node *last_returned_value = NULL;
+ const GDScriptParser::Node *last_returned_value = nullptr;
GDScriptCompletionContext c = p_context;
c._class = base_type.class_type;
c.function = base_type.class_type->functions[i];
@@ -1703,9 +1705,9 @@ static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_con
return false;
} break;
case GDScriptParser::DataType::BUILTIN: {
- Variant::CallError err;
- Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK) {
return false;
}
@@ -1911,8 +1913,8 @@ static void _find_identifiers_in_class(const GDScriptCompletionContext &p_contex
base_type.value = p_context.base;
GDScriptCompletionContext c = p_context;
- c.block = NULL;
- c.function = NULL;
+ c.block = nullptr;
+ c.function = nullptr;
_find_identifiers_in_base(c, base_type, p_only_functions, r_result);
}
@@ -1932,8 +1934,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
case GDScriptParser::DataType::CLASS: {
GDScriptCompletionContext c = p_context;
c._class = base_type.class_type;
- c.block = NULL;
- c.function = NULL;
+ c.block = nullptr;
+ c.function = nullptr;
_find_identifiers_in_class(c, _static, p_only_functions, false, r_result);
base_type = base_type.class_type->base_type;
} break;
@@ -1972,7 +1974,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
}
}
if (!p_only_functions) {
- for (const Map<StringName, Ref<GDScript> >::Element *E = script->get_subclasses().front(); E; E = E->next()) {
+ for (const Map<StringName, Ref<GDScript>>::Element *E = script->get_subclasses().front(); E; E = E->next()) {
ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS);
r_result.insert(option.display, option);
}
@@ -2055,7 +2057,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
List<PropertyInfo> pinfo;
ClassDB::get_property_list(type, &pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) {
+ if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)) {
continue;
}
if (E->get().name.find("/") != -1) {
@@ -2088,15 +2090,15 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
return;
} break;
case GDScriptParser::DataType::BUILTIN: {
- Variant::CallError err;
- Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK) {
return;
}
if (!p_only_functions) {
List<PropertyInfo> members;
- p_base.value.get_property_list(&members);
+ tmp.get_property_list(&members);
for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
if (String(E->get().name).find("/") == -1) {
@@ -2148,13 +2150,13 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p
}
const GDScriptParser::ClassNode *clss = p_context._class;
- bool _static = !p_context.function || p_context.function->_static;
+ bool _static = p_context.function && p_context.function->_static;
while (clss) {
GDScriptCompletionContext c = p_context;
c._class = clss;
- c.block = NULL;
- c.function = NULL;
+ c.block = nullptr;
+ c.function = nullptr;
_find_identifiers_in_class(c, _static, p_only_functions, false, r_result);
_static = true;
clss = clss->owner;
@@ -2172,9 +2174,9 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p
}
static const char *_type_names[Variant::VARIANT_MAX] = {
- "null", "bool", "int", "float", "String", "Vector2", "Rect2", "Vector3", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform",
- "Color", "NodePath", "RID", "Object", "Dictionary", "Array", "PoolByteArray", "PoolIntArray", "PoolRealArray", "PoolStringArray",
- "PoolVector2Array", "PoolVector3Array", "PoolColorArray"
+ "null", "bool", "int", "float", "String", "Vector2", "Vector2i", "Rect2", "Rect2i", "Vector3", "Vector3i", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform",
+ "Color", "StringName", "NodePath", "RID", "Object", "Callable", "Signal", "Dictionary", "Array", "PackedByteArray", "PackedInt32Array", "PackedInt64Array", "PackedFloat32Array", "PackedFloat64Array", "PackedStringArray",
+ "PackedVector2Array", "PackedVector3Array", "PackedColorArray"
};
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
@@ -2186,9 +2188,9 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p
"and", "in", "not", "or", "false", "PI", "TAU", "INF", "NAN", "self", "true", "as", "assert",
"breakpoint", "class", "extends", "is", "func", "preload", "setget", "signal", "tool", "yield",
"const", "enum", "export", "onready", "static", "var", "break", "continue", "if", "elif",
- "else", "for", "pass", "return", "match", "while", "remote", "sync", "master", "puppet", "slave",
+ "else", "for", "pass", "return", "match", "while", "remote", "master", "puppet",
"remotesync", "mastersync", "puppetsync",
- 0
+ nullptr
};
const char **kw = _keywords;
@@ -2234,6 +2236,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
+#define IS_METHOD_SIGNAL(m_method) (m_method == "connect" || m_method == "disconnect" || m_method == "is_connected" || m_method == "emit_signal")
+
while (base_type.has_type) {
switch (base_type.kind) {
case GDScriptParser::DataType::CLASS: {
@@ -2250,7 +2254,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
}
}
- if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) {
+ if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
for (int i = 0; i < base_type.class_type->_signals.size(); i++) {
ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL);
option.insert_text = quote_style + option.display + quote_style;
@@ -2263,7 +2267,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
case GDScriptParser::DataType::GDSCRIPT: {
Ref<GDScript> gds = base_type.script_type;
if (gds.is_valid()) {
- if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) {
+ if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
List<MethodInfo> signals;
gds->get_script_signal_list(&signals);
for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
@@ -2325,7 +2329,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
}
}
- if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) {
+ if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) {
List<MethodInfo> signals;
ClassDB::get_signal_list(class_name, &signals);
for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
@@ -2334,6 +2338,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
r_result.insert(option.display, option);
}
}
+#undef IS_METHOD_SIGNAL
if (ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node") && p_argidx == 0) {
// Get autoloads
@@ -2372,9 +2377,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
} break;
case GDScriptParser::DataType::BUILTIN: {
if (base.get_type() == Variant::NIL) {
- Variant::CallError err;
- base = Variant::construct(base_type.builtin_type, NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ base = Variant::construct(base_type.builtin_type, nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK) {
return;
}
}
@@ -2542,7 +2547,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
context.function = parser.get_completion_function();
context.line = parser.get_completion_line();
- if (!context._class || context._class->owner == NULL) {
+ if (!context._class || context._class->owner == nullptr) {
context.base = p_owner;
context.base_path = p_path.get_base_dir();
}
@@ -2565,7 +2570,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
} break;
case GDScriptParser::COMPLETION_FUNCTION: {
is_function = true;
- FALLTHROUGH;
+ [[fallthrough]];
}
case GDScriptParser::COMPLETION_IDENTIFIER: {
_find_identifiers(context, is_function, options);
@@ -2608,7 +2613,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
} break;
case GDScriptParser::COMPLETION_METHOD: {
is_function = true;
- FALLTHROUGH;
+ [[fallthrough]];
}
case GDScriptParser::COMPLETION_INDEX: {
const GDScriptParser::Node *node = parser.get_completion_node();
@@ -2626,13 +2631,13 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
}
GDScriptCompletionContext c = context;
- c.function = NULL;
- c.block = NULL;
- c.base = base.value.get_type() == Variant::OBJECT ? base.value.operator Object *() : NULL;
+ c.function = nullptr;
+ c.block = nullptr;
+ c.base = base.value.get_type() == Variant::OBJECT ? base.value.operator Object *() : nullptr;
if (base.type.kind == GDScriptParser::DataType::CLASS) {
c._class = base.type.class_type;
} else {
- c._class = NULL;
+ c._class = nullptr;
}
_find_identifiers_in_base(c, base, is_function, options);
@@ -2818,8 +2823,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = clss->constant_expressions.front(); E; E = E->next()) {
GDScriptCompletionIdentifier constant;
GDScriptCompletionContext c = context;
- c.function = NULL;
- c.block = NULL;
+ c.function = nullptr;
+ c.block = nullptr;
c.line = E->value().expression->line;
if (_guess_expression_type(c, E->value().expression, constant)) {
if (constant.type.has_type && constant.type.is_meta_type) {
@@ -2887,9 +2892,9 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
}
GDScriptCompletionContext c = context;
- c._class = NULL;
- c.function = NULL;
- c.block = NULL;
+ c._class = nullptr;
+ c.function = nullptr;
+ c.block = nullptr;
bool finding = true;
index = index.right(index.find(".") + 1);
while (index.find(".") != -1) {
@@ -2917,8 +2922,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
GDScriptCompletionIdentifier constant;
GDScriptCompletionContext c2 = context;
c2._class = base_type.class_type;
- c2.function = NULL;
- c2.block = NULL;
+ c2.function = nullptr;
+ c2.block = nullptr;
c2.line = E->value().expression->line;
if (_guess_expression_type(c2, E->value().expression, constant)) {
if (constant.type.has_type && constant.type.is_meta_type) {
@@ -3219,9 +3224,9 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
v_ref.instance();
v = v_ref;
} else {
- Variant::CallError err;
- v = Variant::construct(base_type.builtin_type, NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ v = Variant::construct(base_type.builtin_type, nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK) {
break;
}
}
@@ -3330,7 +3335,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
case GDScriptParser::COMPLETION_PARENT_FUNCTION:
case GDScriptParser::COMPLETION_FUNCTION: {
is_function = true;
- FALLTHROUGH;
+ [[fallthrough]];
}
case GDScriptParser::COMPLETION_IDENTIFIER: {
@@ -3440,7 +3445,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
// We cannot determine the exact nature of the identifier here
// Otherwise these codes would work
StringName enumName = ClassDB::get_integer_constant_enum("@GlobalScope", p_symbol, true);
- if (enumName != NULL) {
+ if (enumName != nullptr) {
r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_ENUM;
r_result.class_name = "@GlobalScope";
r_result.class_member = enumName;
@@ -3462,7 +3467,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
} break;
case GDScriptParser::COMPLETION_METHOD: {
is_function = true;
- FALLTHROUGH;
+ [[fallthrough]];
}
case GDScriptParser::COMPLETION_INDEX: {
const GDScriptParser::Node *node = parser.get_completion_node();
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 452b1933eb..4e0891921e 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -34,7 +34,7 @@
#include "gdscript.h"
#include "gdscript_functions.h"
-Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const {
+Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const {
int address = p_address & ADDR_MASK;
@@ -45,20 +45,20 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
#ifdef DEBUG_ENABLED
if (unlikely(!p_instance)) {
r_error = "Cannot access self without instance.";
- return NULL;
+ return nullptr;
}
#endif
return &self;
} break;
case ADDR_TYPE_CLASS: {
- return &p_script->_static_ref;
+ return &static_ref;
} break;
case ADDR_TYPE_MEMBER: {
#ifdef DEBUG_ENABLED
if (unlikely(!p_instance)) {
r_error = "Cannot access member without instance.";
- return NULL;
+ return nullptr;
}
#endif
//member indexing is O(1)
@@ -69,7 +69,7 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
//todo change to index!
GDScript *s = p_script;
#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _global_names_count, NULL);
+ ERR_FAIL_INDEX_V(address, _global_names_count, nullptr);
#endif
const StringName *sn = &_global_names_ptr[address];
@@ -86,31 +86,31 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
s = s->_base;
}
- ERR_FAIL_V_MSG(NULL, "GDScriptCompiler bug.");
+ ERR_FAIL_V_MSG(nullptr, "GDScriptCompiler bug.");
} break;
case ADDR_TYPE_LOCAL_CONSTANT: {
#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _constant_count, NULL);
+ ERR_FAIL_INDEX_V(address, _constant_count, nullptr);
#endif
return &_constants_ptr[address];
} break;
case ADDR_TYPE_STACK:
case ADDR_TYPE_STACK_VARIABLE: {
#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _stack_size, NULL);
+ ERR_FAIL_INDEX_V(address, _stack_size, nullptr);
#endif
return &p_stack[address];
} break;
case ADDR_TYPE_GLOBAL: {
#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, GDScriptLanguage::get_singleton()->get_global_array_size(), NULL);
+ ERR_FAIL_INDEX_V(address, GDScriptLanguage::get_singleton()->get_global_array_size(), nullptr);
#endif
return &GDScriptLanguage::get_singleton()->get_global_array()[address];
} break;
#ifdef TOOLS_ENABLED
case ADDR_TYPE_NAMED_GLOBAL: {
#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _named_globals_count, NULL);
+ ERR_FAIL_INDEX_V(address, _named_globals_count, nullptr);
#endif
StringName id = _named_globals_ptr[address];
@@ -118,7 +118,7 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
return (Variant *)&GDScriptLanguage::get_singleton()->get_named_globals_map()[id];
} else {
r_error = "Autoload singleton '" + String(id) + "' has been removed.";
- return NULL;
+ return nullptr;
}
} break;
#endif
@@ -127,8 +127,8 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
} break;
}
- ERR_FAIL_V_MSG(NULL, "Bad code! (unknown addressing mode).");
- return NULL;
+ ERR_FAIL_V_MSG(nullptr, "Bad code! (unknown addressing mode).");
+ return nullptr;
}
#ifdef DEBUG_ENABLED
@@ -137,18 +137,19 @@ static String _get_var_type(const Variant *p_var) {
String basestr;
if (p_var->get_type() == Variant::OBJECT) {
- Object *bobj = *p_var;
+ bool was_freed;
+ Object *bobj = p_var->get_validated_object_with_check(was_freed);
if (!bobj) {
- basestr = "null instance";
- } else {
- if (ObjectDB::instance_validate(bobj)) {
- if (bobj->get_script_instance())
- basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
- else
- basestr = bobj->get_class();
+ if (was_freed) {
+ basestr = "null instance";
} else {
- basestr = "previously freed instance";
+ basestr = "previously freed";
}
+ } else {
+ if (bobj->get_script_instance())
+ basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
+ else
+ basestr = bobj->get_class();
}
} else {
@@ -159,11 +160,11 @@ static String _get_var_type(const Variant *p_var) {
}
#endif // DEBUG_ENABLED
-String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const {
+String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const {
String err_text;
- if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+ if (p_err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
int errorarg = p_err.argument;
// Handle the Object to Object case separately as we don't have further class details.
#ifdef DEBUG_ENABLED
@@ -172,15 +173,15 @@ String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const
} else
#endif // DEBUG_ENABLED
{
- err_text = "Invalid type in " + p_where + ". Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(p_err.expected) + ".";
+ err_text = "Invalid type in " + p_where + ". Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(p_err.expected)) + ".";
}
- } else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
+ } else if (p_err.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
- } else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
+ } else if (p_err.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
- } else if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ } else if (p_err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
err_text = "Invalid call. Nonexistent " + p_where + ".";
- } else if (p_err.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
+ } else if (p_err.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
err_text = "Attempt to call " + p_where + " on a null instance.";
} else {
err_text = "Bug, call error: #" + itos(p_err.error);
@@ -257,7 +258,7 @@ String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const
#define OPCODE_OUT break
#endif
-Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state) {
+Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state) {
OPCODES_TABLE;
@@ -266,11 +267,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
return Variant();
}
- r_err.error = Variant::CallError::CALL_OK;
+ r_err.error = Callable::CallError::CALL_OK;
Variant self;
+ Variant static_ref;
Variant retvalue;
- Variant *stack = NULL;
+ Variant *stack = nullptr;
Variant **call_args;
int defarg = 0;
@@ -304,13 +306,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (p_argcount > _argument_count) {
- r_err.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_err.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_err.argument = _argument_count;
return Variant();
} else if (p_argcount < _argument_count - _default_arg_count) {
- r_err.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_err.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_err.argument = _argument_count - _default_arg_count;
return Variant();
} else {
@@ -335,15 +337,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (!argument_types[i].is_type(*p_args[i], true)) {
- if (argument_types[i].is_type(Variant(), true)) {
- memnew_placement(&stack[i], Variant);
- continue;
- } else {
- r_err.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_err.argument = i;
- r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
- return Variant();
- }
+ r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_err.argument = i;
+ r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
+ return Variant();
}
if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err);
@@ -356,7 +353,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
memnew_placement(&stack[i], Variant);
}
} else {
- stack = NULL;
+ stack = nullptr;
}
if (_call_size) {
@@ -364,12 +361,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
call_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
} else {
- call_args = NULL;
+ call_args = nullptr;
}
} else {
- stack = NULL;
- call_args = NULL;
+ stack = nullptr;
+ call_args = nullptr;
}
if (p_instance) {
@@ -389,7 +386,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton())
+ if (EngineDebugger::is_active())
GDScriptLanguage::get_singleton()->enter_function(p_instance, this, stack, &ip, &line);
#define GD_ERR_BREAK(m_cond) \
@@ -403,10 +400,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#define CHECK_SPACE(m_space) \
GD_ERR_BREAK((ip + m_space) > _code_size)
-#define GET_VARIANT_PTR(m_v, m_code_ofs) \
- Variant *m_v; \
- m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); \
- if (unlikely(!m_v)) \
+#define GET_VARIANT_PTR(m_v, m_code_ofs) \
+ Variant *m_v; \
+ m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text); \
+ if (unlikely(!m_v)) \
OPCODE_BREAK;
#else
@@ -414,7 +411,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#define CHECK_SPACE(m_space)
#define GET_VARIANT_PTR(m_v, m_code_ofs) \
Variant *m_v; \
- m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text);
+ m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text);
#endif
@@ -488,7 +485,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GET_VARIANT_PTR(dst, 3);
#ifdef DEBUG_ENABLED
- if (b->get_type() != Variant::OBJECT || b->operator Object *() == NULL) {
+ if (b->get_type() != Variant::OBJECT || b->operator Object *() == nullptr) {
err_text = "Right operand of 'is' is not a class.";
OPCODE_BREAK;
@@ -496,15 +493,27 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
bool extends_ok = false;
- if (a->get_type() == Variant::OBJECT && a->operator Object *() != NULL) {
- Object *obj_A = *a;
- Object *obj_B = *b;
+ if (a->get_type() == Variant::OBJECT && a->operator Object *() != nullptr) {
#ifdef DEBUG_ENABLED
- if (!ObjectDB::instance_validate(obj_A)) {
- err_text = "Left operand of 'is' was already freed.";
+ bool was_freed;
+ Object *obj_A = a->get_validated_object_with_check(was_freed);
+
+ if (was_freed) {
+ err_text = "Left operand of 'is' is a previously freed instance.";
OPCODE_BREAK;
}
+
+ Object *obj_B = b->get_validated_object_with_check(was_freed);
+
+ if (was_freed) {
+ err_text = "Right operand of 'is' is a previously freed instance.";
+ OPCODE_BREAK;
+ }
+#else
+
+ Object *obj_A = *a;
+ Object *obj_B = *b;
#endif // DEBUG_ENABLED
GDScript *scr_B = Object::cast_to<GDScript>(obj_B);
@@ -778,7 +787,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (Variant::can_convert_strict(src->get_type(), var_type)) {
#endif // DEBUG_ENABLED
- Variant::CallError ce;
+ Callable::CallError ce;
*dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce);
} else {
#ifdef DEBUG_ENABLED
@@ -841,7 +850,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_BREAK;
}
- if (src->get_type() != Variant::NIL && src->operator Object *() != NULL) {
+ if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) {
ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
if (!scr_inst) {
@@ -884,11 +893,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GD_ERR_BREAK(to_type < 0 || to_type >= Variant::VARIANT_MAX);
- Variant::CallError err;
+ Callable::CallError err;
*dst = Variant::construct(to_type, (const Variant **)&src, 1, err);
#ifdef DEBUG_ENABLED
- if (err.error != Variant::CallError::CALL_OK) {
+ if (err.error != Callable::CallError::CALL_OK) {
err_text = "Invalid cast: could not convert value to '" + Variant::get_type_name(to_type) + "'.";
OPCODE_BREAK;
}
@@ -946,7 +955,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
bool valid = false;
- if (src->get_type() != Variant::NIL && src->operator Object *() != NULL) {
+ if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) {
ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
@@ -987,11 +996,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
GET_VARIANT_PTR(dst, 3 + argc);
- Variant::CallError err;
+ Callable::CallError err;
*dst = Variant::construct(t, (const Variant **)argptrs, argc, err);
#ifdef DEBUG_ENABLED
- if (err.error != Variant::CallError::CALL_OK) {
+ if (err.error != Callable::CallError::CALL_OK) {
err_text = _get_call_error(err, "'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs);
OPCODE_BREAK;
@@ -1078,21 +1087,21 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
#endif
- Variant::CallError err;
+ Callable::CallError err;
if (call_ret) {
GET_VARIANT_PTR(ret, argc);
base->call_ptr(*methodname, (const Variant **)argptrs, argc, ret, err);
} else {
- base->call_ptr(*methodname, (const Variant **)argptrs, argc, NULL, err);
+ base->call_ptr(*methodname, (const Variant **)argptrs, argc, nullptr, err);
}
#ifdef DEBUG_ENABLED
if (GDScriptLanguage::get_singleton()->profiling) {
function_call_time += OS::get_singleton()->get_ticks_usec() - call_time;
}
- if (err.error != Variant::CallError::CALL_OK) {
+ if (err.error != Callable::CallError::CALL_OK) {
String methodstr = *methodname;
String basestr = _get_var_type(base);
@@ -1100,13 +1109,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (methodstr == "call") {
if (argc >= 1) {
methodstr = String(*argptrs[0]) + " (via call)";
- if (err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+ if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
err.argument += 1;
}
}
} else if (methodstr == "free") {
- if (err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ if (err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
if (base->is_ref()) {
err_text = "Attempted to free a reference.";
@@ -1123,7 +1132,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
#endif
- //_call_func(NULL,base,*methodname,ip,argc,p_instance,stack);
+ //_call_func(nullptr,base,*methodname,ip,argc,p_instance,stack);
ip += argc + 1;
}
DISPATCH_OPCODE;
@@ -1147,12 +1156,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GET_VARIANT_PTR(dst, argc);
- Variant::CallError err;
+ Callable::CallError err;
GDScriptFunctions::call(func, (const Variant **)argptrs, argc, *dst, err);
#ifdef DEBUG_ENABLED
- if (err.error != Variant::CallError::CALL_OK) {
+ if (err.error != Callable::CallError::CALL_OK) {
String methodstr = GDScriptFunctions::get_func_name(func);
if (dst->get_type() == Variant::STRING) {
@@ -1202,7 +1211,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
const GDScript *gds = _script;
- const Map<StringName, GDScriptFunction *>::Element *E = NULL;
+ const Map<StringName, GDScriptFunction *>::Element *E = nullptr;
while (gds->base.ptr()) {
gds = gds->base.ptr();
E = gds->member_functions.find(*methodname);
@@ -1210,7 +1219,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
break;
}
- Variant::CallError err;
+ Callable::CallError err;
if (E) {
@@ -1221,23 +1230,23 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
MethodBind *mb = ClassDB::get_method(gds->native->get_name(), *methodname);
if (!mb) {
- err.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
} else {
*dst = mb->call(p_instance->owner, (const Variant **)argptrs, argc, err);
}
} else {
- err.error = Variant::CallError::CALL_OK;
+ err.error = Callable::CallError::CALL_OK;
}
} else {
if (*methodname != GDScriptLanguage::get_singleton()->strings._init) {
- err.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
} else {
- err.error = Variant::CallError::CALL_OK;
+ err.error = Callable::CallError::CALL_OK;
}
}
- if (err.error != Variant::CallError::CALL_OK) {
+ if (err.error != Callable::CallError::CALL_OK) {
String methodstr = *methodname;
err_text = _get_call_error(err, "function '" + methodstr + "'", (const Variant **)argptrs);
@@ -1274,7 +1283,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
gdfs->state.script = Ref<GDScript>(_script);
gdfs->state.ip = ip + ipofs;
gdfs->state.line = line;
- gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : 0;
+ gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : ObjectID();
//gdfs->state.result_pos=ip+ipofs-1;
gdfs->state.defarg = defarg;
gdfs->state.instance = p_instance;
@@ -1298,33 +1307,36 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
#endif
- Object *obj = argobj->operator Object *();
+#ifdef DEBUG_ENABLED
+ bool was_freed;
+ Object *obj = argobj->get_validated_object_with_check(was_freed);
String signal = argname->operator String();
-#ifdef DEBUG_ENABLED
+ if (was_freed) {
+ err_text = "First argument of yield() is a previously freed instance.";
+ OPCODE_BREAK;
+ }
+
if (!obj) {
err_text = "First argument of yield() is null.";
OPCODE_BREAK;
}
- if (ScriptDebugger::get_singleton()) {
- if (!ObjectDB::instance_validate(obj)) {
- err_text = "First argument of yield() is a previously freed instance.";
- OPCODE_BREAK;
- }
- }
if (signal.length() == 0) {
err_text = "Second argument of yield() is an empty string (for signal name).";
OPCODE_BREAK;
}
- Error err = obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
+ Error err = obj->connect_compat(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
if (err != OK) {
err_text = "Error connecting to signal: " + signal + " during yield().";
OPCODE_BREAK;
}
#else
- obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
+ Object *obj = argobj->operator Object *();
+ String signal = argname->operator String();
+
+ obj->connect_compat(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
#endif
}
@@ -1505,7 +1517,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE(OPCODE_BREAKPOINT) {
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break("Breakpoint Statement", true);
}
#endif
@@ -1519,26 +1531,26 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
line = _code_ptr[ip + 1];
ip += 2;
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
// line
bool do_break = false;
- if (ScriptDebugger::get_singleton()->get_lines_left() > 0) {
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0) {
- if (ScriptDebugger::get_singleton()->get_depth() <= 0)
- ScriptDebugger::get_singleton()->set_lines_left(ScriptDebugger::get_singleton()->get_lines_left() - 1);
- if (ScriptDebugger::get_singleton()->get_lines_left() <= 0)
+ if (EngineDebugger::get_script_debugger()->get_depth() <= 0)
+ EngineDebugger::get_script_debugger()->set_lines_left(EngineDebugger::get_script_debugger()->get_lines_left() - 1);
+ if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0)
do_break = true;
}
- if (ScriptDebugger::get_singleton()->is_breakpoint(line, source))
+ if (EngineDebugger::get_script_debugger()->is_breakpoint(line, source))
do_break = true;
if (do_break) {
GDScriptLanguage::get_singleton()->debug_break("Breakpoint", true);
}
- ScriptDebugger::get_singleton()->line_poll();
+ EngineDebugger::get_singleton()->line_poll();
}
}
DISPATCH_OPCODE;
@@ -1565,14 +1577,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
//error
// function, file, line, error, explanation
String err_file;
- if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->path != "")
+ if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "")
err_file = p_instance->script->path;
else if (script)
err_file = script->path;
if (err_file == "")
err_file = "<built-in>";
String err_func = name;
- if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->name != "")
+ if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "")
err_func = p_instance->script->name + "." + err_func;
int err_line = line;
if (err_text == "") {
@@ -1605,7 +1617,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
// When it's the last resume it will postpone the exit from stack,
// so the debugger knows which function triggered the resume of the next function (if any)
if (!p_state || yielded) {
- if (ScriptDebugger::get_singleton())
+ if (EngineDebugger::is_active())
GDScriptLanguage::get_singleton()->exit_function();
#endif
@@ -1690,7 +1702,7 @@ struct _GDFKCS {
}
};
-void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const {
+void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const {
int oc = 0;
Map<StringName, _GDFKC> sdmap;
@@ -1750,15 +1762,12 @@ GDScriptFunction::GDScriptFunction() :
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
name = "<anonymous>";
#ifdef DEBUG_ENABLED
- _func_cname = NULL;
+ _func_cname = nullptr;
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->function_list.add(&function_list);
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
+ GDScriptLanguage::get_singleton()->function_list.add(&function_list);
}
profile.call_count = 0;
@@ -1776,26 +1785,22 @@ GDScriptFunction::GDScriptFunction() :
GDScriptFunction::~GDScriptFunction() {
#ifdef DEBUG_ENABLED
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
- }
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
+
+ GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
#endif
}
/////////////////////
-Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant arg;
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
if (p_argcount == 0) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
return Variant();
} else if (p_argcount == 1) {
@@ -1813,7 +1818,7 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
Ref<GDScriptFunctionState> self = *p_args[p_argcount - 1];
if (self.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_argcount - 1;
r_error.expected = Variant::OBJECT;
return Variant();
@@ -1824,12 +1829,12 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
- if (function == NULL)
+ if (function == nullptr)
return false;
if (p_extended_check) {
//class instance gone?
- if (state.instance_id && !ObjectDB::get_instance(state.instance_id))
+ if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id))
return false;
}
@@ -1839,7 +1844,7 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
Variant GDScriptFunctionState::resume(const Variant &p_arg) {
ERR_FAIL_COND_V(!function, Variant());
- if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
+ if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id)) {
#ifdef DEBUG_ENABLED
ERR_FAIL_V_MSG(Variant(), "Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line));
#else
@@ -1848,8 +1853,8 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
}
state.result = p_arg;
- Variant::CallError err;
- Variant ret = function->call(NULL, NULL, 0, err, &state);
+ Callable::CallError err;
+ Variant ret = function->call(nullptr, nullptr, 0, err, &state);
bool completed = true;
@@ -1863,7 +1868,7 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
}
}
- function = NULL; //cleaned up;
+ function = nullptr; //cleaned up;
state.result = Variant();
if (completed) {
@@ -1874,7 +1879,7 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
}
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton())
+ if (EngineDebugger::is_active())
GDScriptLanguage::get_singleton()->exit_function();
if (state.stack_size) {
//free stack
@@ -1899,12 +1904,12 @@ void GDScriptFunctionState::_bind_methods() {
GDScriptFunctionState::GDScriptFunctionState() {
- function = NULL;
+ function = nullptr;
}
GDScriptFunctionState::~GDScriptFunctionState() {
- if (function != NULL) {
+ if (function != nullptr) {
//never called, deinitialize stack
for (int i = 0; i < state.stack_size; i++) {
Variant *v = (Variant *)&state.stack[sizeof(Variant) * i];
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index ad95ebc543..acfc0a95b4 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -77,8 +77,8 @@ struct GDScriptDataType {
return false;
}
- Object *obj = p_variant.operator Object *();
- if (!obj || !ObjectDB::instance_validate(obj)) {
+ Object *obj = p_variant.get_validated_object();
+ if (!obj) {
return false;
}
@@ -100,12 +100,12 @@ struct GDScriptDataType {
return false;
}
- Object *obj = p_variant.operator Object *();
- if (!obj || !ObjectDB::instance_validate(obj)) {
+ Object *obj = p_variant.get_validated_object();
+ if (!obj) {
return false;
}
- Ref<Script> base = obj && obj->get_script_instance() ? obj->get_script_instance()->get_script() : NULL;
+ Ref<Script> base = obj && obj->get_script_instance() ? obj->get_script_instance()->get_script() : nullptr;
bool valid = false;
while (base.is_valid()) {
if (base == script_type) {
@@ -265,8 +265,8 @@ private:
List<StackDebug> stack_debug;
- _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const;
- _FORCE_INLINE_ String _get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const;
+ _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const;
+ _FORCE_INLINE_ String _get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const;
friend class GDScriptLanguage;
@@ -321,7 +321,7 @@ public:
GDScript *get_script() const { return _script; }
StringName get_source() const { return source; }
- void debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const;
+ void debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const;
_FORCE_INLINE_ bool is_empty() const { return _code_size == 0; }
@@ -339,7 +339,7 @@ public:
return default_arguments[p_idx];
}
- Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state = NULL);
+ Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state = nullptr);
_FORCE_INLINE_ MultiplayerAPI::RPCMode get_rpc_mode() const { return rpc_mode; }
GDScriptFunction();
@@ -352,7 +352,7 @@ class GDScriptFunctionState : public Reference {
friend class GDScriptFunction;
GDScriptFunction *function;
GDScriptFunction::CallState state;
- Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Ref<GDScriptFunctionState> first_state;
protected:
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index c398633dc5..9154d6eb89 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -72,7 +72,6 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
"is_equal_approx",
"is_zero_approx",
"ease",
- "decimals",
"step_decimals",
"stepify",
"lerp",
@@ -140,32 +139,32 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
return _names[p_func];
}
-void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Variant::CallError &r_error) {
+void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
#ifdef DEBUG_ENABLED
-#define VALIDATE_ARG_COUNT(m_count) \
- if (p_arg_count < m_count) { \
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; \
- r_error.argument = m_count; \
- r_ret = Variant(); \
- return; \
- } \
- if (p_arg_count > m_count) { \
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; \
- r_error.argument = m_count; \
- r_ret = Variant(); \
- return; \
+#define VALIDATE_ARG_COUNT(m_count) \
+ if (p_arg_count < m_count) { \
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; \
+ r_error.argument = m_count; \
+ r_ret = Variant(); \
+ return; \
+ } \
+ if (p_arg_count > m_count) { \
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; \
+ r_error.argument = m_count; \
+ r_ret = Variant(); \
+ return; \
}
-#define VALIDATE_ARG_NUM(m_arg) \
- if (!p_args[m_arg]->is_num()) { \
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; \
- r_error.argument = m_arg; \
- r_error.expected = Variant::REAL; \
- r_ret = Variant(); \
- return; \
+#define VALIDATE_ARG_NUM(m_arg) \
+ if (!p_args[m_arg]->is_num()) { \
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \
+ r_error.argument = m_arg; \
+ r_error.expected = Variant::FLOAT; \
+ r_ret = Variant(); \
+ return; \
}
#else
@@ -273,15 +272,15 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
int64_t i = *p_args[0];
r_ret = ABS(i);
- } else if (p_args[0]->get_type() == Variant::REAL) {
+ } else if (p_args[0]->get_type() == Variant::FLOAT) {
double r = *p_args[0];
r_ret = Math::abs(r);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
r_ret = Variant();
}
} break;
@@ -291,15 +290,15 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
int64_t i = *p_args[0];
r_ret = i < 0 ? -1 : (i > 0 ? +1 : 0);
- } else if (p_args[0]->get_type() == Variant::REAL) {
+ } else if (p_args[0]->get_type() == Variant::FLOAT) {
real_t r = *p_args[0];
r_ret = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
r_ret = Variant();
}
} break;
@@ -346,12 +345,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_NUM(1);
r_ret = Math::ease((double)*p_args[0], (double)*p_args[1]);
} break;
- case MATH_DECIMALS: {
- VALIDATE_ARG_COUNT(1);
- VALIDATE_ARG_NUM(0);
- r_ret = Math::step_decimals((double)*p_args[0]);
- WARN_DEPRECATED_MSG("GDScript method 'decimals' is deprecated and has been renamed to 'step_decimals', please update your code accordingly.");
- } break;
case MATH_STEP_DECIMALS: {
VALIDATE_ARG_COUNT(1);
VALIDATE_ARG_NUM(0);
@@ -367,12 +360,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_COUNT(3);
VALIDATE_ARG_NUM(2);
const double t = (double)*p_args[2];
- switch (p_args[0]->get_type() == p_args[1]->get_type() ? p_args[0]->get_type() : Variant::REAL) {
+ switch (p_args[0]->get_type() == p_args[1]->get_type() ? p_args[0]->get_type() : Variant::FLOAT) {
case Variant::VECTOR2: {
r_ret = ((Vector2)*p_args[0]).linear_interpolate((Vector2)*p_args[1], t);
} break;
case Variant::VECTOR3: {
- r_ret = ((Vector3)*p_args[0]).linear_interpolate((Vector3)*p_args[1], t);
+ r_ret = (p_args[0]->operator Vector3()).linear_interpolate(p_args[1]->operator Vector3(), t);
} break;
case Variant::COLOR: {
r_ret = ((Color)*p_args[0]).linear_interpolate((Color)*p_args[1], t);
@@ -592,7 +585,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Ref<WeakRef> wref = memnew(WeakRef);
r_ret = wref;
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
r_ret = Variant();
@@ -603,7 +596,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_COUNT(2);
if (p_args[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
r_ret = Variant();
@@ -611,7 +604,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
}
if (p_args[1]->get_type() != Variant::STRING && p_args[1]->get_type() != Variant::NODE_PATH) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -633,7 +626,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (type < 0 || type >= Variant::VARIANT_MAX) {
r_ret = RTR("Invalid type argument to convert(), use TYPE_* constants.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::INT;
return;
@@ -667,7 +660,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -678,7 +671,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (str.length() != 1) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = RTR("Expected a string of length 1 (a character).");
@@ -690,7 +683,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case TEXT_STR: {
if (p_arg_count < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
r_ret = Variant();
@@ -792,7 +785,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case PUSH_ERROR: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -806,7 +799,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case PUSH_WARNING: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -826,7 +819,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case STR_TO_VAR: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -844,17 +837,17 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case VAR_TO_BYTES: {
bool full_objects = false;
if (p_arg_count < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
r_ret = Variant();
return;
} else if (p_arg_count > 2) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = 2;
r_ret = Variant();
} else if (p_arg_count == 2) {
if (p_args[1]->get_type() != Variant::BOOL) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::BOOL;
r_ret = Variant();
@@ -863,11 +856,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
full_objects = *p_args[1];
}
- PoolByteArray barr;
+ PackedByteArray barr;
int len;
- Error err = encode_variant(*p_args[0], NULL, len, full_objects);
+ Error err = encode_variant(*p_args[0], nullptr, len, full_objects);
if (err) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::NIL;
r_ret = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
@@ -876,25 +869,25 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
barr.resize(len);
{
- PoolByteArray::Write w = barr.write();
- encode_variant(*p_args[0], w.ptr(), len, full_objects);
+ uint8_t *w = barr.ptrw();
+ encode_variant(*p_args[0], w, len, full_objects);
}
r_ret = barr;
} break;
case BYTES_TO_VAR: {
bool allow_objects = false;
if (p_arg_count < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
r_ret = Variant();
return;
} else if (p_arg_count > 2) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = 2;
r_ret = Variant();
} else if (p_arg_count == 2) {
if (p_args[1]->get_type() != Variant::BOOL) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::BOOL;
r_ret = Variant();
@@ -903,24 +896,24 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
allow_objects = *p_args[1];
}
- if (p_args[0]->get_type() != Variant::POOL_BYTE_ARRAY) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
r_ret = Variant();
return;
}
- PoolByteArray varr = *p_args[0];
+ PackedByteArray varr = *p_args[0];
Variant ret;
{
- PoolByteArray::Read r = varr.read();
- Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects);
+ const uint8_t *r = varr.ptr();
+ Error err = decode_variant(ret, r, varr.size(), nullptr, allow_objects);
if (err != OK) {
r_ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
return;
}
}
@@ -934,7 +927,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case 0: {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
r_ret = Variant();
@@ -950,7 +943,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
}
Error err = arr.resize(count);
if (err != OK) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_ret = Variant();
return;
}
@@ -976,7 +969,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
}
Error err = arr.resize(to - from);
if (err != OK) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_ret = Variant();
return;
}
@@ -996,7 +989,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (incr == 0) {
r_ret = RTR("Step argument is zero!");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return;
}
@@ -1023,7 +1016,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Error err = arr.resize(count);
if (err != OK) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_ret = Variant();
return;
}
@@ -1045,7 +1038,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
default: {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = 3;
r_ret = Variant();
@@ -1056,7 +1049,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case RESOURCE_LOAD: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -1072,7 +1065,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (p_args[0]->get_type() == Variant::NIL) {
r_ret = Variant();
} else if (p_args[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_ret = Variant();
} else {
@@ -1083,7 +1076,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} else if (!obj->get_script_instance() || obj->get_script_instance()->get_language() != GDScriptLanguage::get_singleton()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::DICTIONARY;
r_ret = RTR("Not a script with an instance");
@@ -1094,7 +1087,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Ref<GDScript> base = ins->get_script();
if (base.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::DICTIONARY;
r_ret = RTR("Not based on a script");
@@ -1112,7 +1105,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
sname.invert();
if (!p->path.is_resource_file()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::DICTIONARY;
r_ret = Variant();
@@ -1144,7 +1137,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (p_args[0]->get_type() != Variant::DICTIONARY) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::DICTIONARY;
r_ret = Variant();
@@ -1156,7 +1149,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (!d.has("@path")) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
r_ret = RTR("Invalid instance dictionary format (missing @path)");
@@ -1167,7 +1160,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Ref<Script> scr = ResourceLoader::load(d["@path"]);
if (!scr.is_valid()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
r_ret = RTR("Invalid instance dictionary format (can't load script at @path)");
@@ -1178,7 +1171,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (!gdscr.is_valid()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
r_ret = Variant();
@@ -1196,7 +1189,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
gdscr = gdscr->subclasses[sub.get_name(i)];
if (!gdscr.is_valid()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
r_ret = Variant();
@@ -1205,7 +1198,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
}
}
- r_ret = gdscr->_new(NULL, 0, r_error);
+ r_ret = gdscr->_new(nullptr, 0, r_error);
GDScriptInstance *ins = static_cast<GDScriptInstance *>(static_cast<Object *>(r_ret)->get_script_instance());
Ref<GDScript> gd_ref = ins->get_script();
@@ -1222,7 +1215,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -1246,7 +1239,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
r_ret = Variant();
@@ -1278,14 +1271,14 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case COLOR8: {
if (p_arg_count < 3) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 3;
r_ret = Variant();
return;
}
if (p_arg_count > 4) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = 4;
r_ret = Variant();
@@ -1309,21 +1302,21 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case COLORN: {
if (p_arg_count < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
r_ret = Variant();
return;
}
if (p_arg_count > 2) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = 2;
r_ret = Variant();
return;
}
if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_ret = Variant();
} else {
@@ -1366,15 +1359,15 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case INSTANCE_FROM_ID: {
VALIDATE_ARG_COUNT(1);
- if (p_args[0]->get_type() != Variant::INT && p_args[0]->get_type() != Variant::REAL) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::INT && p_args[0]->get_type() != Variant::FLOAT) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::INT;
r_ret = Variant();
break;
}
- uint32_t id = *p_args[0];
+ ObjectID id = *p_args[0];
r_ret = ObjectDB::get_instance(id);
} break;
@@ -1397,43 +1390,53 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Array d = *p_args[0];
r_ret = d.size();
} break;
- case Variant::POOL_BYTE_ARRAY: {
+ case Variant::PACKED_BYTE_ARRAY: {
+
+ Vector<uint8_t> d = *p_args[0];
+ r_ret = d.size();
+ } break;
+ case Variant::PACKED_INT32_ARRAY: {
- PoolVector<uint8_t> d = *p_args[0];
+ Vector<int32_t> d = *p_args[0];
r_ret = d.size();
} break;
- case Variant::POOL_INT_ARRAY: {
+ case Variant::PACKED_INT64_ARRAY: {
- PoolVector<int> d = *p_args[0];
+ Vector<int64_t> d = *p_args[0];
r_ret = d.size();
} break;
- case Variant::POOL_REAL_ARRAY: {
+ case Variant::PACKED_FLOAT32_ARRAY: {
- PoolVector<real_t> d = *p_args[0];
+ Vector<float> d = *p_args[0];
r_ret = d.size();
} break;
- case Variant::POOL_STRING_ARRAY: {
+ case Variant::PACKED_FLOAT64_ARRAY: {
- PoolVector<String> d = *p_args[0];
+ Vector<double> d = *p_args[0];
r_ret = d.size();
} break;
- case Variant::POOL_VECTOR2_ARRAY: {
+ case Variant::PACKED_STRING_ARRAY: {
- PoolVector<Vector2> d = *p_args[0];
+ Vector<String> d = *p_args[0];
r_ret = d.size();
} break;
- case Variant::POOL_VECTOR3_ARRAY: {
+ case Variant::PACKED_VECTOR2_ARRAY: {
- PoolVector<Vector3> d = *p_args[0];
+ Vector<Vector2> d = *p_args[0];
r_ret = d.size();
} break;
- case Variant::POOL_COLOR_ARRAY: {
+ case Variant::PACKED_VECTOR3_ARRAY: {
- PoolVector<Color> d = *p_args[0];
+ Vector<Vector3> d = *p_args[0];
+ r_ret = d.size();
+ } break;
+ case Variant::PACKED_COLOR_ARRAY: {
+
+ Vector<Color> d = *p_args[0];
r_ret = d.size();
} break;
default: {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
r_ret = Variant();
@@ -1448,8 +1451,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (p_args[0]->get_type() != Variant::OBJECT) {
r_ret = false;
} else {
- Object *obj = *p_args[0];
- r_ret = ObjectDB::instance_validate(obj);
+ Object *obj = p_args[0]->get_validated_object();
+ r_ret = obj != nullptr;
}
} break;
@@ -1492,7 +1495,6 @@ bool GDScriptFunctions::is_deterministic(Function p_func) {
case MATH_ISNAN:
case MATH_ISINF:
case MATH_EASE:
- case MATH_DECIMALS:
case MATH_STEP_DECIMALS:
case MATH_STEPIFY:
case MATH_LERP:
@@ -1538,69 +1540,69 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
switch (p_func) {
case MATH_SIN: {
- MethodInfo mi("sin", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("sin", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_COS: {
- MethodInfo mi("cos", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("cos", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_TAN: {
- MethodInfo mi("tan", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("tan", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_SINH: {
- MethodInfo mi("sinh", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("sinh", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_COSH: {
- MethodInfo mi("cosh", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("cosh", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_TANH: {
- MethodInfo mi("tanh", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("tanh", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_ASIN: {
- MethodInfo mi("asin", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("asin", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_ACOS: {
- MethodInfo mi("acos", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("acos", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_ATAN: {
- MethodInfo mi("atan", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("atan", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_ATAN2: {
- MethodInfo mi("atan2", PropertyInfo(Variant::REAL, "y"), PropertyInfo(Variant::REAL, "x"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("atan2", PropertyInfo(Variant::FLOAT, "y"), PropertyInfo(Variant::FLOAT, "x"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_SQRT: {
- MethodInfo mi("sqrt", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("sqrt", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_FMOD: {
- MethodInfo mi("fmod", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("fmod", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_FPOSMOD: {
- MethodInfo mi("fposmod", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("fposmod", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_POSMOD: {
@@ -1609,119 +1611,114 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case MATH_FLOOR: {
- MethodInfo mi("floor", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("floor", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_CEIL: {
- MethodInfo mi("ceil", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("ceil", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_ROUND: {
- MethodInfo mi("round", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("round", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_ABS: {
- MethodInfo mi("abs", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("abs", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_SIGN: {
- MethodInfo mi("sign", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("sign", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_POW: {
- MethodInfo mi("pow", PropertyInfo(Variant::REAL, "base"), PropertyInfo(Variant::REAL, "exp"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("pow", PropertyInfo(Variant::FLOAT, "base"), PropertyInfo(Variant::FLOAT, "exp"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_LOG: {
- MethodInfo mi("log", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("log", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_EXP: {
- MethodInfo mi("exp", PropertyInfo(Variant::REAL, "s"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("exp", PropertyInfo(Variant::FLOAT, "s"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_ISNAN: {
- MethodInfo mi("is_nan", PropertyInfo(Variant::REAL, "s"));
+ MethodInfo mi("is_nan", PropertyInfo(Variant::FLOAT, "s"));
mi.return_val.type = Variant::BOOL;
return mi;
} break;
case MATH_ISINF: {
- MethodInfo mi("is_inf", PropertyInfo(Variant::REAL, "s"));
+ MethodInfo mi("is_inf", PropertyInfo(Variant::FLOAT, "s"));
mi.return_val.type = Variant::BOOL;
return mi;
} break;
case MATH_ISEQUALAPPROX: {
- MethodInfo mi("is_equal_approx", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
+ MethodInfo mi("is_equal_approx", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b"));
mi.return_val.type = Variant::BOOL;
return mi;
} break;
case MATH_ISZEROAPPROX: {
- MethodInfo mi("is_zero_approx", PropertyInfo(Variant::REAL, "s"));
+ MethodInfo mi("is_zero_approx", PropertyInfo(Variant::FLOAT, "s"));
mi.return_val.type = Variant::BOOL;
return mi;
} break;
case MATH_EASE: {
- MethodInfo mi("ease", PropertyInfo(Variant::REAL, "s"), PropertyInfo(Variant::REAL, "curve"));
- mi.return_val.type = Variant::REAL;
- return mi;
- } break;
- case MATH_DECIMALS: {
- MethodInfo mi("decimals", PropertyInfo(Variant::REAL, "step"));
- mi.return_val.type = Variant::INT;
+ MethodInfo mi("ease", PropertyInfo(Variant::FLOAT, "s"), PropertyInfo(Variant::FLOAT, "curve"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_STEP_DECIMALS: {
- MethodInfo mi("step_decimals", PropertyInfo(Variant::REAL, "step"));
+ MethodInfo mi("step_decimals", PropertyInfo(Variant::FLOAT, "step"));
mi.return_val.type = Variant::INT;
return mi;
} break;
case MATH_STEPIFY: {
- MethodInfo mi("stepify", PropertyInfo(Variant::REAL, "s"), PropertyInfo(Variant::REAL, "step"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("stepify", PropertyInfo(Variant::FLOAT, "s"), PropertyInfo(Variant::FLOAT, "step"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_LERP: {
- MethodInfo mi("lerp", PropertyInfo(Variant::NIL, "from"), PropertyInfo(Variant::NIL, "to"), PropertyInfo(Variant::REAL, "weight"));
+ MethodInfo mi("lerp", PropertyInfo(Variant::NIL, "from"), PropertyInfo(Variant::NIL, "to"), PropertyInfo(Variant::FLOAT, "weight"));
mi.return_val.type = Variant::NIL;
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case MATH_LERP_ANGLE: {
- MethodInfo mi("lerp_angle", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("lerp_angle", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "weight"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_INVERSE_LERP: {
- MethodInfo mi("inverse_lerp", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("inverse_lerp", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "weight"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_RANGE_LERP: {
- MethodInfo mi("range_lerp", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "istart"), PropertyInfo(Variant::REAL, "istop"), PropertyInfo(Variant::REAL, "ostart"), PropertyInfo(Variant::REAL, "ostop"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("range_lerp", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "istart"), PropertyInfo(Variant::FLOAT, "istop"), PropertyInfo(Variant::FLOAT, "ostart"), PropertyInfo(Variant::FLOAT, "ostop"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_SMOOTHSTEP: {
- MethodInfo mi("smoothstep", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("smoothstep", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "weight"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_MOVE_TOWARD: {
- MethodInfo mi("move_toward", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "delta"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("move_toward", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "delta"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_DECTIME: {
- MethodInfo mi("dectime", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "amount"), PropertyInfo(Variant::REAL, "step"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("dectime", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "amount"), PropertyInfo(Variant::FLOAT, "step"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_RANDOMIZE: {
@@ -1736,12 +1733,12 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case MATH_RANDF: {
MethodInfo mi("randf");
- mi.return_val.type = Variant::REAL;
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_RANDOM: {
- MethodInfo mi("rand_range", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("rand_range", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_SEED: {
@@ -1755,32 +1752,32 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case MATH_DEG2RAD: {
- MethodInfo mi("deg2rad", PropertyInfo(Variant::REAL, "deg"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("deg2rad", PropertyInfo(Variant::FLOAT, "deg"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_RAD2DEG: {
- MethodInfo mi("rad2deg", PropertyInfo(Variant::REAL, "rad"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("rad2deg", PropertyInfo(Variant::FLOAT, "rad"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_LINEAR2DB: {
- MethodInfo mi("linear2db", PropertyInfo(Variant::REAL, "nrg"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("linear2db", PropertyInfo(Variant::FLOAT, "nrg"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_DB2LINEAR: {
- MethodInfo mi("db2linear", PropertyInfo(Variant::REAL, "db"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("db2linear", PropertyInfo(Variant::FLOAT, "db"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case MATH_POLAR2CARTESIAN: {
- MethodInfo mi("polar2cartesian", PropertyInfo(Variant::REAL, "r"), PropertyInfo(Variant::REAL, "th"));
+ MethodInfo mi("polar2cartesian", PropertyInfo(Variant::FLOAT, "r"), PropertyInfo(Variant::FLOAT, "th"));
mi.return_val.type = Variant::VECTOR2;
return mi;
} break;
case MATH_CARTESIAN2POLAR: {
- MethodInfo mi("cartesian2polar", PropertyInfo(Variant::REAL, "x"), PropertyInfo(Variant::REAL, "y"));
+ MethodInfo mi("cartesian2polar", PropertyInfo(Variant::FLOAT, "x"), PropertyInfo(Variant::FLOAT, "y"));
mi.return_val.type = Variant::VECTOR2;
return mi;
} break;
@@ -1790,24 +1787,24 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case MATH_WRAPF: {
- MethodInfo mi("wrapf", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("wrapf", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case LOGIC_MAX: {
- MethodInfo mi("max", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("max", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case LOGIC_MIN: {
- MethodInfo mi("min", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("min", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case LOGIC_CLAMP: {
- MethodInfo mi("clamp", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max"));
- mi.return_val.type = Variant::REAL;
+ MethodInfo mi("clamp", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max"));
+ mi.return_val.type = Variant::FLOAT;
return mi;
} break;
case LOGIC_NEAREST_PO2: {
@@ -1954,12 +1951,12 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::BOOL, "full_objects"));
mi.default_arguments.push_back(false);
- mi.return_val.type = Variant::POOL_BYTE_ARRAY;
+ mi.return_val.type = Variant::PACKED_BYTE_ARRAY;
return mi;
} break;
case BYTES_TO_VAR: {
- MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes"), PropertyInfo(Variant::BOOL, "allow_objects"));
+ MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytes"), PropertyInfo(Variant::BOOL, "allow_objects"));
mi.default_arguments.push_back(false);
mi.return_val.type = Variant::NIL;
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
@@ -2025,7 +2022,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case COLORN: {
- MethodInfo mi("ColorN", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::REAL, "alpha"));
+ MethodInfo mi("ColorN", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "alpha"));
mi.default_arguments.push_back(1.0f);
mi.return_val.type = Variant::COLOR;
return mi;
diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h
index 1812ddf121..2c6dc02913 100644
--- a/modules/gdscript/gdscript_functions.h
+++ b/modules/gdscript/gdscript_functions.h
@@ -63,7 +63,6 @@ public:
MATH_ISEQUALAPPROX,
MATH_ISZEROAPPROX,
MATH_EASE,
- MATH_DECIMALS,
MATH_STEP_DECIMALS,
MATH_STEPIFY,
MATH_LERP,
@@ -130,7 +129,7 @@ public:
};
static const char *get_func_name(Function p_func);
- static void call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Variant::CallError &r_error);
+ static void call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Callable::CallError &r_error);
static bool is_deterministic(Function p_func);
static MethodInfo get_info(Function p_func);
};
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index d125da5b79..c74d8cfbb0 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -242,7 +242,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
Vector<Expression> expression;
- Node *expr = NULL;
+ Node *expr = nullptr;
int op_line = tokenizer->get_token_line(); // when operators are created at the bottom, the line might have been changed (\n found)
@@ -276,12 +276,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
Node *subexpr = _parse_expression(p_parent, p_static, p_allow_assign, p_parsing_constant);
parenthesis--;
if (!subexpr)
- return NULL;
+ return nullptr;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')' in expression");
- return NULL;
+ return nullptr;
}
tokenizer->advance();
@@ -318,7 +318,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token_constant().get_type() != Variant::STRING) {
_set_error("Expected string constant or identifier after '$' or '/'.");
- return NULL;
+ return nullptr;
}
path += String(tokenizer->get_token_constant());
@@ -355,7 +355,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (path == "") {
_set_error("Path expected after $.");
- return NULL;
+ return nullptr;
}
OperatorNode *op = alloc_node<OperatorNode>();
@@ -427,7 +427,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
_set_error("Expected '(' after 'preload'");
- return NULL;
+ return nullptr;
}
tokenizer->advance();
@@ -476,7 +476,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (!valid) {
_set_error("expected string constant as 'preload' argument.");
- return NULL;
+ return nullptr;
}
if (!path.is_abs_path() && base_path != "")
@@ -485,7 +485,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (path == self_path) {
_set_error("Can't preload itself (use 'get_script()').");
- return NULL;
+ return nullptr;
}
Ref<Resource> res;
@@ -503,26 +503,26 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (!FileAccess::exists(path)) {
_set_error("Can't preload resource at path: " + path);
- return NULL;
+ return nullptr;
} else if (ScriptCodeCompletionCache::get_singleton()) {
res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path);
}
}
if (!res.is_valid()) {
_set_error("Can't preload resource at path: " + path);
- return NULL;
+ return nullptr;
}
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')' after 'preload' path");
- return NULL;
+ return nullptr;
}
Ref<GDScript> gds = res;
if (gds.is_valid() && !gds->is_valid()) {
_set_error("Couldn't fully preload the script, possible cyclic reference or compilation error. Use \"load()\" instead if a cyclic reference is intended.");
- return NULL;
+ return nullptr;
}
tokenizer->advance();
@@ -536,7 +536,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (!current_function) {
_set_error("\"yield()\" can only be used inside function blocks.");
- return NULL;
+ return nullptr;
}
current_function->has_yield = true;
@@ -544,7 +544,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
_set_error("Expected \"(\" after \"yield\".");
- return NULL;
+ return nullptr;
}
tokenizer->advance();
@@ -565,12 +565,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
Node *object = _parse_and_reduce_expression(p_parent, p_static);
if (!object)
- return NULL;
+ return nullptr;
yield->arguments.push_back(object);
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
_set_error("Expected \",\" after the first argument of \"yield\".");
- return NULL;
+ return nullptr;
}
tokenizer->advance();
@@ -591,12 +591,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
Node *signal = _parse_and_reduce_expression(p_parent, p_static);
if (!signal)
- return NULL;
+ return nullptr;
yield->arguments.push_back(signal);
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" after the second argument of \"yield\".");
- return NULL;
+ return nullptr;
}
parenthesis--;
@@ -610,7 +610,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (p_static) {
_set_error("\"self\" isn't allowed in a static function or constant expression.");
- return NULL;
+ return nullptr;
}
//constant defined by tokenizer
SelfNode *self = alloc_node<SelfNode>();
@@ -631,7 +631,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (identifier == StringName()) {
_set_error("Built-in type constant or static function expected after \".\".");
- return NULL;
+ return nullptr;
}
if (!Variant::has_constant(bi_type, identifier)) {
@@ -657,7 +657,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
op->arguments.push_back(id);
if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
- return NULL;
+ return nullptr;
expr = op;
} else {
@@ -674,7 +674,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
if (!valid) {
_set_error("Static constant '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
- return NULL;
+ return nullptr;
}
}
} else {
@@ -746,10 +746,17 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
_make_completable_call(0);
completion_node = op;
+
+ if (op->arguments[0]->type == GDScriptParser::Node::Type::TYPE_BUILT_IN_FUNCTION) {
+ BuiltInFunctionNode *bn = static_cast<BuiltInFunctionNode *>(op->arguments[0]);
+ if (bn->function == GDScriptFunctions::Function::RESOURCE_LOAD) {
+ completion_type = COMPLETION_RESOURCE_PATH;
+ }
+ }
}
if (!replaced) {
if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
- return NULL;
+ return nullptr;
expr = op;
}
} else if (tokenizer->is_token_literal(0, true)) {
@@ -789,11 +796,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (lv->assignments == 0) {
if (!lv->datatype.has_type) {
_set_error("Using assignment with operation on a variable that was never assigned.");
- return NULL;
+ return nullptr;
}
_add_warning(GDScriptWarning::UNASSIGNED_VARIABLE_OP_ASSIGN, -1, identifier.operator String());
}
- FALLTHROUGH;
+ [[fallthrough]];
}
case GDScriptTokenizer::TK_OP_ASSIGN: {
lv->assignments += 1;
@@ -827,6 +834,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
//check from singletons
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = GDScriptLanguage::get_singleton()->get_named_globals_map()[identifier];
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -837,6 +845,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (scr.is_valid() && scr->is_valid()) {
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = scr;
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -852,6 +861,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (parent_constants.has(identifier)) {
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = parent_constants[identifier];
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -912,7 +922,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (e.op != OperatorNode::OP_NOT && tokenizer->get_token() == GDScriptTokenizer::TK_OP_NOT) {
_set_error("Misplaced 'not'.");
- return NULL;
+ return nullptr;
}
expression.push_back(e);
@@ -921,7 +931,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
/*
Node *subexpr=_parse_expression(op,p_static);
if (!subexpr)
- return NULL;
+ return nullptr;
op->arguments.push_back(subexpr);
expr=op;*/
@@ -929,7 +939,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
// 'is' operator with built-in type
if (!expr) {
_set_error("Expected identifier before 'is' operator");
- return NULL;
+ return nullptr;
}
OperatorNode *op = alloc_node<OperatorNode>();
op->op = OperatorNode::OP_IS_BUILTIN;
@@ -955,7 +965,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
_set_error("Unterminated array");
- return NULL;
+ return nullptr;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) {
tokenizer->advance();
@@ -966,7 +976,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
if (!expecting_comma) {
_set_error("expression or ']' expected");
- return NULL;
+ return nullptr;
}
expecting_comma = false;
@@ -975,11 +985,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
//parse expression
if (expecting_comma) {
_set_error("',' or ']' expected");
- return NULL;
+ return nullptr;
}
Node *n = _parse_expression(arr, p_static, p_allow_assign, p_parsing_constant);
if (!n)
- return NULL;
+ return nullptr;
arr->elements.push_back(n);
expecting_comma = true;
}
@@ -1001,7 +1011,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
};
- Node *key = NULL;
+ Node *key = nullptr;
Set<Variant> keys;
DictExpect expecting = DICT_EXPECT_KEY;
@@ -1011,17 +1021,17 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
_set_error("Unterminated dictionary");
- return NULL;
+ return nullptr;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
if (expecting == DICT_EXPECT_COLON) {
_set_error("':' expected");
- return NULL;
+ return nullptr;
}
if (expecting == DICT_EXPECT_VALUE) {
_set_error("value expected");
- return NULL;
+ return nullptr;
}
tokenizer->advance();
break;
@@ -1032,15 +1042,15 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (expecting == DICT_EXPECT_KEY) {
_set_error("key or '}' expected");
- return NULL;
+ return nullptr;
}
if (expecting == DICT_EXPECT_VALUE) {
_set_error("value expected");
- return NULL;
+ return nullptr;
}
if (expecting == DICT_EXPECT_COLON) {
_set_error("':' expected");
- return NULL;
+ return nullptr;
}
expecting = DICT_EXPECT_KEY;
@@ -1050,15 +1060,15 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (expecting == DICT_EXPECT_KEY) {
_set_error("key or '}' expected");
- return NULL;
+ return nullptr;
}
if (expecting == DICT_EXPECT_VALUE) {
_set_error("value expected");
- return NULL;
+ return nullptr;
}
if (expecting == DICT_EXPECT_COMMA) {
_set_error("',' or '}' expected");
- return NULL;
+ return nullptr;
}
expecting = DICT_EXPECT_VALUE;
@@ -1067,11 +1077,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (expecting == DICT_EXPECT_COMMA) {
_set_error("',' or '}' expected");
- return NULL;
+ return nullptr;
}
if (expecting == DICT_EXPECT_COLON) {
_set_error("':' expected");
- return NULL;
+ return nullptr;
}
if (expecting == DICT_EXPECT_KEY) {
@@ -1089,7 +1099,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
//python/js style more flexible
key = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant);
if (!key)
- return NULL;
+ return nullptr;
expecting = DICT_EXPECT_COLON;
}
}
@@ -1097,7 +1107,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (expecting == DICT_EXPECT_VALUE) {
Node *value = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant);
if (!value)
- return NULL;
+ return nullptr;
expecting = DICT_EXPECT_COMMA;
if (key->type == GDScriptParser::Node::TYPE_CONSTANT) {
@@ -1105,7 +1115,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (keys.has(keyName)) {
_set_error("Duplicate key found in Dictionary literal");
- return NULL;
+ return nullptr;
}
keys.insert(keyName);
}
@@ -1114,7 +1124,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
pair.key = key;
pair.value = value;
dict->elements.push_back(pair);
- key = NULL;
+ key = nullptr;
}
}
}
@@ -1142,12 +1152,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
if (!is_completion) {
_set_error("Expected '(' for parent function call.");
- return NULL;
+ return nullptr;
}
} else {
tokenizer->advance();
if (!_parse_arguments(op, op->arguments, p_static, false, p_parsing_constant)) {
- return NULL;
+ return nullptr;
}
}
@@ -1166,10 +1176,10 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
//find list [ or find dictionary {
_set_error("Error parsing expression, misplaced: " + String(tokenizer->get_token_name(tokenizer->get_token())));
- return NULL; //nothing
+ return nullptr; //nothing
}
- ERR_FAIL_COND_V_MSG(!expr, NULL, "GDScriptParser bug, couldn't figure out what expression is.");
+ ERR_FAIL_COND_V_MSG(!expr, nullptr, "GDScriptParser bug, couldn't figure out what expression is.");
/******************/
/* Parse Indexing */
@@ -1186,7 +1196,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_CURSOR && !tokenizer->is_token_literal(1)) {
// We check with is_token_literal, as this allows us to use match/sync/etc. as a name
_set_error("Expected identifier as member");
- return NULL;
+ return nullptr;
} else if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
//call!!
OperatorNode *op = alloc_node<OperatorNode>();
@@ -1212,7 +1222,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
completion_node = op;
}
if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
- return NULL;
+ return nullptr;
expr = op;
} else {
@@ -1251,12 +1261,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
Node *subexpr = _parse_expression(op, p_static, p_allow_assign, p_parsing_constant);
if (!subexpr) {
- return NULL;
+ return nullptr;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
- return NULL;
+ return nullptr;
}
op->arguments.push_back(expr);
@@ -1276,12 +1286,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_AS) {
if (has_casting) {
_set_error("Unexpected 'as'.");
- return NULL;
+ return nullptr;
}
CastNode *cn = alloc_node<CastNode>();
if (!_parse_type(cn->cast_type)) {
_set_error("Expected type after 'as'.");
- return NULL;
+ return nullptr;
}
has_casting = true;
cn->source_node = expr;
@@ -1313,7 +1323,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
#define _VALIDATE_ASSIGN \
if (!p_allow_assign || has_casting) { \
_set_error("Unexpected assign."); \
- return NULL; \
+ return nullptr; \
} \
p_allow_assign = false;
@@ -1479,7 +1489,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
default: {
_set_error("GDScriptParser bug, invalid operator in expression: " + itos(expression[i].op));
- return NULL;
+ return nullptr;
}
}
@@ -1488,7 +1498,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
// <= is used for right to left
if (error) {
_set_error("Unexpected operator");
- return NULL;
+ return nullptr;
}
next_op = i;
min_priority = priority;
@@ -1500,7 +1510,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (next_op == -1) {
_set_error("Yet another parser bug....");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
// OK! create operator..
@@ -1513,11 +1523,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (expr_pos == expression.size()) {
//can happen..
_set_error("Unexpected end of expression...");
- return NULL;
+ return nullptr;
}
}
- //consecutively do unary opeators
+ //consecutively do unary operators
for (int i = expr_pos - 1; i >= next_op; i--) {
OperatorNode *op = alloc_node<OperatorNode>();
@@ -1532,16 +1542,16 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
} else if (is_ternary) {
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
if (next_op >= (expression.size() - 2) || expression[next_op + 2].op != OperatorNode::OP_TERNARY_ELSE) {
_set_error("Expected else after ternary if.");
- return NULL;
+ return nullptr;
}
if (next_op >= (expression.size() - 3)) {
_set_error("Expected value after ternary else.");
- return NULL;
+ return nullptr;
}
OperatorNode *op = alloc_node<OperatorNode>();
@@ -1551,7 +1561,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (expression[next_op - 1].is_op) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
if (expression[next_op + 1].is_op) {
@@ -1561,7 +1571,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators after ternary if.");
- return NULL;
+ return nullptr;
}
if (expression[next_op + 3].is_op) {
@@ -1571,7 +1581,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators after ternary else.");
- return NULL;
+ return nullptr;
}
op->arguments.push_back(expression[next_op + 1].node); //next expression goes as first
@@ -1588,7 +1598,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
OperatorNode *op = alloc_node<OperatorNode>();
@@ -1598,7 +1608,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (expression[next_op - 1].is_op) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
if (expression[next_op + 1].is_op) {
@@ -1608,7 +1618,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators.");
- return NULL;
+ return nullptr;
}
op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
@@ -1725,7 +1735,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
if ((op->arguments[0]->type == Node::TYPE_TYPE || (op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && GDScriptFunctions::is_deterministic(static_cast<BuiltInFunctionNode *>(op->arguments[0])->function))) && last_not_constant == 0) {
//native type constructor or intrinsic function
- const Variant **vptr = NULL;
+ const Variant **vptr = nullptr;
Vector<Variant *> ptrs;
if (op->arguments.size() > 1) {
@@ -1739,7 +1749,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
vptr = (const Variant **)&ptrs[0];
}
- Variant::CallError ce;
+ Callable::CallError ce;
Variant v;
if (op->arguments[0]->type == Node::TYPE_TYPE) {
@@ -1751,7 +1761,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
GDScriptFunctions::call(func, vptr, ptrs.size(), v, ce);
}
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
String errwhere;
if (op->arguments[0]->type == Node::TYPE_TYPE) {
@@ -1765,16 +1775,16 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
switch (ce.error) {
- case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
_set_error("Invalid argument (#" + itos(ce.argument + 1) + ") for " + errwhere + ".");
} break;
- case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
_set_error("Too many arguments for " + errwhere + ".");
} break;
- case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
_set_error("Too few arguments for " + errwhere + ".");
} break;
@@ -2015,10 +2025,10 @@ GDScriptParser::Node *GDScriptParser::_parse_and_reduce_expression(Node *p_paren
Node *expr = _parse_expression(p_parent, p_static, p_allow_assign, p_reduce_const);
if (!expr || error_set)
- return NULL;
+ return nullptr;
expr = _reduce_expression(expr, p_reduce_const);
if (!expr || error_set)
- return NULL;
+ return nullptr;
return expr;
}
@@ -2046,10 +2056,10 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
GDScriptTokenizer::Token token = tokenizer->get_token();
if (error_set)
- return NULL;
+ return nullptr;
if (token == GDScriptTokenizer::TK_EOF) {
- return NULL;
+ return nullptr;
}
switch (token) {
@@ -2078,13 +2088,13 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
break;
} else {
_set_error("'..' pattern only allowed at the end of an array pattern");
- return NULL;
+ return nullptr;
}
}
PatternNode *sub_pattern = _parse_pattern(p_static);
if (!sub_pattern) {
- return NULL;
+ return nullptr;
}
pattern->array.push_back(sub_pattern);
@@ -2097,7 +2107,7 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
break;
} else {
_set_error("Not a valid pattern");
- return NULL;
+ return nullptr;
}
}
} break;
@@ -2106,7 +2116,7 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
tokenizer->advance();
if (!tokenizer->is_token_literal()) {
_set_error("Expected identifier for binding variable name.");
- return NULL;
+ return nullptr;
}
pattern->pt_type = GDScriptParser::PatternNode::PT_BIND;
pattern->bind = tokenizer->get_token_literal();
@@ -2115,7 +2125,7 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
while (bl) {
if (bl->variables.has(pattern->bind)) {
_set_error("Binding name of '" + pattern->bind.operator String() + "' is already declared in this scope.");
- return NULL;
+ return nullptr;
}
bl = bl->parent_block;
}
@@ -2150,19 +2160,19 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
break;
} else {
_set_error("'..' pattern only allowed at the end of a dictionary pattern");
- return NULL;
+ return nullptr;
}
}
Node *key = _parse_and_reduce_expression(pattern, p_static);
if (!key) {
_set_error("Not a valid key in pattern");
- return NULL;
+ return nullptr;
}
if (key->type != GDScriptParser::Node::TYPE_CONSTANT) {
_set_error("Not a constant expression as key");
- return NULL;
+ return nullptr;
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
@@ -2171,12 +2181,12 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
PatternNode *value = _parse_pattern(p_static);
if (!value) {
_set_error("Expected pattern in dictionary value");
- return NULL;
+ return nullptr;
}
pattern->dictionary.insert(static_cast<ConstantNode *>(key), value);
} else {
- pattern->dictionary.insert(static_cast<ConstantNode *>(key), NULL);
+ pattern->dictionary.insert(static_cast<ConstantNode *>(key), nullptr);
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
@@ -2187,7 +2197,7 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
break;
} else {
_set_error("Not a valid pattern");
- return NULL;
+ return nullptr;
}
}
} break;
@@ -2200,7 +2210,7 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
Node *value = _parse_and_reduce_expression(pattern, p_static);
if (!value) {
_set_error("Expect constant expression or variables in a pattern");
- return NULL;
+ return nullptr;
}
if (value->type == Node::TYPE_OPERATOR) {
@@ -2212,19 +2222,19 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
if (op_node->op != OperatorNode::OP_INDEX_NAMED) {
_set_error("Invalid operator in pattern. Only index (`A.B`) is allowed");
- return NULL;
+ return nullptr;
}
current_value = op_node->arguments[0];
}
if (current_value->type != Node::TYPE_IDENTIFIER) {
_set_error("Only constant expression or variables allowed in a pattern");
- return NULL;
+ return nullptr;
}
} else if (value->type != Node::TYPE_IDENTIFIER && value->type != Node::TYPE_CONSTANT) {
_set_error("Only constant expressions or variables allowed in a pattern");
- return NULL;
+ return nullptr;
}
pattern->pt_type = PatternNode::PT_CONSTANT;
@@ -2332,7 +2342,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
return;
}
- OperatorNode *type_comp = NULL;
+ OperatorNode *type_comp = nullptr;
// static type check if possible
if (pattern_type.has_type && to_match_type.has_type) {
@@ -2386,6 +2396,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// a bind always matches
ConstantNode *true_value = alloc_node<ConstantNode>();
true_value->value = Variant(true);
+ true_value->datatype = _type_from_variant(true_value->value);
p_resulting_node = true_value;
} break;
case PatternNode::PT_ARRAY: {
@@ -2402,7 +2413,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// typeof(value_to_match) == TYPE_ARRAY && value_to_match.size() == length
{
- OperatorNode *type_comp = NULL;
+ OperatorNode *type_comp = nullptr;
// static type check if possible
if (to_match_type.has_type) {
// must be an array
@@ -2432,6 +2443,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// size
ConstantNode *length = alloc_node<ConstantNode>();
length->value = Variant(open_ended ? p_pattern->array.size() - 1 : p_pattern->array.size());
+ length->datatype = _type_from_variant(length->value);
OperatorNode *call = alloc_node<OperatorNode>();
call->op = OperatorNode::OP_CALL;
@@ -2461,10 +2473,11 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
for (int i = 0; i < p_pattern->array.size(); i++) {
PatternNode *pattern = p_pattern->array[i];
- Node *condition = NULL;
+ Node *condition = nullptr;
ConstantNode *index = alloc_node<ConstantNode>();
index->value = Variant(i);
+ index->datatype = _type_from_variant(index->value);
OperatorNode *indexed_value = alloc_node<OperatorNode>();
indexed_value->op = OperatorNode::OP_INDEX;
@@ -2495,7 +2508,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// typeof(value_to_match) == TYPE_DICTIONARY && value_to_match.size() == length
{
- OperatorNode *type_comp = NULL;
+ OperatorNode *type_comp = nullptr;
// static type check if possible
if (to_match_type.has_type) {
// must be an dictionary
@@ -2525,6 +2538,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// size
ConstantNode *length = alloc_node<ConstantNode>();
length->value = Variant(open_ended ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size());
+ length->datatype = _type_from_variant(length->value);
OperatorNode *call = alloc_node<OperatorNode>();
call->op = OperatorNode::OP_CALL;
@@ -2553,7 +2567,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
for (Map<ConstantNode *, PatternNode *>::Element *e = p_pattern->dictionary.front(); e; e = e->next()) {
- Node *condition = NULL;
+ Node *condition = nullptr;
// check for has, then for pattern
@@ -2601,6 +2615,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// simply generate a `true`
ConstantNode *true_value = alloc_node<ConstantNode>();
true_value->value = Variant(true);
+ true_value->datatype = _type_from_variant(true_value->value);
p_resulting_node = true_value;
} break;
default: {
@@ -2629,7 +2644,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
PatternBranchNode *branch = p_match_statement->branches[i];
MatchNode::CompiledPatternBranch compiled_branch;
- compiled_branch.compiled_pattern = NULL;
+ compiled_branch.compiled_pattern = nullptr;
Map<StringName, Node *> binding;
@@ -2638,7 +2653,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
_mark_line_as_safe(pattern->line);
Map<StringName, Node *> bindings;
- Node *resulting_node = NULL;
+ Node *resulting_node = nullptr;
_generate_pattern(pattern, id, resulting_node, bindings);
if (!resulting_node) {
@@ -2683,6 +2698,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
LocalVarNode *local_var = branch->body->variables[e->key()];
local_var->assign = e->value();
local_var->set_datatype(local_var->assign->get_datatype());
+ local_var->assignments++;
IdentifierNode *id2 = alloc_node<IdentifierNode>();
id2->name = local_var->name;
@@ -2766,13 +2782,12 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
#endif // DEBUG_ENABLED
switch (token) {
- case GDScriptTokenizer::TK_EOF:
+ case GDScriptTokenizer::TK_EOF: {
p_block->end_line = tokenizer->get_token_line();
+ return; // End of file!
+ } break;
case GDScriptTokenizer::TK_ERROR: {
- return; //go back
-
- //end of file!
-
+ return;
} break;
case GDScriptTokenizer::TK_NEWLINE: {
@@ -2786,6 +2801,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+ _mark_line_as_safe(line);
NewLineNode *nl2 = alloc_node<NewLineNode>();
nl2->line = line;
p_block->statements.push_back(nl2);
@@ -2839,7 +2855,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
lv->line = var_line;
p_block->statements.push_back(lv);
- Node *assigned = NULL;
+ Node *assigned = nullptr;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
if (tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
@@ -3103,15 +3119,14 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
Vector<Node *> args;
Vector<double> constants;
- bool constant = false;
+ bool constant = true;
for (int i = 1; i < op->arguments.size(); i++) {
args.push_back(op->arguments[i]);
- if (constant && op->arguments[i]->type == Node::TYPE_CONSTANT) {
+ if (op->arguments[i]->type == Node::TYPE_CONSTANT) {
ConstantNode *c = static_cast<ConstantNode *>(op->arguments[i]);
- if (c->value.get_type() == Variant::REAL || c->value.get_type() == Variant::INT) {
+ if (c->value.get_type() == Variant::FLOAT || c->value.get_type() == Variant::INT) {
constants.push_back(c->value);
- constant = true;
}
} else {
constant = false;
@@ -3300,6 +3315,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+ int assert_line = tokenizer->get_token_line();
+
tokenizer->advance();
Vector<Node *> args;
@@ -3313,14 +3330,21 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+#ifdef DEBUG_ENABLED
+ // Mark as safe, let type check mark as unsafe if needed
+ _mark_line_as_safe(assert_line);
+ _reduce_node_type(args[0]);
+#endif
AssertNode *an = alloc_node<AssertNode>();
an->condition = _reduce_expression(args[0], p_static);
+ an->line = assert_line;
if (args.size() == 2) {
an->message = _reduce_expression(args[1], p_static);
} else {
ConstantNode *message_node = alloc_node<ConstantNode>();
message_node->value = String();
+ message_node->datatype = _type_from_variant(message_node->value);
an->message = message_node;
}
@@ -3525,11 +3549,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
case GDScriptTokenizer::TK_CURSOR: {
tokenizer->advance();
} break;
- case GDScriptTokenizer::TK_EOF:
+ case GDScriptTokenizer::TK_EOF: {
p_class->end_line = tokenizer->get_token_line();
+ return; // End of file!
+ } break;
case GDScriptTokenizer::TK_ERROR: {
- return; //go back
- //end of file!
+ return; // Go back.
} break;
case GDScriptTokenizer::TK_NEWLINE: {
if (!_parse_newline()) {
@@ -3674,6 +3699,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ").");
return;
}
+ for (int i = 0; i < outer_class->variables.size(); i++) {
+ if (outer_class->variables[i].identifier == name) {
+ _set_error("A variable named \"" + String(name) + "\" already exists in the outer class scope (at line " + itos(outer_class->variables[i].line) + ").");
+ return;
+ }
+ }
outer_class = outer_class->owner;
}
@@ -3719,7 +3750,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- FALLTHROUGH;
+ [[fallthrough]];
}
case GDScriptTokenizer::TK_PR_FUNCTION: {
@@ -3809,6 +3840,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
StringName argname = tokenizer->get_token_identifier();
+ for (int i = 0; i < arguments.size(); i++) {
+ if (arguments[i] == argname) {
+ _set_error("The argument name \"" + String(argname) + "\" is defined multiple times.");
+ return;
+ }
+ }
arguments.push_back(argname);
#ifdef DEBUG_ENABLED
arguments_usage.push_back(0);
@@ -3929,7 +3966,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_function = function;
Node *arg = _parse_and_reduce_expression(p_class, _static);
- current_function = NULL;
+ current_function = nullptr;
cparent->arguments.push_back(arg);
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
@@ -3984,7 +4021,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
function->body = block;
current_block = block;
_parse_block(block, _static);
- current_block = NULL;
+ current_block = nullptr;
//arguments
} break;
@@ -4099,10 +4136,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
- WARN_DEPRECATED_MSG("Exporting bit flags hint requires string constants.");
- break;
- }
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
_set_error("Expected \",\" in the bit flags hint.");
return;
@@ -4224,9 +4257,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
break;
}
- FALLTHROUGH;
+ [[fallthrough]];
}
- case Variant::REAL: {
+ case Variant::FLOAT: {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") {
current_export.hint = PROPERTY_HINT_EXP_EASING;
@@ -4588,10 +4621,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
#undef _ADVANCE_AND_CONSUME_NEWLINES
}
- if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE) {
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC) {
current_export = PropertyInfo();
- _set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"sync\", \"remotesync\", \"mastersync\", \"puppetsync\".");
+ _set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"remotesync\", \"mastersync\", \"puppetsync\".");
return;
}
@@ -4648,11 +4681,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
continue;
} break;
- case GDScriptTokenizer::TK_PR_SLAVE:
-#ifdef DEBUG_ENABLED
- _add_warning(GDScriptWarning::DEPRECATED_KEYWORD, tokenizer->get_token_line(), "slave", "puppet");
-#endif
- FALLTHROUGH;
case GDScriptTokenizer::TK_PR_PUPPET: {
//may be fallthrough from export, ignore if so
@@ -4673,8 +4701,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET;
continue;
} break;
- case GDScriptTokenizer::TK_PR_REMOTESYNC:
- case GDScriptTokenizer::TK_PR_SYNC: {
+ case GDScriptTokenizer::TK_PR_REMOTESYNC: {
//may be fallthrough from export, ignore if so
tokenizer->advance();
@@ -4740,7 +4767,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
member.identifier = tokenizer->get_token_literal();
- member.expression = NULL;
+ member.expression = nullptr;
member._export.name = member.identifier;
member.line = tokenizer->get_token_line();
member.usages = 0;
@@ -4819,8 +4846,8 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
#ifdef TOOLS_ENABLED
- Variant::CallError ce;
- member.default_value = Variant::construct(member._export.type, NULL, 0, ce);
+ Callable::CallError ce;
+ member.default_value = Variant::construct(member._export.type, nullptr, 0, ce);
#endif
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
@@ -4873,7 +4900,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (cn->value.get_type() == Variant::OBJECT) {
Object *obj = cn->value;
Resource *res = Object::cast_to<Resource>(obj);
- if (res == NULL) {
+ if (res == nullptr) {
_set_error("The exported constant isn't a type or resource.");
return;
}
@@ -4888,7 +4915,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (cn->value.get_type() != Variant::NIL) {
if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) {
if (Variant::can_convert(cn->value.get_type(), member._export.type)) {
- Variant::CallError err;
+ Callable::CallError err;
const Variant *args = &cn->value;
cn->value = Variant::construct(member._export.type, &args, 1, err);
} else {
@@ -5237,6 +5264,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
} break;
+ case GDScriptTokenizer::TK_CF_PASS: {
+ tokenizer->advance();
+ } break;
+
default: {
_set_error(String() + "Unexpected token: " + tokenizer->get_token_name(tokenizer->get_token()) + ":" + tokenizer->get_token_identifier());
@@ -5257,7 +5288,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
Ref<GDScript> script;
StringName native;
- ClassNode *base_class = NULL;
+ ClassNode *base_class = nullptr;
if (path != "") {
//path (and optionally subclasses)
@@ -5319,7 +5350,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
_set_error("The class \"" + base + "\" couldn't be fully loaded (script error or cyclic dependency).", p_class->line);
return;
}
- p = NULL;
+ p = nullptr;
} else {
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
@@ -5342,7 +5373,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
_set_error("Class '" + base + "' could not be fully loaded (script error or cyclic inheritance).", p_class->line);
return;
}
- p = NULL;
+ p = nullptr;
}
}
}
@@ -5499,7 +5530,7 @@ String GDScriptParser::DataType::to_string() const {
if (!gds_class.empty()) {
return gds_class;
}
- FALLTHROUGH;
+ [[fallthrough]];
}
case SCRIPT: {
if (is_meta_type) {
@@ -5662,7 +5693,7 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
StringName id = full_name[name_part];
DataType base_type = result;
- ClassNode *p = NULL;
+ ClassNode *p = nullptr;
if (name_part == 0) {
if (ScriptServer::is_global_class(id)) {
String script_path = ScriptServer::get_global_class_path(id);
@@ -5943,9 +5974,9 @@ GDScriptParser::DataType GDScriptParser::_get_operation_type(const Variant::Oper
a_ref.instance();
a = a_ref;
} else {
- Variant::CallError err;
- a = Variant::construct(a_type, NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ a = Variant::construct(a_type, nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK) {
r_valid = false;
return DataType();
}
@@ -5956,19 +5987,19 @@ GDScriptParser::DataType GDScriptParser::_get_operation_type(const Variant::Oper
b_ref.instance();
b = b_ref;
} else {
- Variant::CallError err;
- b = Variant::construct(b_type, NULL, 0, err);
- if (err.error != Variant::CallError::CALL_OK) {
+ Callable::CallError err;
+ b = Variant::construct(b_type, nullptr, 0, err);
+ if (err.error != Callable::CallError::CALL_OK) {
r_valid = false;
return DataType();
}
}
// Avoid division by zero
- if (a_type == Variant::INT || a_type == Variant::REAL) {
+ if (a_type == Variant::INT || a_type == Variant::FLOAT) {
Variant::evaluate(Variant::OP_ADD, a, 1, a, r_valid);
}
- if (b_type == Variant::INT || b_type == Variant::REAL) {
+ if (b_type == Variant::INT || b_type == Variant::FLOAT) {
Variant::evaluate(Variant::OP_ADD, b, 1, b, r_valid);
}
if (a_type == Variant::STRING && b_type != Variant::ARRAY) {
@@ -6118,7 +6149,7 @@ bool GDScriptParser::_is_type_compatible(const DataType &p_container, const Data
StringName expr_native;
Ref<Script> expr_script;
- ClassNode *expr_class = NULL;
+ ClassNode *expr_class = nullptr;
switch (p_expression.kind) {
case DataType::NATIVE: {
@@ -6228,13 +6259,15 @@ GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType
result = alloc_node<DictionaryNode>();
} else {
ConstantNode *c = alloc_node<ConstantNode>();
- Variant::CallError err;
- c->value = Variant::construct(p_type.builtin_type, NULL, 0, err);
+ Callable::CallError err;
+ c->value = Variant::construct(p_type.builtin_type, nullptr, 0, err);
+ c->datatype = _type_from_variant(c->value);
result = c;
}
} else {
ConstantNode *c = alloc_node<ConstantNode>();
c->value = Variant();
+ c->datatype = _type_from_variant(c->value);
result = c;
}
@@ -6308,7 +6341,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
int idx = current_function->arguments.find(id->name);
node_type = current_function->argument_types[idx];
} else {
- node_type = _reduce_identifier_type(NULL, id->name, id->line, false);
+ node_type = _reduce_identifier_type(nullptr, id->name, id->line, false);
}
} break;
case Node::TYPE_CAST: {
@@ -6541,8 +6574,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
result.has_type = false;
} break;
default: {
- Variant::CallError err;
- Variant temp = Variant::construct(base_type.builtin_type, NULL, 0, err);
+ Callable::CallError err;
+ Variant temp = Variant::construct(base_type.builtin_type, nullptr, 0, err);
bool valid = false;
Variant res = temp.get(member_id->name.operator String(), &valid);
@@ -6563,6 +6596,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true);
#ifdef DEBUG_ENABLED
if (!node_type.has_type) {
+ _mark_line_as_unsafe(op->line);
_add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string());
}
#endif // DEBUG_ENABLED
@@ -6606,16 +6640,18 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
if (!error) {
switch (base_type.builtin_type) {
// Expect int or real as index
- case Variant::POOL_BYTE_ARRAY:
- case Variant::POOL_COLOR_ARRAY:
- case Variant::POOL_INT_ARRAY:
- case Variant::POOL_REAL_ARRAY:
- case Variant::POOL_STRING_ARRAY:
- case Variant::POOL_VECTOR2_ARRAY:
- case Variant::POOL_VECTOR3_ARRAY:
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_COLOR_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY:
case Variant::ARRAY:
case Variant::STRING: {
- error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::REAL;
+ error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT;
} break;
// Expect String only
case Variant::RECT2:
@@ -6631,7 +6667,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case Variant::TRANSFORM2D:
case Variant::BASIS:
case Variant::TRANSFORM: {
- error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::REAL &&
+ error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT &&
index_type.builtin_type != Variant::STRING;
} break;
// Expect String or int
@@ -6656,18 +6692,20 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case Variant::STRING:
case Variant::ARRAY:
case Variant::DICTIONARY:
- case Variant::POOL_BYTE_ARRAY:
- case Variant::POOL_COLOR_ARRAY:
- case Variant::POOL_INT_ARRAY:
- case Variant::POOL_REAL_ARRAY:
- case Variant::POOL_STRING_ARRAY:
- case Variant::POOL_VECTOR2_ARRAY:
- case Variant::POOL_VECTOR3_ARRAY: {
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_COLOR_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY: {
break;
}
default: {
- Variant::CallError err;
- Variant temp = Variant::construct(base_type.builtin_type, NULL, 0, err);
+ Callable::CallError err;
+ Variant temp = Variant::construct(base_type.builtin_type, nullptr, 0, err);
bool valid = false;
Variant res = temp.get(cn->value, &valid);
@@ -6701,41 +6739,43 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case Variant::NIL:
case Variant::BOOL:
case Variant::INT:
- case Variant::REAL:
+ case Variant::FLOAT:
case Variant::NODE_PATH:
case Variant::_RID: {
_set_error("Can't index on a value of type \"" + base_type.to_string() + "\".", op->line);
return DataType();
} break;
// Return int
- case Variant::POOL_BYTE_ARRAY:
- case Variant::POOL_INT_ARRAY: {
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY: {
result.builtin_type = Variant::INT;
} break;
// Return real
- case Variant::POOL_REAL_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
case Variant::VECTOR2:
case Variant::VECTOR3:
case Variant::QUAT: {
- result.builtin_type = Variant::REAL;
+ result.builtin_type = Variant::FLOAT;
} break;
// Return color
- case Variant::POOL_COLOR_ARRAY: {
+ case Variant::PACKED_COLOR_ARRAY: {
result.builtin_type = Variant::COLOR;
} break;
// Return string
- case Variant::POOL_STRING_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
case Variant::STRING: {
result.builtin_type = Variant::STRING;
} break;
// Return Vector2
- case Variant::POOL_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
case Variant::TRANSFORM2D:
case Variant::RECT2: {
result.builtin_type = Variant::VECTOR2;
} break;
// Return Vector3
- case Variant::POOL_VECTOR3_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY:
case Variant::AABB:
case Variant::BASIS: {
result.builtin_type = Variant::VECTOR3;
@@ -6772,8 +6812,8 @@ bool GDScriptParser::_get_function_signature(DataType &p_base_type, const String
r_default_arg_count = 0;
DataType original_type = p_base_type;
- ClassNode *base = NULL;
- FunctionNode *callee = NULL;
+ ClassNode *base = nullptr;
+ FunctionNode *callee = nullptr;
if (p_base_type.kind == DataType::CLASS) {
base = p_base_type.class_type;
@@ -7012,7 +7052,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
break;
} else {
#ifdef DEBUG_ENABLED
- if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_types[i].kind == DataType::BUILTIN && par_types[i].builtin_type == Variant::REAL) {
+ if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_types[i].kind == DataType::BUILTIN && par_types[i].builtin_type == Variant::FLOAT) {
_add_warning(GDScriptWarning::NARROWING_CONVERSION, p_call->line, Variant::get_type_name(tn->vtype));
}
if (par_types[i].may_yield && p_call->arguments[i + 1]->type == Node::TYPE_OPERATOR) {
@@ -7105,8 +7145,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
}
if (base_type.kind == DataType::BUILTIN) {
- Variant::CallError err;
- Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
+ Callable::CallError err;
+ Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err);
if (check_types) {
if (!tmp.has_method(callee_name)) {
@@ -7255,7 +7295,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
_mark_line_as_unsafe(p_call->line);
}
} else {
- if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_type.kind == DataType::BUILTIN && par_type.builtin_type == Variant::REAL) {
+ if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_type.kind == DataType::BUILTIN && par_type.builtin_type == Variant::FLOAT) {
_add_warning(GDScriptWarning::NARROWING_CONVERSION, p_call->line, callee_name);
}
}
@@ -7270,7 +7310,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
DataType base_type = p_base_type;
// Check classes in current file
- ClassNode *base = NULL;
+ ClassNode *base = nullptr;
if (base_type.kind == DataType::CLASS) {
base = base_type.class_type;
}
@@ -7359,6 +7399,8 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
}
}
+#define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)))
+
// Check other script types
while (scr.is_valid()) {
Map<StringName, Variant> constants;
@@ -7371,7 +7413,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
List<PropertyInfo> properties;
scr->get_script_property_list(&properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_member) {
+ if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
r_member_type = _type_from_property(E->get());
return true;
}
@@ -7413,7 +7455,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
List<PropertyInfo> properties;
ClassDB::get_property_list(native, &properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_member) {
+ if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
// Check if a getter exists
StringName getter_name = ClassDB::get_property_getter(native, p_member);
if (getter_name != StringName()) {
@@ -7453,7 +7495,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
List<PropertyInfo> properties;
ClassDB::get_property_list(native, &properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_member) {
+ if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
// Check if a getter exists
StringName getter_name = ClassDB::get_property_getter(native, p_member);
if (getter_name != StringName()) {
@@ -7475,6 +7517,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
}
}
}
+#undef IS_USAGE_MEMBER
return false;
}
@@ -7988,8 +8031,8 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
current_block = current_function->body;
_mark_line_as_safe(current_function->line);
_check_block_types(current_block);
- current_block = NULL;
- current_function = NULL;
+ current_block = nullptr;
+ current_function = nullptr;
if (error_set) return;
}
@@ -7998,8 +8041,8 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
current_block = current_function->body;
_mark_line_as_safe(current_function->line);
_check_block_types(current_block);
- current_block = NULL;
- current_function = NULL;
+ current_block = nullptr;
+ current_function = nullptr;
if (error_set) return;
}
@@ -8048,7 +8091,7 @@ static String _find_function_name(const GDScriptParser::OperatorNode *p_call) {
void GDScriptParser::_check_block_types(BlockNode *p_block) {
- Node *last_var_assign = NULL;
+ Node *last_var_assign = nullptr;
// Check each statement
for (List<Node *>::Element *E = p_block->statements.front(); E; E = E->next()) {
@@ -8102,6 +8145,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
ConstantNode *tgt_type = alloc_node<ConstantNode>();
tgt_type->line = lv->line;
tgt_type->value = (int)lv->datatype.builtin_type;
+ tgt_type->datatype = _type_from_variant(tgt_type->value);
OperatorNode *convert_call = alloc_node<OperatorNode>();
convert_call->line = lv->line;
@@ -8113,7 +8157,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
lv->assign = convert_call;
lv->assign_op->arguments.write[1] = convert_call;
#ifdef DEBUG_ENABLED
- if (lv->datatype.builtin_type == Variant::INT && assign_type.builtin_type == Variant::REAL) {
+ if (lv->datatype.builtin_type == Variant::INT && assign_type.builtin_type == Variant::FLOAT) {
_add_warning(GDScriptWarning::NARROWING_CONVERSION, lv->line);
}
#endif // DEBUG_ENABLED
@@ -8237,6 +8281,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
ConstantNode *tgt_type = alloc_node<ConstantNode>();
tgt_type->line = op->line;
tgt_type->value = (int)lh_type.builtin_type;
+ tgt_type->datatype = _type_from_variant(tgt_type->value);
OperatorNode *convert_call = alloc_node<OperatorNode>();
convert_call->line = op->line;
@@ -8250,7 +8295,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
type_match = true; // Since we are converting, the type is matching
}
#ifdef DEBUG_ENABLED
- if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::REAL) {
+ if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::FLOAT) {
_add_warning(GDScriptWarning::NARROWING_CONVERSION, op->line);
}
#endif // DEBUG_ENABLED
@@ -8355,7 +8400,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
if (cn->value.get_type() == Variant::STRING) {
break;
}
- FALLTHROUGH;
+ [[fallthrough]];
}
default: {
_mark_line_as_safe(statement->line);
@@ -8439,7 +8484,7 @@ void GDScriptParser::_add_warning(int p_code, int p_line, const Vector<String> &
warn.symbols = p_symbols;
warn.line = p_line == -1 ? tokenizer->get_token_line() : p_line;
- List<GDScriptWarning>::Element *before = NULL;
+ List<GDScriptWarning>::Element *before = nullptr;
for (List<GDScriptWarning>::Element *E = warnings.front(); E; E = E->next()) {
if (E->get().line > warn.line) {
break;
@@ -8506,8 +8551,8 @@ Error GDScriptParser::_parse(const String &p_base_path) {
}
current_class = main_class;
- current_function = NULL;
- current_block = NULL;
+ current_function = nullptr;
+ current_block = nullptr;
if (for_completion) check_types = false;
@@ -8528,7 +8573,7 @@ Error GDScriptParser::_parse(const String &p_base_path) {
#ifdef DEBUG_ENABLED
// Resolve warning ignores
- Vector<Pair<int, String> > warning_skips = tokenizer->get_warning_skips();
+ Vector<Pair<int, String>> warning_skips = tokenizer->get_warning_skips();
bool warning_is_error = GLOBAL_GET("debug/gdscript/warnings/treat_warnings_as_errors").booleanize();
for (List<GDScriptWarning>::Element *E = warnings.front(); E;) {
GDScriptWarning &w = E->get();
@@ -8570,7 +8615,7 @@ Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const St
tokenizer = tb;
Error ret = _parse(p_base_path);
memdelete(tb);
- tokenizer = NULL;
+ tokenizer = nullptr;
return ret;
}
@@ -8591,7 +8636,7 @@ Error GDScriptParser::parse(const String &p_code, const String &p_base_path, boo
tokenizer = tt;
Error ret = _parse(p_base_path);
memdelete(tt);
- tokenizer = NULL;
+ tokenizer = nullptr;
return ret;
}
@@ -8614,21 +8659,21 @@ void GDScriptParser::clear() {
memdelete(l);
}
- head = NULL;
- list = NULL;
+ head = nullptr;
+ list = nullptr;
completion_type = COMPLETION_NONE;
- completion_node = NULL;
- completion_class = NULL;
- completion_function = NULL;
- completion_block = NULL;
- current_block = NULL;
- current_class = NULL;
+ completion_node = nullptr;
+ completion_class = nullptr;
+ completion_function = nullptr;
+ completion_block = nullptr;
+ current_block = nullptr;
+ current_class = nullptr;
completion_found = false;
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
- current_function = NULL;
+ current_function = nullptr;
validating = false;
for_completion = false;
@@ -8645,7 +8690,7 @@ void GDScriptParser::clear() {
dependencies.clear();
error = "";
#ifdef DEBUG_ENABLED
- safe_lines = NULL;
+ safe_lines = nullptr;
#endif // DEBUG_ENABLED
}
@@ -8701,9 +8746,9 @@ int GDScriptParser::get_completion_identifier_is_function() {
GDScriptParser::GDScriptParser() {
- head = NULL;
- list = NULL;
- tokenizer = NULL;
+ head = nullptr;
+ list = nullptr;
+ tokenizer = nullptr;
pending_newline = -1;
clear();
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index c74d7dd856..eca5f83f7a 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -102,7 +102,7 @@ public:
infer_type(false),
may_yield(false),
builtin_type(Variant::NIL),
- class_type(NULL) {}
+ class_type(nullptr) {}
};
struct Node {
@@ -201,7 +201,7 @@ public:
extends_used = false;
classname_used = false;
end_line = -1;
- owner = NULL;
+ owner = nullptr;
}
};
@@ -248,11 +248,11 @@ public:
List<BlockNode *> sub_blocks;
int end_line;
BlockNode() {
- if_condition = NULL;
+ if_condition = nullptr;
type = TYPE_BLOCK;
end_line = -1;
- parent_block = NULL;
- parent_class = NULL;
+ parent_block = nullptr;
+ parent_class = nullptr;
has_return = false;
}
};
@@ -276,7 +276,7 @@ public:
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
IdentifierNode() {
type = TYPE_IDENTIFIER;
- declared_block = NULL;
+ declared_block = nullptr;
}
};
@@ -292,8 +292,8 @@ public:
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
LocalVarNode() {
type = TYPE_LOCAL_VAR;
- assign = NULL;
- assign_op = NULL;
+ assign = nullptr;
+ assign_op = nullptr;
assignments = 0;
usages = 0;
}
@@ -465,8 +465,8 @@ public:
ControlFlowNode() {
type = TYPE_CONTROL_FLOW;
cf_type = CF_IF;
- body = NULL;
- body_else = NULL;
+ body = nullptr;
+ body_else = nullptr;
}
};
@@ -608,7 +608,7 @@ private:
bool _recover_from_completion();
bool _parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete = false, bool p_parsing_constant = false);
- bool _enter_indent_block(BlockNode *p_block = NULL);
+ bool _enter_indent_block(BlockNode *p_block = nullptr);
bool _parse_newline();
Node *_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign = false, bool p_parsing_constant = false);
Node *_reduce_expression(Node *p_node, bool p_to_const = false);
@@ -665,7 +665,7 @@ public:
#ifdef DEBUG_ENABLED
const List<GDScriptWarning> &get_warnings() const { return warnings; }
#endif // DEBUG_ENABLED
- Error parse(const String &p_code, const String &p_base_path = "", bool p_just_validate = false, const String &p_self_path = "", bool p_for_completion = false, Set<int> *r_safe_lines = NULL, bool p_dependencies_only = false);
+ Error parse(const String &p_code, const String &p_base_path = "", bool p_just_validate = false, const String &p_self_path = "", bool p_for_completion = false, Set<int> *r_safe_lines = nullptr, bool p_dependencies_only = false);
Error parse_bytecode(const Vector<uint8_t> &p_bytecode, const String &p_base_path = "", const String &p_self_path = "");
bool is_tool_script() const;
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 11ffa22906..d42ca52731 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -106,11 +106,9 @@ const char *GDScriptTokenizer::token_names[TK_MAX] = {
"yield",
"signal",
"breakpoint",
- "rpc",
- "sync",
+ "remote",
"master",
"puppet",
- "slave",
"remotesync",
"mastersync",
"puppetsync",
@@ -148,12 +146,15 @@ static const _bit _type_list[] = {
//types
{ Variant::BOOL, "bool" },
{ Variant::INT, "int" },
- { Variant::REAL, "float" },
+ { Variant::FLOAT, "float" },
{ Variant::STRING, "String" },
{ Variant::VECTOR2, "Vector2" },
+ { Variant::VECTOR2I, "Vector2i" },
{ Variant::RECT2, "Rect2" },
+ { Variant::RECT2I, "Rect2i" },
{ Variant::TRANSFORM2D, "Transform2D" },
{ Variant::VECTOR3, "Vector3" },
+ { Variant::VECTOR3I, "Vector3i" },
{ Variant::AABB, "AABB" },
{ Variant::PLANE, "Plane" },
{ Variant::QUAT, "Quat" },
@@ -162,17 +163,22 @@ static const _bit _type_list[] = {
{ Variant::COLOR, "Color" },
{ Variant::_RID, "RID" },
{ Variant::OBJECT, "Object" },
+ { Variant::STRING_NAME, "StringName" },
{ Variant::NODE_PATH, "NodePath" },
{ Variant::DICTIONARY, "Dictionary" },
+ { Variant::CALLABLE, "Callable" },
+ { Variant::SIGNAL, "Signal" },
{ Variant::ARRAY, "Array" },
- { Variant::POOL_BYTE_ARRAY, "PoolByteArray" },
- { Variant::POOL_INT_ARRAY, "PoolIntArray" },
- { Variant::POOL_REAL_ARRAY, "PoolRealArray" },
- { Variant::POOL_STRING_ARRAY, "PoolStringArray" },
- { Variant::POOL_VECTOR2_ARRAY, "PoolVector2Array" },
- { Variant::POOL_VECTOR3_ARRAY, "PoolVector3Array" },
- { Variant::POOL_COLOR_ARRAY, "PoolColorArray" },
- { Variant::VARIANT_MAX, NULL },
+ { Variant::PACKED_BYTE_ARRAY, "PackedByteArray" },
+ { Variant::PACKED_INT32_ARRAY, "PackedInt32Array" },
+ { Variant::PACKED_INT64_ARRAY, "PackedInt64Array" },
+ { Variant::PACKED_FLOAT32_ARRAY, "PackedFloat32Array" },
+ { Variant::PACKED_FLOAT64_ARRAY, "PackedFloat64Array" },
+ { Variant::PACKED_STRING_ARRAY, "PackedStringArray" },
+ { Variant::PACKED_VECTOR2_ARRAY, "PackedVector2Array" },
+ { Variant::PACKED_VECTOR3_ARRAY, "PackedVector3Array" },
+ { Variant::PACKED_COLOR_ARRAY, "PackedColorArray" },
+ { Variant::VARIANT_MAX, nullptr },
};
struct _kws {
@@ -207,9 +213,7 @@ static const _kws _keyword_list[] = {
{ GDScriptTokenizer::TK_PR_BREAKPOINT, "breakpoint" },
{ GDScriptTokenizer::TK_PR_REMOTE, "remote" },
{ GDScriptTokenizer::TK_PR_MASTER, "master" },
- { GDScriptTokenizer::TK_PR_SLAVE, "slave" },
{ GDScriptTokenizer::TK_PR_PUPPET, "puppet" },
- { GDScriptTokenizer::TK_PR_SYNC, "sync" },
{ GDScriptTokenizer::TK_PR_REMOTESYNC, "remotesync" },
{ GDScriptTokenizer::TK_PR_MASTERSYNC, "mastersync" },
{ GDScriptTokenizer::TK_PR_PUPPETSYNC, "puppetsync" },
@@ -232,7 +236,7 @@ static const _kws _keyword_list[] = {
{ GDScriptTokenizer::TK_WILDCARD, "_" },
{ GDScriptTokenizer::TK_CONST_INF, "INF" },
{ GDScriptTokenizer::TK_CONST_NAN, "NAN" },
- { GDScriptTokenizer::TK_ERROR, NULL }
+ { GDScriptTokenizer::TK_ERROR, nullptr }
};
const char *GDScriptTokenizer::get_token_name(Token p_token) {
@@ -255,7 +259,6 @@ bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const
case TK_PR_REMOTE:
case TK_PR_MASTER:
case TK_PR_PUPPET:
- case TK_PR_SYNC:
case TK_PR_REMOTESYNC:
case TK_PR_MASTERSYNC:
case TK_PR_PUPPETSYNC:
@@ -342,7 +345,7 @@ StringName GDScriptTokenizer::get_token_literal(int p_offset) const {
default: {
}
}
- }
+ } break;
case TK_OP_AND:
case TK_OP_OR:
break; // Don't get into default, since they can be non-literal
@@ -480,7 +483,7 @@ void GDScriptTokenizerText::_advance() {
}
while (true) {
- bool is_node_path = false;
+ bool is_string_name = false;
StringMode string_mode = STRING_DOUBLE_QUOTE;
switch (GETCHAR(0)) {
@@ -538,7 +541,7 @@ void GDScriptTokenizerText::_advance() {
ignore_warnings = true;
}
#endif // DEBUG_ENABLED
- FALLTHROUGH;
+ [[fallthrough]];
}
case '\n': {
line++;
@@ -754,8 +757,8 @@ void GDScriptTokenizerText::_advance() {
return;
}
INCPOS(1);
- is_node_path = true;
- FALLTHROUGH;
+ is_string_name = true;
+ [[fallthrough]];
case '\'':
case '"': {
@@ -815,7 +818,7 @@ void GDScriptTokenizerText::_advance() {
break; //wtf
case 'u': {
- //hexnumbarh - oct is deprecated
+ // hex number
i += 1;
for (int j = 0; j < 4; j++) {
CharType c = GETCHAR(i + j);
@@ -865,8 +868,8 @@ void GDScriptTokenizerText::_advance() {
}
INCPOS(i);
- if (is_node_path) {
- _make_constant(NodePath(str));
+ if (is_string_name) {
+ _make_constant(StringName(str));
} else {
_make_constant(str);
}
@@ -1072,7 +1075,7 @@ void GDScriptTokenizerText::set_code(const String &p_code) {
if (len) {
_code = &code[0];
} else {
- _code = NULL;
+ _code = nullptr;
}
code_pos = 0;
line = 1; //it is stand-ar-ized that lines begin in 1 in code..
@@ -1355,7 +1358,7 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
}
Map<int, Variant> rev_constant_map;
- const Variant *K = NULL;
+ const Variant *K = nullptr;
while ((K = constant_map.next(K))) {
rev_constant_map[constant_map[*K]] = *K;
}
@@ -1404,7 +1407,7 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
int len;
// Objects cannot be constant, never encode objects
- Error err = encode_variant(E->get(), NULL, len, false);
+ Error err = encode_variant(E->get(), nullptr, len, false);
ERR_FAIL_COND_V_MSG(err != OK, Vector<uint8_t>(), "Error when trying to encode Variant.");
int pos = buf.size();
buf.resize(pos + len);
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 0efc8551cb..180ec3c77e 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -32,6 +32,7 @@
#define GDSCRIPT_TOKENIZER_H
#include "core/pair.h"
+#include "core/set.h"
#include "core/string_name.h"
#include "core/ustring.h"
#include "core/variant.h"
@@ -113,9 +114,7 @@ public:
TK_PR_SIGNAL,
TK_PR_BREAKPOINT,
TK_PR_REMOTE,
- TK_PR_SYNC,
TK_PR_MASTER,
- TK_PR_SLAVE, // Deprecated by TK_PR_PUPPET, to remove in 4.0
TK_PR_PUPPET,
TK_PR_REMOTESYNC,
TK_PR_MASTERSYNC,
@@ -172,7 +171,7 @@ public:
virtual String get_token_error(int p_offset = 0) const = 0;
virtual void advance(int p_amount = 1) = 0;
#ifdef DEBUG_ENABLED
- virtual const Vector<Pair<int, String> > &get_warning_skips() const = 0;
+ virtual const Vector<Pair<int, String>> &get_warning_skips() const = 0;
virtual const Set<String> &get_warning_global_skips() const = 0;
virtual bool is_ignoring_warnings() const = 0;
#endif // DEBUG_ENABLED
@@ -225,7 +224,7 @@ class GDScriptTokenizerText : public GDScriptTokenizer {
bool error_flag;
#ifdef DEBUG_ENABLED
- Vector<Pair<int, String> > warning_skips;
+ Vector<Pair<int, String>> warning_skips;
Set<String> warning_global_skips;
bool ignore_warnings;
#endif // DEBUG_ENABLED
@@ -246,7 +245,7 @@ public:
virtual String get_token_error(int p_offset = 0) const;
virtual void advance(int p_amount = 1);
#ifdef DEBUG_ENABLED
- virtual const Vector<Pair<int, String> > &get_warning_skips() const { return warning_skips; }
+ virtual const Vector<Pair<int, String>> &get_warning_skips() const { return warning_skips; }
virtual const Set<String> &get_warning_global_skips() const { return warning_global_skips; }
virtual bool is_ignoring_warnings() const { return ignore_warnings; }
#endif // DEBUG_ENABLED
@@ -285,8 +284,8 @@ public:
virtual String get_token_error(int p_offset = 0) const;
virtual void advance(int p_amount = 1);
#ifdef DEBUG_ENABLED
- virtual const Vector<Pair<int, String> > &get_warning_skips() const {
- static Vector<Pair<int, String> > v;
+ virtual const Vector<Pair<int, String>> &get_warning_skips() const {
+ static Vector<Pair<int, String>> v;
return v;
}
virtual const Set<String> &get_warning_global_skips() const {
diff --git a/modules/gdscript/icons/icon_g_d_script.svg b/modules/gdscript/icons/GDScript.svg
index 953bb9ae9e..953bb9ae9e 100644
--- a/modules/gdscript/icons/icon_g_d_script.svg
+++ b/modules/gdscript/icons/GDScript.svg
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index 0f6f13944b..b2c6b0e1ab 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -327,7 +327,7 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN
int default_value_idx = i - (p_func->arguments.size() - p_func->default_values.size());
if (default_value_idx >= 0) {
const GDScriptParser::ConstantNode *const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(p_func->default_values[default_value_idx]);
- if (const_node == NULL) {
+ if (const_node == nullptr) {
const GDScriptParser::OperatorNode *operator_node = dynamic_cast<const GDScriptParser::OperatorNode *>(p_func->default_values[default_value_idx]);
if (operator_node) {
const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(operator_node->next);
@@ -507,7 +507,7 @@ String ExtendGDScriptParser::get_uri() const {
}
const lsp::DocumentSymbol *ExtendGDScriptParser::search_symbol_defined_at_line(int p_line, const lsp::DocumentSymbol &p_parent) const {
- const lsp::DocumentSymbol *ret = NULL;
+ const lsp::DocumentSymbol *ret = nullptr;
if (p_line < p_parent.range.start.line) {
return ret;
} else if (p_parent.range.start.line == p_line) {
@@ -591,7 +591,7 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String
}
}
- return NULL;
+ return nullptr;
}
const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const {
@@ -602,7 +602,7 @@ const Array &ExtendGDScriptParser::get_member_completions() {
if (member_completions.empty()) {
- const String *name = members.next(NULL);
+ const String *name = members.next(nullptr);
while (name) {
const lsp::DocumentSymbol *symbol = members.get(*name);
@@ -613,11 +613,11 @@ const Array &ExtendGDScriptParser::get_member_completions() {
name = members.next(name);
}
- const String *_class = inner_classes.next(NULL);
+ const String *_class = inner_classes.next(nullptr);
while (_class) {
const ClassMembers *inner_class = inner_classes.getptr(*_class);
- const String *member_name = inner_class->next(NULL);
+ const String *member_name = inner_class->next(nullptr);
while (member_name) {
const lsp::DocumentSymbol *symbol = inner_class->get(*member_name);
lsp::CompletionItem item = symbol->make_completion_item();
@@ -648,7 +648,7 @@ Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::Functio
int default_value_idx = i - (p_func->arguments.size() - p_func->default_values.size());
if (default_value_idx >= 0) {
const GDScriptParser::ConstantNode *const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(p_func->default_values[default_value_idx]);
- if (const_node == NULL) {
+ if (const_node == nullptr) {
const GDScriptParser::OperatorNode *operator_node = dynamic_cast<const GDScriptParser::OperatorNode *>(p_func->default_values[default_value_idx]);
if (operator_node) {
const_node = dynamic_cast<const GDScriptParser::ConstantNode *>(operator_node->next);
@@ -778,7 +778,7 @@ Error ExtendGDScriptParser::parse(const String &p_code, const String &p_path) {
path = p_path;
lines = p_code.split("\n");
- Error err = GDScriptParser::parse(p_code, p_path.get_base_dir(), false, p_path, false, NULL, false);
+ Error err = GDScriptParser::parse(p_code, p_path.get_base_dir(), false, p_path, false, nullptr, false);
update_diagnostics();
update_symbols();
update_document_links(p_code);
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp
index 7133c6b4be..69662e96f7 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.cpp
+++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp
@@ -32,32 +32,107 @@
#include "core/io/json.h"
#include "core/os/copymem.h"
#include "core/project_settings.h"
+#include "editor/editor_log.h"
#include "editor/editor_node.h"
-GDScriptLanguageProtocol *GDScriptLanguageProtocol::singleton = NULL;
-
-void GDScriptLanguageProtocol::on_data_received(int p_id) {
- lastest_client_id = p_id;
- Ref<WebSocketPeer> peer = server->get_peer(p_id);
- PoolByteArray data;
- if (OK == peer->get_packet_buffer(data)) {
- String message;
- message.parse_utf8((const char *)data.read().ptr(), data.size());
- if (message.begins_with("Content-Length:")) return;
- String output = process_message(message);
+GDScriptLanguageProtocol *GDScriptLanguageProtocol::singleton = nullptr;
+
+Error GDScriptLanguageProtocol::LSPeer::handle_data() {
+ int read = 0;
+ // Read headers
+ if (!has_header) {
+ while (true) {
+ if (req_pos >= LSP_MAX_BUFFER_SIZE) {
+ req_pos = 0;
+ ERR_FAIL_COND_V_MSG(true, ERR_OUT_OF_MEMORY, "Response header too big");
+ }
+ Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
+ if (err != OK)
+ return FAILED;
+ else if (read != 1) // Busy, wait until next poll
+ return ERR_BUSY;
+ char *r = (char *)req_buf;
+ int l = req_pos;
+
+ // End of headers
+ if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
+ r[l - 3] = '\0'; // Null terminate to read string
+ String header;
+ header.parse_utf8(r);
+ content_length = header.substr(16).to_int();
+ has_header = true;
+ req_pos = 0;
+ break;
+ }
+ req_pos++;
+ }
+ }
+ if (has_header) {
+ while (req_pos < content_length) {
+ if (req_pos >= LSP_MAX_BUFFER_SIZE) {
+ req_pos = 0;
+ has_header = false;
+ ERR_FAIL_COND_V_MSG(req_pos >= LSP_MAX_BUFFER_SIZE, ERR_OUT_OF_MEMORY, "Response content too big");
+ }
+ Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
+ if (err != OK)
+ return FAILED;
+ else if (read != 1)
+ return ERR_BUSY;
+ req_pos++;
+ }
+
+ // Parse data
+ String msg;
+ msg.parse_utf8((const char *)req_buf, req_pos);
+
+ // Reset to read again
+ req_pos = 0;
+ has_header = false;
+
+ // Response
+ String output = GDScriptLanguageProtocol::get_singleton()->process_message(msg);
if (!output.empty()) {
- CharString charstr = output.utf8();
- peer->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
+ res_queue.push_back(output.utf8());
}
}
+ return OK;
}
-void GDScriptLanguageProtocol::on_client_connected(int p_id, const String &p_protocal) {
- clients.set(p_id, server->get_peer(p_id));
+Error GDScriptLanguageProtocol::LSPeer::send_data() {
+ int sent = 0;
+ if (!res_queue.empty()) {
+ CharString c_res = res_queue[0];
+ if (res_sent < c_res.size()) {
+ Error err = connection->put_partial_data((const uint8_t *)c_res.get_data() + res_sent, c_res.size() - res_sent - 1, sent);
+ if (err != OK) {
+ return err;
+ }
+ res_sent += sent;
+ }
+ // Response sent
+ if (res_sent >= c_res.size() - 1) {
+ res_sent = 0;
+ res_queue.remove(0);
+ }
+ }
+ return OK;
+}
+
+Error GDScriptLanguageProtocol::on_client_connected() {
+ Ref<StreamPeerTCP> tcp_peer = server->take_connection();
+ ERR_FAIL_COND_V_MSG(clients.size() >= LSP_MAX_CLIENTS, FAILED, "Max client limits reached");
+ Ref<LSPeer> peer = memnew(LSPeer);
+ peer->connection = tcp_peer;
+ clients.set(next_client_id, peer);
+ next_client_id++;
+ EditorNode::get_log()->add_message("Connection Taken", EditorLog::MSG_TYPE_EDITOR);
+ return OK;
}
-void GDScriptLanguageProtocol::on_client_disconnected(int p_id, bool p_was_clean_close) {
- clients.erase(p_id);
+void GDScriptLanguageProtocol::on_client_disconnected(const int &p_client_id) {
+ clients.erase(p_client_id);
+ EditorNode::get_log()->add_message("Disconnected", EditorLog::MSG_TYPE_EDITOR);
}
String GDScriptLanguageProtocol::process_message(const String &p_text) {
@@ -83,11 +158,9 @@ String GDScriptLanguageProtocol::format_output(const String &p_text) {
void GDScriptLanguageProtocol::_bind_methods() {
ClassDB::bind_method(D_METHOD("initialize", "params"), &GDScriptLanguageProtocol::initialize);
ClassDB::bind_method(D_METHOD("initialized", "params"), &GDScriptLanguageProtocol::initialized);
- ClassDB::bind_method(D_METHOD("on_data_received"), &GDScriptLanguageProtocol::on_data_received);
ClassDB::bind_method(D_METHOD("on_client_connected"), &GDScriptLanguageProtocol::on_client_connected);
ClassDB::bind_method(D_METHOD("on_client_disconnected"), &GDScriptLanguageProtocol::on_client_disconnected);
- ClassDB::bind_method(D_METHOD("notify_all_clients", "p_method", "p_params"), &GDScriptLanguageProtocol::notify_all_clients, DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("notify_client", "p_method", "p_params", "p_client"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("notify_client", "p_method", "p_params"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("is_smart_resolve_enabled"), &GDScriptLanguageProtocol::is_smart_resolve_enabled);
ClassDB::bind_method(D_METHOD("get_text_document"), &GDScriptLanguageProtocol::get_text_document);
ClassDB::bind_method(D_METHOD("get_workspace"), &GDScriptLanguageProtocol::get_workspace);
@@ -116,11 +189,12 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
Dictionary params;
params["path"] = workspace->root;
Dictionary request = make_notification("gdscrip_client/changeWorkspace", params);
- if (Ref<WebSocketPeer> *peer = clients.getptr(lastest_client_id)) {
+
+ Ref<LSPeer> peer = clients.get(latest_client_id);
+ if (peer != nullptr) {
String msg = JSON::print(request);
msg = format_output(msg);
- CharString charstr = msg.utf8();
- (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
+ (*peer)->res_queue.push_back(msg.utf8());
}
}
@@ -153,61 +227,59 @@ void GDScriptLanguageProtocol::initialized(const Variant &p_params) {
}
void GDScriptLanguageProtocol::poll() {
- server->poll();
+ if (server->is_connection_available()) {
+ on_client_connected();
+ }
+ const int *id = nullptr;
+ while ((id = clients.next(id))) {
+ Ref<LSPeer> peer = clients.get(*id);
+ StreamPeerTCP::Status status = peer->connection->get_status();
+ if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) {
+ on_client_disconnected(*id);
+ id = nullptr;
+ } else {
+ if (peer->connection->get_available_bytes() > 0) {
+ latest_client_id = *id;
+ Error err = peer->handle_data();
+ if (err != OK && err != ERR_BUSY) {
+ on_client_disconnected(*id);
+ id = nullptr;
+ }
+ }
+ Error err = peer->send_data();
+ if (err != OK && err != ERR_BUSY) {
+ on_client_disconnected(*id);
+ id = nullptr;
+ }
+ }
+ }
}
Error GDScriptLanguageProtocol::start(int p_port, const IP_Address &p_bind_ip) {
- if (server == NULL) {
- server = dynamic_cast<WebSocketServer *>(ClassDB::instance("WebSocketServer"));
- ERR_FAIL_COND_V(!server, FAILED);
- server->set_buffers(8192, 1024, 8192, 1024); // 8mb should be way more than enough
- server->connect("data_received", this, "on_data_received");
- server->connect("client_connected", this, "on_client_connected");
- server->connect("client_disconnected", this, "on_client_disconnected");
- }
- server->set_bind_ip(p_bind_ip);
- return server->listen(p_port);
+ return server->listen(p_port, p_bind_ip);
}
void GDScriptLanguageProtocol::stop() {
- const int *ptr = clients.next(NULL);
- while (ptr) {
- clients.get(*ptr)->close();
- ptr = clients.next(ptr);
+ const int *id = nullptr;
+ while ((id = clients.next(id))) {
+ Ref<LSPeer> peer = clients.get(*id);
+ peer->connection->disconnect_from_host();
}
- server->stop();
- clients.clear();
-}
-
-void GDScriptLanguageProtocol::notify_all_clients(const String &p_method, const Variant &p_params) {
- Dictionary message = make_notification(p_method, p_params);
- String msg = JSON::print(message);
- msg = format_output(msg);
- CharString charstr = msg.utf8();
- const int *p_id = clients.next(NULL);
- while (p_id != NULL) {
- Ref<WebSocketPeer> peer = clients.get(*p_id);
- (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
- p_id = clients.next(p_id);
- }
+ server->stop();
}
-void GDScriptLanguageProtocol::notify_client(const String &p_method, const Variant &p_params, int p_client) {
-
- if (p_client == -1) {
- p_client = lastest_client_id;
+void GDScriptLanguageProtocol::notify_client(const String &p_method, const Variant &p_params, int p_client_id) {
+ if (p_client_id == -1) {
+ p_client_id = latest_client_id;
}
-
- Ref<WebSocketPeer> *peer = clients.getptr(p_client);
- ERR_FAIL_COND(peer == NULL);
+ Ref<LSPeer> peer = clients.get(p_client_id);
+ ERR_FAIL_COND(peer == nullptr);
Dictionary message = make_notification(p_method, p_params);
String msg = JSON::print(message);
msg = format_output(msg);
- CharString charstr = msg.utf8();
-
- (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length());
+ peer->res_queue.push_back(msg.utf8());
}
bool GDScriptLanguageProtocol::is_smart_resolve_enabled() const {
@@ -219,7 +291,7 @@ bool GDScriptLanguageProtocol::is_goto_native_symbols_enabled() const {
}
GDScriptLanguageProtocol::GDScriptLanguageProtocol() {
- server = NULL;
+ server.instance();
singleton = this;
_initialized = false;
workspace.instance();
@@ -228,9 +300,6 @@ GDScriptLanguageProtocol::GDScriptLanguageProtocol() {
set_scope("completionItem", text_document.ptr());
set_scope("workspace", workspace.ptr());
workspace->root = ProjectSettings::get_singleton()->get_resource_path();
-}
-
-GDScriptLanguageProtocol::~GDScriptLanguageProtocol() {
- memdelete(server);
- server = NULL;
+ latest_client_id = 0;
+ next_client_id = 0;
}
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h
index 52c680ab19..d929fd255d 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.h
+++ b/modules/gdscript/language_server/gdscript_language_protocol.h
@@ -31,16 +31,36 @@
#ifndef GDSCRIPT_PROTOCAL_SERVER_H
#define GDSCRIPT_PROTOCAL_SERVER_H
+#include "core/io/stream_peer.h"
+#include "core/io/stream_peer_tcp.h"
+#include "core/io/tcp_server.h"
#include "gdscript_text_document.h"
#include "gdscript_workspace.h"
#include "lsp.hpp"
#include "modules/jsonrpc/jsonrpc.h"
-#include "modules/websocket/websocket_peer.h"
-#include "modules/websocket/websocket_server.h"
+
+#define LSP_MAX_BUFFER_SIZE 4194304
+#define LSP_MAX_CLIENTS 8
class GDScriptLanguageProtocol : public JSONRPC {
GDCLASS(GDScriptLanguageProtocol, JSONRPC)
+private:
+ struct LSPeer : Reference {
+ Ref<StreamPeerTCP> connection;
+
+ uint8_t req_buf[LSP_MAX_BUFFER_SIZE];
+ int req_pos = 0;
+ bool has_header = false;
+ bool has_content = false;
+ int content_length = 0;
+ Vector<CharString> res_queue;
+ int res_sent = 0;
+
+ Error handle_data();
+ Error send_data();
+ };
+
enum LSPErrorCode {
RequestCancelled = -32800,
ContentModified = -32801,
@@ -48,16 +68,16 @@ class GDScriptLanguageProtocol : public JSONRPC {
static GDScriptLanguageProtocol *singleton;
- HashMap<int, Ref<WebSocketPeer> > clients;
- WebSocketServer *server;
- int lastest_client_id;
+ HashMap<int, Ref<LSPeer>> clients;
+ Ref<TCP_Server> server;
+ int latest_client_id;
+ int next_client_id;
Ref<GDScriptTextDocument> text_document;
Ref<GDScriptWorkspace> workspace;
- void on_data_received(int p_id);
- void on_client_connected(int p_id, const String &p_protocal);
- void on_client_disconnected(int p_id, bool p_was_clean_close);
+ Error on_client_connected();
+ void on_client_disconnected(const int &p_client_id);
String process_message(const String &p_text);
String format_output(const String &p_text);
@@ -80,14 +100,12 @@ public:
Error start(int p_port, const IP_Address &p_bind_ip);
void stop();
- void notify_all_clients(const String &p_method, const Variant &p_params = Variant());
- void notify_client(const String &p_method, const Variant &p_params = Variant(), int p_client = -1);
+ void notify_client(const String &p_method, const Variant &p_params = Variant(), int p_client_id = -1);
bool is_smart_resolve_enabled() const;
bool is_goto_native_symbols_enabled() const;
GDScriptLanguageProtocol();
- ~GDScriptLanguageProtocol();
};
#endif
diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp
index 7170c63058..e1d86ecdd4 100644
--- a/modules/gdscript/language_server/gdscript_language_server.cpp
+++ b/modules/gdscript/language_server/gdscript_language_server.cpp
@@ -35,7 +35,7 @@
#include "editor/editor_node.h"
GDScriptLanguageServer::GDScriptLanguageServer() {
- thread = NULL;
+ thread = nullptr;
thread_running = false;
started = false;
@@ -87,7 +87,7 @@ void GDScriptLanguageServer::start() {
if (protocol.start(port, IP_Address("127.0.0.1")) == OK) {
EditorNode::get_log()->add_message("--- GDScript language server started ---", EditorLog::MSG_TYPE_EDITOR);
if (use_thread) {
- ERR_FAIL_COND(thread != NULL);
+ ERR_FAIL_COND(thread != nullptr);
thread_running = true;
thread = Thread::create(GDScriptLanguageServer::thread_main, this);
}
@@ -98,11 +98,11 @@ void GDScriptLanguageServer::start() {
void GDScriptLanguageServer::stop() {
if (use_thread) {
- ERR_FAIL_COND(NULL == thread);
+ ERR_FAIL_COND(nullptr == thread);
thread_running = false;
Thread::wait_to_finish(thread);
memdelete(thread);
- thread = NULL;
+ thread = nullptr;
}
protocol.stop();
started = false;
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index 0572c5f746..f065b33570 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -35,6 +35,7 @@
#include "editor/plugins/script_text_editor.h"
#include "gdscript_extend_parser.h"
#include "gdscript_language_protocol.h"
+#include "servers/display_server.h"
void GDScriptTextDocument::_bind_methods() {
ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
@@ -89,12 +90,12 @@ void GDScriptTextDocument::initialize() {
const HashMap<StringName, ClassMembers> &native_members = GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members;
- const StringName *class_ptr = native_members.next(NULL);
+ const StringName *class_ptr = native_members.next(nullptr);
while (class_ptr) {
const ClassMembers &members = native_members.get(*class_ptr);
- const String *name = members.next(NULL);
+ const String *name = members.next(nullptr);
while (name) {
const lsp::DocumentSymbol *symbol = members.get(*name);
@@ -226,7 +227,7 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
lsp::CompletionParams params;
Variant data = p_params["data"];
- const lsp::DocumentSymbol *symbol = NULL;
+ const lsp::DocumentSymbol *symbol = nullptr;
if (data.get_type() == Variant::DICTIONARY) {
@@ -321,6 +322,8 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) {
lsp::Hover hover;
hover.contents = symbol->render();
+ hover.range.start = params.position;
+ hover.range.end = params.position;
return hover.to_json();
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
@@ -417,7 +420,8 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin
void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) {
ScriptEditor::get_singleton()->call_deferred("_help_class_goto", p_symbol_id);
- OS::get_singleton()->move_window_to_foreground();
+
+ DisplayServer::get_singleton()->window_move_to_foreground();
}
Array GDScriptTextDocument::find_symbols(const lsp::TextDocumentPositionParams &p_location, List<const lsp::DocumentSymbol *> &r_list) {
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index 1c0590cff1..32fc8f36f0 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -33,8 +33,11 @@
#include "../gdscript_parser.h"
#include "core/project_settings.h"
#include "core/script_language.h"
+#include "editor/editor_file_system.h"
#include "editor/editor_help.h"
+#include "editor/editor_node.h"
#include "gdscript_language_protocol.h"
+#include "scene/resources/packed_scene.h"
void GDScriptWorkspace::_bind_methods() {
ClassDB::bind_method(D_METHOD("symbol"), &GDScriptWorkspace::symbol);
@@ -50,7 +53,7 @@ void GDScriptWorkspace::remove_cache_parser(const String &p_path) {
Map<String, ExtendGDScriptParser *>::Element *parser = parse_results.find(p_path);
Map<String, ExtendGDScriptParser *>::Element *script = scripts.find(p_path);
if (parser && script) {
- if (script->get() && script->get() == script->get()) {
+ if (script->get() && script->get() == parser->get()) {
memdelete(script->get());
} else {
memdelete(script->get());
@@ -90,7 +93,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_native_symbol(const String &p_
class_name = ClassDB::get_parent_class(class_name);
}
- return NULL;
+ return nullptr;
}
const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_path) const {
@@ -98,7 +101,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_
if (S) {
return &(S->get()->get_symbols());
}
- return NULL;
+ return nullptr;
}
void GDScriptWorkspace::reload_all_workspace_scripts() {
@@ -149,7 +152,7 @@ ExtendGDScriptParser *GDScriptWorkspace::get_parse_successed_script(const String
if (S) {
return S->get();
}
- return NULL;
+ return nullptr;
}
ExtendGDScriptParser *GDScriptWorkspace::get_parse_result(const String &p_path) {
@@ -161,7 +164,7 @@ ExtendGDScriptParser *GDScriptWorkspace::get_parse_result(const String &p_path)
if (S) {
return S->get();
}
- return NULL;
+ return nullptr;
}
Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
@@ -373,6 +376,50 @@ void GDScriptWorkspace::publish_diagnostics(const String &p_path) {
GDScriptLanguageProtocol::get_singleton()->notify_client("textDocument/publishDiagnostics", params);
}
+void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners) {
+ if (!efsd)
+ return;
+
+ for (int i = 0; i < efsd->get_subdir_count(); i++) {
+ _get_owners(efsd->get_subdir(i), p_path, owners);
+ }
+
+ for (int i = 0; i < efsd->get_file_count(); i++) {
+
+ Vector<String> deps = efsd->get_file_deps(i);
+ bool found = false;
+ for (int j = 0; j < deps.size(); j++) {
+ if (deps[j] == p_path) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ continue;
+
+ owners.push_back(efsd->get_file_path(i));
+ }
+}
+
+Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) {
+ Node *owner_scene_node = nullptr;
+ List<String> owners;
+
+ _get_owners(EditorFileSystem::get_singleton()->get_filesystem(), p_path, owners);
+
+ for (int i = 0; i < owners.size(); i++) {
+ NodePath owner_path = owners[i];
+ RES owner_res = ResourceLoader::load(owner_path);
+ if (Object::cast_to<PackedScene>(owner_res.ptr())) {
+ Ref<PackedScene> owner_packed_scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*owner_res));
+ owner_scene_node = owner_packed_scene->instance();
+ break;
+ }
+ }
+
+ return owner_scene_node;
+}
+
void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) {
String path = get_file_path(p_params.textDocument.uri);
@@ -380,14 +427,18 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S
bool forced = false;
if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
+ Node *owner_scene_node = _get_owner_scene_node(path);
String code = parser->get_text_for_completion(p_params.position);
- GDScriptLanguage::get_singleton()->complete_code(code, path, NULL, r_options, forced, call_hint);
+ GDScriptLanguage::get_singleton()->complete_code(code, path, owner_scene_node, r_options, forced, call_hint);
+ if (owner_scene_node) {
+ memdelete(owner_scene_node);
+ }
}
}
const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_requred) {
- const lsp::DocumentSymbol *symbol = NULL;
+ const lsp::DocumentSymbol *symbol = nullptr;
String path = get_file_path(p_doc_pos.textDocument.uri);
if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
@@ -415,7 +466,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
} else {
ScriptLanguage::LookupResult ret;
- if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, NULL, ret)) {
+ if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, nullptr, ret)) {
if (ret.type == ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION) {
@@ -455,7 +506,7 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
Vector2i offset;
symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset);
- const StringName *class_ptr = native_members.next(NULL);
+ const StringName *class_ptr = native_members.next(nullptr);
while (class_ptr) {
const ClassMembers &members = native_members.get(*class_ptr);
if (const lsp::DocumentSymbol *const *symbol = members.getptr(symbol_identifier)) {
@@ -472,7 +523,7 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
}
const HashMap<String, ClassMembers> &inner_classes = script->get_inner_classes();
- const String *_class = inner_classes.next(NULL);
+ const String *_class = inner_classes.next(nullptr);
while (_class) {
const ClassMembers *inner_class = inner_classes.getptr(*_class);
@@ -501,7 +552,7 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::N
}
}
- return NULL;
+ return nullptr;
}
void GDScriptWorkspace::resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list) {
diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h
index 146a5cb7c9..e45b06747d 100644
--- a/modules/gdscript/language_server/gdscript_workspace.h
+++ b/modules/gdscript/language_server/gdscript_workspace.h
@@ -33,12 +33,17 @@
#include "../gdscript_parser.h"
#include "core/variant.h"
+#include "editor/editor_file_system.h"
#include "gdscript_extend_parser.h"
#include "lsp.hpp"
class GDScriptWorkspace : public Reference {
GDCLASS(GDScriptWorkspace, Reference);
+private:
+ void _get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners);
+ Node *_get_owner_scene_node(String p_path);
+
protected:
static void _bind_methods();
void remove_cache_parser(const String &p_path);
diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp
index a2dcc48820..124fcbfed8 100644
--- a/modules/gdscript/language_server/lsp.hpp
+++ b/modules/gdscript/language_server/lsp.hpp
@@ -33,7 +33,7 @@
#include "core/class_db.h"
#include "core/list.h"
-#include "editor/doc/doc_data.h"
+#include "editor/doc_data.h"
namespace lsp {
@@ -156,7 +156,7 @@ struct LocationLink {
* Used as the underlined span for mouse interaction. Defaults to the word range at
* the mouse position.
*/
- Range *originSelectionRange = NULL;
+ Range *originSelectionRange = nullptr;
/**
* The target resource identifier of this link.
@@ -1686,8 +1686,8 @@ struct InitializeResult {
struct GodotNativeClassInfo {
String name;
- const DocData::ClassDoc *class_doc = NULL;
- const ClassDB::ClassInfo *class_info = NULL;
+ const DocData::ClassDoc *class_doc = nullptr;
+ const ClassDB::ClassInfo *class_info = nullptr;
Dictionary to_json() {
Dictionary dict;
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index b5eb09d6ba..62b9d94d6c 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -37,7 +37,7 @@
#include "gdscript.h"
#include "gdscript_tokenizer.h"
-GDScriptLanguage *script_language_gd = NULL;
+GDScriptLanguage *script_language_gd = nullptr;
Ref<ResourceFormatLoaderGDScript> resource_loader_gd;
Ref<ResourceFormatSaverGDScript> resource_saver_gd;
diff --git a/modules/gdscript/register_types.h b/modules/gdscript/register_types.h
index 55920e8b97..18e57c1211 100644
--- a/modules/gdscript/register_types.h
+++ b/modules/gdscript/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef GDSCRIPT_REGISTER_TYPES_H
+#define GDSCRIPT_REGISTER_TYPES_H
+
void register_gdscript_types();
void unregister_gdscript_types();
+
+#endif // GDSCRIPT_REGISTER_TYPES_H
diff --git a/modules/glslang/SCsub b/modules/glslang/SCsub
new file mode 100644
index 0000000000..c1d23a138b
--- /dev/null
+++ b/modules/glslang/SCsub
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_modules")
+
+env_glslang = env_modules.Clone()
+
+# Thirdparty source files
+if env["builtin_glslang"]:
+ thirdparty_dir = "#thirdparty/glslang/"
+ thirdparty_sources = [
+ "glslang/MachineIndependent/RemoveTree.cpp",
+ "glslang/MachineIndependent/ParseHelper.cpp",
+ "glslang/MachineIndependent/iomapper.cpp",
+ "glslang/MachineIndependent/propagateNoContraction.cpp",
+ "glslang/MachineIndependent/Intermediate.cpp",
+ "glslang/MachineIndependent/linkValidate.cpp",
+ "glslang/MachineIndependent/attribute.cpp",
+ "glslang/MachineIndependent/Scan.cpp",
+ "glslang/MachineIndependent/Initialize.cpp",
+ "glslang/MachineIndependent/Constant.cpp",
+ "glslang/MachineIndependent/reflection.cpp",
+ "glslang/MachineIndependent/limits.cpp",
+ "glslang/MachineIndependent/preprocessor/PpScanner.cpp",
+ "glslang/MachineIndependent/preprocessor/PpTokens.cpp",
+ "glslang/MachineIndependent/preprocessor/PpAtom.cpp",
+ "glslang/MachineIndependent/preprocessor/PpContext.cpp",
+ "glslang/MachineIndependent/preprocessor/Pp.cpp",
+ "glslang/MachineIndependent/InfoSink.cpp",
+ "glslang/MachineIndependent/intermOut.cpp",
+ "glslang/MachineIndependent/SymbolTable.cpp",
+ "glslang/MachineIndependent/glslang_tab.cpp",
+ "glslang/MachineIndependent/pch.cpp",
+ "glslang/MachineIndependent/Versions.cpp",
+ "glslang/MachineIndependent/ShaderLang.cpp",
+ "glslang/MachineIndependent/parseConst.cpp",
+ "glslang/MachineIndependent/PoolAlloc.cpp",
+ "glslang/MachineIndependent/ParseContextBase.cpp",
+ "glslang/MachineIndependent/IntermTraverse.cpp",
+ "glslang/GenericCodeGen/Link.cpp",
+ "glslang/GenericCodeGen/CodeGen.cpp",
+ "OGLCompilersDLL/InitializeDll.cpp",
+ "SPIRV/InReadableOrder.cpp",
+ "SPIRV/GlslangToSpv.cpp",
+ "SPIRV/SpvBuilder.cpp",
+ "SPIRV/SpvTools.cpp",
+ "SPIRV/disassemble.cpp",
+ "SPIRV/doc.cpp",
+ "SPIRV/SPVRemapper.cpp",
+ "SPIRV/SpvPostProcess.cpp",
+ "SPIRV/Logger.cpp",
+ ]
+
+ if env["platform"] == "windows":
+ thirdparty_sources.append("glslang/OSDependent/Windows/ossource.cpp")
+ else:
+ thirdparty_sources.append("glslang/OSDependent/Unix/ossource.cpp")
+
+ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+
+ # Treat glslang headers as system headers to avoid raising warnings. Not supported on MSVC.
+ if not env.msvc:
+ env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path])
+ else:
+ env_glslang.Prepend(CPPPATH=[thirdparty_dir])
+
+ env_thirdparty = env_glslang.Clone()
+ env_thirdparty.disable_warnings()
+ env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
+
+# Godot's own source files
+env_glslang.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/glslang/config.py b/modules/glslang/config.py
new file mode 100644
index 0000000000..d22f9454ed
--- /dev/null
+++ b/modules/glslang/config.py
@@ -0,0 +1,6 @@
+def can_build(env, platform):
+ return True
+
+
+def configure(env):
+ pass
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp
new file mode 100644
index 0000000000..2540ba476c
--- /dev/null
+++ b/modules/glslang/register_types.cpp
@@ -0,0 +1,246 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "register_types.h"
+
+#include "servers/rendering/rendering_device.h"
+
+#include <SPIRV/GlslangToSpv.h>
+#include <glslang/Include/Types.h>
+#include <glslang/Public/ShaderLang.h>
+
+static const TBuiltInResource default_builtin_resource = {
+ /*maxLights*/ 32,
+ /*maxClipPlanes*/ 6,
+ /*maxTextureUnits*/ 32,
+ /*maxTextureCoords*/ 32,
+ /*maxVertexAttribs*/ 64,
+ /*maxVertexUniformComponents*/ 4096,
+ /*maxVaryingFloats*/ 64,
+ /*maxVertexTextureImageUnits*/ 32,
+ /*maxCombinedTextureImageUnits*/ 80,
+ /*maxTextureImageUnits*/ 32,
+ /*maxFragmentUniformComponents*/ 4096,
+ /*maxDrawBuffers*/ 32,
+ /*maxVertexUniformVectors*/ 128,
+ /*maxVaryingVectors*/ 8,
+ /*maxFragmentUniformVectors*/ 16,
+ /*maxVertexOutputVectors*/ 16,
+ /*maxFragmentInputVectors*/ 15,
+ /*minProgramTexelOffset*/ -8,
+ /*maxProgramTexelOffset*/ 7,
+ /*maxClipDistances*/ 8,
+ /*maxComputeWorkGroupCountX*/ 65535,
+ /*maxComputeWorkGroupCountY*/ 65535,
+ /*maxComputeWorkGroupCountZ*/ 65535,
+ /*maxComputeWorkGroupSizeX*/ 1024,
+ /*maxComputeWorkGroupSizeY*/ 1024,
+ /*maxComputeWorkGroupSizeZ*/ 64,
+ /*maxComputeUniformComponents*/ 1024,
+ /*maxComputeTextureImageUnits*/ 16,
+ /*maxComputeImageUniforms*/ 8,
+ /*maxComputeAtomicCounters*/ 8,
+ /*maxComputeAtomicCounterBuffers*/ 1,
+ /*maxVaryingComponents*/ 60,
+ /*maxVertexOutputComponents*/ 64,
+ /*maxGeometryInputComponents*/ 64,
+ /*maxGeometryOutputComponents*/ 128,
+ /*maxFragmentInputComponents*/ 128,
+ /*maxImageUnits*/ 8,
+ /*maxCombinedImageUnitsAndFragmentOutputs*/ 8,
+ /*maxCombinedShaderOutputResources*/ 8,
+ /*maxImageSamples*/ 0,
+ /*maxVertexImageUniforms*/ 0,
+ /*maxTessControlImageUniforms*/ 0,
+ /*maxTessEvaluationImageUniforms*/ 0,
+ /*maxGeometryImageUniforms*/ 0,
+ /*maxFragmentImageUniforms*/ 8,
+ /*maxCombinedImageUniforms*/ 8,
+ /*maxGeometryTextureImageUnits*/ 16,
+ /*maxGeometryOutputVertices*/ 256,
+ /*maxGeometryTotalOutputComponents*/ 1024,
+ /*maxGeometryUniformComponents*/ 1024,
+ /*maxGeometryVaryingComponents*/ 64,
+ /*maxTessControlInputComponents*/ 128,
+ /*maxTessControlOutputComponents*/ 128,
+ /*maxTessControlTextureImageUnits*/ 16,
+ /*maxTessControlUniformComponents*/ 1024,
+ /*maxTessControlTotalOutputComponents*/ 4096,
+ /*maxTessEvaluationInputComponents*/ 128,
+ /*maxTessEvaluationOutputComponents*/ 128,
+ /*maxTessEvaluationTextureImageUnits*/ 16,
+ /*maxTessEvaluationUniformComponents*/ 1024,
+ /*maxTessPatchComponents*/ 120,
+ /*maxPatchVertices*/ 32,
+ /*maxTessGenLevel*/ 64,
+ /*maxViewports*/ 16,
+ /*maxVertexAtomicCounters*/ 0,
+ /*maxTessControlAtomicCounters*/ 0,
+ /*maxTessEvaluationAtomicCounters*/ 0,
+ /*maxGeometryAtomicCounters*/ 0,
+ /*maxFragmentAtomicCounters*/ 8,
+ /*maxCombinedAtomicCounters*/ 8,
+ /*maxAtomicCounterBindings*/ 1,
+ /*maxVertexAtomicCounterBuffers*/ 0,
+ /*maxTessControlAtomicCounterBuffers*/ 0,
+ /*maxTessEvaluationAtomicCounterBuffers*/ 0,
+ /*maxGeometryAtomicCounterBuffers*/ 0,
+ /*maxFragmentAtomicCounterBuffers*/ 1,
+ /*maxCombinedAtomicCounterBuffers*/ 1,
+ /*maxAtomicCounterBufferSize*/ 16384,
+ /*maxTransformFeedbackBuffers*/ 4,
+ /*maxTransformFeedbackInterleavedComponents*/ 64,
+ /*maxCullDistances*/ 8,
+ /*maxCombinedClipAndCullDistances*/ 8,
+ /*maxSamples*/ 4,
+ /*maxMeshOutputVerticesNV*/ 0,
+ /*maxMeshOutputPrimitivesNV*/ 0,
+ /*maxMeshWorkGroupSizeX_NV*/ 0,
+ /*maxMeshWorkGroupSizeY_NV*/ 0,
+ /*maxMeshWorkGroupSizeZ_NV*/ 0,
+ /*maxTaskWorkGroupSizeX_NV*/ 0,
+ /*maxTaskWorkGroupSizeY_NV*/ 0,
+ /*maxTaskWorkGroupSizeZ_NV*/ 0,
+ /*maxMeshViewCountNV*/ 0,
+ /*limits*/ {
+ /*nonInductiveForLoops*/ 1,
+ /*whileLoops*/ 1,
+ /*doWhileLoops*/ 1,
+ /*generalUniformIndexing*/ 1,
+ /*generalAttributeMatrixVectorIndexing*/ 1,
+ /*generalVaryingIndexing*/ 1,
+ /*generalSamplerIndexing*/ 1,
+ /*generalVariableIndexing*/ 1,
+ /*generalConstantMatrixVectorIndexing*/ 1,
+ }
+};
+
+static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error) {
+
+ Vector<uint8_t> ret;
+
+ ERR_FAIL_COND_V(p_language == RenderingDevice::SHADER_LANGUAGE_HLSL, ret);
+
+ EShLanguage stages[RenderingDevice::SHADER_STAGE_MAX] = {
+ EShLangVertex,
+ EShLangFragment,
+ EShLangTessControl,
+ EShLangTessEvaluation,
+ EShLangCompute
+ };
+
+ int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
+
+ glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0;
+ glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0;
+ glslang::TShader::ForbidIncluder includer;
+
+ glslang::TShader shader(stages[p_stage]);
+ CharString cs = p_source_code.ascii();
+ const char *cs_strings = cs.get_data();
+
+ shader.setStrings(&cs_strings, 1);
+ shader.setEnvInput(glslang::EShSourceGlsl, stages[p_stage], glslang::EShClientVulkan, ClientInputSemanticsVersion);
+ shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
+ shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion);
+
+ EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
+ const int DefaultVersion = 100;
+ std::string pre_processed_code;
+
+ //preprocess
+ if (!shader.preprocess(&default_builtin_resource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) {
+
+ if (r_error) {
+ (*r_error) = "Failed pre-process:\n";
+ (*r_error) += shader.getInfoLog();
+ (*r_error) += "\n";
+ (*r_error) += shader.getInfoDebugLog();
+ }
+
+ return ret;
+ }
+ //set back..
+ cs_strings = pre_processed_code.c_str();
+ shader.setStrings(&cs_strings, 1);
+
+ //parse
+ if (!shader.parse(&default_builtin_resource, DefaultVersion, false, messages)) {
+ if (r_error) {
+ (*r_error) = "Failed parse:\n";
+ (*r_error) += shader.getInfoLog();
+ (*r_error) += "\n";
+ (*r_error) += shader.getInfoDebugLog();
+ }
+ return ret;
+ }
+
+ //link
+ glslang::TProgram program;
+ program.addShader(&shader);
+
+ if (!program.link(messages)) {
+ if (r_error) {
+ (*r_error) = "Failed link:\n";
+ (*r_error) += program.getInfoLog();
+ (*r_error) += "\n";
+ (*r_error) += program.getInfoDebugLog();
+ }
+
+ return ret;
+ }
+
+ std::vector<uint32_t> SpirV;
+ spv::SpvBuildLogger logger;
+ glslang::SpvOptions spvOptions;
+ glslang::GlslangToSpv(*program.getIntermediate(stages[p_stage]), SpirV, &logger, &spvOptions);
+
+ ret.resize(SpirV.size() * sizeof(uint32_t));
+ {
+ uint8_t *w = ret.ptrw();
+ copymem(w, &SpirV[0], SpirV.size() * sizeof(uint32_t));
+ }
+
+ return ret;
+}
+
+void preregister_glslang_types() {
+ // initialize in case it's not initialized. This is done once per thread
+ // and it's safe to call multiple times
+ glslang::InitializeProcess();
+ RenderingDevice::shader_set_compile_function(_compile_shader_glsl);
+}
+
+void register_glslang_types() {
+}
+void unregister_glslang_types() {
+
+ glslang::FinalizeProcess();
+}
diff --git a/modules/vorbis/stub/register_types.h b/modules/glslang/register_types.h
index 83d4904a87..2437e2b27a 100644
--- a/modules/vorbis/stub/register_types.h
+++ b/modules/glslang/register_types.h
@@ -28,5 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_vorbis_types();
-void unregister_vorbis_types();
+#ifndef GLSLANG_REGISTER_TYPES_H
+#define GLSLANG_REGISTER_TYPES_H
+
+#define MODULE_GLSLANG_HAS_PREREGISTER
+
+void preregister_glslang_types();
+void register_glslang_types();
+void unregister_glslang_types();
+
+#endif // GLSLANG_REGISTER_TYPES_H
diff --git a/modules/gridmap/SCsub b/modules/gridmap/SCsub
index 62b8a0ff93..970ce534f0 100644
--- a/modules/gridmap/SCsub
+++ b/modules/gridmap/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_gridmap = env_modules.Clone()
diff --git a/modules/gridmap/config.py b/modules/gridmap/config.py
index 5022116c9b..a6319fe1ea 100644
--- a/modules/gridmap/config.py
+++ b/modules/gridmap/config.py
@@ -1,13 +1,16 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"GridMap",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index 37ebb3e5d5..a213069e19 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GridMap" inherits="Spatial" version="4.0">
+<class name="GridMap" inherits="Node3D" version="4.0">
<brief_description>
Node for 3D tile-based maps.
</brief_description>
diff --git a/modules/gridmap/doc_classes/README.md b/modules/gridmap/doc_classes/README.md
index b1ec9058c8..37ad93b6d3 100644
--- a/modules/gridmap/doc_classes/README.md
+++ b/modules/gridmap/doc_classes/README.md
@@ -1 +1 @@
-Doc classes will appear here when generating \ No newline at end of file
+Doc classes will appear here when generating
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 3d40220869..df7c2f397f 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -32,11 +32,12 @@
#include "core/io/marshalls.h"
#include "core/message_queue.h"
-#include "scene/3d/light.h"
+#include "scene/3d/light_3d.h"
#include "scene/resources/mesh_library.h"
#include "scene/resources/surface_tool.h"
#include "scene/scene_string_names.h"
-#include "servers/visual_server.h"
+#include "servers/navigation_server_3d.h"
+#include "servers/rendering_server.h"
bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
@@ -48,9 +49,9 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
if (d.has("cells")) {
- PoolVector<int> cells = d["cells"];
+ Vector<int> cells = d["cells"];
int amount = cells.size();
- PoolVector<int>::Read r = cells.read();
+ const int *r = cells.ptr();
ERR_FAIL_COND_V(amount % 3, false); // not even
cell_map.clear();
for (int i = 0; i < amount / 3; i++) {
@@ -75,12 +76,12 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
BakedMesh bm;
bm.mesh = meshes[i];
ERR_CONTINUE(!bm.mesh.is_valid());
- bm.instance = VS::get_singleton()->instance_create();
- VS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
- VS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
+ bm.instance = RS::get_singleton()->instance_create();
+ RS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
+ RS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
if (is_inside_tree()) {
- VS::get_singleton()->instance_set_scenario(bm.instance, get_world()->get_scenario());
- VS::get_singleton()->instance_set_transform(bm.instance, get_global_transform());
+ RS::get_singleton()->instance_set_scenario(bm.instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_transform(bm.instance, get_global_transform());
}
baked_meshes.push_back(bm);
}
@@ -102,10 +103,10 @@ bool GridMap::_get(const StringName &p_name, Variant &r_ret) const {
Dictionary d;
- PoolVector<int> cells;
+ Vector<int> cells;
cells.resize(cell_map.size() * 3);
{
- PoolVector<int>::Write w = cells.write();
+ int *w = cells.ptrw();
int i = 0;
for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) {
@@ -305,17 +306,17 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) {
//create octant because it does not exist
Octant *g = memnew(Octant);
g->dirty = true;
- g->static_body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
- PhysicsServer::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id());
- PhysicsServer::get_singleton()->body_set_collision_layer(g->static_body, collision_layer);
- PhysicsServer::get_singleton()->body_set_collision_mask(g->static_body, collision_mask);
+ g->static_body = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
+ PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id());
+ PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer);
+ PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask);
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_debugging_collisions_hint()) {
- g->collision_debug = VisualServer::get_singleton()->mesh_create();
- g->collision_debug_instance = VisualServer::get_singleton()->instance_create();
- VisualServer::get_singleton()->instance_set_base(g->collision_debug_instance, g->collision_debug);
+ g->collision_debug = RenderingServer::get_singleton()->mesh_create();
+ g->collision_debug_instance = RenderingServer::get_singleton()->instance_create();
+ RenderingServer::get_singleton()->instance_set_base(g->collision_debug_instance, g->collision_debug);
}
octant_map[octantkey] = g;
@@ -391,14 +392,14 @@ void GridMap::_octant_transform(const OctantKey &p_key) {
ERR_FAIL_COND(!octant_map.has(p_key));
Octant &g = *octant_map[p_key];
- PhysicsServer::get_singleton()->body_set_state(g.static_body, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
+ PhysicsServer3D::get_singleton()->body_set_state(g.static_body, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
if (g.collision_debug_instance.is_valid()) {
- VS::get_singleton()->instance_set_transform(g.collision_debug_instance, get_global_transform());
+ RS::get_singleton()->instance_set_transform(g.collision_debug_instance, get_global_transform());
}
for (int i = 0; i < g.multimesh_instances.size(); i++) {
- VS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
+ RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
}
}
@@ -409,28 +410,26 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
return false;
//erase body shapes
- PhysicsServer::get_singleton()->body_clear_shapes(g.static_body);
+ PhysicsServer3D::get_singleton()->body_clear_shapes(g.static_body);
//erase body shapes debug
if (g.collision_debug.is_valid()) {
- VS::get_singleton()->mesh_clear(g.collision_debug);
+ RS::get_singleton()->mesh_clear(g.collision_debug);
}
//erase navigation
- if (navigation) {
- for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
- navigation->navmesh_remove(E->get().id);
- }
- g.navmesh_ids.clear();
+ for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
+ NavigationServer3D::get_singleton()->free(E->get().region);
}
+ g.navmesh_ids.clear();
//erase multimeshes
for (int i = 0; i < g.multimesh_instances.size(); i++) {
- VS::get_singleton()->free(g.multimesh_instances[i].instance);
- VS::get_singleton()->free(g.multimesh_instances[i].multimesh);
+ RS::get_singleton()->free(g.multimesh_instances[i].instance);
+ RS::get_singleton()->free(g.multimesh_instances[i].multimesh);
}
g.multimesh_instances.clear();
@@ -440,7 +439,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
return true;
}
- PoolVector<Vector3> col_debug;
+ Vector<Vector3> col_debug;
/*
* foreach item in this octant,
@@ -448,7 +447,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
* and set said multimesh bounding box to one containing all cells which have this item
*/
- Map<int, List<Pair<Transform, IndexKey> > > multimesh_items;
+ Map<int, List<Pair<Transform, IndexKey>>> multimesh_items;
for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) {
@@ -469,7 +468,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
if (baked_meshes.size() == 0) {
if (mesh_library->get_item_mesh(c.item).is_valid()) {
if (!multimesh_items.has(c.item)) {
- multimesh_items[c.item] = List<Pair<Transform, IndexKey> >();
+ multimesh_items[c.item] = List<Pair<Transform, IndexKey>>();
}
Pair<Transform, IndexKey> p;
@@ -485,7 +484,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
// add the item's shape
if (!shapes[i].shape.is_valid())
continue;
- PhysicsServer::get_singleton()->body_add_shape(g.static_body, shapes[i].shape->get_rid(), xform * shapes[i].local_transform);
+ PhysicsServer3D::get_singleton()->body_add_shape(g.static_body, shapes[i].shape->get_rid(), xform * shapes[i].local_transform);
if (g.collision_debug.is_valid()) {
shapes.write[i].shape->add_vertices_to_array(col_debug, xform * shapes[i].local_transform);
}
@@ -498,9 +497,11 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item);
if (navigation) {
- nm.id = navigation->navmesh_add(navmesh, xform, this);
- } else {
- nm.id = -1;
+ RID region = NavigationServer3D::get_singleton()->region_create();
+ NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh);
+ NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * nm.xform);
+ NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
+ nm.region = region;
}
g.navmesh_ids[E->get()] = nm;
}
@@ -509,16 +510,16 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
//update multimeshes, only if not baked
if (baked_meshes.size() == 0) {
- for (Map<int, List<Pair<Transform, IndexKey> > >::Element *E = multimesh_items.front(); E; E = E->next()) {
+ for (Map<int, List<Pair<Transform, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) {
Octant::MultimeshInstance mmi;
- RID mm = VS::get_singleton()->multimesh_create();
- VS::get_singleton()->multimesh_allocate(mm, E->get().size(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_NONE);
- VS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid());
+ RID mm = RS::get_singleton()->multimesh_create();
+ RS::get_singleton()->multimesh_allocate(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D);
+ RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid());
int idx = 0;
- for (List<Pair<Transform, IndexKey> >::Element *F = E->get().front(); F; F = F->next()) {
- VS::get_singleton()->multimesh_instance_set_transform(mm, idx, F->get().first);
+ for (List<Pair<Transform, IndexKey>>::Element *F = E->get().front(); F; F = F->next()) {
+ RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F->get().first);
#ifdef TOOLS_ENABLED
Octant::MultimeshInstance::Item it;
@@ -531,12 +532,12 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
idx++;
}
- RID instance = VS::get_singleton()->instance_create();
- VS::get_singleton()->instance_set_base(instance, mm);
+ RID instance = RS::get_singleton()->instance_create();
+ RS::get_singleton()->instance_set_base(instance, mm);
if (is_inside_tree()) {
- VS::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario());
- VS::get_singleton()->instance_set_transform(instance, get_global_transform());
+ RS::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_transform(instance, get_global_transform());
}
mmi.multimesh = mm;
@@ -549,13 +550,13 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
if (col_debug.size()) {
Array arr;
- arr.resize(VS::ARRAY_MAX);
- arr[VS::ARRAY_VERTEX] = col_debug;
+ arr.resize(RS::ARRAY_MAX);
+ arr[RS::ARRAY_VERTEX] = col_debug;
- VS::get_singleton()->mesh_add_surface_from_arrays(g.collision_debug, VS::PRIMITIVE_LINES, arr);
+ RS::get_singleton()->mesh_add_surface_from_arrays(g.collision_debug, RS::PRIMITIVE_LINES, arr);
SceneTree *st = SceneTree::get_singleton();
if (st) {
- VS::get_singleton()->mesh_surface_set_material(g.collision_debug, 0, st->get_debug_collision_material()->get_rid());
+ RS::get_singleton()->mesh_surface_set_material(g.collision_debug, 0, st->get_debug_collision_material()->get_rid());
}
}
@@ -566,8 +567,8 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
void GridMap::_reset_physic_bodies_collision_filters() {
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
- PhysicsServer::get_singleton()->body_set_collision_layer(E->get()->static_body, collision_layer);
- PhysicsServer::get_singleton()->body_set_collision_mask(E->get()->static_body, collision_mask);
+ PhysicsServer3D::get_singleton()->body_set_collision_layer(E->get()->static_body, collision_layer);
+ PhysicsServer3D::get_singleton()->body_set_collision_mask(E->get()->static_body, collision_mask);
}
}
@@ -575,26 +576,30 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) {
ERR_FAIL_COND(!octant_map.has(p_key));
Octant &g = *octant_map[p_key];
- PhysicsServer::get_singleton()->body_set_state(g.static_body, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
- PhysicsServer::get_singleton()->body_set_space(g.static_body, get_world()->get_space());
+ PhysicsServer3D::get_singleton()->body_set_state(g.static_body, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
+ PhysicsServer3D::get_singleton()->body_set_space(g.static_body, get_world()->get_space());
if (g.collision_debug_instance.is_valid()) {
- VS::get_singleton()->instance_set_scenario(g.collision_debug_instance, get_world()->get_scenario());
- VS::get_singleton()->instance_set_transform(g.collision_debug_instance, get_global_transform());
+ RS::get_singleton()->instance_set_scenario(g.collision_debug_instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_transform(g.collision_debug_instance, get_global_transform());
}
for (int i = 0; i < g.multimesh_instances.size(); i++) {
- VS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, get_world()->get_scenario());
- VS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
+ RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
}
if (navigation && mesh_library.is_valid()) {
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
- if (cell_map.has(F->key()) && F->get().id < 0) {
+ if (cell_map.has(F->key()) && F->get().region.is_valid() == false) {
Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item);
if (nm.is_valid()) {
- F->get().id = navigation->navmesh_add(nm, F->get().xform, this);
+ RID region = NavigationServer3D::get_singleton()->region_create();
+ NavigationServer3D::get_singleton()->region_set_navmesh(region, nm);
+ NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * F->get().xform);
+ NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
+ F->get().region = region;
}
}
}
@@ -605,24 +610,24 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) {
ERR_FAIL_COND(!octant_map.has(p_key));
Octant &g = *octant_map[p_key];
- PhysicsServer::get_singleton()->body_set_state(g.static_body, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
- PhysicsServer::get_singleton()->body_set_space(g.static_body, RID());
+ PhysicsServer3D::get_singleton()->body_set_state(g.static_body, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
+ PhysicsServer3D::get_singleton()->body_set_space(g.static_body, RID());
if (g.collision_debug_instance.is_valid()) {
- VS::get_singleton()->instance_set_scenario(g.collision_debug_instance, RID());
+ RS::get_singleton()->instance_set_scenario(g.collision_debug_instance, RID());
}
for (int i = 0; i < g.multimesh_instances.size(); i++) {
- VS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID());
+ RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID());
}
if (navigation) {
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
- if (F->get().id >= 0) {
- navigation->navmesh_remove(F->get().id);
- F->get().id = -1;
+ if (F->get().region.is_valid()) {
+ NavigationServer3D::get_singleton()->free(F->get().region);
+ F->get().region = RID();
}
}
}
@@ -634,26 +639,24 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
Octant &g = *octant_map[p_key];
if (g.collision_debug.is_valid())
- VS::get_singleton()->free(g.collision_debug);
+ RS::get_singleton()->free(g.collision_debug);
if (g.collision_debug_instance.is_valid())
- VS::get_singleton()->free(g.collision_debug_instance);
+ RS::get_singleton()->free(g.collision_debug_instance);
- PhysicsServer::get_singleton()->free(g.static_body);
+ PhysicsServer3D::get_singleton()->free(g.static_body);
- //erase navigation
- if (navigation) {
- for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
- navigation->navmesh_remove(E->get().id);
- }
- g.navmesh_ids.clear();
+ // Erase navigation
+ for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
+ NavigationServer3D::get_singleton()->free(E->get().region);
}
+ g.navmesh_ids.clear();
//erase multimeshes
for (int i = 0; i < g.multimesh_instances.size(); i++) {
- VS::get_singleton()->free(g.multimesh_instances[i].instance);
- VS::get_singleton()->free(g.multimesh_instances[i].multimesh);
+ RS::get_singleton()->free(g.multimesh_instances[i].instance);
+ RS::get_singleton()->free(g.multimesh_instances[i].multimesh);
}
g.multimesh_instances.clear();
}
@@ -664,14 +667,14 @@ void GridMap::_notification(int p_what) {
case NOTIFICATION_ENTER_WORLD: {
- Spatial *c = this;
+ Node3D *c = this;
while (c) {
- navigation = Object::cast_to<Navigation>(c);
+ navigation = Object::cast_to<Navigation3D>(c);
if (navigation) {
break;
}
- c = Object::cast_to<Spatial>(c->get_parent());
+ c = Object::cast_to<Node3D>(c->get_parent());
}
last_transform = get_global_transform();
@@ -681,8 +684,8 @@ void GridMap::_notification(int p_what) {
}
for (int i = 0; i < baked_meshes.size(); i++) {
- VS::get_singleton()->instance_set_scenario(baked_meshes[i].instance, get_world()->get_scenario());
- VS::get_singleton()->instance_set_transform(baked_meshes[i].instance, get_global_transform());
+ RS::get_singleton()->instance_set_scenario(baked_meshes[i].instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_transform(baked_meshes[i].instance, get_global_transform());
}
} break;
@@ -699,7 +702,7 @@ void GridMap::_notification(int p_what) {
last_transform = new_xform;
for (int i = 0; i < baked_meshes.size(); i++) {
- VS::get_singleton()->instance_set_transform(baked_meshes[i].instance, get_global_transform());
+ RS::get_singleton()->instance_set_transform(baked_meshes[i].instance, get_global_transform());
}
} break;
@@ -709,13 +712,13 @@ void GridMap::_notification(int p_what) {
_octant_exit_world(E->key());
}
- navigation = NULL;
+ navigation = nullptr;
//_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS);
//_update_octants_callback();
//_update_area_instances();
for (int i = 0; i < baked_meshes.size(); i++) {
- VS::get_singleton()->instance_set_scenario(baked_meshes[i].instance, RID());
+ RS::get_singleton()->instance_set_scenario(baked_meshes[i].instance, RID());
}
} break;
@@ -735,7 +738,7 @@ void GridMap::_update_visibility() {
Octant *octant = e->value();
for (int i = 0; i < octant->multimesh_instances.size(); i++) {
const Octant::MultimeshInstance &mi = octant->multimesh_instances[i];
- VS::get_singleton()->instance_set_visible(mi.instance, is_visible());
+ RS::get_singleton()->instance_set_visible(mi.instance, is_visible());
}
}
}
@@ -871,7 +874,7 @@ void GridMap::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_x"), "set_center_x", "get_center_x");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_y"), "set_center_y", "get_center_y");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_z"), "set_center_z", "get_center_z");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_scale"), "set_cell_scale", "get_cell_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_scale"), "set_cell_scale", "get_cell_scale");
ADD_GROUP("Collision", "collision_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
@@ -972,7 +975,7 @@ Vector3 GridMap::_get_offset() const {
void GridMap::clear_baked_meshes() {
for (int i = 0; i < baked_meshes.size(); i++) {
- VS::get_singleton()->free(baked_meshes[i].instance);
+ RS::get_singleton()->free(baked_meshes[i].instance);
}
baked_meshes.clear();
@@ -985,7 +988,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
return;
//generate
- Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool> > > surface_map;
+ Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>> surface_map;
for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) {
@@ -1014,10 +1017,10 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
ok.z = key.z / octant_size;
if (!surface_map.has(ok)) {
- surface_map[ok] = Map<Ref<Material>, Ref<SurfaceTool> >();
+ surface_map[ok] = Map<Ref<Material>, Ref<SurfaceTool>>();
}
- Map<Ref<Material>, Ref<SurfaceTool> > &mat_map = surface_map[ok];
+ Map<Ref<Material>, Ref<SurfaceTool>> &mat_map = surface_map[ok];
for (int i = 0; i < mesh->get_surface_count(); i++) {
@@ -1037,22 +1040,22 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
}
}
- for (Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool> > >::Element *E = surface_map.front(); E; E = E->next()) {
+ for (Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>>::Element *E = surface_map.front(); E; E = E->next()) {
Ref<ArrayMesh> mesh;
mesh.instance();
- for (Map<Ref<Material>, Ref<SurfaceTool> >::Element *F = E->get().front(); F; F = F->next()) {
+ for (Map<Ref<Material>, Ref<SurfaceTool>>::Element *F = E->get().front(); F; F = F->next()) {
F->get()->commit(mesh);
}
BakedMesh bm;
bm.mesh = mesh;
- bm.instance = VS::get_singleton()->instance_create();
- VS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
- VS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
+ bm.instance = RS::get_singleton()->instance_create();
+ RS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
+ RS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
if (is_inside_tree()) {
- VS::get_singleton()->instance_set_scenario(bm.instance, get_world()->get_scenario());
- VS::get_singleton()->instance_set_transform(bm.instance, get_global_transform());
+ RS::get_singleton()->instance_set_scenario(bm.instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_transform(bm.instance, get_global_transform());
}
if (p_gen_lightmap_uv) {
@@ -1104,7 +1107,7 @@ GridMap::GridMap() {
clip_above = true;
cell_scale = 1.0;
- navigation = NULL;
+ navigation = nullptr;
set_notify_transform(true);
recreating_octants = false;
}
diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h
index 705f4929e1..3f3da09fe9 100644
--- a/modules/gridmap/grid_map.h
+++ b/modules/gridmap/grid_map.h
@@ -31,17 +31,17 @@
#ifndef GRID_MAP_H
#define GRID_MAP_H
-#include "scene/3d/navigation.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/navigation_3d.h"
+#include "scene/3d/node_3d.h"
#include "scene/resources/mesh_library.h"
#include "scene/resources/multimesh.h"
//heh heh, godotsphir!! this shares no code and the design is completely different with previous projects i've done..
//should scale better with hardware that supports instancing
-class GridMap : public Spatial {
+class GridMap : public Node3D {
- GDCLASS(GridMap, Spatial);
+ GDCLASS(GridMap, Node3D);
enum {
MAP_DIRTY_TRANSFORMS = 1,
@@ -91,7 +91,7 @@ class GridMap : public Spatial {
struct Octant {
struct NavMesh {
- int id;
+ RID region;
Transform xform;
};
@@ -147,7 +147,7 @@ class GridMap : public Spatial {
int octant_size;
bool center_x, center_y, center_z;
float cell_scale;
- Navigation *navigation;
+ Navigation3D *navigation;
bool clip;
bool clip_above;
@@ -166,10 +166,10 @@ class GridMap : public Spatial {
struct BakeLight {
- VS::LightType type;
+ RS::LightType type;
Vector3 pos;
Vector3 dir;
- float param[VS::LIGHT_PARAM_MAX];
+ float param[RS::LIGHT_PARAM_MAX];
};
_FORCE_INLINE_ Vector3 _octant_get_offset(const OctantKey &p_key) const {
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 4aa407f966..eb8feb5bc7 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -29,19 +29,20 @@
/*************************************************************************/
#include "grid_map_editor_plugin.h"
-#include "core/os/input.h"
+#include "core/input/input_filter.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
-#include "editor/plugins/spatial_editor_plugin.h"
-#include "scene/3d/camera.h"
+#include "editor/plugins/node_3d_editor_plugin.h"
+#include "scene/3d/camera_3d.h"
#include "core/math/geometry.h"
#include "core/os/keyboard.h"
+#include "scene/main/window.h"
void GridMapEditor::_node_removed(Node *p_node) {
if (p_node == node)
- node = NULL;
+ node = nullptr;
}
void GridMapEditor::_configure() {
@@ -280,8 +281,8 @@ void GridMapEditor::_update_cursor_transform() {
cursor_transform = node->get_global_transform() * cursor_transform;
if (cursor_instance.is_valid()) {
- VisualServer::get_singleton()->instance_set_transform(cursor_instance, cursor_transform);
- VisualServer::get_singleton()->instance_set_visible(cursor_instance, cursor_visible);
+ RenderingServer::get_singleton()->instance_set_transform(cursor_instance, cursor_transform);
+ RenderingServer::get_singleton()->instance_set_visible(cursor_instance, cursor_visible);
}
}
@@ -291,9 +292,9 @@ void GridMapEditor::_update_selection_transform() {
if (!selection.active) {
- VisualServer::get_singleton()->instance_set_transform(selection_instance, xf_zero);
+ RenderingServer::get_singleton()->instance_set_transform(selection_instance, xf_zero);
for (int i = 0; i < 3; i++) {
- VisualServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf_zero);
+ RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf_zero);
}
return;
}
@@ -302,11 +303,11 @@ void GridMapEditor::_update_selection_transform() {
xf.scale((Vector3(1, 1, 1) + (selection.end - selection.begin)) * node->get_cell_size());
xf.origin = selection.begin * node->get_cell_size();
- VisualServer::get_singleton()->instance_set_transform(selection_instance, node->get_global_transform() * xf);
+ RenderingServer::get_singleton()->instance_set_transform(selection_instance, node->get_global_transform() * xf);
for (int i = 0; i < 3; i++) {
if (i != edit_axis || (edit_floor[edit_axis] < selection.begin[edit_axis]) || (edit_floor[edit_axis] > selection.end[edit_axis] + 1)) {
- VisualServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf_zero);
+ RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf_zero);
} else {
Vector3 scale = (selection.end - selection.begin + Vector3(1, 1, 1));
@@ -321,7 +322,7 @@ void GridMapEditor::_update_selection_transform() {
xf2.basis.scale(scale);
xf2.origin = pos;
- VisualServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf2);
+ RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf2);
}
}
}
@@ -361,7 +362,7 @@ void GridMapEditor::_set_selection(bool p_active, const Vector3 &p_begin, const
options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_FILL), !selection.active);
}
-bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, bool p_click) {
+bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, bool p_click) {
if (!spatial_editor)
return false;
@@ -374,7 +375,7 @@ bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, boo
if (input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE && !mesh_library->has_item(selected_palette))
return false;
- Camera *camera = p_camera;
+ Camera3D *camera = p_camera;
Vector3 from = camera->project_ray_origin(p_point);
Vector3 normal = camera->project_ray_normal(p_point);
Transform local_xform = node->get_global_transform().affine_inverse();
@@ -415,7 +416,7 @@ bool GridMapEditor::do_input_action(Camera *p_camera, const Point2 &p_point, boo
}
}
- VS::get_singleton()->instance_set_transform(grid_instance[edit_axis], node->get_global_transform() * edit_grid_xform);
+ RS::get_singleton()->instance_set_transform(grid_instance[edit_axis], node->get_global_transform() * edit_grid_xform);
if (cursor_instance.is_valid()) {
@@ -527,7 +528,7 @@ void GridMapEditor::_clear_clipboard_data() {
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
- VisualServer::get_singleton()->free(E->get().instance);
+ RenderingServer::get_singleton()->free(E->get().instance);
}
clipboard_items.clear();
@@ -555,7 +556,7 @@ void GridMapEditor::_set_clipboard_data() {
item.cell_item = itm;
item.grid_offset = Vector3(i, j, k) - selection.begin;
item.orientation = node->get_cell_item_orientation(i, j, k);
- item.instance = VisualServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world()->get_scenario());
+ item.instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world()->get_scenario());
clipboard_items.push_back(item);
}
@@ -569,7 +570,7 @@ void GridMapEditor::_update_paste_indicator() {
Transform xf;
xf.basis.set_zero();
- VisualServer::get_singleton()->instance_set_transform(paste_instance, xf);
+ RenderingServer::get_singleton()->instance_set_transform(paste_instance, xf);
return;
}
@@ -583,7 +584,7 @@ void GridMapEditor::_update_paste_indicator() {
xf.basis = rot * xf.basis;
xf.translate((-center * node->get_cell_size()) / scale);
- VisualServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf);
+ RenderingServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf);
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
@@ -598,7 +599,7 @@ void GridMapEditor::_update_paste_indicator() {
item_rot.set_orthogonal_index(item.orientation);
xf.basis = item_rot * xf.basis * node->get_cell_scale();
- VisualServer::get_singleton()->instance_set_transform(item.instance, node->get_global_transform() * xf);
+ RenderingServer::get_singleton()->instance_set_transform(item.instance, node->get_global_transform() * xf);
}
}
@@ -638,7 +639,7 @@ void GridMapEditor::_do_paste() {
_clear_clipboard_data();
}
-bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<InputEvent> &p_event) {
+bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
if (!node) {
return false;
}
@@ -659,8 +660,8 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu
}
if (mb->is_pressed()) {
- SpatialEditorViewport::NavigationScheme nav_scheme = (SpatialEditorViewport::NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
- if ((nav_scheme == SpatialEditorViewport::NAVIGATION_MAYA || nav_scheme == SpatialEditorViewport::NAVIGATION_MODO) && mb->get_alt()) {
+ Node3DEditorViewport::NavigationScheme nav_scheme = (Node3DEditorViewport::NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
+ if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->get_alt()) {
input_action = INPUT_NONE;
} else if (mb->get_button_index() == BUTTON_LEFT) {
@@ -752,7 +753,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu
if (k.is_valid()) {
if (k->is_pressed()) {
- if (k->get_scancode() == KEY_ESCAPE) {
+ if (k->get_keycode() == KEY_ESCAPE) {
if (input_action == INPUT_PASTE) {
_clear_clipboard_data();
@@ -773,12 +774,12 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu
if (k->get_shift() && selection.active && input_action != INPUT_PASTE) {
- if (k->get_scancode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) {
+ if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) {
selection.click[edit_axis]--;
_validate_selection();
return true;
}
- if (k->get_scancode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL))) {
+ if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL))) {
selection.click[edit_axis]++;
_validate_selection();
return true;
@@ -840,15 +841,33 @@ void GridMapEditor::_text_changed(const String &p_text) {
void GridMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
- Ref<InputEventKey> k = p_ie;
+ const Ref<InputEventKey> k = p_ie;
- if (k.is_valid() && (k->get_scancode() == KEY_UP || k->get_scancode() == KEY_DOWN || k->get_scancode() == KEY_PAGEUP || k->get_scancode() == KEY_PAGEDOWN)) {
+ if (k.is_valid() && (k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_PAGEUP || k->get_keycode() == KEY_PAGEDOWN)) {
+ // Forward the key input to the ItemList so it can be scrolled
mesh_library_palette->call("_gui_input", k);
search_box->accept_event();
}
}
+void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) {
+
+ const Ref<InputEventMouseButton> mb = p_ie;
+
+ // Zoom in/out using Ctrl + mouse wheel
+ if (mb.is_valid() && mb->is_pressed() && mb->get_command()) {
+
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
+ size_slider->set_value(size_slider->get_value() + 0.2);
+ }
+
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ size_slider->set_value(size_slider->get_value() - 0.2);
+ }
+ }
+}
+
void GridMapEditor::_icon_size_changed(float p_value) {
mesh_library_palette->set_icon_scale(p_value);
update_palette();
@@ -877,7 +896,7 @@ void GridMapEditor::update_palette() {
Ref<MeshLibrary> mesh_library = node->get_mesh_library();
if (mesh_library.is_null()) {
- last_mesh_library = NULL;
+ last_mesh_library = nullptr;
search_box->set_text("");
search_box->set_editable(false);
info_message->show();
@@ -907,7 +926,7 @@ void GridMapEditor::update_palette() {
for (List<_CGMEItemSort>::Element *E = il.front(); E; E = E->next()) {
int id = E->get().id;
String name = mesh_library->get_item_name(id);
- Ref<Texture> preview = mesh_library->get_item_preview(id);
+ Ref<Texture2D> preview = mesh_library->get_item_preview(id);
if (name == "") {
name = "#" + itos(id);
@@ -936,7 +955,7 @@ void GridMapEditor::update_palette() {
void GridMapEditor::edit(GridMap *p_gridmap) {
if (!p_gridmap && node)
- node->disconnect("cell_size_changed", this, "_draw_grids");
+ node->disconnect("cell_size_changed", callable_mp(this, &GridMapEditor::_draw_grids));
node = p_gridmap;
@@ -945,16 +964,16 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
_update_selection_transform();
_update_paste_indicator();
- spatial_editor = Object::cast_to<SpatialEditorPlugin>(editor->get_editor_plugin_screen());
+ spatial_editor = Object::cast_to<Node3DEditorPlugin>(editor->get_editor_plugin_screen());
if (!node) {
set_process(false);
for (int i = 0; i < 3; i++) {
- VisualServer::get_singleton()->instance_set_visible(grid_instance[i], false);
+ RenderingServer::get_singleton()->instance_set_visible(grid_instance[i], false);
}
if (cursor_instance.is_valid()) {
- VisualServer::get_singleton()->instance_set_visible(cursor_instance, false);
+ RenderingServer::get_singleton()->instance_set_visible(cursor_instance, false);
}
return;
@@ -970,7 +989,7 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
update_grid();
_update_clip();
- node->connect("cell_size_changed", this, "_draw_grids");
+ node->connect("cell_size_changed", callable_mp(this, &GridMapEditor::_draw_grids));
}
void GridMapEditor::_update_clip() {
@@ -992,7 +1011,7 @@ void GridMapEditor::update_grid() {
edit_grid_xform.basis = Basis();
for (int i = 0; i < 3; i++) {
- VisualServer::get_singleton()->instance_set_visible(grid_instance[i], i == edit_axis);
+ RenderingServer::get_singleton()->instance_set_visible(grid_instance[i], i == edit_axis);
}
updating = true;
@@ -1004,8 +1023,7 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) {
Vector3 edited_floor = node->has_meta("_editor_floor_") ? node->get_meta("_editor_floor_") : Variant();
for (int i = 0; i < 3; i++) {
- if (VS::get_singleton()->mesh_get_surface_count(grid[i]) > 0)
- VS::get_singleton()->mesh_remove_surface(grid[i], 0);
+ RS::get_singleton()->mesh_clear(grid[i]);
edit_floor[i] = edited_floor[i];
}
@@ -1047,11 +1065,11 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) {
}
Array d;
- d.resize(VS::ARRAY_MAX);
- d[VS::ARRAY_VERTEX] = grid_points[i];
- d[VS::ARRAY_COLOR] = grid_colors[i];
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(grid[i], VisualServer::PRIMITIVE_LINES, d);
- VisualServer::get_singleton()->mesh_surface_set_material(grid[i], 0, indicator_mat->get_rid());
+ d.resize(RS::ARRAY_MAX);
+ d[RS::ARRAY_VERTEX] = grid_points[i];
+ d[RS::ARRAY_COLOR] = grid_colors[i];
+ RenderingServer::get_singleton()->mesh_add_surface_from_arrays(grid[i], RenderingServer::PRIMITIVE_LINES, d);
+ RenderingServer::get_singleton()->mesh_surface_set_material(grid[i], 0, indicator_mat->get_rid());
}
}
@@ -1060,37 +1078,37 @@ void GridMapEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- get_tree()->connect("node_removed", this, "_node_removed");
- mesh_library_palette->connect("item_selected", this, "_item_selected_cbk");
+ get_tree()->connect("node_removed", callable_mp(this, &GridMapEditor::_node_removed));
+ mesh_library_palette->connect("item_selected", callable_mp(this, &GridMapEditor::_item_selected_cbk));
for (int i = 0; i < 3; i++) {
- grid[i] = VS::get_singleton()->mesh_create();
- grid_instance[i] = VS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world()->get_scenario());
- selection_level_instance[i] = VisualServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world()->get_scenario());
+ grid[i] = RS::get_singleton()->mesh_create();
+ grid_instance[i] = RS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world()->get_scenario());
+ selection_level_instance[i] = RenderingServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world()->get_scenario());
}
- selection_instance = VisualServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world()->get_scenario());
- paste_instance = VisualServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world()->get_scenario());
+ selection_instance = RenderingServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world()->get_scenario());
+ paste_instance = RenderingServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world()->get_scenario());
_update_selection_transform();
_update_paste_indicator();
} break;
case NOTIFICATION_EXIT_TREE: {
- get_tree()->disconnect("node_removed", this, "_node_removed");
+ get_tree()->disconnect("node_removed", callable_mp(this, &GridMapEditor::_node_removed));
_clear_clipboard_data();
for (int i = 0; i < 3; i++) {
- VS::get_singleton()->free(grid_instance[i]);
- VS::get_singleton()->free(grid[i]);
+ RS::get_singleton()->free(grid_instance[i]);
+ RS::get_singleton()->free(grid[i]);
grid_instance[i] = RID();
grid[i] = RID();
- VisualServer::get_singleton()->free(selection_level_instance[i]);
+ RenderingServer::get_singleton()->free(selection_level_instance[i]);
}
- VisualServer::get_singleton()->free(selection_instance);
- VisualServer::get_singleton()->free(paste_instance);
+ RenderingServer::get_singleton()->free(selection_instance);
+ RenderingServer::get_singleton()->free(paste_instance);
selection_instance = RID();
paste_instance = RID();
} break;
@@ -1105,7 +1123,7 @@ void GridMapEditor::_notification(int p_what) {
if (xf != grid_xform) {
for (int i = 0; i < 3; i++) {
- VS::get_singleton()->instance_set_transform(grid_instance[i], xf * edit_grid_xform);
+ RS::get_singleton()->instance_set_transform(grid_instance[i], xf * edit_grid_xform);
}
grid_xform = xf;
}
@@ -1122,15 +1140,15 @@ void GridMapEditor::_notification(int p_what) {
p.d = edit_floor[edit_axis] * node->get_cell_size()[edit_axis];
p = node->get_transform().xform(p); // plane to snap
- SpatialEditorPlugin *sep = Object::cast_to<SpatialEditorPlugin>(editor->get_editor_plugin_screen());
+ Node3DEditorPlugin *sep = Object::cast_to<Node3DEditorPlugin>(editor->get_editor_plugin_screen());
if (sep)
sep->snap_cursor_to_plane(p);
}
} break;
case NOTIFICATION_THEME_CHANGED: {
- options->set_icon(get_icon("GridMap", "EditorIcons"));
- search_box->set_right_icon(get_icon("Search", "EditorIcons"));
+ options->set_icon(get_theme_icon("GridMap", "EditorIcons"));
+ search_box->set_right_icon(get_theme_icon("Search", "EditorIcons"));
} break;
}
}
@@ -1141,7 +1159,7 @@ void GridMapEditor::_update_cursor_instance() {
}
if (cursor_instance.is_valid())
- VisualServer::get_singleton()->free(cursor_instance);
+ RenderingServer::get_singleton()->free(cursor_instance);
cursor_instance = RID();
if (selected_palette >= 0) {
@@ -1150,8 +1168,8 @@ void GridMapEditor::_update_cursor_instance() {
Ref<Mesh> mesh = node->get_mesh_library()->get_item_mesh(selected_palette);
if (!mesh.is_null() && mesh->get_rid().is_valid()) {
- cursor_instance = VisualServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world()->get_scenario());
- VisualServer::get_singleton()->instance_set_transform(cursor_instance, cursor_transform);
+ cursor_instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world()->get_scenario());
+ RenderingServer::get_singleton()->instance_set_transform(cursor_instance, cursor_transform);
}
}
}
@@ -1181,19 +1199,8 @@ void GridMapEditor::_floor_mouse_exited() {
void GridMapEditor::_bind_methods() {
- ClassDB::bind_method("_text_changed", &GridMapEditor::_text_changed);
- ClassDB::bind_method("_sbox_input", &GridMapEditor::_sbox_input);
- ClassDB::bind_method("_icon_size_changed", &GridMapEditor::_icon_size_changed);
- ClassDB::bind_method("_menu_option", &GridMapEditor::_menu_option);
ClassDB::bind_method("_configure", &GridMapEditor::_configure);
- ClassDB::bind_method("_item_selected_cbk", &GridMapEditor::_item_selected_cbk);
- ClassDB::bind_method("_floor_changed", &GridMapEditor::_floor_changed);
- ClassDB::bind_method("_floor_mouse_exited", &GridMapEditor::_floor_mouse_exited);
ClassDB::bind_method("_set_selection", &GridMapEditor::_set_selection);
- ClassDB::bind_method("_node_removed", &GridMapEditor::_node_removed);
-
- ClassDB::bind_method(D_METHOD("_set_display_mode", "mode"), &GridMapEditor::_set_display_mode);
- ClassDB::bind_method("_draw_grids", &GridMapEditor::_draw_grids);
}
GridMapEditor::GridMapEditor(EditorNode *p_editor) {
@@ -1210,7 +1217,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
spatial_editor_hb = memnew(HBoxContainer);
spatial_editor_hb->set_h_size_flags(SIZE_EXPAND_FILL);
spatial_editor_hb->set_alignment(BoxContainer::ALIGN_END);
- SpatialEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb);
+ Node3DEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb);
spin_box_label = memnew(Label);
spin_box_label->set_text(TTR("Floor:"));
@@ -1220,12 +1227,12 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
floor->set_min(-32767);
floor->set_max(32767);
floor->set_step(1);
- floor->get_line_edit()->add_constant_override("minimum_spaces", 16);
+ floor->get_line_edit()->add_theme_constant_override("minimum_spaces", 16);
spatial_editor_hb->add_child(floor);
- floor->connect("value_changed", this, "_floor_changed");
- floor->connect("mouse_exited", this, "_floor_mouse_exited");
- floor->get_line_edit()->connect("mouse_exited", this, "_floor_mouse_exited");
+ floor->connect("value_changed", callable_mp(this, &GridMapEditor::_floor_changed));
+ floor->connect("mouse_exited", callable_mp(this, &GridMapEditor::_floor_mouse_exited));
+ floor->get_line_edit()->connect("mouse_exited", callable_mp(this, &GridMapEditor::_floor_mouse_exited));
spatial_editor_hb->add_child(memnew(VSeparator));
@@ -1282,7 +1289,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
settings_vbc->add_margin_child(TTR("Pick Distance:"), settings_pick_distance);
clip_mode = CLIP_DISABLED;
- options->get_popup()->connect("id_pressed", this, "_menu_option");
+ options->get_popup()->connect("id_pressed", callable_mp(this, &GridMapEditor::_menu_option));
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
@@ -1292,30 +1299,30 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
search_box->set_placeholder(TTR("Filter meshes"));
hb->add_child(search_box);
- search_box->connect("text_changed", this, "_text_changed");
- search_box->connect("gui_input", this, "_sbox_input");
+ search_box->connect("text_changed", callable_mp(this, &GridMapEditor::_text_changed));
+ search_box->connect("gui_input", callable_mp(this, &GridMapEditor::_sbox_input));
mode_thumbnail = memnew(ToolButton);
mode_thumbnail->set_toggle_mode(true);
mode_thumbnail->set_pressed(true);
- mode_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail", "EditorIcons"));
+ mode_thumbnail->set_icon(p_editor->get_gui_base()->get_theme_icon("FileThumbnail", "EditorIcons"));
hb->add_child(mode_thumbnail);
- mode_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL));
+ mode_thumbnail->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode), varray(DISPLAY_THUMBNAIL));
mode_list = memnew(ToolButton);
mode_list->set_toggle_mode(true);
mode_list->set_pressed(false);
- mode_list->set_icon(p_editor->get_gui_base()->get_icon("FileList", "EditorIcons"));
+ mode_list->set_icon(p_editor->get_gui_base()->get_theme_icon("FileList", "EditorIcons"));
hb->add_child(mode_list);
- mode_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST));
+ mode_list->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode), varray(DISPLAY_LIST));
size_slider = memnew(HSlider);
size_slider->set_h_size_flags(SIZE_EXPAND_FILL);
- size_slider->set_min(0.1f);
+ size_slider->set_min(0.2f);
size_slider->set_max(4.0f);
size_slider->set_step(0.1f);
size_slider->set_value(1.0f);
- size_slider->connect("value_changed", this, "_icon_size_changed");
+ size_slider->connect("value_changed", callable_mp(this, &GridMapEditor::_icon_size_changed));
add_child(size_slider);
EDITOR_DEF("editors/grid_map/preview_size", 64);
@@ -1325,6 +1332,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
mesh_library_palette = memnew(ItemList);
add_child(mesh_library_palette);
mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL);
+ mesh_library_palette->connect("gui_input", callable_mp(this, &GridMapEditor::_mesh_library_palette_input));
info_message = memnew(Label);
info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes."));
@@ -1345,15 +1353,15 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
lock_view = false;
cursor_rot = 0;
- selection_mesh = VisualServer::get_singleton()->mesh_create();
- paste_mesh = VisualServer::get_singleton()->mesh_create();
+ selection_mesh = RenderingServer::get_singleton()->mesh_create();
+ paste_mesh = RenderingServer::get_singleton()->mesh_create();
{
// Selection mesh create.
- PoolVector<Vector3> lines;
- PoolVector<Vector3> triangles;
- PoolVector<Vector3> square[3];
+ Vector<Vector3> lines;
+ Vector<Vector3> triangles;
+ Vector<Vector3> square[3];
for (int i = 0; i < 6; i++) {
@@ -1423,47 +1431,46 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
}
Array d;
- d.resize(VS::ARRAY_MAX);
+ d.resize(RS::ARRAY_MAX);
inner_mat.instance();
inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.2));
- inner_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- inner_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ inner_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ inner_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
- d[VS::ARRAY_VERTEX] = triangles;
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_TRIANGLES, d);
- VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh, 0, inner_mat->get_rid());
+ d[RS::ARRAY_VERTEX] = triangles;
+ RenderingServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, RS::PRIMITIVE_TRIANGLES, d);
+ RenderingServer::get_singleton()->mesh_surface_set_material(selection_mesh, 0, inner_mat->get_rid());
outer_mat.instance();
outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.8));
outer_mat->set_on_top_of_alpha();
- outer_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- outer_mat->set_line_width(3.0);
- outer_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+
+ outer_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ outer_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
selection_floor_mat.instance();
selection_floor_mat->set_albedo(Color(0.80, 0.80, 1.0, 1));
selection_floor_mat->set_on_top_of_alpha();
- selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- selection_floor_mat->set_line_width(3.0);
+ selection_floor_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
- d[VS::ARRAY_VERTEX] = lines;
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_LINES, d);
- VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh, 1, outer_mat->get_rid());
+ d[RS::ARRAY_VERTEX] = lines;
+ RenderingServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, RS::PRIMITIVE_LINES, d);
+ RenderingServer::get_singleton()->mesh_surface_set_material(selection_mesh, 1, outer_mat->get_rid());
- d[VS::ARRAY_VERTEX] = triangles;
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(paste_mesh, VS::PRIMITIVE_TRIANGLES, d);
- VisualServer::get_singleton()->mesh_surface_set_material(paste_mesh, 0, inner_mat->get_rid());
+ d[RS::ARRAY_VERTEX] = triangles;
+ RenderingServer::get_singleton()->mesh_add_surface_from_arrays(paste_mesh, RS::PRIMITIVE_TRIANGLES, d);
+ RenderingServer::get_singleton()->mesh_surface_set_material(paste_mesh, 0, inner_mat->get_rid());
- d[VS::ARRAY_VERTEX] = lines;
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(paste_mesh, VS::PRIMITIVE_LINES, d);
- VisualServer::get_singleton()->mesh_surface_set_material(paste_mesh, 1, outer_mat->get_rid());
+ d[RS::ARRAY_VERTEX] = lines;
+ RenderingServer::get_singleton()->mesh_add_surface_from_arrays(paste_mesh, RS::PRIMITIVE_LINES, d);
+ RenderingServer::get_singleton()->mesh_surface_set_material(paste_mesh, 1, outer_mat->get_rid());
for (int i = 0; i < 3; i++) {
- d[VS::ARRAY_VERTEX] = square[i];
- selection_level_mesh[i] = VS::get_singleton()->mesh_create();
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_level_mesh[i], VS::PRIMITIVE_LINES, d);
- VisualServer::get_singleton()->mesh_surface_set_material(selection_level_mesh[i], 0, selection_floor_mat->get_rid());
+ d[RS::ARRAY_VERTEX] = square[i];
+ selection_level_mesh[i] = RS::get_singleton()->mesh_create();
+ RenderingServer::get_singleton()->mesh_add_surface_from_arrays(selection_level_mesh[i], RS::PRIMITIVE_LINES, d);
+ RenderingServer::get_singleton()->mesh_surface_set_material(selection_level_mesh[i], 0, selection_floor_mat->get_rid());
}
}
@@ -1472,10 +1479,10 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
accumulated_floor_delta = 0.0;
indicator_mat.instance();
- indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- indicator_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- indicator_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- indicator_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ indicator_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ indicator_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
+ indicator_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
+ indicator_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
indicator_mat->set_albedo(Color(0.8, 0.5, 0.1));
}
@@ -1486,24 +1493,24 @@ GridMapEditor::~GridMapEditor() {
for (int i = 0; i < 3; i++) {
if (grid[i].is_valid())
- VisualServer::get_singleton()->free(grid[i]);
+ RenderingServer::get_singleton()->free(grid[i]);
if (grid_instance[i].is_valid())
- VisualServer::get_singleton()->free(grid_instance[i]);
+ RenderingServer::get_singleton()->free(grid_instance[i]);
if (cursor_instance.is_valid())
- VisualServer::get_singleton()->free(cursor_instance);
+ RenderingServer::get_singleton()->free(cursor_instance);
if (selection_level_instance[i].is_valid())
- VisualServer::get_singleton()->free(selection_level_instance[i]);
+ RenderingServer::get_singleton()->free(selection_level_instance[i]);
if (selection_level_mesh[i].is_valid())
- VisualServer::get_singleton()->free(selection_level_mesh[i]);
+ RenderingServer::get_singleton()->free(selection_level_mesh[i]);
}
- VisualServer::get_singleton()->free(selection_mesh);
+ RenderingServer::get_singleton()->free(selection_mesh);
if (selection_instance.is_valid())
- VisualServer::get_singleton()->free(selection_instance);
+ RenderingServer::get_singleton()->free(selection_instance);
- VisualServer::get_singleton()->free(paste_mesh);
+ RenderingServer::get_singleton()->free(paste_mesh);
if (paste_instance.is_valid())
- VisualServer::get_singleton()->free(paste_instance);
+ RenderingServer::get_singleton()->free(paste_instance);
}
void GridMapEditorPlugin::_notification(int p_what) {
@@ -1512,10 +1519,10 @@ void GridMapEditorPlugin::_notification(int p_what) {
switch ((int)EditorSettings::get_singleton()->get("editors/grid_map/editor_side")) {
case 0: { // Left.
- SpatialEditor::get_singleton()->get_palette_split()->move_child(grid_map_editor, 0);
+ Node3DEditor::get_singleton()->get_palette_split()->move_child(grid_map_editor, 0);
} break;
case 1: { // Right.
- SpatialEditor::get_singleton()->get_palette_split()->move_child(grid_map_editor, 1);
+ Node3DEditor::get_singleton()->get_palette_split()->move_child(grid_map_editor, 1);
} break;
}
}
@@ -1541,7 +1548,7 @@ void GridMapEditorPlugin::make_visible(bool p_visible) {
grid_map_editor->spatial_editor_hb->hide();
grid_map_editor->hide();
- grid_map_editor->edit(NULL);
+ grid_map_editor->edit(nullptr);
grid_map_editor->set_process(false);
}
}
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index 404e95b74c..fd880e8b7b 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -36,7 +36,7 @@
#include "editor/pane_drag.h"
#include "grid_map.h"
-class SpatialEditorPlugin;
+class Node3DEditorPlugin;
class GridMapEditor : public VBoxContainer {
GDCLASS(GridMapEditor, VBoxContainer);
@@ -125,10 +125,10 @@ class GridMapEditor : public VBoxContainer {
List<ClipboardItem> clipboard_items;
- Ref<SpatialMaterial> indicator_mat;
- Ref<SpatialMaterial> inner_mat;
- Ref<SpatialMaterial> outer_mat;
- Ref<SpatialMaterial> selection_floor_mat;
+ Ref<StandardMaterial3D> indicator_mat;
+ Ref<StandardMaterial3D> inner_mat;
+ Ref<StandardMaterial3D> outer_mat;
+ Ref<StandardMaterial3D> selection_floor_mat;
bool updating;
@@ -188,7 +188,7 @@ class GridMapEditor : public VBoxContainer {
};
- SpatialEditorPlugin *spatial_editor;
+ Node3DEditorPlugin *spatial_editor;
struct AreaDisplay {
@@ -214,6 +214,7 @@ class GridMapEditor : public VBoxContainer {
void _text_changed(const String &p_text);
void _sbox_input(const Ref<InputEvent> &p_ie);
+ void _mesh_library_palette_input(const Ref<InputEvent> &p_ie);
void _icon_size_changed(float p_value);
@@ -231,7 +232,7 @@ class GridMapEditor : public VBoxContainer {
void _delete_selection();
void _fill_selection();
- bool do_input_action(Camera *p_camera, const Point2 &p_point, bool p_click);
+ bool do_input_action(Camera3D *p_camera, const Point2 &p_point, bool p_click);
friend class GridMapEditorPlugin;
@@ -241,7 +242,7 @@ protected:
static void _bind_methods();
public:
- bool forward_spatial_input_event(Camera *p_camera, const Ref<InputEvent> &p_event);
+ bool forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event);
void edit(GridMap *p_gridmap);
GridMapEditor() {}
@@ -260,7 +261,7 @@ protected:
void _notification(int p_what);
public:
- virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); }
+ virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); }
virtual String get_name() const { return "GridMap"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_object);
diff --git a/modules/gridmap/icons/icon_grid_map.svg b/modules/gridmap/icons/GridMap.svg
index eafe1211f2..eafe1211f2 100644
--- a/modules/gridmap/icons/icon_grid_map.svg
+++ b/modules/gridmap/icons/GridMap.svg
diff --git a/modules/gridmap/register_types.h b/modules/gridmap/register_types.h
index bc720f460c..c0e3c39ca8 100644
--- a/modules/gridmap/register_types.h
+++ b/modules/gridmap/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef GRIDMAP_REGISTER_TYPES_H
+#define GRIDMAP_REGISTER_TYPES_H
+
void register_gridmap_types();
void unregister_gridmap_types();
+
+#endif // GRIDMAP_REGISTER_TYPES_H
diff --git a/modules/hdr/SCsub b/modules/hdr/SCsub
index c960e8126b..a709397c9a 100644
--- a/modules/hdr/SCsub
+++ b/modules/hdr/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_hdr = env_modules.Clone()
diff --git a/modules/hdr/config.py b/modules/hdr/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/hdr/config.py
+++ b/modules/hdr/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index 3fa7266f1a..c03ae4ab1f 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -63,15 +63,15 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
int width = f->get_line().to_int();
- PoolVector<uint8_t> imgdata;
+ Vector<uint8_t> imgdata;
imgdata.resize(height * width * sizeof(uint32_t));
{
- PoolVector<uint8_t>::Write w = imgdata.write();
+ uint8_t *w = imgdata.ptrw();
- uint8_t *ptr = (uint8_t *)w.ptr();
+ uint8_t *ptr = (uint8_t *)w;
if (width < 8 || width >= 32768) {
// Read flat data
diff --git a/modules/hdr/register_types.cpp b/modules/hdr/register_types.cpp
index 2ef6b7cd07..5f2d1578c5 100644
--- a/modules/hdr/register_types.cpp
+++ b/modules/hdr/register_types.cpp
@@ -32,7 +32,7 @@
#include "image_loader_hdr.h"
-static ImageLoaderHDR *image_loader_hdr = NULL;
+static ImageLoaderHDR *image_loader_hdr = nullptr;
void register_hdr_types() {
diff --git a/modules/hdr/register_types.h b/modules/hdr/register_types.h
index c1c69a1e27..02441516ec 100644
--- a/modules/hdr/register_types.h
+++ b/modules/hdr/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef HDR_REGISTER_TYPES_H
+#define HDR_REGISTER_TYPES_H
+
void register_hdr_types();
void unregister_hdr_types();
+
+#endif // HDR_REGISTER_TYPES_H
diff --git a/modules/jpg/SCsub b/modules/jpg/SCsub
index 96e8e704dd..8ee8e6dd6e 100644
--- a/modules/jpg/SCsub
+++ b/modules/jpg/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_jpg = env_modules.Clone()
diff --git a/modules/jpg/config.py b/modules/jpg/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/jpg/config.py
+++ b/modules/jpg/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp
index a1f0f0ef6a..9e87d11ac1 100644
--- a/modules/jpg/image_loader_jpegd.cpp
+++ b/modules/jpg/image_loader_jpegd.cpp
@@ -57,13 +57,13 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
const int dst_bpl = image_width * comps;
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(dst_bpl * image_height);
- PoolVector<uint8_t>::Write dw = data.write();
+ uint8_t *dw = data.ptrw();
- jpgd::uint8 *pImage_data = (jpgd::uint8 *)dw.ptr();
+ jpgd::uint8 *pImage_data = (jpgd::uint8 *)dw;
for (int y = 0; y < image_height; y++) {
const jpgd::uint8 *pScan_line;
@@ -96,7 +96,6 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
else
fmt = Image::FORMAT_RGB8;
- dw.release();
p_image->create(image_width, image_height, 0, fmt, data);
return OK;
@@ -104,18 +103,18 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
- PoolVector<uint8_t> src_image;
+ Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
src_image.resize(src_image_len);
- PoolVector<uint8_t>::Write w = src_image.write();
+ uint8_t *w = src_image.ptrw();
f->get_buffer(&w[0], src_image_len);
f->close();
- Error err = jpeg_load_image_from_buffer(p_image.ptr(), w.ptr(), src_image_len);
+ Error err = jpeg_load_image_from_buffer(p_image.ptr(), w, src_image_len);
return err;
}
diff --git a/modules/jpg/register_types.cpp b/modules/jpg/register_types.cpp
index f6077d5c68..61375fef10 100644
--- a/modules/jpg/register_types.cpp
+++ b/modules/jpg/register_types.cpp
@@ -32,7 +32,7 @@
#include "image_loader_jpegd.h"
-static ImageLoaderJPG *image_loader_jpg = NULL;
+static ImageLoaderJPG *image_loader_jpg = nullptr;
void register_jpg_types() {
diff --git a/modules/jpg/register_types.h b/modules/jpg/register_types.h
index 291098fae2..52cd378b3a 100644
--- a/modules/jpg/register_types.h
+++ b/modules/jpg/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef JPG_REGISTER_TYPES_H
+#define JPG_REGISTER_TYPES_H
+
void register_jpg_types();
void unregister_jpg_types();
+
+#endif // JPG_REGISTER_TYPES_H
diff --git a/modules/jsonrpc/SCsub b/modules/jsonrpc/SCsub
index 13c9ffb253..fe5312670a 100644
--- a/modules/jsonrpc/SCsub
+++ b/modules/jsonrpc/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_jsonrpc = env_modules.Clone()
env_jsonrpc.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/jsonrpc/config.py b/modules/jsonrpc/config.py
index 53bc827027..d22f9454ed 100644
--- a/modules/jsonrpc/config.py
+++ b/modules/jsonrpc/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return True
+ return True
+
def configure(env):
- pass
+ pass
diff --git a/modules/jsonrpc/jsonrpc.cpp b/modules/jsonrpc/jsonrpc.cpp
index 014b65e3e2..393269d422 100644
--- a/modules/jsonrpc/jsonrpc.cpp
+++ b/modules/jsonrpc/jsonrpc.cpp
@@ -119,7 +119,7 @@ Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elem
id = dict["id"];
}
- if (object == NULL || !object->has_method(method)) {
+ if (object == nullptr || !object->has_method(method)) {
ret = make_response_error(JSONRPC::METHOD_NOT_FOUND, "Method not found", id);
} else {
Variant call_ret = object->callv(method, args);
diff --git a/modules/jsonrpc/register_types.h b/modules/jsonrpc/register_types.h
index 958f16344a..854d73a21f 100644
--- a/modules/jsonrpc/register_types.h
+++ b/modules/jsonrpc/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef JSONRPC_REGISTER_TYPES_H
+#define JSONRPC_REGISTER_TYPES_H
+
void register_jsonrpc_types();
void unregister_jsonrpc_types();
+
+#endif // JSONRPC_REGISTER_TYPES_H
diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub
index 0c6c703e16..5f5d25a3ee 100755
--- a/modules/mbedtls/SCsub
+++ b/modules/mbedtls/SCsub
@@ -1,11 +1,11 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_mbed_tls = env_modules.Clone()
-if env['builtin_mbedtls']:
+if env["builtin_mbedtls"]:
# Thirdparty source files
thirdparty_sources = [
"aes.c",
@@ -86,7 +86,7 @@ if env['builtin_mbedtls']:
"x509_csr.c",
"x509write_crt.c",
"x509write_csr.c",
- "xtea.c"
+ "xtea.c",
]
thirdparty_dir = "#thirdparty/mbedtls/library/"
diff --git a/modules/mbedtls/config.py b/modules/mbedtls/config.py
index 1c8cd12a2d..d22f9454ed 100755
--- a/modules/mbedtls/config.py
+++ b/modules/mbedtls/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
index 2bd80064e3..a47a4503a5 100644
--- a/modules/mbedtls/crypto_mbedtls.cpp
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -53,22 +53,22 @@ CryptoKey *CryptoKeyMbedTLS::create() {
Error CryptoKeyMbedTLS::load(String p_path) {
ERR_FAIL_COND_V_MSG(locks, ERR_ALREADY_IN_USE, "Key is in use");
- PoolByteArray out;
+ PackedByteArray out;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_INVALID_PARAMETER, "Cannot open CryptoKeyMbedTLS file '" + p_path + "'.");
int flen = f->get_len();
out.resize(flen + 1);
{
- PoolByteArray::Write w = out.write();
- f->get_buffer(w.ptr(), flen);
+ uint8_t *w = out.ptrw();
+ f->get_buffer(w, flen);
w[flen] = 0; //end f string
}
memdelete(f);
- int ret = mbedtls_pk_parse_key(&pkey, out.read().ptr(), out.size(), NULL, 0);
+ int ret = mbedtls_pk_parse_key(&pkey, out.ptr(), out.size(), nullptr, 0);
// We MUST zeroize the memory for safety!
- mbedtls_platform_zeroize(out.write().ptr(), out.size());
+ mbedtls_platform_zeroize(out.ptrw(), out.size());
ERR_FAIL_COND_V_MSG(ret, FAILED, "Error parsing private key '" + itos(ret) + "'.");
return OK;
@@ -102,20 +102,20 @@ X509Certificate *X509CertificateMbedTLS::create() {
Error X509CertificateMbedTLS::load(String p_path) {
ERR_FAIL_COND_V_MSG(locks, ERR_ALREADY_IN_USE, "Certificate is in use");
- PoolByteArray out;
+ PackedByteArray out;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_INVALID_PARAMETER, "Cannot open X509CertificateMbedTLS file '" + p_path + "'.");
int flen = f->get_len();
out.resize(flen + 1);
{
- PoolByteArray::Write w = out.write();
- f->get_buffer(w.ptr(), flen);
+ uint8_t *w = out.ptrw();
+ f->get_buffer(w, flen);
w[flen] = 0; //end f string
}
memdelete(f);
- int ret = mbedtls_x509_crt_parse(&cert, out.read().ptr(), out.size());
+ int ret = mbedtls_x509_crt_parse(&cert, out.ptr(), out.size());
ERR_FAIL_COND_V_MSG(ret, FAILED, "Error parsing some certificates: " + itos(ret));
return OK;
@@ -167,11 +167,11 @@ void CryptoMbedTLS::initialize_crypto() {
}
void CryptoMbedTLS::finalize_crypto() {
- Crypto::_create = NULL;
- Crypto::_load_default_certificates = NULL;
+ Crypto::_create = nullptr;
+ Crypto::_load_default_certificates = nullptr;
if (default_certs) {
memdelete(default_certs);
- default_certs = NULL;
+ default_certs = nullptr;
}
X509CertificateMbedTLS::finalize();
CryptoKeyMbedTLS::finalize();
@@ -180,7 +180,7 @@ void CryptoMbedTLS::finalize_crypto() {
CryptoMbedTLS::CryptoMbedTLS() {
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_entropy_init(&entropy);
- int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
+ int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, nullptr, 0);
if (ret != 0) {
ERR_PRINT(" failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
}
@@ -191,17 +191,17 @@ CryptoMbedTLS::~CryptoMbedTLS() {
mbedtls_entropy_free(&entropy);
}
-X509CertificateMbedTLS *CryptoMbedTLS::default_certs = NULL;
+X509CertificateMbedTLS *CryptoMbedTLS::default_certs = nullptr;
X509CertificateMbedTLS *CryptoMbedTLS::get_default_certificates() {
return default_certs;
}
void CryptoMbedTLS::load_default_certificates(String p_path) {
- ERR_FAIL_COND(default_certs != NULL);
+ ERR_FAIL_COND(default_certs != nullptr);
default_certs = memnew(X509CertificateMbedTLS);
- ERR_FAIL_COND(default_certs == NULL);
+ ERR_FAIL_COND(default_certs == nullptr);
if (p_path != "") {
// Use certs defined in project settings.
@@ -210,15 +210,15 @@ void CryptoMbedTLS::load_default_certificates(String p_path) {
#ifdef BUILTIN_CERTS_ENABLED
else {
// Use builtin certs only if user did not override it in project settings.
- PoolByteArray out;
+ PackedByteArray out;
out.resize(_certs_uncompressed_size + 1);
- PoolByteArray::Write w = out.write();
- Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
+ uint8_t *w = out.ptrw();
+ Compression::decompress(w, _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
#ifdef DEBUG_ENABLED
print_verbose("Loaded builtin certs");
#endif
- default_certs->load_from_memory(out.read().ptr(), out.size());
+ default_certs->load_from_memory(out.ptr(), out.size());
}
#endif
}
@@ -227,15 +227,15 @@ Ref<CryptoKey> CryptoMbedTLS::generate_rsa(int p_bytes) {
Ref<CryptoKeyMbedTLS> out;
out.instance();
int ret = mbedtls_pk_setup(&(out->pkey), mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
- ERR_FAIL_COND_V(ret != 0, NULL);
+ ERR_FAIL_COND_V(ret != 0, nullptr);
ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(out->pkey), mbedtls_ctr_drbg_random, &ctr_drbg, p_bytes, 65537);
- ERR_FAIL_COND_V(ret != 0, NULL);
+ ERR_FAIL_COND_V(ret != 0, nullptr);
return out;
}
Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) {
- Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS> >(p_key);
- ERR_FAIL_COND_V_MSG(key.is_null(), NULL, "Invalid private key argument.");
+ Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS>>(p_key);
+ ERR_FAIL_COND_V_MSG(key.is_null(), nullptr, "Invalid private key argument.");
mbedtls_x509write_cert crt;
mbedtls_x509write_crt_init(&crt);
@@ -250,7 +250,7 @@ Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoK
mbedtls_mpi_init(&serial);
uint8_t rand_serial[20];
mbedtls_ctr_drbg_random(&ctr_drbg, rand_serial, 20);
- ERR_FAIL_COND_V(mbedtls_mpi_read_binary(&serial, rand_serial, 20), NULL);
+ ERR_FAIL_COND_V(mbedtls_mpi_read_binary(&serial, rand_serial, 20), nullptr);
mbedtls_x509write_crt_set_serial(&crt, &serial);
mbedtls_x509write_crt_set_validity(&crt, p_not_before.utf8().get_data(), p_not_after.utf8().get_data());
@@ -268,7 +268,7 @@ Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoK
mbedtls_mpi_free(&serial);
mbedtls_x509write_crt_free(&crt);
ERR_PRINT("Generated invalid certificate: " + itos(err));
- return NULL;
+ return nullptr;
}
mbedtls_mpi_free(&serial);
@@ -276,9 +276,9 @@ Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoK
return out;
}
-PoolByteArray CryptoMbedTLS::generate_random_bytes(int p_bytes) {
- PoolByteArray out;
+PackedByteArray CryptoMbedTLS::generate_random_bytes(int p_bytes) {
+ PackedByteArray out;
out.resize(p_bytes);
- mbedtls_ctr_drbg_random(&ctr_drbg, out.write().ptr(), p_bytes);
+ mbedtls_ctr_drbg_random(&ctr_drbg, out.ptrw(), p_bytes);
return out;
}
diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h
index edb5841761..db3d00a5e3 100644
--- a/modules/mbedtls/crypto_mbedtls.h
+++ b/modules/mbedtls/crypto_mbedtls.h
@@ -49,7 +49,7 @@ private:
public:
static CryptoKey *create();
static void make_default() { CryptoKey::_create = create; }
- static void finalize() { CryptoKey::_create = NULL; }
+ static void finalize() { CryptoKey::_create = nullptr; }
virtual Error load(String p_path);
virtual Error save(String p_path);
@@ -78,7 +78,7 @@ private:
public:
static X509Certificate *create();
static void make_default() { X509Certificate::_create = create; }
- static void finalize() { X509Certificate::_create = NULL; }
+ static void finalize() { X509Certificate::_create = nullptr; }
virtual Error load(String p_path);
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len);
@@ -113,7 +113,7 @@ public:
static X509CertificateMbedTLS *get_default_certificates();
static void load_default_certificates(String p_path);
- virtual PoolByteArray generate_random_bytes(int p_bytes);
+ virtual PackedByteArray generate_random_bytes(int p_bytes);
virtual Ref<CryptoKey> generate_rsa(int p_bytes);
virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
diff --git a/modules/mbedtls/dtls_server_mbedtls.cpp b/modules/mbedtls/dtls_server_mbedtls.cpp
new file mode 100644
index 0000000000..f31f067f4e
--- /dev/null
+++ b/modules/mbedtls/dtls_server_mbedtls.cpp
@@ -0,0 +1,78 @@
+/*************************************************************************/
+/* dtls_server_mbedtls.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "dtls_server_mbedtls.h"
+#include "packet_peer_mbed_dtls.h"
+
+Error DTLSServerMbedTLS::setup(Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain) {
+ ERR_FAIL_COND_V(_cookies->setup() != OK, ERR_ALREADY_IN_USE);
+ _key = p_key;
+ _cert = p_cert;
+ _ca_chain = p_ca_chain;
+ return OK;
+}
+
+void DTLSServerMbedTLS::stop() {
+ _cookies->clear();
+}
+
+Ref<PacketPeerDTLS> DTLSServerMbedTLS::take_connection(Ref<PacketPeerUDP> p_udp_peer) {
+ Ref<PacketPeerMbedDTLS> out;
+ out.instance();
+
+ ERR_FAIL_COND_V(!out.is_valid(), out);
+ ERR_FAIL_COND_V(!p_udp_peer.is_valid(), out);
+ out->accept_peer(p_udp_peer, _key, _cert, _ca_chain, _cookies);
+ return out;
+}
+
+DTLSServer *DTLSServerMbedTLS::_create_func() {
+
+ return memnew(DTLSServerMbedTLS);
+}
+
+void DTLSServerMbedTLS::initialize() {
+
+ _create = _create_func;
+ available = true;
+}
+
+void DTLSServerMbedTLS::finalize() {
+ _create = nullptr;
+ available = false;
+}
+
+DTLSServerMbedTLS::DTLSServerMbedTLS() {
+ _cookies.instance();
+}
+
+DTLSServerMbedTLS::~DTLSServerMbedTLS() {
+ stop();
+}
diff --git a/modules/mono/utils/mutex_utils.h b/modules/mbedtls/dtls_server_mbedtls.h
index bafd875395..d61ab3179e 100644
--- a/modules/mono/utils/mutex_utils.h
+++ b/modules/mbedtls/dtls_server_mbedtls.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* mutex_utils.h */
+/* dtls_server_mbedtls.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,40 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef MUTEX_UTILS_H
-#define MUTEX_UTILS_H
+#ifndef MBED_DTLS_SERVER_H
+#define MBED_DTLS_SERVER_H
-#include "core/error_macros.h"
-#include "core/os/mutex.h"
+#include "core/io/dtls_server.h"
+#include "ssl_context_mbedtls.h"
-#include "macros.h"
+class DTLSServerMbedTLS : public DTLSServer {
-class ScopedMutexLock {
- Mutex *mutex;
+private:
+ static DTLSServer *_create_func();
+ Ref<CryptoKey> _key;
+ Ref<X509Certificate> _cert;
+ Ref<X509Certificate> _ca_chain;
+ Ref<CookieContextMbedTLS> _cookies;
public:
- ScopedMutexLock(Mutex *mutex) {
- this->mutex = mutex;
-#ifndef NO_THREADS
-#ifdef DEBUG_ENABLED
- CRASH_COND(!mutex);
-#endif
- this->mutex->lock();
-#endif
- }
+ static void initialize();
+ static void finalize();
- ~ScopedMutexLock() {
-#ifndef NO_THREADS
-#ifdef DEBUG_ENABLED
- CRASH_COND(!mutex);
-#endif
- mutex->unlock();
-#endif
- }
-};
-
-#define SCOPED_MUTEX_LOCK(m_mutex) ScopedMutexLock GD_UNIQUE_NAME(__scoped_mutex_lock__)(m_mutex);
+ virtual Error setup(Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>());
+ virtual void stop();
+ virtual Ref<PacketPeerDTLS> take_connection(Ref<PacketPeerUDP> p_peer);
-// TODO: Add version that receives a lambda instead, once C++11 is allowed
+ DTLSServerMbedTLS();
+ ~DTLSServerMbedTLS();
+};
-#endif // MUTEX_UTILS_H
+#endif // MBED_DTLS_SERVER_H
diff --git a/modules/mbedtls/packet_peer_mbed_dtls.cpp b/modules/mbedtls/packet_peer_mbed_dtls.cpp
new file mode 100755
index 0000000000..b2aa5f5827
--- /dev/null
+++ b/modules/mbedtls/packet_peer_mbed_dtls.cpp
@@ -0,0 +1,297 @@
+/*************************************************************************/
+/* packet_peer_mbed_dtls.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "packet_peer_mbed_dtls.h"
+#include "mbedtls/platform_util.h"
+
+#include "core/io/stream_peer_ssl.h"
+#include "core/os/file_access.h"
+
+int PacketPeerMbedDTLS::bio_send(void *ctx, const unsigned char *buf, size_t len) {
+
+ if (buf == nullptr || len <= 0) return 0;
+
+ PacketPeerMbedDTLS *sp = (PacketPeerMbedDTLS *)ctx;
+
+ ERR_FAIL_COND_V(sp == nullptr, 0);
+
+ Error err = sp->base->put_packet((const uint8_t *)buf, len);
+ if (err == ERR_BUSY) {
+ return MBEDTLS_ERR_SSL_WANT_WRITE;
+ } else if (err != OK) {
+ ERR_FAIL_V(MBEDTLS_ERR_SSL_INTERNAL_ERROR);
+ }
+ return len;
+}
+
+int PacketPeerMbedDTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
+
+ if (buf == nullptr || len <= 0) return 0;
+
+ PacketPeerMbedDTLS *sp = (PacketPeerMbedDTLS *)ctx;
+
+ ERR_FAIL_COND_V(sp == nullptr, 0);
+
+ int pc = sp->base->get_available_packet_count();
+ if (pc == 0) {
+ return MBEDTLS_ERR_SSL_WANT_READ;
+ } else if (pc < 0) {
+ ERR_FAIL_V(MBEDTLS_ERR_SSL_INTERNAL_ERROR);
+ }
+
+ const uint8_t *buffer;
+ int buffer_size = 0;
+ Error err = sp->base->get_packet(&buffer, buffer_size);
+ if (err != OK) {
+ return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ }
+ copymem(buf, buffer, buffer_size);
+ return buffer_size;
+}
+
+void PacketPeerMbedDTLS::_cleanup() {
+
+ ssl_ctx->clear();
+ base = Ref<PacketPeer>();
+ status = STATUS_DISCONNECTED;
+}
+
+int PacketPeerMbedDTLS::_set_cookie() {
+ // Setup DTLS session cookie for this client
+ uint8_t client_id[18];
+ IP_Address addr = base->get_packet_address();
+ uint16_t port = base->get_packet_port();
+ copymem(client_id, addr.get_ipv6(), 16);
+ copymem(&client_id[16], (uint8_t *)&port, 2);
+ return mbedtls_ssl_set_client_transport_id(ssl_ctx->get_context(), client_id, 18);
+}
+
+Error PacketPeerMbedDTLS::_do_handshake() {
+ int ret = 0;
+ while ((ret = mbedtls_ssl_handshake(ssl_ctx->get_context())) != 0) {
+ if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ if (ret != MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
+ ERR_PRINT("TLS handshake error: " + itos(ret));
+ SSLContextMbedTLS::print_mbedtls_error(ret);
+ }
+ _cleanup();
+ status = STATUS_ERROR;
+ return FAILED;
+ }
+ // Will retry via poll later
+ return OK;
+ }
+
+ status = STATUS_CONNECTED;
+ return OK;
+}
+
+Error PacketPeerMbedDTLS::connect_to_peer(Ref<PacketPeerUDP> p_base, bool p_validate_certs, const String &p_for_hostname, Ref<X509Certificate> p_ca_certs) {
+
+ ERR_FAIL_COND_V(!p_base.is_valid() || !p_base->is_connected_to_host(), ERR_INVALID_PARAMETER);
+
+ base = p_base;
+ int ret = 0;
+ int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE;
+
+ Error err = ssl_ctx->init_client(MBEDTLS_SSL_TRANSPORT_DATAGRAM, authmode, p_ca_certs);
+ ERR_FAIL_COND_V(err != OK, err);
+
+ mbedtls_ssl_set_hostname(ssl_ctx->get_context(), p_for_hostname.utf8().get_data());
+ mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, nullptr);
+ mbedtls_ssl_set_timer_cb(ssl_ctx->get_context(), &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay);
+
+ status = STATUS_HANDSHAKING;
+
+ if ((ret = _do_handshake()) != OK) {
+ status = STATUS_ERROR_HOSTNAME_MISMATCH;
+ return FAILED;
+ }
+
+ return OK;
+}
+
+Error PacketPeerMbedDTLS::accept_peer(Ref<PacketPeerUDP> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain, Ref<CookieContextMbedTLS> p_cookies) {
+
+ Error err = ssl_ctx->init_server(MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_VERIFY_NONE, p_key, p_cert, p_cookies);
+ ERR_FAIL_COND_V(err != OK, err);
+
+ base = p_base;
+ base->set_blocking_mode(false);
+
+ mbedtls_ssl_session_reset(ssl_ctx->get_context());
+
+ int ret = _set_cookie();
+ if (ret != 0) {
+ _cleanup();
+ ERR_FAIL_V_MSG(FAILED, "Error setting DTLS client cookie");
+ }
+
+ mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, nullptr);
+ mbedtls_ssl_set_timer_cb(ssl_ctx->get_context(), &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay);
+
+ status = STATUS_HANDSHAKING;
+
+ if ((ret = _do_handshake()) != OK) {
+ status = STATUS_ERROR;
+ return FAILED;
+ }
+
+ return OK;
+}
+
+Error PacketPeerMbedDTLS::put_packet(const uint8_t *p_buffer, int p_bytes) {
+
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
+
+ if (p_bytes == 0)
+ return OK;
+
+ int ret = mbedtls_ssl_write(ssl_ctx->get_context(), p_buffer, p_bytes);
+ if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
+ ret = 0; // non blocking io
+ } else if (ret <= 0) {
+ SSLContextMbedTLS::print_mbedtls_error(ret);
+ _cleanup();
+ return ERR_CONNECTION_ERROR;
+ }
+
+ return OK;
+}
+
+Error PacketPeerMbedDTLS::get_packet(const uint8_t **r_buffer, int &r_bytes) {
+
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
+
+ r_bytes = 0;
+
+ int ret = mbedtls_ssl_read(ssl_ctx->get_context(), packet_buffer, PACKET_BUFFER_SIZE);
+ if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
+ ret = 0; // non blocking io
+ } else if (ret <= 0) {
+ if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ // Also send close notify back
+ disconnect_from_peer();
+ } else {
+ _cleanup();
+ status = STATUS_ERROR;
+ SSLContextMbedTLS::print_mbedtls_error(ret);
+ }
+ return ERR_CONNECTION_ERROR;
+ }
+ *r_buffer = packet_buffer;
+ r_bytes = ret;
+
+ return OK;
+}
+
+void PacketPeerMbedDTLS::poll() {
+
+ if (status == STATUS_HANDSHAKING) {
+ _do_handshake();
+ return;
+ } else if (status != STATUS_CONNECTED) {
+ return;
+ }
+
+ ERR_FAIL_COND(!base.is_valid());
+
+ int ret = mbedtls_ssl_read(ssl_ctx->get_context(), nullptr, 0);
+
+ if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ // Also send close notify back
+ disconnect_from_peer();
+ } else {
+ _cleanup();
+ status = STATUS_ERROR;
+ SSLContextMbedTLS::print_mbedtls_error(ret);
+ }
+ }
+}
+
+int PacketPeerMbedDTLS::get_available_packet_count() const {
+
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, 0);
+
+ return mbedtls_ssl_get_bytes_avail(&(ssl_ctx->ssl)) > 0 ? 1 : 0;
+}
+
+int PacketPeerMbedDTLS::get_max_packet_size() const {
+
+ return 488; // 512 (UDP in Godot) - 24 (DTLS header)
+}
+
+PacketPeerMbedDTLS::PacketPeerMbedDTLS() {
+
+ ssl_ctx.instance();
+ status = STATUS_DISCONNECTED;
+}
+
+PacketPeerMbedDTLS::~PacketPeerMbedDTLS() {
+ disconnect_from_peer();
+}
+
+void PacketPeerMbedDTLS::disconnect_from_peer() {
+
+ if (status != STATUS_CONNECTED && status != STATUS_HANDSHAKING)
+ return;
+
+ if (status == STATUS_CONNECTED) {
+ int ret = 0;
+ // Send SSL close notification, blocking, but ignore other errors.
+ do
+ ret = mbedtls_ssl_close_notify(ssl_ctx->get_context());
+ while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
+ }
+
+ _cleanup();
+}
+
+PacketPeerMbedDTLS::Status PacketPeerMbedDTLS::get_status() const {
+
+ return status;
+}
+
+PacketPeerDTLS *PacketPeerMbedDTLS::_create_func() {
+
+ return memnew(PacketPeerMbedDTLS);
+}
+
+void PacketPeerMbedDTLS::initialize_dtls() {
+
+ _create = _create_func;
+ available = true;
+}
+
+void PacketPeerMbedDTLS::finalize_dtls() {
+ _create = nullptr;
+ available = false;
+}
diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h
new file mode 100755
index 0000000000..b958fa3b95
--- /dev/null
+++ b/modules/mbedtls/packet_peer_mbed_dtls.h
@@ -0,0 +1,88 @@
+/*************************************************************************/
+/* packet_peer_mbed_dtls.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 PACKET_PEER_MBED_DTLS_H
+#define PACKET_PEER_MBED_DTLS_H
+
+#include "core/io/packet_peer_dtls.h"
+#include "ssl_context_mbedtls.h"
+
+#include <mbedtls/timing.h>
+
+class PacketPeerMbedDTLS : public PacketPeerDTLS {
+private:
+ enum {
+ PACKET_BUFFER_SIZE = 65536
+ };
+
+ uint8_t packet_buffer[PACKET_BUFFER_SIZE];
+
+ Status status;
+ String hostname;
+
+ Ref<PacketPeerUDP> base;
+
+ static PacketPeerDTLS *_create_func();
+
+ static int bio_recv(void *ctx, unsigned char *buf, size_t len);
+ static int bio_send(void *ctx, const unsigned char *buf, size_t len);
+ void _cleanup();
+
+protected:
+ Ref<SSLContextMbedTLS> ssl_ctx;
+ mbedtls_timing_delay_context timer;
+
+ static void _bind_methods();
+
+ Error _do_handshake();
+ int _set_cookie();
+
+public:
+ virtual void poll();
+ virtual Error accept_peer(Ref<PacketPeerUDP> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert = Ref<X509Certificate>(), Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>(), Ref<CookieContextMbedTLS> p_cookies = Ref<CookieContextMbedTLS>());
+ virtual Error connect_to_peer(Ref<PacketPeerUDP> p_base, bool p_validate_certs = true, const String &p_for_hostname = String(), Ref<X509Certificate> p_ca_certs = Ref<X509Certificate>());
+ virtual Status get_status() const;
+
+ virtual void disconnect_from_peer();
+
+ virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size);
+ virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
+
+ virtual int get_available_packet_count() const;
+ virtual int get_max_packet_size() const;
+
+ static void initialize_dtls();
+ static void finalize_dtls();
+
+ PacketPeerMbedDTLS();
+ ~PacketPeerMbedDTLS();
+};
+
+#endif // PACKET_PEER_MBED_DTLS_H
diff --git a/modules/mbedtls/register_types.cpp b/modules/mbedtls/register_types.cpp
index 8f9e2c370b..d39af7fe87 100755
--- a/modules/mbedtls/register_types.cpp
+++ b/modules/mbedtls/register_types.cpp
@@ -31,16 +31,22 @@
#include "register_types.h"
#include "crypto_mbedtls.h"
+#include "dtls_server_mbedtls.h"
+#include "packet_peer_mbed_dtls.h"
#include "stream_peer_mbedtls.h"
void register_mbedtls_types() {
CryptoMbedTLS::initialize_crypto();
StreamPeerMbedTLS::initialize_ssl();
+ PacketPeerMbedDTLS::initialize_dtls();
+ DTLSServerMbedTLS::initialize();
}
void unregister_mbedtls_types() {
+ DTLSServerMbedTLS::finalize();
+ PacketPeerMbedDTLS::finalize_dtls();
StreamPeerMbedTLS::finalize_ssl();
CryptoMbedTLS::finalize_crypto();
}
diff --git a/modules/mbedtls/register_types.h b/modules/mbedtls/register_types.h
index f179d39438..90c81b1682 100755
--- a/modules/mbedtls/register_types.h
+++ b/modules/mbedtls/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef MBEDTLS_REGISTER_TYPES_H
+#define MBEDTLS_REGISTER_TYPES_H
+
void register_mbedtls_types();
void unregister_mbedtls_types();
+
+#endif // MBEDTLS_REGISTER_TYPES_H
diff --git a/modules/mbedtls/ssl_context_mbedtls.cpp b/modules/mbedtls/ssl_context_mbedtls.cpp
index 82584e3494..1ffb9bda05 100644
--- a/modules/mbedtls/ssl_context_mbedtls.cpp
+++ b/modules/mbedtls/ssl_context_mbedtls.cpp
@@ -38,6 +38,53 @@ static void my_debug(void *ctx, int level,
fflush(stdout);
}
+void SSLContextMbedTLS::print_mbedtls_error(int p_ret) {
+ printf("mbedtls error: returned -0x%x\n\n", -p_ret);
+ fflush(stdout);
+}
+
+/// CookieContextMbedTLS
+
+Error CookieContextMbedTLS::setup() {
+ ERR_FAIL_COND_V_MSG(inited, ERR_ALREADY_IN_USE, "This cookie context is already in use");
+
+ mbedtls_ctr_drbg_init(&ctr_drbg);
+ mbedtls_entropy_init(&entropy);
+ mbedtls_ssl_cookie_init(&cookie_ctx);
+ inited = true;
+
+ int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, nullptr, 0);
+ if (ret != 0) {
+ clear(); // Never leave unusable resources around.
+ ERR_FAIL_V_MSG(FAILED, "mbedtls_ctr_drbg_seed returned an error " + itos(ret));
+ }
+
+ ret = mbedtls_ssl_cookie_setup(&cookie_ctx, mbedtls_ctr_drbg_random, &ctr_drbg);
+ if (ret != 0) {
+ clear();
+ ERR_FAIL_V_MSG(FAILED, "mbedtls_ssl_cookie_setup returned an error " + itos(ret));
+ }
+ return OK;
+}
+
+void CookieContextMbedTLS::clear() {
+ if (!inited)
+ return;
+ mbedtls_ctr_drbg_free(&ctr_drbg);
+ mbedtls_entropy_free(&entropy);
+ mbedtls_ssl_cookie_free(&cookie_ctx);
+}
+
+CookieContextMbedTLS::CookieContextMbedTLS() {
+ inited = false;
+}
+
+CookieContextMbedTLS::~CookieContextMbedTLS() {
+ clear();
+}
+
+/// SSLContextMbedTLS
+
Error SSLContextMbedTLS::_setup(int p_endpoint, int p_transport, int p_authmode) {
ERR_FAIL_COND_V_MSG(inited, ERR_ALREADY_IN_USE, "This SSL context is already active");
@@ -47,10 +94,10 @@ Error SSLContextMbedTLS::_setup(int p_endpoint, int p_transport, int p_authmode)
mbedtls_entropy_init(&entropy);
inited = true;
- int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
+ int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, nullptr, 0);
if (ret != 0) {
clear(); // Never leave unusable resources around.
- ERR_FAIL_V_MSG(FAILED, "mbedtls_ctr_drbg_seed returned an error" + itos(ret));
+ ERR_FAIL_V_MSG(FAILED, "mbedtls_ctr_drbg_seed returned an error " + itos(ret));
}
ret = mbedtls_ssl_config_defaults(&conf, p_endpoint, p_transport, MBEDTLS_SSL_PRESET_DEFAULT);
@@ -64,7 +111,7 @@ Error SSLContextMbedTLS::_setup(int p_endpoint, int p_transport, int p_authmode)
return OK;
}
-Error SSLContextMbedTLS::init_server(int p_transport, int p_authmode, Ref<CryptoKeyMbedTLS> p_pkey, Ref<X509CertificateMbedTLS> p_cert) {
+Error SSLContextMbedTLS::init_server(int p_transport, int p_authmode, Ref<CryptoKeyMbedTLS> p_pkey, Ref<X509CertificateMbedTLS> p_cert, Ref<CookieContextMbedTLS> p_cookies) {
ERR_FAIL_COND_V(!p_pkey.is_valid(), ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!p_cert.is_valid(), ERR_INVALID_PARAMETER);
@@ -87,7 +134,16 @@ Error SSLContextMbedTLS::init_server(int p_transport, int p_authmode, Ref<Crypto
}
// Adding CA chain if available.
if (certs->cert.next) {
- mbedtls_ssl_conf_ca_chain(&conf, certs->cert.next, NULL);
+ mbedtls_ssl_conf_ca_chain(&conf, certs->cert.next, nullptr);
+ }
+ // DTLS Cookies
+ if (p_transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+ if (p_cookies.is_null() || !p_cookies->inited) {
+ clear();
+ ERR_FAIL_V(ERR_BUG);
+ }
+ cookies = p_cookies;
+ mbedtls_ssl_conf_dtls_cookies(&conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &(cookies->cookie_ctx));
}
mbedtls_ssl_setup(&ssl, &conf);
return OK;
@@ -97,7 +153,7 @@ Error SSLContextMbedTLS::init_client(int p_transport, int p_authmode, Ref<X509Ce
Error err = _setup(MBEDTLS_SSL_IS_CLIENT, p_transport, p_authmode);
ERR_FAIL_COND_V(err != OK, err);
- X509CertificateMbedTLS *cas = NULL;
+ X509CertificateMbedTLS *cas = nullptr;
if (p_valid_cas.is_valid()) {
// Locking CA certificates
@@ -107,14 +163,14 @@ Error SSLContextMbedTLS::init_client(int p_transport, int p_authmode, Ref<X509Ce
} else {
// Fall back to default certificates (no need to lock those).
cas = CryptoMbedTLS::get_default_certificates();
- if (cas == NULL) {
+ if (cas == nullptr) {
clear();
ERR_FAIL_V_MSG(ERR_UNCONFIGURED, "SSL module failed to initialize!");
}
}
// Set valid CAs
- mbedtls_ssl_conf_ca_chain(&conf, &(cas->cert), NULL);
+ mbedtls_ssl_conf_ca_chain(&conf, &(cas->cert), nullptr);
mbedtls_ssl_setup(&ssl, &conf);
return OK;
}
@@ -134,11 +190,12 @@ void SSLContextMbedTLS::clear() {
if (pkey.is_valid())
pkey->unlock();
pkey = Ref<CryptoKeyMbedTLS>();
+ cookies = Ref<CookieContextMbedTLS>();
inited = false;
}
mbedtls_ssl_context *SSLContextMbedTLS::get_context() {
- ERR_FAIL_COND_V(!inited, NULL);
+ ERR_FAIL_COND_V(!inited, nullptr);
return &ssl;
}
diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h
index 9145e0fd72..d3e1f87a8e 100644
--- a/modules/mbedtls/ssl_context_mbedtls.h
+++ b/modules/mbedtls/ssl_context_mbedtls.h
@@ -34,7 +34,7 @@
#include "crypto_mbedtls.h"
#include "core/os/file_access.h"
-#include "core/pool_vector.h"
+
#include "core/reference.h"
#include <mbedtls/config.h>
@@ -42,25 +42,49 @@
#include <mbedtls/debug.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ssl.h>
+#include <mbedtls/ssl_cookie.h>
+
+class SSLContextMbedTLS;
+
+class CookieContextMbedTLS : public Reference {
+
+ friend class SSLContextMbedTLS;
+
+protected:
+ bool inited;
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ mbedtls_ssl_cookie_ctx cookie_ctx;
+
+public:
+ Error setup();
+ void clear();
+
+ CookieContextMbedTLS();
+ ~CookieContextMbedTLS();
+};
class SSLContextMbedTLS : public Reference {
protected:
bool inited;
- static PoolByteArray _read_file(String p_path);
+ static PackedByteArray _read_file(String p_path);
public:
+ static void print_mbedtls_error(int p_ret);
+
Ref<X509CertificateMbedTLS> certs;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
+ Ref<CookieContextMbedTLS> cookies;
Ref<CryptoKeyMbedTLS> pkey;
Error _setup(int p_endpoint, int p_transport, int p_authmode);
- Error init_server(int p_transport, int p_authmode, Ref<CryptoKeyMbedTLS> p_pkey, Ref<X509CertificateMbedTLS> p_cert);
+ Error init_server(int p_transport, int p_authmode, Ref<CryptoKeyMbedTLS> p_pkey, Ref<X509CertificateMbedTLS> p_cert, Ref<CookieContextMbedTLS> p_cookies = Ref<CookieContextMbedTLS>());
Error init_client(int p_transport, int p_authmode, Ref<X509CertificateMbedTLS> p_valid_cas);
void clear();
diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp
index f06327e0d5..983095c536 100755
--- a/modules/mbedtls/stream_peer_mbedtls.cpp
+++ b/modules/mbedtls/stream_peer_mbedtls.cpp
@@ -33,18 +33,13 @@
#include "core/io/stream_peer_tcp.h"
#include "core/os/file_access.h"
-void _print_error(int ret) {
- printf("mbedtls error: returned -0x%x\n\n", -ret);
- fflush(stdout);
-}
-
int StreamPeerMbedTLS::bio_send(void *ctx, const unsigned char *buf, size_t len) {
- if (buf == NULL || len <= 0) return 0;
+ if (buf == nullptr || len <= 0) return 0;
StreamPeerMbedTLS *sp = (StreamPeerMbedTLS *)ctx;
- ERR_FAIL_COND_V(sp == NULL, 0);
+ ERR_FAIL_COND_V(sp == nullptr, 0);
int sent;
Error err = sp->base->put_partial_data((const uint8_t *)buf, len, sent);
@@ -59,11 +54,11 @@ int StreamPeerMbedTLS::bio_send(void *ctx, const unsigned char *buf, size_t len)
int StreamPeerMbedTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
- if (buf == NULL || len <= 0) return 0;
+ if (buf == nullptr || len <= 0) return 0;
StreamPeerMbedTLS *sp = (StreamPeerMbedTLS *)ctx;
- ERR_FAIL_COND_V(sp == NULL, 0);
+ ERR_FAIL_COND_V(sp == nullptr, 0);
int got;
Error err = sp->base->get_partial_data((uint8_t *)buf, len, got);
@@ -89,7 +84,7 @@ Error StreamPeerMbedTLS::_do_handshake() {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
// An error occurred.
ERR_PRINT("TLS handshake error: " + itos(ret));
- _print_error(ret);
+ SSLContextMbedTLS::print_mbedtls_error(ret);
disconnect_from_stream();
status = STATUS_ERROR;
return FAILED;
@@ -117,7 +112,7 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
ERR_FAIL_COND_V(err != OK, err);
mbedtls_ssl_set_hostname(ssl_ctx->get_context(), p_for_hostname.utf8().get_data());
- mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, NULL);
+ mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, nullptr);
status = STATUS_HANDSHAKING;
@@ -138,7 +133,7 @@ Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_
base = p_base;
- mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, NULL);
+ mbedtls_ssl_set_bio(ssl_ctx->get_context(), this, bio_send, bio_recv, nullptr);
status = STATUS_HANDSHAKING;
@@ -188,7 +183,7 @@ Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, in
disconnect_from_stream();
return ERR_FILE_EOF;
} else if (ret <= 0) {
- _print_error(ret);
+ SSLContextMbedTLS::print_mbedtls_error(ret);
disconnect_from_stream();
return ERR_CONNECTION_ERROR;
}
@@ -233,7 +228,7 @@ Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r
disconnect_from_stream();
return ERR_FILE_EOF;
} else if (ret <= 0) {
- _print_error(ret);
+ SSLContextMbedTLS::print_mbedtls_error(ret);
disconnect_from_stream();
return ERR_CONNECTION_ERROR;
}
@@ -264,7 +259,7 @@ void StreamPeerMbedTLS::poll() {
disconnect_from_stream();
return;
} else if (ret < 0) {
- _print_error(ret);
+ SSLContextMbedTLS::print_mbedtls_error(ret);
disconnect_from_stream();
return;
}
@@ -325,5 +320,5 @@ void StreamPeerMbedTLS::initialize_ssl() {
void StreamPeerMbedTLS::finalize_ssl() {
available = false;
- _create = NULL;
+ _create = nullptr;
}
diff --git a/modules/mobile_vr/SCsub b/modules/mobile_vr/SCsub
index 4bd184f025..e6c43228b4 100644
--- a/modules/mobile_vr/SCsub
+++ b/modules/mobile_vr/SCsub
@@ -1,8 +1,8 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_mobile_vr = env_modules.Clone()
-env_mobile_vr.add_source_files(env.modules_sources, '*.cpp')
+env_mobile_vr.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/mobile_vr/config.py b/modules/mobile_vr/config.py
index e85fa631dd..ee401c1a2a 100644
--- a/modules/mobile_vr/config.py
+++ b/modules/mobile_vr/config.py
@@ -1,13 +1,16 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"MobileVRInterface",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml
index 7552abe61d..120535bd41 100644
--- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml
+++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="MobileVRInterface" inherits="ARVRInterface" version="4.0">
+<class name="MobileVRInterface" inherits="XRInterface" version="4.0">
<brief_description>
Generic mobile VR implementation.
</brief_description>
@@ -8,9 +8,9 @@
Note that even though there is no positional tracking, the camera will assume the headset is at a height of 1.85 meters. You can change this by setting [member eye_height].
You can initialise this interface as follows:
[codeblock]
- var interface = ARVRServer.find_interface("Native mobile")
+ var interface = XRServer.find_interface("Native mobile")
if interface and interface.initialize():
- get_viewport().arvr = true
+ get_viewport().xr = true
[/codeblock]
</description>
<tutorials>
@@ -25,7 +25,7 @@
The width of the display in centimeters.
</member>
<member name="eye_height" type="float" setter="set_eye_height" getter="get_eye_height" default="1.85">
- The height at which the camera is placed in relation to the ground (i.e. [ARVROrigin] node).
+ The height at which the camera is placed in relation to the ground (i.e. [XROrigin3D] node).
</member>
<member name="iod" type="float" setter="set_iod" getter="get_iod" default="6.0">
The interocular distance, also known as the interpupillary distance. The distance between the pupils of the left and right eye.
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index 22b708f206..2f0a15f20b 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -29,16 +29,17 @@
/*************************************************************************/
#include "mobile_vr_interface.h"
-#include "core/os/input.h"
+#include "core/input/input_filter.h"
#include "core/os/os.h"
-#include "servers/visual/visual_server_globals.h"
+#include "servers/display_server.h"
+#include "servers/rendering/rendering_server_globals.h"
StringName MobileVRInterface::get_name() const {
return "Native mobile";
};
int MobileVRInterface::get_capabilities() const {
- return ARVRInterface::ARVR_STEREO;
+ return XRInterface::XR_STEREO;
};
Vector3 MobileVRInterface::scale_magneto(const Vector3 &p_magnetometer) {
@@ -117,7 +118,7 @@ void MobileVRInterface::set_position_from_sensors() {
float delta_time = (double)ticks_elapsed / 1000000.0;
// few things we need
- Input *input = Input::get_singleton();
+ InputFilter *input = InputFilter::get_singleton();
Vector3 down(0.0, -1.0, 0.0); // Down is Y negative
Vector3 north(0.0, 0.0, 1.0); // North is Z positive
@@ -164,7 +165,7 @@ void MobileVRInterface::set_position_from_sensors() {
rotate.rotate(orientation.get_axis(2), gyro.z * delta_time);
orientation = rotate * orientation;
- tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
+ tracking_state = XRInterface::XR_NORMAL_TRACKING;
};
///@TODO improve this, the magnetometer is very fidgity sometimes flipping the axis for no apparent reason (probably a bug on my part)
@@ -176,7 +177,7 @@ void MobileVRInterface::set_position_from_sensors() {
transform_quat = transform_quat.slerp(acc_mag_quat, 0.1);
orientation = Basis(transform_quat);
- tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
+ tracking_state = XRInterface::XR_NORMAL_TRACKING;
} else if (has_grav) {
// use gravity vector to make sure down is down...
// transform gravity into our world space
@@ -221,13 +222,13 @@ void MobileVRInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_k2", "k"), &MobileVRInterface::set_k2);
ClassDB::bind_method(D_METHOD("get_k2"), &MobileVRInterface::get_k2);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "eye_height", PROPERTY_HINT_RANGE, "0.0,3.0,0.1"), "set_eye_height", "get_eye_height");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "iod", PROPERTY_HINT_RANGE, "4.0,10.0,0.1"), "set_iod", "get_iod");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "display_width", PROPERTY_HINT_RANGE, "5.0,25.0,0.1"), "set_display_width", "get_display_width");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "display_to_lens", PROPERTY_HINT_RANGE, "5.0,25.0,0.1"), "set_display_to_lens", "get_display_to_lens");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "oversample", PROPERTY_HINT_RANGE, "1.0,2.0,0.1"), "set_oversample", "get_oversample");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "k1", PROPERTY_HINT_RANGE, "0.1,10.0,0.0001"), "set_k1", "get_k1");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "k2", PROPERTY_HINT_RANGE, "0.1,10.0,0.0001"), "set_k2", "get_k2");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "eye_height", PROPERTY_HINT_RANGE, "0.0,3.0,0.1"), "set_eye_height", "get_eye_height");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "iod", PROPERTY_HINT_RANGE, "4.0,10.0,0.1"), "set_iod", "get_iod");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "display_width", PROPERTY_HINT_RANGE, "5.0,25.0,0.1"), "set_display_width", "get_display_width");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "display_to_lens", PROPERTY_HINT_RANGE, "5.0,25.0,0.1"), "set_display_to_lens", "get_display_to_lens");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversample", PROPERTY_HINT_RANGE, "1.0,2.0,0.1"), "set_oversample", "get_oversample");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "k1", PROPERTY_HINT_RANGE, "0.1,10.0,0.0001"), "set_k1", "get_k1");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "k2", PROPERTY_HINT_RANGE, "0.1,10.0,0.0001"), "set_k2", "get_k2");
}
void MobileVRInterface::set_eye_height(const real_t p_eye_height) {
@@ -296,8 +297,8 @@ bool MobileVRInterface::is_initialized() const {
};
bool MobileVRInterface::initialize() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, false);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, false);
if (!initialized) {
// reset our sensor data and orientation
@@ -313,7 +314,7 @@ bool MobileVRInterface::initialize() {
orientation = Basis();
// make this our primary interface
- arvr_server->set_primary_interface(this);
+ xr_server->set_primary_interface(this);
last_ticks = OS::get_singleton()->get_ticks_usec();
@@ -325,10 +326,10 @@ bool MobileVRInterface::initialize() {
void MobileVRInterface::uninitialize() {
if (initialized) {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != NULL) {
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
// no longer our primary interface
- arvr_server->clear_primary_interface_if(this);
+ xr_server->clear_primary_interface_if(this);
}
initialized = false;
@@ -339,7 +340,7 @@ Size2 MobileVRInterface::get_render_targetsize() {
_THREAD_SAFE_METHOD_
// we use half our window size
- Size2 target_size = OS::get_singleton()->get_window_size();
+ Size2 target_size = DisplayServer::get_singleton()->window_get_size();
target_size.x *= 0.5 * oversample;
target_size.y *= oversample;
@@ -347,22 +348,22 @@ Size2 MobileVRInterface::get_render_targetsize() {
return target_size;
};
-Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+Transform MobileVRInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) {
_THREAD_SAFE_METHOD_
Transform transform_for_eye;
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- ERR_FAIL_NULL_V(arvr_server, transform_for_eye);
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, transform_for_eye);
if (initialized) {
- float world_scale = arvr_server->get_world_scale();
+ float world_scale = xr_server->get_world_scale();
// we don't need to check for the existence of our HMD, doesn't effect our values...
// note * 0.01 to convert cm to m and * 0.5 as we're moving half in each direction...
- if (p_eye == ARVRInterface::EYE_LEFT) {
+ if (p_eye == XRInterface::EYE_LEFT) {
transform_for_eye.origin.x = -(intraocular_dist * 0.01 * 0.5 * world_scale);
- } else if (p_eye == ARVRInterface::EYE_RIGHT) {
+ } else if (p_eye == XRInterface::EYE_RIGHT) {
transform_for_eye.origin.x = intraocular_dist * 0.01 * 0.5 * world_scale;
} else {
// for mono we don't reposition, we want our center position.
@@ -373,7 +374,7 @@ Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, co
hmd_transform.basis = orientation;
hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0);
- transform_for_eye = p_cam_transform * (arvr_server->get_reference_frame()) * hmd_transform * transform_for_eye;
+ transform_for_eye = p_cam_transform * (xr_server->get_reference_frame()) * hmd_transform * transform_for_eye;
} else {
// huh? well just return what we got....
transform_for_eye = p_cam_transform;
@@ -382,12 +383,12 @@ Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, co
return transform_for_eye;
};
-CameraMatrix MobileVRInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+CameraMatrix MobileVRInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
_THREAD_SAFE_METHOD_
CameraMatrix eye;
- if (p_eye == ARVRInterface::EYE_MONO) {
+ if (p_eye == XRInterface::EYE_MONO) {
///@TODO for now hardcode some of this, what is really needed here is that this needs to be in sync with the real cameras properties
// which probably means implementing a specific class for iOS and Android. For now this is purely here as an example.
// Note also that if you use a normal viewport with AR/VR turned off you can still use the tracker output of this interface
@@ -395,13 +396,13 @@ CameraMatrix MobileVRInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye
// This will make more sense when we implement ARkit on iOS (probably a separate interface).
eye.set_perspective(60.0, p_aspect, p_z_near, p_z_far, false);
} else {
- eye.set_for_hmd(p_eye == ARVRInterface::EYE_LEFT ? 1 : 2, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far);
+ eye.set_for_hmd(p_eye == XRInterface::EYE_LEFT ? 1 : 2, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far);
};
return eye;
};
-void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+void MobileVRInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
_THREAD_SAFE_METHOD_
// We must have a valid render target
@@ -416,21 +417,15 @@ void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_t
// we output half a screen
dest.size.x *= 0.5;
- if (p_eye == ARVRInterface::EYE_LEFT) {
+ if (p_eye == XRInterface::EYE_LEFT) {
eye_center.x = ((-intraocular_dist / 2.0) + (display_width / 4.0)) / (display_width / 2.0);
- } else if (p_eye == ARVRInterface::EYE_RIGHT) {
+ } else if (p_eye == XRInterface::EYE_RIGHT) {
dest.position.x = dest.size.x;
eye_center.x = ((intraocular_dist / 2.0) - (display_width / 4.0)) / (display_width / 2.0);
}
// we don't offset the eye center vertically (yet)
eye_center.y = 0.0;
-
- // unset our render target so we are outputting to our main screen by making RasterizerStorageGLES3::system_fbo our current FBO
- VSG::rasterizer->set_current_render_target(RID());
-
- // and output
- VSG::rasterizer->output_lens_distorted_to_screen(p_render_target, dest, k1, k2, eye_center, oversample);
-};
+}
void MobileVRInterface::process() {
_THREAD_SAFE_METHOD_
diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h
index c762c9b799..3a9ed1314a 100644
--- a/modules/mobile_vr/mobile_vr_interface.h
+++ b/modules/mobile_vr/mobile_vr_interface.h
@@ -31,8 +31,8 @@
#ifndef MOBILE_VR_INTERFACE_H
#define MOBILE_VR_INTERFACE_H
-#include "servers/arvr/arvr_interface.h"
-#include "servers/arvr/arvr_positional_tracker.h"
+#include "servers/xr/xr_interface.h"
+#include "servers/xr/xr_positional_tracker.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
@@ -47,8 +47,8 @@
more advanced interfaces.
*/
-class MobileVRInterface : public ARVRInterface {
- GDCLASS(MobileVRInterface, ARVRInterface);
+class MobileVRInterface : public XRInterface {
+ GDCLASS(MobileVRInterface, XRInterface);
private:
bool initialized;
@@ -137,9 +137,9 @@ public:
virtual Size2 get_render_targetsize();
virtual bool is_stereo();
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+ virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform);
+ virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+ virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
virtual void process();
virtual void notification(int p_what);
diff --git a/modules/mobile_vr/register_types.cpp b/modules/mobile_vr/register_types.cpp
index faf6c3b151..75638d47c4 100644
--- a/modules/mobile_vr/register_types.cpp
+++ b/modules/mobile_vr/register_types.cpp
@@ -37,7 +37,7 @@ void register_mobile_vr_types() {
Ref<MobileVRInterface> mobile_vr;
mobile_vr.instance();
- ARVRServer::get_singleton()->add_interface(mobile_vr);
+ XRServer::get_singleton()->add_interface(mobile_vr);
}
void unregister_mobile_vr_types() {
diff --git a/modules/mobile_vr/register_types.h b/modules/mobile_vr/register_types.h
index 602fae1f4e..33f608b6ed 100644
--- a/modules/mobile_vr/register_types.h
+++ b/modules/mobile_vr/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef MOBILE_VR_REGISTER_TYPES_H
+#define MOBILE_VR_REGISTER_TYPES_H
+
void register_mobile_vr_types();
void unregister_mobile_vr_types();
+
+#endif // MOBILE_VR_REGISTER_TYPES_H
diff --git a/modules/modules_builders.py b/modules/modules_builders.py
index 0e9cba2b0b..e7be6380d1 100644
--- a/modules/modules_builders.py
+++ b/modules/modules_builders.py
@@ -7,10 +7,10 @@ from platform_methods import subprocess_main
def generate_modules_enabled(target, source, env):
- with open(target[0].path, 'w') as f:
+ with open(target[0].path, "w") as f:
for module in env.module_list:
- f.write('#define %s\n' % ("MODULE_" + module.upper() + "_ENABLED"))
+ f.write("#define %s\n" % ("MODULE_" + module.upper() + "_ENABLED"))
-if __name__ == '__main__':
+if __name__ == "__main__":
subprocess_main(globals())
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index 41be367f2f..c723b210cb 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -1,54 +1,57 @@
#!/usr/bin/env python
-import build_scripts.tls_configure as tls_configure
import build_scripts.mono_configure as mono_configure
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_mono = env_modules.Clone()
-if env_mono['tools']:
+if env_mono["tools"]:
# NOTE: It is safe to generate this file here, since this is still executed serially
import build_scripts.gen_cs_glue_version as gen_cs_glue_version
- gen_cs_glue_version.generate_header('glue/GodotSharp', 'glue/cs_glue_version.gen.h')
+
+ gen_cs_glue_version.generate_header("glue/GodotSharp", "glue/cs_glue_version.gen.h")
# Glue sources
-if env_mono['mono_glue']:
- env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED'])
+if env_mono["mono_glue"]:
+ env_mono.Append(CPPDEFINES=["MONO_GLUE_ENABLED"])
import os.path
- if not os.path.isfile('glue/mono_glue.gen.cpp'):
- raise RuntimeError("Mono glue sources not found. Did you forget to run '--generate-mono-glue'?")
-if env_mono['tools'] or env_mono['target'] != 'release':
- env_mono.Append(CPPDEFINES=['GD_MONO_HOT_RELOAD'])
-
-# Configure Thread Local Storage
+ if not os.path.isfile("glue/mono_glue.gen.cpp"):
+ raise RuntimeError("Mono glue sources not found. Did you forget to run '--generate-mono-glue'?")
-conf = Configure(env_mono)
-tls_configure.configure(conf)
-env_mono = conf.Finish()
+if env_mono["tools"] or env_mono["target"] != "release":
+ env_mono.Append(CPPDEFINES=["GD_MONO_HOT_RELOAD"])
# Configure Mono
mono_configure.configure(env, env_mono)
-if env_mono['tools'] and env_mono['mono_glue']:
+if env_mono["tools"] and env_mono["mono_glue"]:
# Build Godot API solution
import build_scripts.api_solution_build as api_solution_build
+
api_sln_cmd = api_solution_build.build(env_mono)
# Build GodotTools
import build_scripts.godot_tools_build as godot_tools_build
+
godot_tools_build.build(env_mono, api_sln_cmd)
# Add sources
-env_mono.add_source_files(env.modules_sources, '*.cpp')
-env_mono.add_source_files(env.modules_sources, 'glue/*.cpp')
-env_mono.add_source_files(env.modules_sources, 'mono_gd/*.cpp')
-env_mono.add_source_files(env.modules_sources, 'utils/*.cpp')
+env_mono.add_source_files(env.modules_sources, "*.cpp")
+env_mono.add_source_files(env.modules_sources, "glue/*.cpp")
+env_mono.add_source_files(env.modules_sources, "mono_gd/*.cpp")
+env_mono.add_source_files(env.modules_sources, "utils/*.cpp")
+
+env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.cpp")
+
+if env["platform"] in ["osx", "iphone"]:
+ env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.mm")
+ env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.m")
-if env['tools']:
- env_mono.add_source_files(env.modules_sources, 'editor/*.cpp')
+if env["tools"]:
+ env_mono.add_source_files(env.modules_sources, "editor/*.cpp")
diff --git a/modules/mono/build_scripts/api_solution_build.py b/modules/mono/build_scripts/api_solution_build.py
index 639197c285..9abac22df6 100644
--- a/modules/mono/build_scripts/api_solution_build.py
+++ b/modules/mono/build_scripts/api_solution_build.py
@@ -8,21 +8,22 @@ from SCons.Script import Dir
def build_api_solution(source, target, env):
# source and target elements are of type SCons.Node.FS.File, hence why we convert them to str
- module_dir = env['module_dir']
+ module_dir = env["module_dir"]
- solution_path = os.path.join(module_dir, 'glue/GodotSharp/GodotSharp.sln')
+ solution_path = os.path.join(module_dir, "glue/GodotSharp/GodotSharp.sln")
- build_config = env['solution_build_config']
+ build_config = env["solution_build_config"]
- extra_msbuild_args = ['/p:NoWarn=1591'] # Ignore missing documentation warnings
+ extra_msbuild_args = ["/p:NoWarn=1591"] # Ignore missing documentation warnings
from .solution_builder import build_solution
+
build_solution(env, solution_path, build_config, extra_msbuild_args=extra_msbuild_args)
# Copy targets
- core_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, 'GodotSharp', 'bin', build_config))
- editor_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, 'GodotSharpEditor', 'bin', build_config))
+ core_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, "GodotSharp", "bin", build_config))
+ editor_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, "GodotSharpEditor", "bin", build_config))
dst_dir = os.path.abspath(os.path.join(str(target[0]), os.pardir))
@@ -32,6 +33,7 @@ def build_api_solution(source, target, env):
def copy_target(target_path):
from shutil import copy
+
filename = os.path.basename(target_path)
src_path = os.path.join(core_src_dir, filename)
@@ -45,23 +47,28 @@ def build_api_solution(source, target, env):
def build(env_mono):
- assert env_mono['tools']
+ assert env_mono["tools"]
target_filenames = [
- 'GodotSharp.dll', 'GodotSharp.pdb', 'GodotSharp.xml',
- 'GodotSharpEditor.dll', 'GodotSharpEditor.pdb', 'GodotSharpEditor.xml'
+ "GodotSharp.dll",
+ "GodotSharp.pdb",
+ "GodotSharp.xml",
+ "GodotSharpEditor.dll",
+ "GodotSharpEditor.pdb",
+ "GodotSharpEditor.xml",
]
depend_cmd = []
- for build_config in ['Debug', 'Release']:
- output_dir = Dir('#bin').abspath
- editor_api_dir = os.path.join(output_dir, 'GodotSharp', 'Api', build_config)
+ for build_config in ["Debug", "Release"]:
+ output_dir = Dir("#bin").abspath
+ editor_api_dir = os.path.join(output_dir, "GodotSharp", "Api", build_config)
targets = [os.path.join(editor_api_dir, filename) for filename in target_filenames]
- cmd = env_mono.CommandNoCache(targets, depend_cmd, build_api_solution,
- module_dir=os.getcwd(), solution_build_config=build_config)
+ cmd = env_mono.CommandNoCache(
+ targets, depend_cmd, build_api_solution, module_dir=os.getcwd(), solution_build_config=build_config
+ )
env_mono.AlwaysBuild(cmd)
# Make the Release build of the API solution depend on the Debug build.
diff --git a/modules/mono/build_scripts/gen_cs_glue_version.py b/modules/mono/build_scripts/gen_cs_glue_version.py
index 5d1056c2fc..98bbb4d9be 100644
--- a/modules/mono/build_scripts/gen_cs_glue_version.py
+++ b/modules/mono/build_scripts/gen_cs_glue_version.py
@@ -1,20 +1,20 @@
-
def generate_header(solution_dir, version_header_dst):
import os
+
latest_mtime = 0
for root, dirs, files in os.walk(solution_dir, topdown=True):
- dirs[:] = [d for d in dirs if d not in ['Generated']] # Ignored generated files
- files = [f for f in files if f.endswith('.cs')]
+ dirs[:] = [d for d in dirs if d not in ["Generated"]] # Ignored generated files
+ files = [f for f in files if f.endswith(".cs")]
for file in files:
filepath = os.path.join(root, file)
mtime = os.path.getmtime(filepath)
latest_mtime = mtime if mtime > latest_mtime else latest_mtime
- glue_version = int(latest_mtime) # The latest modified time will do for now
+ glue_version = int(latest_mtime) # The latest modified time will do for now
- with open(version_header_dst, 'w') as version_header:
- version_header.write('/* THIS FILE IS GENERATED DO NOT EDIT */\n')
- version_header.write('#ifndef CS_GLUE_VERSION_H\n')
- version_header.write('#define CS_GLUE_VERSION_H\n\n')
- version_header.write('#define CS_GLUE_VERSION UINT32_C(' + str(glue_version) + ')\n')
- version_header.write('\n#endif // CS_GLUE_VERSION_H\n')
+ with open(version_header_dst, "w") as version_header:
+ version_header.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ version_header.write("#ifndef CS_GLUE_VERSION_H\n")
+ version_header.write("#define CS_GLUE_VERSION_H\n\n")
+ version_header.write("#define CS_GLUE_VERSION UINT32_C(" + str(glue_version) + ")\n")
+ version_header.write("\n#endif // CS_GLUE_VERSION_H\n")
diff --git a/modules/mono/build_scripts/godot_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py
index 99341c631e..cffacf2577 100644
--- a/modules/mono/build_scripts/godot_tools_build.py
+++ b/modules/mono/build_scripts/godot_tools_build.py
@@ -8,30 +8,31 @@ from SCons.Script import Dir
def build_godot_tools(source, target, env):
# source and target elements are of type SCons.Node.FS.File, hence why we convert them to str
- module_dir = env['module_dir']
+ module_dir = env["module_dir"]
- solution_path = os.path.join(module_dir, 'editor/GodotTools/GodotTools.sln')
- build_config = 'Debug' if env['target'] == 'debug' else 'Release'
+ solution_path = os.path.join(module_dir, "editor/GodotTools/GodotTools.sln")
+ build_config = "Debug" if env["target"] == "debug" else "Release"
# Custom build target to make sure output is always copied to the data dir.
- extra_build_args = ['/Target:Build;GodotTools:BuildAlwaysCopyToDataDir']
+ extra_build_args = ["/Target:Build;GodotTools:BuildAlwaysCopyToDataDir"]
+
+ from .solution_builder import build_solution, nuget_restore
- from . solution_builder import build_solution, nuget_restore
nuget_restore(env, solution_path)
build_solution(env, solution_path, build_config, extra_build_args)
# No need to copy targets. The GodotTools csproj takes care of copying them.
def build(env_mono, api_sln_cmd):
- assert env_mono['tools']
+ assert env_mono["tools"]
- output_dir = Dir('#bin').abspath
- editor_tools_dir = os.path.join(output_dir, 'GodotSharp', 'Tools')
+ output_dir = Dir("#bin").abspath
+ editor_tools_dir = os.path.join(output_dir, "GodotSharp", "Tools")
- target_filenames = ['GodotTools.dll']
+ target_filenames = ["GodotTools.dll"]
- if env_mono['target'] == 'debug':
- target_filenames += ['GodotTools.pdb']
+ if env_mono["target"] == "debug":
+ target_filenames += ["GodotTools.pdb"]
targets = [os.path.join(editor_tools_dir, filename) for filename in target_filenames]
diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py
index 8cad204d7b..d276d7d886 100644
--- a/modules/mono/build_scripts/make_android_mono_config.py
+++ b/modules/mono/build_scripts/make_android_mono_config.py
@@ -1,30 +1,30 @@
-
def generate_compressed_config(config_src, output_dir):
import os.path
- from compat import byte_to_str
# Source file
- with open(os.path.join(output_dir, 'android_mono_config.gen.cpp'), 'w') as cpp:
- with open(config_src, 'rb') as f:
+ with open(os.path.join(output_dir, "android_mono_config.gen.cpp"), "w") as cpp:
+ with open(config_src, "rb") as f:
buf = f.read()
decompr_size = len(buf)
import zlib
+
buf = zlib.compress(buf)
compr_size = len(buf)
- bytes_seq_str = ''
+ bytes_seq_str = ""
for i, buf_idx in enumerate(range(compr_size)):
if i > 0:
- bytes_seq_str += ', '
- bytes_seq_str += byte_to_str(buf[buf_idx])
+ bytes_seq_str += ", "
+ bytes_seq_str += str(buf[buf_idx])
- cpp.write('''/* THIS FILE IS GENERATED DO NOT EDIT */
+ cpp.write(
+ """/* THIS FILE IS GENERATED DO NOT EDIT */
#include "android_mono_config.h"
#ifdef ANDROID_ENABLED
#include "core/io/compression.h"
-#include "core/pool_vector.h"
+
namespace {
@@ -36,9 +36,9 @@ static const unsigned char config_compressed_data[] = { %s };
} // namespace
String get_godot_android_mono_config() {
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(config_uncompressed_size);
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t* w = data.ptrw();
Compression::decompress(w.ptr(), config_uncompressed_size, config_compressed_data,
config_compressed_size, Compression::MODE_DEFLATE);
String s;
@@ -49,4 +49,6 @@ String get_godot_android_mono_config() {
}
#endif // ANDROID_ENABLED
-''' % (compr_size, decompr_size, bytes_seq_str))
+"""
+ % (compr_size, decompr_size, bytes_seq_str)
+ )
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 033c467da9..23f01b3cca 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -5,178 +5,230 @@ import subprocess
from SCons.Script import Dir, Environment
-if os.name == 'nt':
+if os.name == "nt":
from . import mono_reg_utils as monoreg
android_arch_dirs = {
- 'armv7': 'armeabi-v7a',
- 'arm64v8': 'arm64-v8a',
- 'x86': 'x86',
- 'x86_64': 'x86_64'
+ "armv7": "armeabi-v7a",
+ "arm64v8": "arm64-v8a",
+ "x86": "x86",
+ "x86_64": "x86_64",
}
def get_android_out_dir(env):
- return os.path.join(Dir('#platform/android/java/lib/libs').abspath,
- 'release' if env['target'] == 'release' else 'debug',
- android_arch_dirs[env['android_arch']])
-
-
-def find_file_in_dir(directory, files, prefix='', extension=''):
- if not extension.startswith('.'):
- extension = '.' + extension
- for curfile in files:
- if os.path.isfile(os.path.join(directory, prefix + curfile + extension)):
- return curfile
- return ''
-
-
-def copy_file(src_dir, dst_dir, name):
+ return os.path.join(
+ Dir("#platform/android/java/lib/libs").abspath,
+ "release" if env["target"] == "release" else "debug",
+ android_arch_dirs[env["android_arch"]],
+ )
+
+
+def find_name_in_dir_files(directory, names, prefixes=[""], extensions=[""]):
+ for extension in extensions:
+ if extension and not extension.startswith("."):
+ extension = "." + extension
+ for prefix in prefixes:
+ for curname in names:
+ if os.path.isfile(os.path.join(directory, prefix + curname + extension)):
+ return curname
+ return ""
+
+
+def find_file_in_dir(directory, names, prefixes=[""], extensions=[""]):
+ for extension in extensions:
+ if extension and not extension.startswith("."):
+ extension = "." + extension
+ for prefix in prefixes:
+ for curname in names:
+ filename = prefix + curname + extension
+ if os.path.isfile(os.path.join(directory, filename)):
+ return filename
+ return ""
+
+
+def copy_file(src_dir, dst_dir, src_name, dst_name=""):
from shutil import copy
- src_path = os.path.join(Dir(src_dir).abspath, name)
+ src_path = os.path.join(Dir(src_dir).abspath, src_name)
dst_dir = Dir(dst_dir).abspath
if not os.path.isdir(dst_dir):
os.makedirs(dst_dir)
- copy(src_path, dst_dir)
+ if dst_name:
+ copy(src_path, os.path.join(dst_dir, dst_name))
+ else:
+ copy(src_path, dst_dir)
def is_desktop(platform):
- return platform in ['windows', 'osx', 'x11', 'server', 'uwp', 'haiku']
+ return platform in ["windows", "osx", "linuxbsd", "server", "uwp", "haiku"]
def is_unix_like(platform):
- return platform in ['osx', 'x11', 'server', 'android', 'haiku']
+ return platform in ["osx", "linuxbsd", "server", "android", "haiku", "iphone"]
def module_supports_tools_on(platform):
- return platform not in ['android', 'javascript']
+ return platform not in ["android", "javascript", "iphone"]
def find_wasm_src_dir(mono_root):
hint_dirs = [
- os.path.join(mono_root, 'src'),
- os.path.join(mono_root, '../src'),
+ os.path.join(mono_root, "src"),
+ os.path.join(mono_root, "../src"),
]
for hint_dir in hint_dirs:
- if os.path.isfile(os.path.join(hint_dir, 'driver.c')):
+ if os.path.isfile(os.path.join(hint_dir, "driver.c")):
return hint_dir
- return ''
+ return ""
def configure(env, env_mono):
- bits = env['bits']
- is_android = env['platform'] == 'android'
- is_javascript = env['platform'] == 'javascript'
+ bits = env["bits"]
+ is_android = env["platform"] == "android"
+ is_javascript = env["platform"] == "javascript"
+ is_ios = env["platform"] == "iphone"
+ is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"]
- tools_enabled = env['tools']
- mono_static = env['mono_static']
- copy_mono_root = env['copy_mono_root']
+ tools_enabled = env["tools"]
+ mono_static = env["mono_static"]
+ copy_mono_root = env["copy_mono_root"]
- mono_prefix = env['mono_prefix']
+ mono_prefix = env["mono_prefix"]
- mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
+ mono_lib_names = ["mono-2.0-sgen", "monosgen-2.0"]
- is_travis = os.environ.get('TRAVIS') == 'true'
+ is_travis = os.environ.get("TRAVIS") == "true"
if is_travis:
# Travis CI may have a Mono version lower than 5.12
- env_mono.Append(CPPDEFINES=['NO_PENDING_EXCEPTIONS'])
+ env_mono.Append(CPPDEFINES=["NO_PENDING_EXCEPTIONS"])
- if is_android and not env['android_arch'] in android_arch_dirs:
- raise RuntimeError('This module does not support the specified \'android_arch\': ' + env['android_arch'])
+ if is_android and not env["android_arch"] in android_arch_dirs:
+ raise RuntimeError("This module does not support the specified 'android_arch': " + env["android_arch"])
- if tools_enabled and not module_supports_tools_on(env['platform']):
+ if tools_enabled and not module_supports_tools_on(env["platform"]):
# TODO:
# Android: We have to add the data directory to the apk, concretely the Api and Tools folders.
- raise RuntimeError('This module does not currently support building for this platform with tools enabled')
+ raise RuntimeError("This module does not currently support building for this platform with tools enabled")
if is_android and mono_static:
- # Android: When static linking and doing something that requires libmono-native, we get a dlopen error as libmono-native seems to depend on libmonosgen-2.0
- raise RuntimeError('Statically linking Mono is not currently supported on this platform')
+ # FIXME: When static linking and doing something that requires libmono-native, we get a dlopen error as 'libmono-native'
+ # seems to depend on 'libmonosgen-2.0'. Could be fixed by re-directing to '__Internal' with a dllmap or in the dlopen hook.
+ raise RuntimeError("Statically linking Mono is not currently supported for this platform")
+
+ if not mono_static and (is_javascript or is_ios):
+ raise RuntimeError("Dynamically linking Mono is not currently supported for this platform")
+
+ if not mono_prefix and (os.getenv("MONO32_PREFIX") or os.getenv("MONO64_PREFIX")):
+ print(
+ "WARNING: The environment variables 'MONO32_PREFIX' and 'MONO64_PREFIX' are deprecated; use the 'mono_prefix' SCons parameter instead"
+ )
+
+ # Although we don't support building with tools for any platform where we currently use static AOT,
+ # if these are supported in the future, we won't be using static AOT for them as that would be
+ # too restrictive for the editor. These builds would probably be made to only use the interpreter.
+ mono_aot_static = (is_ios and not is_ios_sim) and not env["tools"]
- if is_javascript:
- mono_static = True
+ # Static AOT is only supported on the root domain
+ mono_single_appdomain = mono_aot_static
- if not mono_prefix and (os.getenv('MONO32_PREFIX') or os.getenv('MONO64_PREFIX')):
- print("WARNING: The environment variables 'MONO32_PREFIX' and 'MONO64_PREFIX' are deprecated; use the 'mono_prefix' SCons parameter instead")
+ if mono_single_appdomain:
+ env_mono.Append(CPPDEFINES=["GD_MONO_SINGLE_APPDOMAIN"])
- if env['platform'] == 'windows':
+ if (env["tools"] or env["target"] != "release") and not mono_single_appdomain:
+ env_mono.Append(CPPDEFINES=["GD_MONO_HOT_RELOAD"])
+
+ if env["platform"] == "windows":
mono_root = mono_prefix
- if not mono_root and os.name == 'nt':
+ if not mono_root and os.name == "nt":
mono_root = monoreg.find_mono_root_dir(bits)
if not mono_root:
- raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
+ raise RuntimeError(
+ "Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter"
+ )
- print('Found Mono root directory: ' + mono_root)
+ print("Found Mono root directory: " + mono_root)
- mono_lib_path = os.path.join(mono_root, 'lib')
+ mono_lib_path = os.path.join(mono_root, "lib")
env.Append(LIBPATH=mono_lib_path)
- env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0'))
+ env_mono.Prepend(CPPPATH=os.path.join(mono_root, "include", "mono-2.0"))
+
+ lib_suffixes = [".lib"]
- lib_suffix = Environment()['LIBSUFFIX']
+ if not env.msvc:
+ # MingW supports both '.a' and '.lib'
+ lib_suffixes.insert(0, ".a")
if mono_static:
if env.msvc:
- mono_static_lib_name = 'libmono-static-sgen'
+ mono_static_lib_name = "libmono-static-sgen"
else:
- mono_static_lib_name = 'libmonosgen-2.0'
+ mono_static_lib_name = "libmonosgen-2.0"
- if not os.path.isfile(os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix)):
- raise RuntimeError('Could not find static mono library in: ' + mono_lib_path)
+ mono_static_lib_file = find_file_in_dir(mono_lib_path, [mono_static_lib_name], extensions=lib_suffixes)
+
+ if not mono_static_lib_file:
+ raise RuntimeError("Could not find static mono library in: " + mono_lib_path)
if env.msvc:
- env.Append(LINKFLAGS=mono_static_lib_name + lib_suffix)
+ env.Append(LINKFLAGS=mono_static_lib_file)
- env.Append(LINKFLAGS='Mincore' + lib_suffix)
- env.Append(LINKFLAGS='msvcrt' + lib_suffix)
- env.Append(LINKFLAGS='LIBCMT' + lib_suffix)
- env.Append(LINKFLAGS='Psapi' + lib_suffix)
+ env.Append(LINKFLAGS="Mincore.lib")
+ env.Append(LINKFLAGS="msvcrt.lib")
+ env.Append(LINKFLAGS="LIBCMT.lib")
+ env.Append(LINKFLAGS="Psapi.lib")
else:
- env.Append(LINKFLAGS=os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix))
+ mono_static_lib_file_path = os.path.join(mono_lib_path, mono_static_lib_file)
+ env.Append(LINKFLAGS=["-Wl,-whole-archive", mono_static_lib_file_path, "-Wl,-no-whole-archive"])
- env.Append(LIBS=['psapi'])
- env.Append(LIBS=['version'])
+ env.Append(LIBS=["psapi"])
+ env.Append(LIBS=["version"])
else:
- mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension=lib_suffix)
+ mono_lib_name = find_name_in_dir_files(
+ mono_lib_path, mono_lib_names, prefixes=["", "lib"], extensions=lib_suffixes
+ )
if not mono_lib_name:
- raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
+ raise RuntimeError("Could not find mono library in: " + mono_lib_path)
if env.msvc:
- env.Append(LINKFLAGS=mono_lib_name + lib_suffix)
+ env.Append(LINKFLAGS=mono_lib_name + ".lib")
else:
env.Append(LIBS=[mono_lib_name])
- mono_bin_path = os.path.join(mono_root, 'bin')
+ mono_bin_path = os.path.join(mono_root, "bin")
- mono_dll_name = find_file_in_dir(mono_bin_path, mono_lib_names, extension='.dll')
+ mono_dll_file = find_file_in_dir(mono_bin_path, mono_lib_names, prefixes=["", "lib"], extensions=[".dll"])
- if not mono_dll_name:
- raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
+ if not mono_dll_file:
+ raise RuntimeError("Could not find mono shared library in: " + mono_bin_path)
- copy_file(mono_bin_path, '#bin', mono_dll_name + '.dll')
+ copy_file(mono_bin_path, "#bin", mono_dll_file)
else:
- is_apple = (sys.platform == 'darwin' or "osxcross" in env)
+ is_apple = env["platform"] in ["osx", "iphone"]
+ is_macos = is_apple and not is_ios
- sharedlib_ext = '.dylib' if is_apple else '.so'
+ sharedlib_ext = ".dylib" if is_apple else ".so"
mono_root = mono_prefix
- mono_lib_path = ''
- mono_so_name = ''
+ mono_lib_path = ""
+ mono_so_file = ""
- if not mono_root and (is_android or is_javascript):
- raise RuntimeError("Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter")
+ if not mono_root and (is_android or is_javascript or is_ios):
+ raise RuntimeError(
+ "Mono installation directory not found; specify one manually with the 'mono_prefix' SCons parameter"
+ )
- if not mono_root and is_apple:
+ if not mono_root and is_macos:
# Try with some known directories under OSX
- hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current', '/usr/local/var/homebrew/linked/mono']
+ hint_dirs = ["/Library/Frameworks/Mono.framework/Versions/Current", "/usr/local/var/homebrew/linked/mono"]
for hint_dir in hint_dirs:
if os.path.isdir(hint_dir):
mono_root = hint_dir
@@ -187,126 +239,165 @@ def configure(env, env_mono):
if not mono_root and mono_static:
mono_root = pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext)
if not mono_root:
- raise RuntimeError("Building with mono_static=yes, but failed to find the mono prefix with pkg-config; " + \
- "specify one manually with the 'mono_prefix' SCons parameter")
+ raise RuntimeError(
+ "Building with mono_static=yes, but failed to find the mono prefix with pkg-config; "
+ + "specify one manually with the 'mono_prefix' SCons parameter"
+ )
+
+ if is_ios and not is_ios_sim:
+ env_mono.Append(CPPDEFINES=["IOS_DEVICE"])
if mono_root:
- print('Found Mono root directory: ' + mono_root)
+ print("Found Mono root directory: " + mono_root)
- mono_lib_path = os.path.join(mono_root, 'lib')
+ mono_lib_path = os.path.join(mono_root, "lib")
env.Append(LIBPATH=[mono_lib_path])
- env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0'))
+ env_mono.Prepend(CPPPATH=os.path.join(mono_root, "include", "mono-2.0"))
- mono_lib = find_file_in_dir(mono_lib_path, mono_lib_names, prefix='lib', extension='.a')
+ mono_lib = find_name_in_dir_files(mono_lib_path, mono_lib_names, prefixes=["lib"], extensions=[".a"])
if not mono_lib:
- raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
+ raise RuntimeError("Could not find mono library in: " + mono_lib_path)
- env_mono.Append(CPPDEFINES=['_REENTRANT'])
+ env_mono.Append(CPPDEFINES=["_REENTRANT"])
if mono_static:
- env.Append(LINKFLAGS=['-rdynamic'])
+ env.Append(LINKFLAGS=["-rdynamic"])
- mono_lib_file = os.path.join(mono_lib_path, 'lib' + mono_lib + '.a')
+ mono_lib_file = os.path.join(mono_lib_path, "lib" + mono_lib + ".a")
if is_apple:
- env.Append(LINKFLAGS=['-Wl,-force_load,' + mono_lib_file])
+ if is_macos:
+ env.Append(LINKFLAGS=["-Wl,-force_load," + mono_lib_file])
+ else:
+ arch = env["arch"]
+
+ def copy_mono_lib(libname_wo_ext):
+ copy_file(
+ mono_lib_path, "#bin", libname_wo_ext + ".a", "%s.iphone.%s.a" % (libname_wo_ext, arch)
+ )
+
+ # Copy Mono libraries to the output folder. These are meant to be bundled with
+ # the export templates and added to the Xcode project when exporting a game.
+ copy_mono_lib("lib" + mono_lib)
+ copy_mono_lib("libmono-native")
+ copy_mono_lib("libmono-profiler-log")
+
+ if not is_ios_sim:
+ copy_mono_lib("libmono-ee-interp")
+ copy_mono_lib("libmono-icall-table")
+ copy_mono_lib("libmono-ilgen")
else:
- assert is_desktop(env['platform']) or is_android or is_javascript
- env.Append(LINKFLAGS=['-Wl,-whole-archive', mono_lib_file, '-Wl,-no-whole-archive'])
+ assert is_desktop(env["platform"]) or is_android or is_javascript
+ env.Append(LINKFLAGS=["-Wl,-whole-archive", mono_lib_file, "-Wl,-no-whole-archive"])
if is_javascript:
- env.Append(LIBS=['mono-icall-table', 'mono-native', 'mono-ilgen', 'mono-ee-interp'])
+ env.Append(LIBS=["mono-icall-table", "mono-native", "mono-ilgen", "mono-ee-interp"])
- wasm_src_dir = os.path.join(mono_root, 'src')
+ wasm_src_dir = os.path.join(mono_root, "src")
if not os.path.isdir(wasm_src_dir):
- raise RuntimeError('Could not find mono wasm src directory')
+ raise RuntimeError("Could not find mono wasm src directory")
# Ideally this should be defined only for 'driver.c', but I can't fight scons for another 2 hours
- env_mono.Append(CPPDEFINES=['CORE_BINDINGS'])
-
- env_mono.add_source_files(env.modules_sources, [
- os.path.join(wasm_src_dir, 'driver.c'),
- os.path.join(wasm_src_dir, 'zlib-helper.c'),
- os.path.join(wasm_src_dir, 'corebindings.c')
- ])
-
- env.Append(LINKFLAGS=[
- '--js-library', os.path.join(wasm_src_dir, 'library_mono.js'),
- '--js-library', os.path.join(wasm_src_dir, 'binding_support.js'),
- '--js-library', os.path.join(wasm_src_dir, 'dotnet_support.js')
- ])
+ env_mono.Append(CPPDEFINES=["CORE_BINDINGS"])
+
+ env_mono.add_source_files(
+ env.modules_sources,
+ [
+ os.path.join(wasm_src_dir, "driver.c"),
+ os.path.join(wasm_src_dir, "zlib-helper.c"),
+ os.path.join(wasm_src_dir, "corebindings.c"),
+ ],
+ )
+
+ env.Append(
+ LINKFLAGS=[
+ "--js-library",
+ os.path.join(wasm_src_dir, "library_mono.js"),
+ "--js-library",
+ os.path.join(wasm_src_dir, "binding_support.js"),
+ "--js-library",
+ os.path.join(wasm_src_dir, "dotnet_support.js"),
+ ]
+ )
else:
env.Append(LIBS=[mono_lib])
- if is_apple:
- env.Append(LIBS=['iconv', 'pthread'])
+ if is_macos:
+ env.Append(LIBS=["iconv", "pthread"])
elif is_android:
- pass # Nothing
+ pass # Nothing
+ elif is_ios:
+ pass # Nothing, linking is delegated to the exported Xcode project
elif is_javascript:
- env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
+ env.Append(LIBS=["m", "rt", "dl", "pthread"])
else:
- env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
+ env.Append(LIBS=["m", "rt", "dl", "pthread"])
if not mono_static:
- mono_so_name = find_file_in_dir(mono_lib_path, mono_lib_names, prefix='lib', extension=sharedlib_ext)
+ mono_so_file = find_file_in_dir(
+ mono_lib_path, mono_lib_names, prefixes=["lib"], extensions=[sharedlib_ext]
+ )
- if not mono_so_name:
- raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path)
-
- copy_file(mono_lib_path, '#bin', 'lib' + mono_so_name + sharedlib_ext)
+ if not mono_so_file:
+ raise RuntimeError("Could not find mono shared library in: " + mono_lib_path)
else:
assert not mono_static
# TODO: Add option to force using pkg-config
- print('Mono root directory not found. Using pkg-config instead')
+ print("Mono root directory not found. Using pkg-config instead")
- env.ParseConfig('pkg-config monosgen-2 --libs')
- env_mono.ParseConfig('pkg-config monosgen-2 --cflags')
+ env.ParseConfig("pkg-config monosgen-2 --libs")
+ env_mono.ParseConfig("pkg-config monosgen-2 --cflags")
tmpenv = Environment()
- tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
- tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
+ tmpenv.AppendENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH"))
+ tmpenv.ParseConfig("pkg-config monosgen-2 --libs-only-L")
- for hint_dir in tmpenv['LIBPATH']:
- name_found = find_file_in_dir(hint_dir, mono_lib_names, prefix='lib', extension=sharedlib_ext)
- if name_found:
+ for hint_dir in tmpenv["LIBPATH"]:
+ file_found = find_file_in_dir(hint_dir, mono_lib_names, prefixes=["lib"], extensions=[sharedlib_ext])
+ if file_found:
mono_lib_path = hint_dir
- mono_so_name = name_found
+ mono_so_file = file_found
break
- if not mono_so_name:
- raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH']))
+ if not mono_so_file:
+ raise RuntimeError("Could not find mono shared library in: " + str(tmpenv["LIBPATH"]))
if not mono_static:
- libs_output_dir = get_android_out_dir(env) if is_android else '#bin'
- copy_file(mono_lib_path, libs_output_dir, 'lib' + mono_so_name + sharedlib_ext)
+ libs_output_dir = get_android_out_dir(env) if is_android else "#bin"
+ copy_file(mono_lib_path, libs_output_dir, mono_so_file)
if not tools_enabled:
- if is_desktop(env['platform']):
+ if is_desktop(env["platform"]):
if not mono_root:
- mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
+ mono_root = (
+ subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip()
+ )
make_template_dir(env, mono_root)
elif is_android:
# Compress Android Mono Config
from . import make_android_mono_config
+
module_dir = os.getcwd()
- config_file_path = os.path.join(module_dir, 'build_scripts', 'mono_android_config.xml')
- make_android_mono_config.generate_compressed_config(config_file_path, 'mono_gd/')
+ config_file_path = os.path.join(module_dir, "build_scripts", "mono_android_config.xml")
+ make_android_mono_config.generate_compressed_config(config_file_path, "mono_gd/")
# Copy the required shared libraries
copy_mono_shared_libs(env, mono_root, None)
elif is_javascript:
- pass # No data directory for this platform
+ pass # No data directory for this platform
+ elif is_ios:
+ pass # No data directory for this platform
if copy_mono_root:
if not mono_root:
- mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
+ mono_root = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip()
if tools_enabled:
- copy_mono_root_files(env, mono_root)
+ copy_mono_root_files(env, mono_root)
else:
print("Ignoring option: 'copy_mono_root'; only available for builds with 'tools' enabled.")
@@ -314,26 +405,26 @@ def configure(env, env_mono):
def make_template_dir(env, mono_root):
from shutil import rmtree
- platform = env['platform']
- target = env['target']
+ platform = env["platform"]
+ target = env["target"]
- template_dir_name = ''
+ template_dir_name = ""
assert is_desktop(platform)
- template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target)
+ template_dir_name = "data.mono.%s.%s.%s" % (platform, env["bits"], target)
- output_dir = Dir('#bin').abspath
+ output_dir = Dir("#bin").abspath
template_dir = os.path.join(output_dir, template_dir_name)
- template_mono_root_dir = os.path.join(template_dir, 'Mono')
+ template_mono_root_dir = os.path.join(template_dir, "Mono")
if os.path.isdir(template_mono_root_dir):
- rmtree(template_mono_root_dir) # Clean first
+ rmtree(template_mono_root_dir) # Clean first
# Copy etc/mono/
- template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono')
+ template_mono_config_dir = os.path.join(template_mono_root_dir, "etc", "mono")
copy_mono_etc_dir(mono_root, template_mono_config_dir, platform)
# Copy the required shared libraries
@@ -347,18 +438,18 @@ def copy_mono_root_files(env, mono_root):
from shutil import rmtree
if not mono_root:
- raise RuntimeError('Mono installation directory not found')
+ raise RuntimeError("Mono installation directory not found")
- output_dir = Dir('#bin').abspath
- editor_mono_root_dir = os.path.join(output_dir, 'GodotSharp', 'Mono')
+ output_dir = Dir("#bin").abspath
+ editor_mono_root_dir = os.path.join(output_dir, "GodotSharp", "Mono")
if os.path.isdir(editor_mono_root_dir):
- rmtree(editor_mono_root_dir) # Clean first
+ rmtree(editor_mono_root_dir) # Clean first
# Copy etc/mono/
- editor_mono_config_dir = os.path.join(editor_mono_root_dir, 'etc', 'mono')
- copy_mono_etc_dir(mono_root, editor_mono_config_dir, env['platform'])
+ editor_mono_config_dir = os.path.join(editor_mono_root_dir, "etc", "mono")
+ copy_mono_etc_dir(mono_root, editor_mono_config_dir, env["platform"])
# Copy the required shared libraries
@@ -366,20 +457,20 @@ def copy_mono_root_files(env, mono_root):
# Copy framework assemblies
- mono_framework_dir = os.path.join(mono_root, 'lib', 'mono', '4.5')
- mono_framework_facades_dir = os.path.join(mono_framework_dir, 'Facades')
+ mono_framework_dir = os.path.join(mono_root, "lib", "mono", "4.5")
+ mono_framework_facades_dir = os.path.join(mono_framework_dir, "Facades")
- editor_mono_framework_dir = os.path.join(editor_mono_root_dir, 'lib', 'mono', '4.5')
- editor_mono_framework_facades_dir = os.path.join(editor_mono_framework_dir, 'Facades')
+ editor_mono_framework_dir = os.path.join(editor_mono_root_dir, "lib", "mono", "4.5")
+ editor_mono_framework_facades_dir = os.path.join(editor_mono_framework_dir, "Facades")
if not os.path.isdir(editor_mono_framework_dir):
os.makedirs(editor_mono_framework_dir)
if not os.path.isdir(editor_mono_framework_facades_dir):
os.makedirs(editor_mono_framework_facades_dir)
- for assembly in glob(os.path.join(mono_framework_dir, '*.dll')):
+ for assembly in glob(os.path.join(mono_framework_dir, "*.dll")):
copy(assembly, editor_mono_framework_dir)
- for assembly in glob(os.path.join(mono_framework_facades_dir, '*.dll')):
+ for assembly in glob(os.path.join(mono_framework_facades_dir, "*.dll")):
copy(assembly, editor_mono_framework_facades_dir)
@@ -391,28 +482,28 @@ def copy_mono_etc_dir(mono_root, target_mono_config_dir, platform):
if not os.path.isdir(target_mono_config_dir):
os.makedirs(target_mono_config_dir)
- mono_etc_dir = os.path.join(mono_root, 'etc', 'mono')
+ mono_etc_dir = os.path.join(mono_root, "etc", "mono")
if not os.path.isdir(mono_etc_dir):
- mono_etc_dir = ''
+ mono_etc_dir = ""
etc_hint_dirs = []
- if platform != 'windows':
- etc_hint_dirs += ['/etc/mono', '/usr/local/etc/mono']
- if 'MONO_CFG_DIR' in os.environ:
- etc_hint_dirs += [os.path.join(os.environ['MONO_CFG_DIR'], 'mono')]
+ if platform != "windows":
+ etc_hint_dirs += ["/etc/mono", "/usr/local/etc/mono"]
+ if "MONO_CFG_DIR" in os.environ:
+ etc_hint_dirs += [os.path.join(os.environ["MONO_CFG_DIR"], "mono")]
for etc_hint_dir in etc_hint_dirs:
if os.path.isdir(etc_hint_dir):
mono_etc_dir = etc_hint_dir
break
if not mono_etc_dir:
- raise RuntimeError('Mono installation etc directory not found')
+ raise RuntimeError("Mono installation etc directory not found")
- copy_tree(os.path.join(mono_etc_dir, '2.0'), os.path.join(target_mono_config_dir, '2.0'))
- copy_tree(os.path.join(mono_etc_dir, '4.0'), os.path.join(target_mono_config_dir, '4.0'))
- copy_tree(os.path.join(mono_etc_dir, '4.5'), os.path.join(target_mono_config_dir, '4.5'))
- if os.path.isdir(os.path.join(mono_etc_dir, 'mconfig')):
- copy_tree(os.path.join(mono_etc_dir, 'mconfig'), os.path.join(target_mono_config_dir, 'mconfig'))
+ copy_tree(os.path.join(mono_etc_dir, "2.0"), os.path.join(target_mono_config_dir, "2.0"))
+ copy_tree(os.path.join(mono_etc_dir, "4.0"), os.path.join(target_mono_config_dir, "4.0"))
+ copy_tree(os.path.join(mono_etc_dir, "4.5"), os.path.join(target_mono_config_dir, "4.5"))
+ if os.path.isdir(os.path.join(mono_etc_dir, "mconfig")):
+ copy_tree(os.path.join(mono_etc_dir, "mconfig"), os.path.join(target_mono_config_dir, "mconfig"))
- for file in glob(os.path.join(mono_etc_dir, '*')):
+ for file in glob(os.path.join(mono_etc_dir, "*")):
if os.path.isfile(file):
copy(file, target_mono_config_dir)
@@ -424,48 +515,66 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
if os.path.isfile(src):
copy(src, dst)
- platform = env['platform']
+ platform = env["platform"]
- if platform == 'windows':
- src_mono_bin_dir = os.path.join(mono_root, 'bin')
- target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
+ if platform == "windows":
+ src_mono_bin_dir = os.path.join(mono_root, "bin")
+ target_mono_bin_dir = os.path.join(target_mono_root_dir, "bin")
if not os.path.isdir(target_mono_bin_dir):
os.makedirs(target_mono_bin_dir)
- mono_posix_helper_name = find_file_in_dir(src_mono_bin_dir, ['MonoPosixHelper', 'libMonoPosixHelper'], extension='.dll')
- copy(os.path.join(src_mono_bin_dir, mono_posix_helper_name + '.dll'), os.path.join(target_mono_bin_dir, 'MonoPosixHelper.dll'))
+ mono_posix_helper_file = find_file_in_dir(
+ src_mono_bin_dir, ["MonoPosixHelper"], prefixes=["", "lib"], extensions=[".dll"]
+ )
+ copy(
+ os.path.join(src_mono_bin_dir, mono_posix_helper_file),
+ os.path.join(target_mono_bin_dir, "MonoPosixHelper.dll"),
+ )
# For newer versions
- btls_dll_path = os.path.join(src_mono_bin_dir, 'libmono-btls-shared.dll')
+ btls_dll_path = os.path.join(src_mono_bin_dir, "libmono-btls-shared.dll")
if os.path.isfile(btls_dll_path):
copy(btls_dll_path, target_mono_bin_dir)
else:
- target_mono_lib_dir = get_android_out_dir(env) if platform == 'android' else os.path.join(target_mono_root_dir, 'lib')
+ target_mono_lib_dir = (
+ get_android_out_dir(env) if platform == "android" else os.path.join(target_mono_root_dir, "lib")
+ )
if not os.path.isdir(target_mono_lib_dir):
os.makedirs(target_mono_lib_dir)
lib_file_names = []
- if platform == 'osx':
- lib_file_names = [lib_name + '.dylib' for lib_name in [
- 'libmono-btls-shared', 'libmono-native-compat', 'libMonoPosixHelper'
- ]]
+ if platform == "osx":
+ lib_file_names = [
+ lib_name + ".dylib"
+ for lib_name in ["libmono-btls-shared", "libmono-native-compat", "libMonoPosixHelper"]
+ ]
elif is_unix_like(platform):
- lib_file_names = [lib_name + '.so' for lib_name in [
- 'libmono-btls-shared', 'libmono-ee-interp', 'libmono-native', 'libMonoPosixHelper',
- 'libmono-profiler-aot', 'libmono-profiler-coverage', 'libmono-profiler-log', 'libMonoSupportW'
- ]]
+ lib_file_names = [
+ lib_name + ".so"
+ for lib_name in [
+ "libmono-btls-shared",
+ "libmono-ee-interp",
+ "libmono-native",
+ "libMonoPosixHelper",
+ "libmono-profiler-aot",
+ "libmono-profiler-coverage",
+ "libmono-profiler-log",
+ "libMonoSupportW",
+ ]
+ ]
for lib_file_name in lib_file_names:
- copy_if_exists(os.path.join(mono_root, 'lib', lib_file_name), target_mono_lib_dir)
+ copy_if_exists(os.path.join(mono_root, "lib", lib_file_name), target_mono_lib_dir)
+
def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext):
tmpenv = Environment()
- tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
- tmpenv.ParseConfig('pkg-config monosgen-2 --libs-only-L')
- for hint_dir in tmpenv['LIBPATH']:
- name_found = find_file_in_dir(hint_dir, mono_lib_names, prefix='lib', extension=sharedlib_ext)
- if name_found and os.path.isdir(os.path.join(hint_dir, '..', 'include', 'mono-2.0')):
- return os.path.join(hint_dir, '..')
- return ''
+ tmpenv.AppendENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH"))
+ tmpenv.ParseConfig("pkg-config monosgen-2 --libs-only-L")
+ for hint_dir in tmpenv["LIBPATH"]:
+ name_found = find_name_in_dir_files(hint_dir, mono_lib_names, prefixes=["lib"], extensions=[sharedlib_ext])
+ if name_found and os.path.isdir(os.path.join(hint_dir, "..", "include", "mono-2.0")):
+ return os.path.join(hint_dir, "..")
+ return ""
diff --git a/modules/mono/build_scripts/mono_reg_utils.py b/modules/mono/build_scripts/mono_reg_utils.py
index b2c48f0a61..3090a4759a 100644
--- a/modules/mono/build_scripts/mono_reg_utils.py
+++ b/modules/mono/build_scripts/mono_reg_utils.py
@@ -1,21 +1,16 @@
import os
import platform
-from compat import decode_utf8
-
-if os.name == 'nt':
+if os.name == "nt":
import sys
- if sys.version_info < (3,):
- import _winreg as winreg
- else:
- import winreg
+ import winreg
def _reg_open_key(key, subkey):
try:
return winreg.OpenKey(key, subkey)
except (WindowsError, OSError):
- if platform.architecture()[0] == '32bit':
+ if platform.architecture()[0] == "32bit":
bitness_sam = winreg.KEY_WOW64_64KEY
else:
bitness_sam = winreg.KEY_WOW64_32KEY
@@ -25,12 +20,12 @@ def _reg_open_key(key, subkey):
def _reg_open_key_bits(key, subkey, bits):
sam = winreg.KEY_READ
- if platform.architecture()[0] == '32bit':
- if bits == '64':
+ if platform.architecture()[0] == "32bit":
+ if bits == "64":
# Force 32bit process to search in 64bit registry
sam |= winreg.KEY_WOW64_64KEY
else:
- if bits == '32':
+ if bits == "32":
# Force 64bit process to search in 32bit registry
sam |= winreg.KEY_WOW64_32KEY
@@ -40,7 +35,7 @@ def _reg_open_key_bits(key, subkey, bits):
def _find_mono_in_reg(subkey, bits):
try:
with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
- value = winreg.QueryValueEx(hKey, 'SdkInstallRoot')[0]
+ value = winreg.QueryValueEx(hKey, "SdkInstallRoot")[0]
return value
except (WindowsError, OSError):
return None
@@ -49,70 +44,70 @@ def _find_mono_in_reg(subkey, bits):
def _find_mono_in_reg_old(subkey, bits):
try:
with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
- default_clr = winreg.QueryValueEx(hKey, 'DefaultCLR')[0]
+ default_clr = winreg.QueryValueEx(hKey, "DefaultCLR")[0]
if default_clr:
- return _find_mono_in_reg(subkey + '\\' + default_clr, bits)
+ return _find_mono_in_reg(subkey + "\\" + default_clr, bits)
return None
except (WindowsError, EnvironmentError):
return None
def find_mono_root_dir(bits):
- root_dir = _find_mono_in_reg(r'SOFTWARE\Mono', bits)
+ root_dir = _find_mono_in_reg(r"SOFTWARE\Mono", bits)
if root_dir is not None:
return str(root_dir)
- root_dir = _find_mono_in_reg_old(r'SOFTWARE\Novell\Mono', bits)
+ root_dir = _find_mono_in_reg_old(r"SOFTWARE\Novell\Mono", bits)
if root_dir is not None:
return str(root_dir)
- return ''
+ return ""
def find_msbuild_tools_path_reg():
import subprocess
- vswhere = os.getenv('PROGRAMFILES(X86)')
+ vswhere = os.getenv("PROGRAMFILES(X86)")
if not vswhere:
- vswhere = os.getenv('PROGRAMFILES')
- vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe'
+ vswhere = os.getenv("PROGRAMFILES")
+ vswhere += r"\Microsoft Visual Studio\Installer\vswhere.exe"
- vswhere_args = ['-latest', '-products', '*', '-requires', 'Microsoft.Component.MSBuild']
+ vswhere_args = ["-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"]
try:
lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()
for line in lines:
- parts = decode_utf8(line).split(':', 1)
+ parts = line.decode("utf-8").split(":", 1)
- if len(parts) < 2 or parts[0] != 'installationPath':
+ if len(parts) < 2 or parts[0] != "installationPath":
continue
val = parts[1].strip()
if not val:
- raise ValueError('Value of `installationPath` entry is empty')
+ raise ValueError("Value of `installationPath` entry is empty")
# Since VS2019, the directory is simply named "Current"
- msbuild_dir = os.path.join(val, 'MSBuild\\Current\\Bin')
+ msbuild_dir = os.path.join(val, "MSBuild\\Current\\Bin")
if os.path.isdir(msbuild_dir):
return msbuild_dir
# Directory name "15.0" is used in VS 2017
- return os.path.join(val, 'MSBuild\\15.0\\Bin')
+ return os.path.join(val, "MSBuild\\15.0\\Bin")
- raise ValueError('Cannot find `installationPath` entry')
+ raise ValueError("Cannot find `installationPath` entry")
except ValueError as e:
- print('Error reading output from vswhere: ' + e.message)
+ print("Error reading output from vswhere: " + e.message)
except WindowsError:
- pass # Fine, vswhere not found
+ pass # Fine, vswhere not found
except (subprocess.CalledProcessError, OSError):
pass
# Try to find 14.0 in the Registry
try:
- subkey = r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0'
+ subkey = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0"
with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
- value = winreg.QueryValueEx(hKey, 'MSBuildToolsPath')[0]
+ value = winreg.QueryValueEx(hKey, "MSBuildToolsPath")[0]
return value
except (WindowsError, OSError):
- return ''
+ return ""
diff --git a/modules/mono/build_scripts/solution_builder.py b/modules/mono/build_scripts/solution_builder.py
index d1529a64d2..db6b4ff7aa 100644
--- a/modules/mono/build_scripts/solution_builder.py
+++ b/modules/mono/build_scripts/solution_builder.py
@@ -1,4 +1,3 @@
-
import os
@@ -8,35 +7,38 @@ verbose = False
def find_nuget_unix():
import os
- if 'NUGET_PATH' in os.environ:
- hint_path = os.environ['NUGET_PATH']
+ if "NUGET_PATH" in os.environ:
+ hint_path = os.environ["NUGET_PATH"]
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
- hint_path = os.path.join(hint_path, 'nuget')
+ hint_path = os.path.join(hint_path, "nuget")
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
import os.path
import sys
- hint_dirs = ['/opt/novell/mono/bin']
- if sys.platform == 'darwin':
- hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current/bin', '/usr/local/var/homebrew/linked/mono/bin'] + hint_dirs
+ hint_dirs = ["/opt/novell/mono/bin"]
+ if sys.platform == "darwin":
+ hint_dirs = [
+ "/Library/Frameworks/Mono.framework/Versions/Current/bin",
+ "/usr/local/var/homebrew/linked/mono/bin",
+ ] + hint_dirs
for hint_dir in hint_dirs:
- hint_path = os.path.join(hint_dir, 'nuget')
+ hint_path = os.path.join(hint_dir, "nuget")
if os.path.isfile(hint_path):
return hint_path
- elif os.path.isfile(hint_path + '.exe'):
- return hint_path + '.exe'
+ elif os.path.isfile(hint_path + ".exe"):
+ return hint_path + ".exe"
- for hint_dir in os.environ['PATH'].split(os.pathsep):
+ for hint_dir in os.environ["PATH"].split(os.pathsep):
hint_dir = hint_dir.strip('"')
- hint_path = os.path.join(hint_dir, 'nuget')
+ hint_path = os.path.join(hint_dir, "nuget")
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
- if os.path.isfile(hint_path + '.exe') and os.access(hint_path + '.exe', os.X_OK):
- return hint_path + '.exe'
+ if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK):
+ return hint_path + ".exe"
return None
@@ -44,30 +46,30 @@ def find_nuget_unix():
def find_nuget_windows(env):
import os
- if 'NUGET_PATH' in os.environ:
- hint_path = os.environ['NUGET_PATH']
+ if "NUGET_PATH" in os.environ:
+ hint_path = os.environ["NUGET_PATH"]
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
- hint_path = os.path.join(hint_path, 'nuget.exe')
+ hint_path = os.path.join(hint_path, "nuget.exe")
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
- from . mono_reg_utils import find_mono_root_dir
+ from .mono_reg_utils import find_mono_root_dir
- mono_root = env['mono_prefix'] or find_mono_root_dir(env['bits'])
+ mono_root = env["mono_prefix"] or find_mono_root_dir(env["bits"])
if mono_root:
- mono_bin_dir = os.path.join(mono_root, 'bin')
- nuget_mono = os.path.join(mono_bin_dir, 'nuget.bat')
+ mono_bin_dir = os.path.join(mono_root, "bin")
+ nuget_mono = os.path.join(mono_bin_dir, "nuget.bat")
if os.path.isfile(nuget_mono):
return nuget_mono
# Standalone NuGet
- for hint_dir in os.environ['PATH'].split(os.pathsep):
+ for hint_dir in os.environ["PATH"].split(os.pathsep):
hint_dir = hint_dir.strip('"')
- hint_path = os.path.join(hint_dir, 'nuget.exe')
+ hint_path = os.path.join(hint_dir, "nuget.exe")
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
@@ -78,52 +80,55 @@ def find_msbuild_unix(filename):
import os.path
import sys
- hint_dirs = ['/opt/novell/mono/bin']
- if sys.platform == 'darwin':
- hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current/bin', '/usr/local/var/homebrew/linked/mono/bin'] + hint_dirs
+ hint_dirs = ["/opt/novell/mono/bin"]
+ if sys.platform == "darwin":
+ hint_dirs = [
+ "/Library/Frameworks/Mono.framework/Versions/Current/bin",
+ "/usr/local/var/homebrew/linked/mono/bin",
+ ] + hint_dirs
for hint_dir in hint_dirs:
hint_path = os.path.join(hint_dir, filename)
if os.path.isfile(hint_path):
return hint_path
- elif os.path.isfile(hint_path + '.exe'):
- return hint_path + '.exe'
+ elif os.path.isfile(hint_path + ".exe"):
+ return hint_path + ".exe"
- for hint_dir in os.environ['PATH'].split(os.pathsep):
+ for hint_dir in os.environ["PATH"].split(os.pathsep):
hint_dir = hint_dir.strip('"')
hint_path = os.path.join(hint_dir, filename)
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
- if os.path.isfile(hint_path + '.exe') and os.access(hint_path + '.exe', os.X_OK):
- return hint_path + '.exe'
+ if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK):
+ return hint_path + ".exe"
return None
def find_msbuild_windows(env):
- from . mono_reg_utils import find_mono_root_dir, find_msbuild_tools_path_reg
+ from .mono_reg_utils import find_mono_root_dir, find_msbuild_tools_path_reg
- mono_root = env['mono_prefix'] or find_mono_root_dir(env['bits'])
+ mono_root = env["mono_prefix"] or find_mono_root_dir(env["bits"])
if not mono_root:
- raise RuntimeError('Cannot find mono root directory')
+ raise RuntimeError("Cannot find mono root directory")
- mono_bin_dir = os.path.join(mono_root, 'bin')
- msbuild_mono = os.path.join(mono_bin_dir, 'msbuild.bat')
+ mono_bin_dir = os.path.join(mono_root, "bin")
+ msbuild_mono = os.path.join(mono_bin_dir, "msbuild.bat")
msbuild_tools_path = find_msbuild_tools_path_reg()
if msbuild_tools_path:
- return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), {})
+ return (os.path.join(msbuild_tools_path, "MSBuild.exe"), {})
if os.path.isfile(msbuild_mono):
# The (Csc/Vbc/Fsc)ToolExe environment variables are required when
# building with Mono's MSBuild. They must point to the batch files
# in Mono's bin directory to make sure they are executed with Mono.
mono_msbuild_env = {
- 'CscToolExe': os.path.join(mono_bin_dir, 'csc.bat'),
- 'VbcToolExe': os.path.join(mono_bin_dir, 'vbc.bat'),
- 'FscToolExe': os.path.join(mono_bin_dir, 'fsharpc.bat')
+ "CscToolExe": os.path.join(mono_bin_dir, "csc.bat"),
+ "VbcToolExe": os.path.join(mono_bin_dir, "vbc.bat"),
+ "FscToolExe": os.path.join(mono_bin_dir, "fsharpc.bat"),
}
return (msbuild_mono, mono_msbuild_env)
@@ -132,7 +137,7 @@ def find_msbuild_windows(env):
def run_command(command, args, env_override=None, name=None):
def cmd_args_to_str(cmd_args):
- return ' '.join([arg if not ' ' in arg else '"%s"' % arg for arg in cmd_args])
+ return " ".join([arg if not " " in arg else '"%s"' % arg for arg in cmd_args])
args = [command] + args
@@ -143,6 +148,7 @@ def run_command(command, args, env_override=None, name=None):
print("Running '%s': %s" % (name, cmd_args_to_str(args)))
import subprocess
+
try:
if env_override is None:
subprocess.check_call(args)
@@ -154,61 +160,61 @@ def run_command(command, args, env_override=None, name=None):
def nuget_restore(env, *args):
global verbose
- verbose = env['verbose']
+ verbose = env["verbose"]
# Find NuGet
- nuget_path = find_nuget_windows(env) if os.name == 'nt' else find_nuget_unix()
+ nuget_path = find_nuget_windows(env) if os.name == "nt" else find_nuget_unix()
if nuget_path is None:
- raise RuntimeError('Cannot find NuGet executable')
+ raise RuntimeError("Cannot find NuGet executable")
- print('NuGet path: ' + nuget_path)
+ print("NuGet path: " + nuget_path)
# Do NuGet restore
- run_command(nuget_path, ['restore'] + list(args), name='nuget restore')
+ run_command(nuget_path, ["restore"] + list(args), name="nuget restore")
def build_solution(env, solution_path, build_config, extra_msbuild_args=[]):
global verbose
- verbose = env['verbose']
+ verbose = env["verbose"]
msbuild_env = os.environ.copy()
# Needed when running from Developer Command Prompt for VS
- if 'PLATFORM' in msbuild_env:
- del msbuild_env['PLATFORM']
+ if "PLATFORM" in msbuild_env:
+ del msbuild_env["PLATFORM"]
# Find MSBuild
- if os.name == 'nt':
+ if os.name == "nt":
msbuild_info = find_msbuild_windows(env)
if msbuild_info is None:
- raise RuntimeError('Cannot find MSBuild executable')
+ raise RuntimeError("Cannot find MSBuild executable")
msbuild_path = msbuild_info[0]
msbuild_env.update(msbuild_info[1])
else:
- msbuild_path = find_msbuild_unix('msbuild')
+ msbuild_path = find_msbuild_unix("msbuild")
if msbuild_path is None:
- xbuild_fallback = env['xbuild_fallback']
+ xbuild_fallback = env["xbuild_fallback"]
- if xbuild_fallback and os.name == 'nt':
- print('Option \'xbuild_fallback\' not supported on Windows')
+ if xbuild_fallback and os.name == "nt":
+ print("Option 'xbuild_fallback' not supported on Windows")
xbuild_fallback = False
if xbuild_fallback:
- print('Cannot find MSBuild executable, trying with xbuild')
- print('Warning: xbuild is deprecated')
+ print("Cannot find MSBuild executable, trying with xbuild")
+ print("Warning: xbuild is deprecated")
- msbuild_path = find_msbuild_unix('xbuild')
+ msbuild_path = find_msbuild_unix("xbuild")
if msbuild_path is None:
- raise RuntimeError('Cannot find xbuild executable')
+ raise RuntimeError("Cannot find xbuild executable")
else:
- raise RuntimeError('Cannot find MSBuild executable')
+ raise RuntimeError("Cannot find MSBuild executable")
- print('MSBuild path: ' + msbuild_path)
+ print("MSBuild path: " + msbuild_path)
# Build solution
- msbuild_args = [solution_path, '/p:Configuration=' + build_config]
+ msbuild_args = [solution_path, "/p:Configuration=" + build_config]
msbuild_args += extra_msbuild_args
- run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name='msbuild')
+ run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name="msbuild")
diff --git a/modules/mono/build_scripts/tls_configure.py b/modules/mono/build_scripts/tls_configure.py
deleted file mode 100644
index 622280b00b..0000000000
--- a/modules/mono/build_scripts/tls_configure.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from __future__ import print_function
-
-def supported(result):
- return 'supported' if result else 'not supported'
-
-
-def check_cxx11_thread_local(conf):
- print('Checking for `thread_local` support...', end=" ")
- result = conf.TryCompile('thread_local int foo = 0; int main() { return foo; }', '.cpp')
- print(supported(result))
- return bool(result)
-
-
-def check_declspec_thread(conf):
- print('Checking for `__declspec(thread)` support...', end=" ")
- result = conf.TryCompile('__declspec(thread) int foo = 0; int main() { return foo; }', '.cpp')
- print(supported(result))
- return bool(result)
-
-
-def check_gcc___thread(conf):
- print('Checking for `__thread` support...', end=" ")
- result = conf.TryCompile('__thread int foo = 0; int main() { return foo; }', '.cpp')
- print(supported(result))
- return bool(result)
-
-
-def configure(conf):
- if check_cxx11_thread_local(conf):
- conf.env.Append(CPPDEFINES=['HAVE_CXX11_THREAD_LOCAL'])
- else:
- if conf.env.msvc:
- if check_declspec_thread(conf):
- conf.env.Append(CPPDEFINES=['HAVE_DECLSPEC_THREAD'])
- elif check_gcc___thread(conf):
- conf.env.Append(CPPDEFINES=['HAVE_GCC___THREAD'])
diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp
index b04e53bd81..384685d04b 100644
--- a/modules/mono/class_db_api_json.cpp
+++ b/modules/mono/class_db_api_json.cpp
@@ -42,7 +42,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> names;
- const StringName *k = NULL;
+ const StringName *k = nullptr;
while ((k = ClassDB::classes.next(k))) {
@@ -67,7 +67,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames;
- k = NULL;
+ k = nullptr;
while ((k = t->method_map.next(k))) {
@@ -132,7 +132,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames;
- k = NULL;
+ k = nullptr;
while ((k = t->constant_map.next(k))) {
@@ -160,7 +160,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames;
- k = NULL;
+ k = nullptr;
while ((k = t->signal_map.next(k))) {
@@ -196,7 +196,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames;
- k = NULL;
+ k = nullptr;
while ((k = t->property_setget.next(k))) {
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 70cb464c7a..106ca6e028 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -1,42 +1,70 @@
+supported_platforms = ["windows", "osx", "linuxbsd", "server", "android", "haiku", "javascript", "iphone"]
+
+
def can_build(env, platform):
return True
def configure(env):
- if env['platform'] not in ['windows', 'osx', 'x11', 'server', 'android', 'haiku', 'javascript']:
- raise RuntimeError('This module does not currently support building for this platform')
+ platform = env["platform"]
+
+ if platform not in supported_platforms:
+ raise RuntimeError("This module does not currently support building for this platform")
env.use_ptrcall = True
- env.add_module_version_string('mono')
+ env.add_module_version_string("mono")
- from SCons.Script import BoolVariable, PathVariable, Variables
+ from SCons.Script import BoolVariable, PathVariable, Variables, Help
+
+ default_mono_static = platform in ["iphone", "javascript"]
+ default_mono_bundles_zlib = platform in ["javascript"]
envvars = Variables()
- envvars.Add(PathVariable('mono_prefix', 'Path to the mono installation directory for the target platform and architecture', '', PathVariable.PathAccept))
- envvars.Add(BoolVariable('mono_static', 'Statically link mono', False))
- envvars.Add(BoolVariable('mono_glue', 'Build with the mono glue sources', True))
- envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False))
- envvars.Add(BoolVariable('xbuild_fallback', 'If MSBuild is not found, fallback to xbuild', False))
+ envvars.Add(
+ PathVariable(
+ "mono_prefix",
+ "Path to the mono installation directory for the target platform and architecture",
+ "",
+ PathVariable.PathAccept,
+ )
+ )
+ envvars.Add(BoolVariable("mono_static", "Statically link mono", default_mono_static))
+ envvars.Add(BoolVariable("mono_glue", "Build with the mono glue sources", True))
+ envvars.Add(
+ BoolVariable(
+ "copy_mono_root", "Make a copy of the mono installation directory to bundle with the editor", False
+ )
+ )
+ envvars.Add(BoolVariable("xbuild_fallback", "If MSBuild is not found, fallback to xbuild", False))
+
+ # TODO: It would be great if this could be detected automatically instead
+ envvars.Add(
+ BoolVariable(
+ "mono_bundles_zlib", "Specify if the Mono runtime was built with bundled zlib", default_mono_bundles_zlib
+ )
+ )
+
envvars.Update(env)
+ Help(envvars.GenerateHelpText(env))
- if env['platform'] == 'javascript':
- # Mono wasm already has zlib builtin, so we need this workaround to avoid symbol collisions
- print('Compiling with Mono wasm disables \'builtin_zlib\'')
- env['builtin_zlib'] = False
+ if env["mono_bundles_zlib"]:
+ # Mono may come with zlib bundled for WASM or on newer version when built with MinGW.
+ print("This Mono runtime comes with zlib bundled. Disabling 'builtin_zlib'...")
+ env["builtin_zlib"] = False
thirdparty_zlib_dir = "#thirdparty/zlib/"
env.Prepend(CPPPATH=[thirdparty_zlib_dir])
def get_doc_classes():
return [
- '@C#',
- 'CSharpScript',
- 'GodotSharp',
+ "@C#",
+ "CSharpScript",
+ "GodotSharp",
]
def get_doc_path():
- return 'doc_classes'
+ return "doc_classes"
def is_enabled():
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 752fc9e2cc..f5911275c9 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -31,9 +31,13 @@
#include "csharp_script.h"
#include <mono/metadata/threads.h>
+#include <stdint.h>
+#include "core/debugger/engine_debugger.h"
+#include "core/debugger/script_debugger.h"
#include "core/io/json.h"
#include "core/os/file_access.h"
+#include "core/os/mutex.h"
#include "core/os/os.h"
#include "core/os/thread.h"
#include "core/project_settings.h"
@@ -57,9 +61,7 @@
#include "mono_gd/gd_mono_utils.h"
#include "signal_awaiter_utils.h"
#include "utils/macros.h"
-#include "utils/mutex_utils.h"
#include "utils/string_utils.h"
-#include "utils/thread_local.h"
#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var)
@@ -72,7 +74,7 @@ static bool _create_project_solution_if_needed() {
if (!FileAccess::exists(sln_path) || !FileAccess::exists(csproj_path)) {
// A solution does not yet exist, create a new one
- CRASH_COND(CSharpLanguage::get_singleton()->get_godotsharp_editor() == NULL);
+ CRASH_COND(CSharpLanguage::get_singleton()->get_godotsharp_editor() == nullptr);
return CSharpLanguage::get_singleton()->get_godotsharp_editor()->call("CreateProjectSolution");
}
@@ -80,7 +82,7 @@ static bool _create_project_solution_if_needed() {
}
#endif
-CSharpLanguage *CSharpLanguage::singleton = NULL;
+CSharpLanguage *CSharpLanguage::singleton = nullptr;
String CSharpLanguage::get_name() const {
@@ -139,21 +141,24 @@ void CSharpLanguage::init() {
void CSharpLanguage::finish() {
+ if (finalized)
+ return;
+
finalizing = true;
// Make sure all script binding gchandles are released before finalizing GDMono
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
CSharpScriptBinding &script_binding = E->value();
- if (script_binding.gchandle.is_valid()) {
- script_binding.gchandle->release();
+ if (!script_binding.gchandle.is_released()) {
+ script_binding.gchandle.release();
script_binding.inited = false;
}
}
if (gdmono) {
memdelete(gdmono);
- gdmono = NULL;
+ gdmono = nullptr;
}
// Clear here, after finalizing all domains to make sure there is nothing else referencing the elements.
@@ -161,18 +166,21 @@ void CSharpLanguage::finish() {
#ifdef DEBUG_ENABLED
for (Map<ObjectID, int>::Element *E = unsafe_object_references.front(); E; E = E->next()) {
- const ObjectID &id = E->get();
+ const ObjectID &id = E->key();
Object *obj = ObjectDB::get_instance(id);
if (obj) {
- ERR_PRINT("Leaked unsafe reference to object: " + obj->get_class() + ":" + itos(id));
+ ERR_PRINT("Leaked unsafe reference to object: " + obj->to_string());
} else {
ERR_PRINT("Leaked unsafe reference to deleted object: " + itos(id));
}
}
#endif
+ memdelete(managed_callable_middleman);
+
finalizing = false;
+ finalized = true;
}
void CSharpLanguage::get_reserved_words(List<String> *p_words) const {
@@ -308,7 +316,8 @@ void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const {
p_delimiters->push_back("' '"); // character literal
p_delimiters->push_back("\" \""); // regular string literal
- p_delimiters->push_back("@\" \""); // verbatim string literal
+ // Verbatim string literals (`@" "`) don't render correctly, so don't highlight them.
+ // Generic string highlighting suffices as a workaround for now.
}
static String get_base_class_name(const String &p_base_class_name, const String p_class_name) {
@@ -410,7 +419,7 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
if (p_var_type_name == Variant::get_type_name(Variant::OBJECT))
return "Godot.Object";
- if (p_var_type_name == Variant::get_type_name(Variant::REAL)) {
+ if (p_var_type_name == Variant::get_type_name(Variant::FLOAT)) {
#ifdef REAL_T_IS_DOUBLE
return "double";
#else
@@ -427,32 +436,37 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
if (p_var_type_name == Variant::get_type_name(Variant::ARRAY))
return "Collections.Array";
- if (p_var_type_name == Variant::get_type_name(Variant::POOL_BYTE_ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY))
return "byte[]";
- if (p_var_type_name == Variant::get_type_name(Variant::POOL_INT_ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY))
return "int[]";
- if (p_var_type_name == Variant::get_type_name(Variant::POOL_REAL_ARRAY)) {
-#ifdef REAL_T_IS_DOUBLE
- return "double[]";
-#else
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY))
+ return "long[]";
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY))
return "float[]";
-#endif
- }
- if (p_var_type_name == Variant::get_type_name(Variant::POOL_STRING_ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY))
+ return "double[]";
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY))
return "string[]";
- if (p_var_type_name == Variant::get_type_name(Variant::POOL_VECTOR2_ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY))
return "Vector2[]";
- if (p_var_type_name == Variant::get_type_name(Variant::POOL_VECTOR3_ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY))
return "Vector3[]";
- if (p_var_type_name == Variant::get_type_name(Variant::POOL_COLOR_ARRAY))
+ if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY))
return "Color[]";
+ if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL))
+ return "SignalInfo";
+
Variant::Type var_types[] = {
Variant::BOOL,
Variant::INT,
Variant::VECTOR2,
+ Variant::VECTOR2I,
Variant::RECT2,
+ Variant::RECT2I,
Variant::VECTOR3,
+ Variant::VECTOR3I,
Variant::TRANSFORM2D,
Variant::PLANE,
Variant::QUAT,
@@ -460,8 +474,10 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
Variant::BASIS,
Variant::TRANSFORM,
Variant::COLOR,
+ Variant::STRING_NAME,
Variant::NODE_PATH,
- Variant::_RID
+ Variant::_RID,
+ Variant::CALLABLE
};
for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) {
@@ -472,7 +488,7 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
return "object";
}
-String CSharpLanguage::make_function(const String &, const String &p_name, const PoolStringArray &p_args) const {
+String CSharpLanguage::make_function(const String &, const String &p_name, const PackedStringArray &p_args) const {
// FIXME
// - Due to Godot's API limitation this just appends the function to the end of the file
// - Use fully qualified name if there is ambiguity
@@ -490,7 +506,7 @@ String CSharpLanguage::make_function(const String &, const String &p_name, const
return s;
}
#else
-String CSharpLanguage::make_function(const String &, const String &, const PoolStringArray &) const {
+String CSharpLanguage::make_function(const String &, const String &, const PackedStringArray &) const {
return String();
}
#endif
@@ -558,7 +574,13 @@ String CSharpLanguage::debug_get_stack_level_source(int p_level) const {
Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() {
#ifdef DEBUG_ENABLED
- _TLS_RECURSION_GUARD_V_(Vector<StackInfo>());
+ // Printing an error here will result in endless recursion, so we must be careful
+ static thread_local bool _recursion_flag_ = false;
+ if (_recursion_flag_)
+ return Vector<StackInfo>();
+ _recursion_flag_ = true;
+ SCOPE_EXIT { _recursion_flag_ = false; };
+
GD_MONO_SCOPE_THREAD_ATTACH;
if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated)
@@ -583,10 +605,16 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
#ifdef DEBUG_ENABLED
Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) {
- _TLS_RECURSION_GUARD_V_(Vector<StackInfo>());
+ // Printing an error here will result in endless recursion, so we must be careful
+ static thread_local bool _recursion_flag_ = false;
+ if (_recursion_flag_)
+ return Vector<StackInfo>();
+ _recursion_flag_ = true;
+ SCOPE_EXIT { _recursion_flag_ = false; };
+
GD_MONO_SCOPE_THREAD_ATTACH;
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoArray *frames = CACHED_METHOD_THUNK(System_Diagnostics_StackTrace, GetFrames).invoke(p_stack_trace, &exc);
@@ -632,7 +660,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
#ifdef DEBUG_ENABLED
- SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
+ MutexLock lock(unsafe_object_references_lock);
ObjectID id = p_obj->get_instance_id();
unsafe_object_references[id]++;
#endif
@@ -640,7 +668,7 @@ void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
#ifdef DEBUG_ENABLED
- SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
+ MutexLock lock(unsafe_object_references_lock);
ObjectID id = p_obj->get_instance_id();
Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
ERR_FAIL_NULL(elem);
@@ -651,14 +679,14 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
void CSharpLanguage::frame() {
- if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != NULL) {
- const Ref<MonoGCHandle> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle;
+ if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != nullptr) {
+ const Ref<MonoGCHandleRef> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle;
if (task_scheduler_handle.is_valid()) {
MonoObject *task_scheduler = task_scheduler_handle->get_target();
if (task_scheduler) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
CACHED_METHOD_THUNK(GodotTaskScheduler, Activate).invoke(task_scheduler, &exc);
if (exc) {
@@ -736,7 +764,7 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
if (proj_assembly) {
String proj_asm_path = proj_assembly->get_path();
- if (!FileAccess::exists(proj_assembly->get_path())) {
+ if (!FileAccess::exists(proj_asm_path)) {
// Maybe it wasn't loaded from the default path, so check this as well
proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe);
if (!FileAccess::exists(proj_asm_path))
@@ -760,10 +788,10 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
// There is no soft reloading with Mono. It's always hard reloading.
- List<Ref<CSharpScript> > scripts;
+ List<Ref<CSharpScript>> scripts;
{
- SCOPED_MUTEX_LOCK(script_instances_mutex);
+ MutexLock lock(script_instances_mutex);
for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) {
// Cast to CSharpScript to avoid being erased by accident
@@ -771,10 +799,40 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
}
}
- List<Ref<CSharpScript> > to_reload;
+ scripts.sort_custom<CSharpScriptDepSort>(); // Update in inheritance dependency order
+
+ // Serialize managed callables
+ {
+ MutexLock lock(ManagedCallable::instances_mutex);
+
+ for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) {
+ ManagedCallable *managed_callable = elem->self();
+
+ MonoDelegate *delegate = (MonoDelegate *)managed_callable->delegate_handle.get_target();
+
+ Array serialized_data;
+ MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data);
+
+ MonoException *exc = nullptr;
+ bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TrySerializeDelegate).invoke(delegate, managed_serialized_data, &exc);
+
+ if (exc) {
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ continue;
+ }
+
+ if (success) {
+ ManagedCallable::instances_pending_reload.insert(managed_callable, serialized_data);
+ } else if (OS::get_singleton()->is_stdout_verbose()) {
+ OS::get_singleton()->print("Failed to serialize delegate\n");
+ }
+ }
+ }
+
+ List<Ref<CSharpScript>> to_reload;
// We need to keep reference instances alive during reloading
- List<Ref<Reference> > ref_instances;
+ List<Ref<Reference>> ref_instances;
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
CSharpScriptBinding &script_binding = E->value();
@@ -786,9 +844,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
// As scripts are going to be reloaded, must proceed without locking here
- scripts.sort_custom<CSharpScriptDepSort>(); // Update in inheritance dependency order
-
- for (List<Ref<CSharpScript> >::Element *E = scripts.front(); E; E = E->next()) {
+ for (List<Ref<CSharpScript>>::Element *E = scripts.front(); E; E = E->next()) {
Ref<CSharpScript> &script = E->get();
to_reload.push_back(script);
@@ -842,18 +898,19 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
// TODO: Proper state backup (Not only variants, serialize managed state of scripts)
csi->get_properties_state_for_reloading(state.properties);
+ csi->get_event_signals_state_for_reloading(state.event_signals);
owners_map[obj->get_instance_id()] = state;
}
}
// After the state of all instances is saved, clear scripts and script instances
- for (List<Ref<CSharpScript> >::Element *E = scripts.front(); E; E = E->next()) {
+ for (List<Ref<CSharpScript>>::Element *E = scripts.front(); E; E = E->next()) {
Ref<CSharpScript> &script = E->get();
while (script->instances.front()) {
Object *obj = script->instances.front()->get();
- obj->set_script(RefPtr()); // Remove script and existing script instances (placeholder are not removed before domain reload)
+ obj->set_script(REF()); // Remove script and existing script instances (placeholder are not removed before domain reload)
}
script->_clear();
@@ -863,7 +920,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
if (gdmono->reload_scripts_domain() != OK) {
// Failed to reload the scripts domain
// Make sure to add the scripts back to their owners before returning
- for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) {
+ for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) {
Ref<CSharpScript> scr = E->get();
for (const Map<ObjectID, CSharpScript::StateBackup>::Element *F = scr->pending_reload_state.front(); F; F = F->next()) {
@@ -876,7 +933,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
// Use a placeholder for now to avoid losing the state when saving a scene
- obj->set_script(scr.get_ref_ptr());
+ obj->set_script(scr);
PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
obj->set_script_instance(placeholder);
@@ -888,8 +945,8 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
#endif
// Restore Variant properties state, it will be kept by the placeholder until the next script reloading
- for (List<Pair<StringName, Variant> >::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) {
- placeholder->property_set_fallback(G->get().first, G->get().second, NULL);
+ for (List<Pair<StringName, Variant>>::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) {
+ placeholder->property_set_fallback(G->get().first, G->get().second, nullptr);
}
scr->pending_reload_state.erase(obj_id);
@@ -899,9 +956,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
return;
}
- List<Ref<CSharpScript> > to_reload_state;
+ List<Ref<CSharpScript>> to_reload_state;
- for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) {
+ for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) {
Ref<CSharpScript> script = E->get();
if (!script->get_path().empty()) {
@@ -923,12 +980,12 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
GDMonoAssembly *project_assembly = gdmono->get_project_assembly();
// Search in project and tools assemblies first as those are the most likely to have the class
- GDMonoClass *script_class = (project_assembly ? project_assembly->get_class(class_namespace, class_name) : NULL);
+ GDMonoClass *script_class = (project_assembly ? project_assembly->get_class(class_namespace, class_name) : nullptr);
#ifdef TOOLS_ENABLED
if (!script_class) {
GDMonoAssembly *tools_assembly = gdmono->get_tools_assembly();
- script_class = (tools_assembly ? tools_assembly->get_class(class_namespace, class_name) : NULL);
+ script_class = (tools_assembly ? tools_assembly->get_class(class_namespace, class_name) : nullptr);
}
#endif
@@ -954,7 +1011,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
CSharpScript::initialize_for_managed_type(script, script_class, native);
}
- String native_name = NATIVE_GDMONOCLASS_NAME(script->native);
+ StringName native_name = NATIVE_GDMONOCLASS_NAME(script->native);
{
for (Set<ObjectID>::Element *F = script->pending_reload_instances.front(); F; F = F->next()) {
@@ -999,17 +1056,17 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
continue;
}
#else
- CRASH_COND(si != NULL);
+ CRASH_COND(si != nullptr);
#endif
// Re-create script instance
- obj->set_script(script.get_ref_ptr()); // will create the script instance as well
+ obj->set_script(script); // will create the script instance as well
}
}
to_reload_state.push_back(script);
}
- for (List<Ref<CSharpScript> >::Element *E = to_reload_state.front(); E; E = E->next()) {
+ for (List<Ref<CSharpScript>>::Element *E = to_reload_state.front(); E; E = E->next()) {
Ref<CSharpScript> script = E->get();
for (Set<ObjectID>::Element *F = script->pending_reload_instances.front(); F; F = F->next()) {
@@ -1027,19 +1084,84 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
CSharpScript::StateBackup &state_backup = script->pending_reload_state[obj_id];
- for (List<Pair<StringName, Variant> >::Element *G = state_backup.properties.front(); G; G = G->next()) {
+ for (List<Pair<StringName, Variant>>::Element *G = state_backup.properties.front(); G; G = G->next()) {
obj->get_script_instance()->set(G->get().first, G->get().second);
}
- // Call OnAfterDeserialization
CSharpInstance *csi = CAST_CSHARP_INSTANCE(obj->get_script_instance());
- if (csi && csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener)))
- obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize);
+
+ if (csi) {
+ for (List<Pair<StringName, Array>>::Element *G = state_backup.event_signals.front(); G; G = G->next()) {
+ const StringName &name = G->get().first;
+ const Array &serialized_data = G->get().second;
+
+ Map<StringName, CSharpScript::EventSignal>::Element *match = script->event_signals.find(name);
+
+ if (!match) {
+ // The event or its signal attribute were removed
+ continue;
+ }
+
+ const CSharpScript::EventSignal &event_signal = match->value();
+
+ MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data);
+ MonoDelegate *delegate = nullptr;
+
+ MonoException *exc = nullptr;
+ bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TryDeserializeDelegate).invoke(managed_serialized_data, &delegate, &exc);
+
+ if (exc) {
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ continue;
+ }
+
+ if (success) {
+ ERR_CONTINUE(delegate == nullptr);
+ event_signal.field->set_value(csi->get_mono_object(), (MonoObject *)delegate);
+ } else if (OS::get_singleton()->is_stdout_verbose()) {
+ OS::get_singleton()->print("Failed to deserialize event signal delegate\n");
+ }
+ }
+
+ // Call OnAfterDeserialization
+ if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener)))
+ obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize);
+ }
}
script->pending_reload_instances.clear();
}
+ // Deserialize managed callables
+ {
+ MutexLock lock(ManagedCallable::instances_mutex);
+
+ for (Map<ManagedCallable *, Array>::Element *elem = ManagedCallable::instances_pending_reload.front(); elem; elem = elem->next()) {
+ ManagedCallable *managed_callable = elem->key();
+ const Array &serialized_data = elem->value();
+
+ MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data);
+ MonoDelegate *delegate = nullptr;
+
+ MonoException *exc = nullptr;
+ bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TryDeserializeDelegate).invoke(managed_serialized_data, &delegate, &exc);
+
+ if (exc) {
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ continue;
+ }
+
+ if (success) {
+ ERR_CONTINUE(delegate == nullptr);
+ managed_callable->set_delegate(delegate);
+ } else if (OS::get_singleton()->is_stdout_verbose()) {
+ OS::get_singleton()->print("Failed to deserialize delegate\n");
+ }
+ }
+
+ ManagedCallable::instances_pending_reload.clear();
+ }
+
#ifdef TOOLS_ENABLED
// FIXME: Hack to refresh editor in order to display new properties and signals. See if there is a better alternative.
if (Engine::get_singleton()->is_editor_hint()) {
@@ -1133,11 +1255,11 @@ void CSharpLanguage::thread_exit() {
bool CSharpLanguage::debug_break_parse(const String &p_file, int p_line, const String &p_error) {
// Not a parser error in our case, but it's still used for other type of errors
- if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
+ if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_line = p_line;
_debug_parse_err_file = p_file;
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, false, true);
+ EngineDebugger::get_script_debugger()->debug(this, false, true);
return true;
} else {
return false;
@@ -1146,11 +1268,11 @@ bool CSharpLanguage::debug_break_parse(const String &p_file, int p_line, const S
bool CSharpLanguage::debug_break(const String &p_error, bool p_allow_continue) {
- if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
+ if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, p_allow_continue);
+ EngineDebugger::get_script_debugger()->debug(this, p_allow_continue);
return true;
} else {
return false;
@@ -1160,9 +1282,20 @@ bool CSharpLanguage::debug_break(const String &p_error, bool p_allow_continue) {
void CSharpLanguage::_on_scripts_domain_unloaded() {
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
CSharpScriptBinding &script_binding = E->value();
+ script_binding.gchandle.release();
script_binding.inited = false;
}
+ {
+ MutexLock lock(ManagedCallable::instances_mutex);
+
+ for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) {
+ ManagedCallable *managed_callable = elem->self();
+ managed_callable->delegate_handle.release();
+ managed_callable->delegate_invoke = nullptr;
+ }
+ }
+
scripts_metadata_invalidated = true;
}
@@ -1174,17 +1307,17 @@ void CSharpLanguage::_editor_init_callback() {
// Initialize GodotSharpEditor
GDMonoClass *editor_klass = GDMono::get_singleton()->get_tools_assembly()->get_class("GodotTools", "GodotSharpEditor");
- CRASH_COND(editor_klass == NULL);
+ CRASH_COND(editor_klass == nullptr);
MonoObject *mono_object = mono_object_new(mono_domain_get(), editor_klass->get_mono_ptr());
- CRASH_COND(mono_object == NULL);
+ CRASH_COND(mono_object == nullptr);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::runtime_object_init(mono_object, editor_klass, &exc);
UNHANDLED_EXCEPTION(exc);
EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(GDMonoMarshal::mono_object_to_variant(mono_object));
- CRASH_COND(godotsharp_editor == NULL);
+ CRASH_COND(godotsharp_editor == nullptr);
// Enable it as a plugin
EditorNode::add_editor_plugin(godotsharp_editor);
@@ -1200,98 +1333,45 @@ void CSharpLanguage::set_language_index(int p_idx) {
lang_idx = p_idx;
}
-void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) {
+void CSharpLanguage::release_script_gchandle(MonoGCHandleData &p_gchandle) {
- if (!p_gchandle->is_released()) { // Do not lock unnecessarily
- SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
- p_gchandle->release();
+ if (!p_gchandle.is_released()) { // Do not lock unnecessarily
+ MutexLock lock(get_singleton()->script_gchandle_release_mutex);
+ p_gchandle.release();
}
}
-void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref<MonoGCHandle> &p_gchandle) {
+void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, MonoGCHandleData &p_gchandle) {
- uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it
+ uint32_t pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(p_expected_obj); // We might lock after this, so pin it
- if (!p_gchandle->is_released()) { // Do not lock unnecessarily
- SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
+ if (!p_gchandle.is_released()) { // Do not lock unnecessarily
+ MutexLock lock(get_singleton()->script_gchandle_release_mutex);
- MonoObject *target = p_gchandle->get_target();
+ MonoObject *target = p_gchandle.get_target();
// We release the gchandle if it points to the MonoObject* we expect (otherwise it was
// already released and could have been replaced) or if we can't get its target MonoObject*
// (which doesn't necessarily mean it was released, and we want it released in order to
// avoid locking other threads unnecessarily).
- if (target == p_expected_obj || target == NULL) {
- p_gchandle->release();
+ if (target == p_expected_obj || target == nullptr) {
+ p_gchandle.release();
}
}
- MonoGCHandle::free_handle(pinned_gchandle);
+ GDMonoUtils::free_gchandle(pinned_gchandle);
}
CSharpLanguage::CSharpLanguage() {
ERR_FAIL_COND_MSG(singleton, "C# singleton already exist.");
singleton = this;
-
- finalizing = false;
-
- gdmono = NULL;
-
-#ifdef NO_THREADS
- script_instances_mutex = NULL;
- script_gchandle_release_mutex = NULL;
- language_bind_mutex = NULL;
-#else
- script_instances_mutex = Mutex::create();
- script_gchandle_release_mutex = Mutex::create();
- language_bind_mutex = Mutex::create();
-#endif
-
-#ifdef DEBUG_ENABLED
-#ifdef NO_THREADS
- unsafe_object_references_lock = NULL;
-#else
- unsafe_object_references_lock = Mutex::create();
-#endif
-#endif
-
- lang_idx = -1;
-
- scripts_metadata_invalidated = true;
-
-#ifdef TOOLS_ENABLED
- godotsharp_editor = NULL;
-#endif
}
CSharpLanguage::~CSharpLanguage() {
finish();
-
- if (script_instances_mutex) {
- memdelete(script_instances_mutex);
- script_instances_mutex = NULL;
- }
-
- if (language_bind_mutex) {
- memdelete(language_bind_mutex);
- language_bind_mutex = NULL;
- }
-
- if (script_gchandle_release_mutex) {
- memdelete(script_gchandle_release_mutex);
- script_gchandle_release_mutex = NULL;
- }
-
-#ifdef DEBUG_ENABLED
- if (unsafe_object_references_lock) {
- memdelete(unsafe_object_references_lock);
- unsafe_object_references_lock = NULL;
- }
-#endif
-
- singleton = NULL;
+ singleton = nullptr;
}
bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object) {
@@ -1300,7 +1380,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
// I don't trust you
if (p_object->get_script_instance()) {
CSharpInstance *csharp_instance = CAST_CSHARP_INSTANCE(p_object->get_script_instance());
- CRASH_COND(csharp_instance != NULL && !csharp_instance->is_destructing_script_instance());
+ CRASH_COND(csharp_instance != nullptr && !csharp_instance->is_destructing_script_instance());
}
#endif
@@ -1324,7 +1404,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
r_script_binding.inited = true;
r_script_binding.type_name = type_name;
r_script_binding.wrapper_class = type_class; // cache
- r_script_binding.gchandle = MonoGCHandle::create_strong(mono_object);
+ r_script_binding.gchandle = MonoGCHandleData::new_strong_handle(mono_object);
r_script_binding.owner = p_object;
// Tie managed to unmanaged
@@ -1345,7 +1425,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
- SCOPED_MUTEX_LOCK(language_bind_mutex);
+ MutexLock lock(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
if (match)
@@ -1354,7 +1434,7 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
CSharpScriptBinding script_binding;
if (!setup_csharp_script_binding(script_binding, p_object))
- return NULL;
+ return nullptr;
return (void *)insert_script_binding(p_object, script_binding);
}
@@ -1366,7 +1446,7 @@ Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_bindi
void CSharpLanguage::free_instance_binding_data(void *p_data) {
- if (GDMono::get_singleton() == NULL) {
+ if (GDMono::get_singleton() == nullptr) {
#ifdef DEBUG_ENABLED
CRASH_COND(!script_bindings.empty());
#endif
@@ -1380,7 +1460,7 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
GD_MONO_ASSERT_THREAD_ATTACHED;
{
- SCOPED_MUTEX_LOCK(language_bind_mutex);
+ MutexLock lock(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data;
@@ -1389,10 +1469,11 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
if (script_binding.inited) {
// Set the native instance field to IntPtr.Zero, if not yet garbage collected.
// This is done to avoid trying to dispose the native instance from Dispose(bool).
- MonoObject *mono_object = script_binding.gchandle->get_target();
+ MonoObject *mono_object = script_binding.gchandle.get_target();
if (mono_object) {
- CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, NULL);
+ CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, nullptr);
}
+ script_binding.gchandle.release();
}
script_bindings.erase(data);
@@ -1412,26 +1493,26 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
CRASH_COND(!data);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
+ MonoGCHandleData &gchandle = script_binding.gchandle;
if (!script_binding.inited)
return;
- if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH;
// The reference count was increased after the managed side was the only one referencing our owner.
// This means the owner is being referenced again by the unmanaged side,
// so the owner must hold the managed side alive again to avoid it from being GCed.
- MonoObject *target = gchandle->get_target();
+ MonoObject *target = gchandle.get_target();
if (!target)
return; // Called after the managed side was collected, so nothing to do here
// Release the current weak handle and replace it with a strong handle.
- uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(target);
- gchandle->release();
- gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE);
+ MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target);
+ gchandle.release();
+ gchandle = strong_gchandle;
}
}
@@ -1448,27 +1529,27 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
CRASH_COND(!data);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
+ MonoGCHandleData &gchandle = script_binding.gchandle;
int refcount = ref_owner->reference_get_count();
if (!script_binding.inited)
return refcount == 0;
- if (refcount == 1 && gchandle.is_valid() && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH;
// If owner owner is no longer referenced by the unmanaged side,
// the managed instance takes responsibility of deleting the owner when GCed.
- MonoObject *target = gchandle->get_target();
+ MonoObject *target = gchandle.get_target();
if (!target)
return refcount == 0; // Called after the managed side was collected, so nothing to do here
// Release the current strong handle and replace it with a weak handle.
- uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(target);
- gchandle->release();
- gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE);
+ MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(target);
+ gchandle.release();
+ gchandle = weak_gchandle;
return false;
}
@@ -1476,14 +1557,13 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
return refcount == 0;
}
-CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref<MonoGCHandle> &p_gchandle) {
+CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle) {
- CSharpInstance *instance = memnew(CSharpInstance);
+ CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(p_script)));
Reference *ref = Object::cast_to<Reference>(p_owner);
- instance->base_ref = ref != NULL;
- instance->script = Ref<CSharpScript>(p_script);
+ instance->base_ref = ref != nullptr;
instance->owner = p_owner;
instance->gchandle = p_gchandle;
@@ -1497,8 +1577,8 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS
MonoObject *CSharpInstance::get_mono_object() const {
- ERR_FAIL_COND_V(gchandle.is_null(), NULL);
- return gchandle->get_target();
+ ERR_FAIL_COND_V(gchandle.is_released(), nullptr);
+ return gchandle.get_target();
}
Object *CSharpInstance::get_owner() {
@@ -1582,7 +1662,7 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {
GDMonoProperty *property = top->get_property(p_name);
if (property) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoObject *value = property->get_value(mono_object, &exc);
if (exc) {
r_ret = Variant();
@@ -1623,7 +1703,7 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {
return false;
}
-void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state) {
+void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Variant>> &r_state) {
List<PropertyInfo> pinfo;
get_property_list(&pinfo);
@@ -1648,6 +1728,37 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va
}
}
+void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName, Array>> &r_state) {
+
+ MonoObject *owner_managed = get_mono_object();
+ ERR_FAIL_NULL(owner_managed);
+
+ for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) {
+ const CSharpScript::EventSignal &event_signal = E->value();
+
+ MonoDelegate *delegate_field_value = (MonoDelegate *)event_signal.field->get_value(owner_managed);
+ if (!delegate_field_value)
+ continue; // Empty
+
+ Array serialized_data;
+ MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data);
+
+ MonoException *exc = nullptr;
+ bool success = (bool)CACHED_METHOD_THUNK(DelegateUtils, TrySerializeDelegate).invoke(delegate_field_value, managed_serialized_data, &exc);
+
+ if (exc) {
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ continue;
+ }
+
+ if (success) {
+ r_state.push_back(Pair<StringName, Array>(event_signal.field->get_name(), serialized_data));
+ } else if (OS::get_singleton()->is_stdout_verbose()) {
+ OS::get_singleton()->print("Failed to serialize event signal delegate\n");
+ }
+ }
+}
+
void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
for (Map<StringName, PropertyInfo>::Element *E = script->member_info.front(); E; E = E->next()) {
@@ -1719,17 +1830,16 @@ bool CSharpInstance::has_method(const StringName &p_method) const {
return false;
}
-Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- if (!script.is_valid())
- ERR_FAIL_V(Variant());
+ ERR_FAIL_COND_V(!script.is_valid(), Variant());
GD_MONO_SCOPE_THREAD_ATTACH;
MonoObject *mono_object = get_mono_object();
if (!mono_object) {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
ERR_FAIL_V(Variant());
}
@@ -1741,7 +1851,7 @@ Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args,
if (method) {
MonoObject *return_value = method->invoke(mono_object, p_args);
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
if (return_value) {
return GDMonoMarshal::mono_object_to_variant(return_value);
@@ -1753,7 +1863,7 @@ Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args,
top = top->get_parent_class();
}
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
@@ -1800,7 +1910,7 @@ bool CSharpInstance::_reference_owner_unsafe() {
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
- CRASH_COND(owner == NULL);
+ CRASH_COND(owner == nullptr);
CRASH_COND(unsafe_referenced); // already referenced
#endif
@@ -1822,7 +1932,7 @@ bool CSharpInstance::_unreference_owner_unsafe() {
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
- CRASH_COND(owner == NULL);
+ CRASH_COND(owner == nullptr);
#endif
if (!unsafe_referenced)
@@ -1841,19 +1951,15 @@ bool CSharpInstance::_unreference_owner_unsafe() {
}
MonoObject *CSharpInstance::_internal_new_managed() {
-#ifdef DEBUG_ENABLED
- CRASH_COND(!gchandle.is_valid());
-#endif
-
// Search the constructor first, to fail with an error if it's not found before allocating anything else.
GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
- ERR_FAIL_NULL_V_MSG(ctor, NULL,
+ ERR_FAIL_NULL_V_MSG(ctor, nullptr,
"Cannot create script instance because the class does not define a parameterless constructor: '" + script->get_path() + "'.");
CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
- ERR_FAIL_NULL_V(owner, NULL);
- ERR_FAIL_COND_V(script.is_null(), NULL);
+ ERR_FAIL_NULL_V(owner, nullptr);
+ ERR_FAIL_COND_V(script.is_null(), nullptr);
MonoObject *mono_object = mono_object_new(mono_domain_get(), script->script_class->get_mono_ptr());
@@ -1865,13 +1971,13 @@ MonoObject *CSharpInstance::_internal_new_managed() {
// Not ok for the owner to die here. If there is a situation where this can happen, it will be considered a bug.
CRASH_COND(die == true);
- owner = NULL;
+ owner = nullptr;
- ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
+ ERR_FAIL_V_MSG(nullptr, "Failed to allocate memory for the object.");
}
// Tie managed to unmanaged
- gchandle = MonoGCHandle::create_strong(mono_object);
+ gchandle = MonoGCHandleData::new_strong_handle(mono_object);
if (base_ref)
_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
@@ -1879,16 +1985,18 @@ MonoObject *CSharpInstance::_internal_new_managed() {
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, owner);
// Construct
- ctor->invoke_raw(mono_object, NULL);
+ ctor->invoke_raw(mono_object, nullptr);
return mono_object;
}
void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
+ disconnect_event_signals();
+
#ifdef DEBUG_ENABLED
CRASH_COND(base_ref);
- CRASH_COND(gchandle.is_null());
+ CRASH_COND(gchandle.is_released());
#endif
CSharpLanguage::get_singleton()->release_script_gchandle(p_obj, gchandle);
}
@@ -1897,7 +2005,7 @@ void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_f
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
- CRASH_COND(gchandle.is_null());
+ CRASH_COND(gchandle.is_released());
#endif
r_remove_script_instance = false;
@@ -1927,16 +2035,43 @@ void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_f
}
}
+void CSharpInstance::connect_event_signals() {
+ for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) {
+ const CSharpScript::EventSignal &event_signal = E->value();
+
+ StringName signal_name = event_signal.field->get_name();
+
+ // TODO: Use pooling for ManagedCallable instances.
+ auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal));
+
+ owner->connect(signal_name, Callable(event_signal_callable));
+ }
+}
+
+void CSharpInstance::disconnect_event_signals() {
+ for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) {
+ const CSharpScript::EventSignal &event_signal = E->value();
+
+ StringName signal_name = event_signal.field->get_name();
+
+ // TODO: It would be great if we could store this EventSignalCallable on the stack.
+ // The problem is that Callable memdeletes it when it's destructed...
+ auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal));
+
+ owner->disconnect(signal_name, Callable(event_signal_callable));
+ }
+}
+
void CSharpInstance::refcount_incremented() {
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
- CRASH_COND(owner == NULL);
+ CRASH_COND(owner == nullptr);
#endif
Reference *ref_owner = Object::cast_to<Reference>(owner);
- if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH;
// The reference count was increased after the managed side was the only one referencing our owner.
@@ -1944,9 +2079,9 @@ void CSharpInstance::refcount_incremented() {
// so the owner must hold the managed side alive again to avoid it from being GCed.
// Release the current weak handle and replace it with a strong handle.
- uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(gchandle->get_target());
- gchandle->release();
- gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE);
+ MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(gchandle.get_target());
+ gchandle.release();
+ gchandle = strong_gchandle;
}
}
@@ -1954,23 +2089,23 @@ bool CSharpInstance::refcount_decremented() {
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
- CRASH_COND(owner == NULL);
+ CRASH_COND(owner == nullptr);
#endif
Reference *ref_owner = Object::cast_to<Reference>(owner);
int refcount = ref_owner->reference_get_count();
- if (refcount == 1 && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (refcount == 1 && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH;
// If owner owner is no longer referenced by the unmanaged side,
// the managed instance takes responsibility of deleting the owner when GCed.
// Release the current strong handle and replace it with a weak handle.
- uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(gchandle->get_target());
- gchandle->release();
- gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE);
+ MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(gchandle.get_target());
+ gchandle.release();
+ gchandle = weak_gchandle;
return false;
}
@@ -1980,67 +2115,44 @@ bool CSharpInstance::refcount_decremented() {
return ref_dying;
}
-MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(IMonoClassMember *p_member) const {
-
- if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
- return MultiplayerAPI::RPC_MODE_REMOTE;
- if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
- return MultiplayerAPI::RPC_MODE_MASTER;
- if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute)))
- return MultiplayerAPI::RPC_MODE_PUPPET;
- if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute)))
- return MultiplayerAPI::RPC_MODE_PUPPET;
- if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute)))
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute)))
- return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute)))
- return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+Vector<ScriptNetData> CSharpInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+uint16_t CSharpInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
}
-MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const {
+StringName CSharpInstance::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_method(p_rpc_method_id);
+}
- GD_MONO_SCOPE_THREAD_ATTACH;
+MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_mode_by_id(p_rpc_method_id);
+}
- GDMonoClass *top = script->script_class;
+MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
+}
- while (top && top != script->native) {
- GDMonoMethod *method = top->get_fetched_method_unknown_params(p_method);
+Vector<ScriptNetData> CSharpInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- if (method && !method->is_static())
- return _member_get_rpc_mode(method);
+uint16_t CSharpInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
+}
- top = top->get_parent_class();
- }
+StringName CSharpInstance::get_rset_property(const uint16_t p_rset_member_id) const {
+ return script->get_rset_property(p_rset_member_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ return script->get_rset_mode_by_id(p_rset_member_id);
}
MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const {
-
- GD_MONO_SCOPE_THREAD_ATTACH;
-
- GDMonoClass *top = script->script_class;
-
- while (top && top != script->native) {
- GDMonoField *field = top->get_field(p_variable);
-
- if (field && !field->is_static())
- return _member_get_rpc_mode(field);
-
- GDMonoProperty *property = top->get_property(p_variable);
-
- if (property && !property->is_static())
- return _member_get_rpc_mode(property);
-
- top = top->get_parent_class();
- }
-
- return MultiplayerAPI::RPC_MODE_DISABLED;
+ return script->get_rset_mode(p_variable);
}
void CSharpInstance::notification(int p_notification) {
@@ -2069,7 +2181,7 @@ void CSharpInstance::notification(int p_notification) {
MonoObject *mono_object = get_mono_object();
ERR_FAIL_NULL(mono_object);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::dispose(mono_object, &exc);
if (exc) {
@@ -2114,13 +2226,13 @@ String CSharpInstance::to_string(bool *r_valid) {
MonoObject *mono_object = get_mono_object();
- if (mono_object == NULL) {
+ if (mono_object == nullptr) {
if (r_valid)
*r_valid = false;
return String();
}
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoString *result = GDMonoUtils::object_to_string(mono_object, &exc);
if (exc) {
@@ -2130,7 +2242,7 @@ String CSharpInstance::to_string(bool *r_valid) {
return String();
}
- if (result == NULL) {
+ if (result == nullptr) {
if (r_valid)
*r_valid = false;
return String();
@@ -2149,13 +2261,8 @@ ScriptLanguage *CSharpInstance::get_language() {
return CSharpLanguage::get_singleton();
}
-CSharpInstance::CSharpInstance() :
- owner(NULL),
- base_ref(false),
- ref_dying(false),
- unsafe_referenced(false),
- predelete_notified(false),
- destructing_script_instance(false) {
+CSharpInstance::CSharpInstance(const Ref<CSharpScript> &p_script) :
+ script(p_script) {
}
CSharpInstance::~CSharpInstance() {
@@ -2164,18 +2271,18 @@ CSharpInstance::~CSharpInstance() {
destructing_script_instance = true;
- if (gchandle.is_valid()) {
+ if (!gchandle.is_released()) {
if (!predelete_notified && !ref_dying) {
// This destructor is not called from the owners destructor.
// This could be being called from the owner's set_script_instance method,
// meaning this script is being replaced with another one. If this is the case,
- // we must call Dispose here, because Dispose calls owner->set_script_instance(NULL)
+ // we must call Dispose here, because Dispose calls owner->set_script_instance(nullptr)
// and that would mess up with the new script instance if called later.
- MonoObject *mono_object = gchandle->get_target();
+ MonoObject *mono_object = gchandle.get_target();
if (mono_object) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::dispose(mono_object, &exc);
if (exc) {
@@ -2184,7 +2291,7 @@ CSharpInstance::~CSharpInstance() {
}
}
- gchandle->release(); // Make sure the gchandle is released
+ gchandle.release(); // Make sure the gchandle is released
}
// If not being called from the owner's destructor, and we still hold a reference to the owner
@@ -2205,12 +2312,12 @@ CSharpInstance::~CSharpInstance() {
CRASH_COND(die == true); // `owner_keep_alive` holds a reference, so it can't die
void *data = owner->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
- CRASH_COND(data == NULL);
+ CRASH_COND(data == nullptr);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
if (!script_binding.inited) {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+ MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
if (!script_binding.inited) { // Other thread may have set it up
// Already had a binding that needs to be setup
@@ -2226,7 +2333,7 @@ CSharpInstance::~CSharpInstance() {
}
if (script.is_valid() && owner) {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
#ifdef DEBUG_ENABLED
// CSharpInstance must not be created unless it's going to be added to the list for sure
@@ -2344,23 +2451,23 @@ bool CSharpScript::_update_exports() {
return false;
}
- uint32_t tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed)
+ uint32_t tmp_pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(tmp_object); // pin it (not sure if needed)
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
- ERR_FAIL_NULL_V_MSG(ctor, NULL,
+ ERR_FAIL_NULL_V_MSG(ctor, false,
"Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
- MonoException *ctor_exc = NULL;
- ctor->invoke(tmp_object, NULL, &ctor_exc);
+ MonoException *ctor_exc = nullptr;
+ ctor->invoke(tmp_object, nullptr, &ctor_exc);
Object *tmp_native = GDMonoMarshal::unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(tmp_object));
if (ctor_exc) {
// TODO: Should we free 'tmp_native' if the exception was thrown after its creation?
- MonoGCHandle::free_handle(tmp_pinned_gchandle);
- tmp_object = NULL;
+ GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
+ tmp_object = nullptr;
ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
GDMonoUtils::debug_print_unhandled_exception(ctor_exc);
@@ -2407,7 +2514,7 @@ bool CSharpScript::_update_exports() {
exported_members_cache.push_front(prop_info);
if (tmp_object) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoObject *ret = property->get_value(tmp_object, &exc);
if (exc) {
exported_members_defval_cache[member_name] = Variant();
@@ -2426,11 +2533,11 @@ bool CSharpScript::_update_exports() {
}
// Need to check this here, before disposal
- bool base_ref = Object::cast_to<Reference>(tmp_native) != NULL;
+ bool base_ref = Object::cast_to<Reference>(tmp_native) != nullptr;
// Dispose the temporary managed instance
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::dispose(tmp_object, &exc);
if (exc) {
@@ -2438,8 +2545,8 @@ bool CSharpScript::_update_exports() {
GDMonoUtils::debug_print_unhandled_exception(exc);
}
- MonoGCHandle::free_handle(tmp_pinned_gchandle);
- tmp_object = NULL;
+ GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
+ tmp_object = nullptr;
if (tmp_native && !base_ref) {
Node *node = Object::cast_to<Node>(tmp_native);
@@ -2478,6 +2585,7 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
// make sure this classes signals are empty when loading for the first time
_signals.clear();
+ event_signals.clear();
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -2485,56 +2593,90 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
while (top && top != p_native_class) {
const Vector<GDMonoClass *> &delegates = top->get_all_delegates();
for (int i = delegates.size() - 1; i >= 0; --i) {
- Vector<Argument> parameters;
-
GDMonoClass *delegate = delegates[i];
- if (_get_signal(top, delegate, parameters)) {
+ if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute)))
+ continue;
+
+ // Arguments are accessibles as arguments of .Invoke method
+ GDMonoMethod *invoke_method = delegate->get_method(mono_get_delegate_invoke(delegate->get_mono_ptr()));
+
+ Vector<SignalParameter> parameters;
+ if (_get_signal(top, invoke_method, parameters)) {
_signals[delegate->get_name()] = parameters;
}
}
+ List<StringName> found_event_signals;
+
+ void *iter = nullptr;
+ MonoEvent *raw_event = nullptr;
+ while ((raw_event = mono_class_get_events(top->get_mono_ptr(), &iter)) != nullptr) {
+ MonoCustomAttrInfo *event_attrs = mono_custom_attrs_from_event(top->get_mono_ptr(), raw_event);
+ if (event_attrs) {
+ if (mono_custom_attrs_has_attr(event_attrs, CACHED_CLASS(SignalAttribute)->get_mono_ptr())) {
+ const char *event_name = mono_event_get_name(raw_event);
+ found_event_signals.push_back(StringName(event_name));
+ }
+
+ mono_custom_attrs_free(event_attrs);
+ }
+ }
+
+ const Vector<GDMonoField *> &fields = top->get_all_fields();
+ for (int i = 0; i < fields.size(); i++) {
+ GDMonoField *field = fields[i];
+
+ GDMonoClass *field_class = field->get_type().type_class;
+
+ if (!mono_class_is_delegate(field_class->get_mono_ptr()))
+ continue;
+
+ if (!found_event_signals.find(field->get_name()))
+ continue;
+
+ GDMonoMethod *invoke_method = field_class->get_method(mono_get_delegate_invoke(field_class->get_mono_ptr()));
+
+ Vector<SignalParameter> parameters;
+ if (_get_signal(top, invoke_method, parameters)) {
+ event_signals[field->get_name()] = { field, invoke_method, parameters };
+ }
+ }
+
top = top->get_parent_class();
}
signals_invalidated = false;
}
-bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> &params) {
+bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> &params) {
GD_MONO_ASSERT_THREAD_ATTACHED;
- if (p_delegate->has_attribute(CACHED_CLASS(SignalAttribute))) {
- MonoType *raw_type = p_delegate->get_mono_type();
+ Vector<StringName> names;
+ Vector<ManagedType> types;
+ p_delegate_invoke->get_parameter_names(names);
+ p_delegate_invoke->get_parameter_types(types);
- if (mono_type_get_type(raw_type) == MONO_TYPE_CLASS) {
- // Arguments are accessibles as arguments of .Invoke method
- GDMonoMethod *invoke = p_delegate->get_method("Invoke", -1);
-
- Vector<StringName> names;
- Vector<ManagedType> types;
- invoke->get_parameter_names(names);
- invoke->get_parameter_types(types);
-
- if (names.size() == types.size()) {
- for (int i = 0; i < names.size(); ++i) {
- Argument arg;
- arg.name = names[i];
- arg.type = GDMonoMarshal::managed_to_variant_type(types[i]);
-
- if (arg.type == Variant::NIL) {
- ERR_PRINT("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'.");
- return false;
- }
+ for (int i = 0; i < names.size(); ++i) {
+ SignalParameter arg;
+ arg.name = names[i];
- params.push_back(arg);
- }
+ bool nil_is_variant = false;
+ arg.type = GDMonoMarshal::managed_to_variant_type(types[i], &nil_is_variant);
- return true;
+ if (arg.type == Variant::NIL) {
+ if (nil_is_variant) {
+ arg.nil_is_variant = true;
+ } else {
+ ERR_PRINT("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'.");
+ return false;
}
}
+
+ params.push_back(arg);
}
- return false;
+ return true;
}
#ifdef TOOLS_ENABLED
@@ -2585,7 +2727,8 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
}
}
- Variant::Type variant_type = GDMonoMarshal::managed_to_variant_type(type);
+ bool nil_is_variant = false;
+ Variant::Type variant_type = GDMonoMarshal::managed_to_variant_type(type, &nil_is_variant);
if (!p_inspect_export || !exported) {
r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_SCRIPT_VARIABLE);
@@ -2598,7 +2741,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
PropertyHint hint = PROPERTY_HINT_NONE;
String hint_string;
- if (variant_type == Variant::NIL) {
+ if (variant_type == Variant::NIL && !nil_is_variant) {
ERR_PRINT("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
return false;
}
@@ -2614,7 +2757,14 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
hint_string = CACHED_FIELD(ExportAttribute, hintString)->get_string_value(attr);
}
- r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), hint, hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE);
+ uint32_t prop_usage = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE;
+
+ if (variant_type == Variant::NIL) {
+ // System.Object (Variant)
+ prop_usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
+
+ r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), hint, hint_string, prop_usage);
r_exported = true;
return true;
@@ -2624,6 +2774,11 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string) {
+ if (p_variant_type == Variant::NIL) {
+ // System.Object (Variant)
+ return 1;
+ }
+
GD_MONO_ASSERT_THREAD_ATTACHED;
if (p_variant_type == Variant::INT && p_type.type_encoding == MONO_TYPE_VALUETYPE && mono_class_is_enum(p_type.type_class->get_mono_ptr())) {
@@ -2656,7 +2811,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
// Instead of using mono_field_get_value_object, we can do this without boxing. Check the
// internal mono functions: ves_icall_System_Enum_GetEnumValuesAndNames and the get_enum_field.
- MonoObject *val_obj = mono_field_get_value_object(mono_domain_get(), field, NULL);
+ MonoObject *val_obj = mono_field_get_value_object(mono_domain_get(), field, nullptr);
ERR_FAIL_NULL_V_MSG(val_obj, -1, "Failed to get '" + enum_field_name + "' constant enum value.");
@@ -2680,10 +2835,10 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
}
} else if (p_variant_type == Variant::OBJECT && CACHED_CLASS(GodotResource)->is_assignable_from(p_type.type_class)) {
GDMonoClass *field_native_class = GDMonoUtils::get_class_native_base(p_type.type_class);
- CRASH_COND(field_native_class == NULL);
+ CRASH_COND(field_native_class == nullptr);
r_hint = PROPERTY_HINT_RESOURCE_TYPE;
- r_hint_string = NATIVE_GDMONOCLASS_NAME(field_native_class);
+ r_hint_string = String(NATIVE_GDMONOCLASS_NAME(field_native_class));
} else if (p_allow_generics && p_variant_type == Variant::ARRAY) {
// Nested arrays are not supported in the inspector
@@ -2722,16 +2877,16 @@ void CSharpScript::_clear() {
tool = false;
valid = false;
- base = NULL;
- native = NULL;
- script_class = NULL;
+ base = nullptr;
+ native = nullptr;
+ script_class = nullptr;
}
-Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- if (unlikely(GDMono::get_singleton() == NULL)) {
+ if (unlikely(GDMono::get_singleton() == nullptr)) {
// Probably not the best error but eh.
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
@@ -2743,7 +2898,7 @@ Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, i
GDMonoMethod *method = top->get_method(p_method, p_argcount);
if (method && method->is_static()) {
- MonoObject *result = method->invoke(NULL, p_args);
+ MonoObject *result = method->invoke(nullptr, p_args);
if (result) {
return GDMonoMarshal::mono_object_to_variant(result);
@@ -2805,7 +2960,7 @@ Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GD
// This method should not fail, only assertions allowed
- CRASH_COND(p_class == NULL);
+ CRASH_COND(p_class == nullptr);
// TODO OPTIMIZE: Cache the 'CSharpScript' associated with this 'p_class' instead of allocating a new one every time
Ref<CSharpScript> script = memnew(CSharpScript);
@@ -2819,13 +2974,13 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
// This method should not fail, only assertions allowed
- CRASH_COND(p_class == NULL);
+ CRASH_COND(p_class == nullptr);
p_script->name = p_class->get_name();
p_script->script_class = p_class;
p_script->native = p_native;
- CRASH_COND(p_script->native == NULL);
+ CRASH_COND(p_script->native == nullptr);
GDMonoClass *base = p_script->script_class->get_parent_class();
@@ -2882,22 +3037,6 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
bool CSharpScript::can_instance() const {
#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint()) {
-
- // Hack to lower the risk of attached scripts not being added to the C# project
- if (!get_path().empty() && get_path().find("::") == -1) { // Ignore if built-in script. Can happen if the file is deleted...
- if (_create_project_solution_if_needed()) {
- CSharpProject::add_item(GodotSharpDirs::get_project_csproj_path(),
- "Compile",
- ProjectSettings::get_singleton()->globalize_path(get_path()));
- } else {
- ERR_PRINT("C# project could not be created; cannot add file: '" + get_path() + "'.");
- }
- }
- }
-#endif
-
-#ifdef TOOLS_ENABLED
bool extra_cond = tool || ScriptServer::is_scripting_enabled();
#else
bool extra_cond = true;
@@ -2907,12 +3046,12 @@ bool CSharpScript::can_instance() const {
// For tool scripts, this will never fire if the class is not found. That's because we
// don't know if it's a tool script if we can't find the class to access the attributes.
if (extra_cond && !script_class) {
- if (GDMono::get_singleton()->get_project_assembly() == NULL) {
+ if (GDMono::get_singleton()->get_project_assembly() == nullptr) {
// The project assembly is not loaded
- ERR_FAIL_V_MSG(NULL, "Cannot instance script because the project assembly is not loaded. Script: '" + get_path() + "'.");
+ ERR_FAIL_V_MSG(false, "Cannot instance script because the project assembly is not loaded. Script: '" + get_path() + "'.");
} else {
// The project assembly is loaded, but the class could not found
- ERR_FAIL_V_MSG(NULL, "Cannot instance script because the class '" + name + "' could not be found. Script: '" + get_path() + "'.");
+ ERR_FAIL_V_MSG(false, "Cannot instance script because the class '" + name + "' could not be found. Script: '" + get_path() + "'.");
}
}
@@ -2927,7 +3066,7 @@ StringName CSharpScript::get_instance_base_type() const {
return StringName();
}
-CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) {
+CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
GD_MONO_ASSERT_THREAD_ATTACHED;
@@ -2935,13 +3074,13 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// Search the constructor first, to fail with an error if it's not found before allocating anything else.
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount);
- if (ctor == NULL) {
- ERR_FAIL_COND_V_MSG(p_argcount == 0, NULL,
+ if (ctor == nullptr) {
+ ERR_FAIL_COND_V_MSG(p_argcount == 0, nullptr,
"Cannot create script instance. The class '" + script_class->get_full_name() +
"' does not define a parameterless constructor." +
(get_path().empty() ? String() : " Path: '" + get_path() + "'."));
- ERR_FAIL_V_MSG(NULL, "Constructor not found.");
+ ERR_FAIL_V_MSG(nullptr, "Constructor not found.");
}
Ref<Reference> ref;
@@ -2953,13 +3092,13 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// If the object had a script instance binding, dispose it before adding the CSharpInstance
if (p_owner->has_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index())) {
void *data = p_owner->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
- CRASH_COND(data == NULL);
+ CRASH_COND(data == nullptr);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
- if (script_binding.inited && script_binding.gchandle.is_valid()) {
- MonoObject *mono_object = script_binding.gchandle->get_target();
+ if (script_binding.inited && !script_binding.gchandle.is_released()) {
+ MonoObject *mono_object = script_binding.gchandle.get_target();
if (mono_object) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::dispose(mono_object, &exc);
if (exc) {
@@ -2967,13 +3106,13 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
}
}
+ script_binding.gchandle.release(); // Just in case
script_binding.inited = false;
}
}
- CSharpInstance *instance = memnew(CSharpInstance);
+ CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(this)));
instance->base_ref = p_isref;
- instance->script = Ref<CSharpScript>(this);
instance->owner = p_owner;
instance->owner->set_script_instance(instance);
@@ -2984,25 +3123,25 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
if (!mono_object) {
// Important to clear this before destroying the script instance here
instance->script = Ref<CSharpScript>();
- instance->owner = NULL;
+ instance->owner = nullptr;
bool die = instance->_unreference_owner_unsafe();
// Not ok for the owner to die here. If there is a situation where this can happen, it will be considered a bug.
CRASH_COND(die == true);
- p_owner->set_script_instance(NULL);
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
- ERR_FAIL_V_MSG(NULL, "Failed to allocate memory for the object.");
+ p_owner->set_script_instance(nullptr);
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ ERR_FAIL_V_MSG(nullptr, "Failed to allocate memory for the object.");
}
// Tie managed to unmanaged
- instance->gchandle = MonoGCHandle::create_strong(mono_object);
+ instance->gchandle = MonoGCHandleData::new_strong_handle(mono_object);
if (instance->base_ref)
instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
{
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
instances.insert(instance->owner);
}
@@ -3017,14 +3156,14 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
return instance;
}
-Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
ERR_FAIL_NULL_V(native, Variant());
@@ -3038,7 +3177,7 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Variant::Call
ref = REF(r);
}
- CSharpInstance *instance = _create_instance(p_args, p_argcount, owner, r != NULL, r_error);
+ CSharpInstance *instance = _create_instance(p_args, p_argcount, owner, r != nullptr, r_error);
if (!instance) {
if (ref.is_null()) {
memdelete(owner); //no owner, sorry
@@ -3060,20 +3199,22 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
#endif
if (native) {
- String native_name = NATIVE_GDMONOCLASS_NAME(native);
+ StringName native_name = NATIVE_GDMONOCLASS_NAME(native);
if (!ClassDB::is_parent_class(p_this->get_class_name(), native_name)) {
- if (ScriptDebugger::get_singleton()) {
- CSharpLanguage::get_singleton()->debug_break_parse(get_path(), 0, "Script inherits from native type '" + native_name + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
+ if (EngineDebugger::is_active()) {
+ CSharpLanguage::get_singleton()->debug_break_parse(get_path(), 0,
+ "Script inherits from native type '" + String(native_name) +
+ "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
}
- ERR_FAIL_V_MSG(NULL, "Script inherits from native type '" + native_name +
- "', so it can't be instanced in object of type: '" + p_this->get_class() + "'.");
+ ERR_FAIL_V_MSG(nullptr, "Script inherits from native type '" + String(native_name) +
+ "', so it can't be instanced in object of type: '" + p_this->get_class() + "'.");
}
}
GD_MONO_SCOPE_THREAD_ATTACH;
- Variant::CallError unchecked_error;
- return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error);
+ Callable::CallError unchecked_error;
+ return _create_instance(nullptr, 0, p_this, Object::cast_to<Reference>(p_this) != nullptr, unchecked_error);
}
PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_this) {
@@ -3084,13 +3225,13 @@ PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_t
_update_exports();
return si;
#else
- return NULL;
+ return nullptr;
#endif
}
bool CSharpScript::instance_has(const Object *p_this) const {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
return instances.has((Object *)p_this);
}
@@ -3163,7 +3304,7 @@ Error CSharpScript::reload(bool p_keep_state) {
bool has_instances;
{
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
has_instances = instances.size();
}
@@ -3192,7 +3333,7 @@ Error CSharpScript::reload(bool p_keep_state) {
script_class = project_assembly->get_object_derived_class(name);
}
- valid = script_class != NULL;
+ valid = script_class != nullptr;
if (script_class) {
#ifdef DEBUG_ENABLED
@@ -3214,7 +3355,7 @@ Error CSharpScript::reload(bool p_keep_state) {
native = GDMonoUtils::get_class_native_base(script_class);
- CRASH_COND(native == NULL);
+ CRASH_COND(native == nullptr);
GDMonoClass *base_class = script_class->get_parent_class();
@@ -3252,6 +3393,69 @@ Error CSharpScript::reload(bool p_keep_state) {
_update_exports();
}
+ rpc_functions.clear();
+ rpc_variables.clear();
+
+ GDMonoClass *top = script_class;
+ while (top && top != native) {
+ {
+ Vector<GDMonoMethod *> methods = top->get_all_methods();
+ for (int i = 0; i < methods.size(); i++) {
+ if (!methods[i]->is_static()) {
+ MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(methods[i]);
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
+ ScriptNetData nd;
+ nd.name = methods[i]->get_name();
+ nd.mode = mode;
+ if (-1 == rpc_functions.find(nd)) {
+ rpc_functions.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ {
+ Vector<GDMonoField *> fields = top->get_all_fields();
+ for (int i = 0; i < fields.size(); i++) {
+ if (!fields[i]->is_static()) {
+ MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(fields[i]);
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
+ ScriptNetData nd;
+ nd.name = fields[i]->get_name();
+ nd.mode = mode;
+ if (-1 == rpc_variables.find(nd)) {
+ rpc_variables.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ {
+ Vector<GDMonoProperty *> properties = top->get_all_properties();
+ for (int i = 0; i < properties.size(); i++) {
+ if (!properties[i]->is_static()) {
+ MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(properties[i]);
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
+ ScriptNetData nd;
+ nd.name = properties[i]->get_name();
+ nd.mode = mode;
+ if (-1 == rpc_variables.find(nd)) {
+ rpc_variables.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ top = top->get_parent_class();
+ }
+
+ // Sort so we are 100% that they are always the same.
+ rpc_functions.sort_custom<SortNetData>();
+ rpc_variables.sort_custom<SortNetData>();
+
return OK;
}
@@ -3289,23 +3493,61 @@ void CSharpScript::update_exports() {
}
bool CSharpScript::has_script_signal(const StringName &p_signal) const {
- return _signals.has(p_signal);
+ return event_signals.has(p_signal) || _signals.has(p_signal);
}
void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
- for (const Map<StringName, Vector<Argument> >::Element *E = _signals.front(); E; E = E->next()) {
+
+ for (const Map<StringName, Vector<SignalParameter>>::Element *E = _signals.front(); E; E = E->next()) {
MethodInfo mi;
+ mi.name = E->key();
+
+ const Vector<SignalParameter> &params = E->value();
+ for (int i = 0; i < params.size(); i++) {
+ const SignalParameter &param = params[i];
+
+ PropertyInfo arg_info = PropertyInfo(param.type, param.name);
+ if (param.type == Variant::NIL && param.nil_is_variant)
+ arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+
+ mi.arguments.push_back(arg_info);
+ }
+ r_signals->push_back(mi);
+ }
+
+ for (const Map<StringName, EventSignal>::Element *E = event_signals.front(); E; E = E->next()) {
+ MethodInfo mi;
mi.name = E->key();
- for (int i = 0; i < E->get().size(); i++) {
- PropertyInfo arg;
- arg.name = E->get()[i].name;
- mi.arguments.push_back(arg);
+
+ const EventSignal &event_signal = E->value();
+ const Vector<SignalParameter> &params = event_signal.parameters;
+ for (int i = 0; i < params.size(); i++) {
+ const SignalParameter &param = params[i];
+
+ PropertyInfo arg_info = PropertyInfo(param.type, param.name);
+ if (param.type == Variant::NIL && param.nil_is_variant)
+ arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+
+ mi.arguments.push_back(arg_info);
}
+
r_signals->push_back(mi);
}
}
+bool CSharpScript::inherits_script(const Ref<Script> &p_script) const {
+ Ref<CSharpScript> cs = p_script;
+ if (cs.is_null()) {
+ return false;
+ }
+
+#ifndef _MSC_VER
+#warning TODO: Implement CSharpScript::inherits_script and other relevant changes after GH-38063.
+#endif
+ return false;
+}
+
Ref<Script> CSharpScript::get_base_script() const {
// TODO search in metadata file once we have it, not important any way?
@@ -3325,6 +3567,78 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
return -1;
}
+MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
+
+ if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute)))
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+Vector<ScriptNetData> CSharpScript::get_rpc_methods() const {
+ return rpc_functions;
+}
+
+uint16_t CSharpScript::get_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < rpc_functions.size(); i++) {
+ if (rpc_functions[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName CSharpScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName());
+ return rpc_functions[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode(const StringName &p_method) const {
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> CSharpScript::get_rset_properties() const {
+ return rpc_variables;
+}
+
+uint16_t CSharpScript::get_rset_property_id(const StringName &p_variable) const {
+ for (int i = 0; i < rpc_variables.size(); i++) {
+ if (rpc_variables[i].name == p_variable) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName CSharpScript::get_rset_property(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName());
+ return rpc_variables[p_rset_member_id].name;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rset_member_id].mode;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rset_mode(const StringName &p_variable) const {
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
+}
+
Error CSharpScript::load_source_code(const String &p_path) {
Error ferr = read_all_file_utf8(p_path, source);
@@ -3347,24 +3661,15 @@ StringName CSharpScript::get_script_name() const {
return name;
}
-CSharpScript::CSharpScript() :
- script_list(this) {
+CSharpScript::CSharpScript() {
_clear();
-#ifdef TOOLS_ENABLED
- source_changed_cache = false;
- placeholder_fallback_enabled = false;
- exports_invalidated = true;
-#endif
-
- signals_invalidated = true;
-
_resource_path_changed();
#ifdef DEBUG_ENABLED
{
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
CSharpLanguage::get_singleton()->script_list.add(&this->script_list);
}
#endif
@@ -3373,14 +3678,14 @@ CSharpScript::CSharpScript() :
CSharpScript::~CSharpScript() {
#ifdef DEBUG_ENABLED
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
CSharpLanguage::get_singleton()->script_list.remove(&this->script_list);
#endif
}
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
@@ -3474,7 +3779,7 @@ void ResourceFormatSaverCSharpScript::get_recognized_extensions(const RES &p_res
bool ResourceFormatSaverCSharpScript::recognize(const RES &p_resource) const {
- return Object::cast_to<CSharpScript>(p_resource.ptr()) != NULL;
+ return Object::cast_to<CSharpScript>(p_resource.ptr()) != nullptr;
}
CSharpLanguage::StringNameCache::StringNameCache() {
@@ -3488,4 +3793,5 @@ CSharpLanguage::StringNameCache::StringNameCache() {
on_before_serialize = StaticCString::create("OnBeforeSerialize");
on_after_deserialize = StaticCString::create("OnAfterDeserialize");
dotctor = StaticCString::create(".ctor");
+ delegate_invoke_method_name = StaticCString::create("Invoke");
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index f244bc4119..05e2857538 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -53,8 +53,8 @@ class CSharpLanguage;
template <typename TScriptInstance, typename TScriptLanguage>
TScriptInstance *cast_script_instance(ScriptInstance *p_inst) {
if (!p_inst)
- return NULL;
- return p_inst->get_language() == TScriptLanguage::get_singleton() ? static_cast<TScriptInstance *>(p_inst) : NULL;
+ return nullptr;
+ return p_inst->get_language() == TScriptLanguage::get_singleton() ? static_cast<TScriptInstance *>(p_inst) : nullptr;
}
#else
template <typename TScriptInstance, typename TScriptLanguage>
@@ -69,18 +69,32 @@ class CSharpScript : public Script {
GDCLASS(CSharpScript, Script);
+public:
+ struct SignalParameter {
+ String name;
+ Variant::Type type;
+ bool nil_is_variant = false;
+ };
+
+ struct EventSignal {
+ GDMonoField *field = nullptr;
+ GDMonoMethod *invoke_method = nullptr;
+ Vector<SignalParameter> parameters;
+ };
+
+private:
friend class CSharpInstance;
friend class CSharpLanguage;
friend struct CSharpScriptDepSort;
- bool tool;
- bool valid;
+ bool tool = false;
+ bool valid = false;
bool builtin;
- GDMonoClass *base;
- GDMonoClass *native;
- GDMonoClass *script_class;
+ GDMonoClass *base = nullptr;
+ GDMonoClass *native = nullptr;
+ GDMonoClass *script_class = nullptr;
Ref<CSharpScript> base_cache; // TODO what's this for?
@@ -91,7 +105,8 @@ class CSharpScript : public Script {
// TODO
// Replace with buffer containing the serialized state of managed scripts.
// Keep variant state backup to use only with script instance placeholders.
- List<Pair<StringName, Variant> > properties;
+ List<Pair<StringName, Variant>> properties;
+ List<Pair<StringName, Array>> event_signals;
};
Set<ObjectID> pending_reload_instances;
@@ -103,23 +118,22 @@ class CSharpScript : public Script {
String source;
StringName name;
- SelfList<CSharpScript> script_list;
+ SelfList<CSharpScript> script_list = this;
- struct Argument {
- String name;
- Variant::Type type;
- };
+ Map<StringName, Vector<SignalParameter>> _signals;
+ Map<StringName, EventSignal> event_signals;
+ bool signals_invalidated = true;
- Map<StringName, Vector<Argument> > _signals;
- bool signals_invalidated;
+ Vector<ScriptNetData> rpc_functions;
+ Vector<ScriptNetData> rpc_variables;
#ifdef TOOLS_ENABLED
List<PropertyInfo> exported_members_cache; // members_cache
Map<StringName, Variant> exported_members_defval_cache; // member_default_values_cache
Set<PlaceHolderScriptInstance *> placeholders;
- bool source_changed_cache;
- bool placeholder_fallback_enabled;
- bool exports_invalidated;
+ bool source_changed_cache = false;
+ bool placeholder_fallback_enabled = false;
+ bool exports_invalidated = true;
void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames);
void _update_member_info_no_exports();
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
@@ -130,7 +144,7 @@ class CSharpScript : public Script {
void _clear();
void load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class);
- bool _get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> &params);
+ bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> &params);
bool _update_exports();
#ifdef TOOLS_ENABLED
@@ -138,18 +152,20 @@ class CSharpScript : public Script {
static int _try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string);
#endif
- CSharpInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error);
- Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ CSharpInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error);
+ Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
// Do not use unless you know what you are doing
friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *);
static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native);
static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native);
+ MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const;
+
protected:
static void _bind_methods();
- Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual void _resource_path_changed();
bool _get(const StringName &p_name, Variant &r_ret) const;
bool _set(const StringName &p_name, const Variant &p_value);
@@ -178,6 +194,8 @@ public:
virtual bool is_tool() const { return tool; }
virtual bool is_valid() const { return valid; }
+ bool inherits_script(const Ref<Script> &p_script) const;
+
virtual Ref<Script> get_base_script() const;
virtual ScriptLanguage *get_language() const;
@@ -187,6 +205,18 @@ public:
virtual int get_member_line(const StringName &p_member) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
#ifdef TOOLS_ENABLED
virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; }
#endif
@@ -204,15 +234,17 @@ class CSharpInstance : public ScriptInstance {
friend class CSharpScript;
friend class CSharpLanguage;
- Object *owner;
- bool base_ref;
- bool ref_dying;
- bool unsafe_referenced;
- bool predelete_notified;
- bool destructing_script_instance;
+ Object *owner = nullptr;
+ bool base_ref = false;
+ bool ref_dying = false;
+ bool unsafe_referenced = false;
+ bool predelete_notified = false;
+ bool destructing_script_instance = false;
Ref<CSharpScript> script;
- Ref<MonoGCHandle> gchandle;
+ MonoGCHandleData gchandle;
+
+ Vector<Callable> event_signal_callables;
bool _reference_owner_unsafe();
@@ -222,19 +254,18 @@ class CSharpInstance : public ScriptInstance {
bool _unreference_owner_unsafe();
/*
- * If NULL is returned, the caller must destroy the script instance by removing it from its owner.
+ * If nullptr is returned, the caller must destroy the script instance by removing it from its owner.
*/
MonoObject *_internal_new_managed();
// Do not use unless you know what you are doing
friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *);
- static CSharpInstance *create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref<MonoGCHandle> &p_gchandle);
+ static CSharpInstance *create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle);
void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount);
- MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const;
-
- void get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state);
+ void get_properties_state_for_reloading(List<Pair<StringName, Variant>> &r_state);
+ void get_event_signals_state_for_reloading(List<Pair<StringName, Array>> &r_state);
public:
MonoObject *get_mono_object() const;
@@ -250,22 +281,34 @@ public:
/* TODO */ virtual void get_method_list(List<MethodInfo> *p_list) const {}
virtual bool has_method(const StringName &p_method) const;
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
void mono_object_disposed(MonoObject *p_obj);
/*
- * If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, if
+ * If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, ifevent_signal
* 'r_remove_script_instance' is set to true, the caller must destroy the script instance by removing it from its owner.
*/
void mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_delete_owner, bool &r_remove_script_instance);
+ void connect_event_signals();
+ void disconnect_event_signals();
+
virtual void refcount_incremented();
virtual bool refcount_decremented();
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
virtual void notification(int p_notification);
@@ -277,7 +320,7 @@ public:
virtual ScriptLanguage *get_language();
- CSharpInstance();
+ CSharpInstance(const Ref<CSharpScript> &p_script);
~CSharpInstance();
};
@@ -285,8 +328,18 @@ struct CSharpScriptBinding {
bool inited;
StringName type_name;
GDMonoClass *wrapper_class;
- Ref<MonoGCHandle> gchandle;
+ MonoGCHandleData gchandle;
Object *owner;
+
+ CSharpScriptBinding() :
+ inited(false),
+ wrapper_class(nullptr),
+ owner(nullptr) {
+ }
+};
+
+class ManagedCallableMiddleman : public Object {
+ GDCLASS(ManagedCallableMiddleman, Object);
};
class CSharpLanguage : public ScriptLanguage {
@@ -296,23 +349,26 @@ class CSharpLanguage : public ScriptLanguage {
static CSharpLanguage *singleton;
- bool finalizing;
+ bool finalizing = false;
+ bool finalized = false;
- GDMono *gdmono;
+ GDMono *gdmono = nullptr;
SelfList<CSharpScript>::List script_list;
- Mutex *script_instances_mutex;
- Mutex *script_gchandle_release_mutex;
- Mutex *language_bind_mutex;
+ Mutex script_instances_mutex;
+ Mutex script_gchandle_release_mutex;
+ Mutex language_bind_mutex;
Map<Object *, CSharpScriptBinding> script_bindings;
#ifdef DEBUG_ENABLED
// List of unsafe object references
Map<ObjectID, int> unsafe_object_references;
- Mutex *unsafe_object_references_lock;
+ Mutex unsafe_object_references_lock;
#endif
+ ManagedCallableMiddleman *managed_callable_middleman = memnew(ManagedCallableMiddleman);
+
struct StringNameCache {
StringName _signal_callback;
@@ -324,17 +380,18 @@ class CSharpLanguage : public ScriptLanguage {
StringName dotctor; // .ctor
StringName on_before_serialize; // OnBeforeSerialize
StringName on_after_deserialize; // OnAfterDeserialize
+ StringName delegate_invoke_method_name;
StringNameCache();
};
- int lang_idx;
+ int lang_idx = -1;
Dictionary scripts_metadata;
- bool scripts_metadata_invalidated;
+ bool scripts_metadata_invalidated = true;
// For debug_break and debug_break_parse
- int _debug_parse_err_line;
+ int _debug_parse_err_line = -1;
String _debug_parse_err_file;
String _debug_error;
@@ -344,7 +401,7 @@ class CSharpLanguage : public ScriptLanguage {
void _on_scripts_domain_unloaded();
#ifdef TOOLS_ENABLED
- EditorPlugin *godotsharp_editor;
+ EditorPlugin *godotsharp_editor = nullptr;
static void _editor_init_callback();
#endif
@@ -352,7 +409,7 @@ class CSharpLanguage : public ScriptLanguage {
public:
StringNameCache string_names;
- Mutex *get_language_bind_mutex() { return language_bind_mutex; }
+ const Mutex &get_language_bind_mutex() { return language_bind_mutex; }
_FORCE_INLINE_ int get_language_index() { return lang_idx; }
void set_language_index(int p_idx);
@@ -365,8 +422,8 @@ public:
_FORCE_INLINE_ EditorPlugin *get_godotsharp_editor() const { return godotsharp_editor; }
#endif
- static void release_script_gchandle(Ref<MonoGCHandle> &p_gchandle);
- static void release_script_gchandle(MonoObject *p_expected_obj, Ref<MonoGCHandle> &p_gchandle);
+ static void release_script_gchandle(MonoGCHandleData &p_gchandle);
+ static void release_script_gchandle(MonoObject *p_expected_obj, MonoGCHandleData &p_gchandle);
bool debug_break(const String &p_error, bool p_allow_continue = true);
bool debug_break_parse(const String &p_file, int p_line, const String &p_error);
@@ -386,6 +443,8 @@ public:
return scripts_metadata;
}
+ _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
+
virtual String get_name() const;
/* LANGUAGE FUNCTIONS */
@@ -402,13 +461,13 @@ public:
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
virtual bool is_using_templates();
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
- /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = NULL, Set<int> *r_safe_lines = NULL) const { return true; }
+ /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const { return true; }
virtual String validate_path(const String &p_path) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
virtual bool supports_builtin_mode() const;
/* TODO? */ virtual int find_function(const String &p_function, const String &p_code) const { return -1; }
- virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const;
virtual String _get_indentation() const;
/* TODO? */ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {}
/* TODO */ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) {}
@@ -434,7 +493,7 @@ public:
virtual void frame();
/* TODO? */ virtual void get_public_functions(List<MethodInfo> *p_functions) const {}
- /* TODO? */ virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const {}
+ /* TODO? */ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const {}
virtual void reload_all_scripts();
virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload);
@@ -473,7 +532,7 @@ public:
class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/mono/doc_classes/@C#.xml b/modules/mono/doc_classes/@C#.xml
index 826c106d7e..83a7fbf02c 100644
--- a/modules/mono/doc_classes/@C#.xml
+++ b/modules/mono/doc_classes/@C#.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="@C#" category="Core" version="3.2">
+<class name="@C#" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/modules/mono/doc_classes/CSharpScript.xml b/modules/mono/doc_classes/CSharpScript.xml
index de2e246ea9..1eb3404f9e 100644
--- a/modules/mono/doc_classes/CSharpScript.xml
+++ b/modules/mono/doc_classes/CSharpScript.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSharpScript" inherits="Script" category="Core" version="3.2">
+<class name="CSharpScript" inherits="Script" version="4.0">
<brief_description>
</brief_description>
<description>
@@ -8,7 +8,7 @@
</tutorials>
<methods>
<method name="new" qualifiers="vararg">
- <return type="Object">
+ <return type="Variant">
</return>
<description>
</description>
diff --git a/modules/mono/doc_classes/GodotSharp.xml b/modules/mono/doc_classes/GodotSharp.xml
index 18556a84ba..19a08d2036 100644
--- a/modules/mono/doc_classes/GodotSharp.xml
+++ b/modules/mono/doc_classes/GodotSharp.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GodotSharp" inherits="Object" category="Core" version="3.2">
+<class name="GodotSharp" inherits="Object" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs
index 8717c4901e..4374f21cfa 100644
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs
new file mode 100644
index 0000000000..85760a3705
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs
@@ -0,0 +1,27 @@
+using System.IO;
+
+namespace GodotTools.Core
+{
+ public static class FileUtils
+ {
+ public static void SaveBackupCopy(string filePath)
+ {
+ string backupPathBase = filePath + ".old";
+ string backupPath = backupPathBase;
+
+ const int maxAttempts = 5;
+ int attempt = 1;
+
+ while (File.Exists(backupPath) && attempt <= maxAttempts)
+ {
+ backupPath = backupPathBase + "." + (attempt);
+ attempt++;
+ }
+
+ if (attempt > maxAttempts + 1)
+ return;
+
+ File.Copy(filePath, backupPath, overwrite: true);
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
index 2c35ef540a..c9ea7d3a2c 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
@@ -31,6 +31,7 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="FileUtils.cs" />
<Compile Include="ProcessExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StringExtensions.cs" />
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
index b531b6aeee..326c49f096 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
@@ -30,7 +30,7 @@ namespace GodotTools.Core
path = string.Join(Path.DirectorySeparatorChar.ToString(), parts).Trim();
- return rooted ? Path.DirectorySeparatorChar.ToString() + path : path;
+ return rooted ? Path.DirectorySeparatorChar + path : path;
}
private static readonly string driveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
index c7c00e66a2..0806d02ca0 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
index 76cb249acf..6f318aab4a 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
@@ -1,6 +1,8 @@
using GodotTools.Core;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
namespace GodotTools.ProjectEditor
{
@@ -118,5 +120,45 @@ EndProject";
const string ProjectPlatformsConfig =
@" {{{0}}}.{1}|Any CPU.ActiveCfg = {1}|Any CPU
{{{0}}}.{1}|Any CPU.Build.0 = {1}|Any CPU";
+
+ public static void MigrateFromOldConfigNames(string slnPath)
+ {
+ if (!File.Exists(slnPath))
+ return;
+
+ var input = File.ReadAllText(slnPath);
+
+ if (!Regex.IsMatch(input, Regex.Escape("Tools|Any CPU")))
+ return;
+
+ // This method renames old configurations in solutions to the new ones.
+ //
+ // This is the order configs appear in the solution and what we want to rename them to:
+ // Debug|Any CPU = Debug|Any CPU -> ExportDebug|Any CPU = ExportDebug|Any CPU
+ // Tools|Any CPU = Tools|Any CPU -> Debug|Any CPU = Debug|Any CPU
+ //
+ // But we want to move Tools (now Debug) to the top, so it's easier to rename like this:
+ // Debug|Any CPU = Debug|Any CPU -> Debug|Any CPU = Debug|Any CPU
+ // Release|Any CPU = Release|Any CPU -> ExportDebug|Any CPU = ExportDebug|Any CPU
+ // Tools|Any CPU = Tools|Any CPU -> ExportRelease|Any CPU = ExportRelease|Any CPU
+
+ var dict = new Dictionary<string, string>
+ {
+ {"Debug|Any CPU", "Debug|Any CPU"},
+ {"Release|Any CPU", "ExportDebug|Any CPU"},
+ {"Tools|Any CPU", "ExportRelease|Any CPU"}
+ };
+
+ var regex = new Regex(string.Join("|",dict.Keys.Select(Regex.Escape)));
+ var result = regex.Replace(input,m => dict[m.Value]);
+
+ if (result != input)
+ {
+ // Save a copy of the solution before replacing it
+ FileUtils.SaveBackupCopy(slnPath);
+
+ File.WriteAllText(slnPath, result);
+ }
+ }
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs
index 36961eb45e..f0e0d1b33d 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs
@@ -1,5 +1,7 @@
using GodotTools.Core;
using System;
+using System.Collections.Generic;
+using System.IO;
using DotNet.Globbing;
using Microsoft.Build.Construction;
@@ -7,16 +9,15 @@ namespace GodotTools.ProjectEditor
{
public static class ProjectExtensions
{
- public static bool HasItem(this ProjectRootElement root, string itemType, string include)
+ public static ProjectItemElement FindItemOrNull(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
{
- GlobOptions globOptions = new GlobOptions();
- globOptions.Evaluation.CaseInsensitive = false;
+ GlobOptions globOptions = new GlobOptions {Evaluation = {CaseInsensitive = false}};
string normalizedInclude = include.NormalizePath();
foreach (var itemGroup in root.ItemGroups)
{
- if (itemGroup.Condition.Length != 0)
+ if (noCondition && itemGroup.Condition.Length != 0)
continue;
foreach (var item in itemGroup.Items)
@@ -27,18 +28,65 @@ namespace GodotTools.ProjectEditor
var glob = Glob.Parse(item.Include.NormalizePath(), globOptions);
if (glob.IsMatch(normalizedInclude))
- {
- return true;
- }
+ return item;
}
}
- return false;
+ return null;
+ }
+ public static ProjectItemElement FindItemOrNullAbs(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
+ {
+ GlobOptions globOptions = new GlobOptions {Evaluation = {CaseInsensitive = false}};
+
+ string normalizedInclude = Path.GetFullPath(include).NormalizePath();
+
+ foreach (var itemGroup in root.ItemGroups)
+ {
+ if (noCondition && itemGroup.Condition.Length != 0)
+ continue;
+
+ foreach (var item in itemGroup.Items)
+ {
+ if (item.ItemType != itemType)
+ continue;
+
+ var glob = Glob.Parse(Path.GetFullPath(item.Include).NormalizePath(), globOptions);
+
+ if (glob.IsMatch(normalizedInclude))
+ return item;
+ }
+ }
+
+ return null;
+ }
+
+ public static IEnumerable<ProjectItemElement> FindAllItemsInFolder(this ProjectRootElement root, string itemType, string folder)
+ {
+ string absFolderNormalizedWithSep = Path.GetFullPath(folder).NormalizePath() + Path.DirectorySeparatorChar;
+
+ foreach (var itemGroup in root.ItemGroups)
+ {
+ foreach (var item in itemGroup.Items)
+ {
+ if (item.ItemType != itemType)
+ continue;
+
+ string absPathNormalized = Path.GetFullPath(item.Include).NormalizePath();
+
+ if (absPathNormalized.StartsWith(absFolderNormalizedWithSep))
+ yield return item;
+ }
+ }
+ }
+
+ public static bool HasItem(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
+ {
+ return root.FindItemOrNull(itemType, include, noCondition) != null;
}
public static bool AddItemChecked(this ProjectRootElement root, string itemType, string include)
{
- if (!root.HasItem(itemType, include))
+ if (!root.HasItem(itemType, include, noCondition: true))
{
root.AddItem(itemType, include);
return true;
@@ -47,6 +95,18 @@ namespace GodotTools.ProjectEditor
return false;
}
+ public static bool RemoveItemChecked(this ProjectRootElement root, string itemType, string include)
+ {
+ var item = root.FindItemOrNullAbs(itemType, include);
+ if (item != null)
+ {
+ item.Parent.RemoveChild(item);
+ return true;
+ }
+
+ return false;
+ }
+
public static Guid GetGuid(this ProjectRootElement root)
{
foreach (var property in root.Properties)
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
index 28b7832f90..cbe3afaedd 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
@@ -17,30 +17,30 @@ namespace GodotTools.ProjectEditor
string path = Path.Combine(dir, name + ".csproj");
ProjectPropertyGroupElement mainGroup;
- var root = CreateLibraryProject(name, "Tools", out mainGroup);
+ var root = CreateLibraryProject(name, "Debug", out mainGroup);
mainGroup.SetProperty("OutputPath", Path.Combine(".mono", "temp", "bin", "$(Configuration)"));
mainGroup.SetProperty("BaseIntermediateOutputPath", Path.Combine(".mono", "temp", "obj"));
mainGroup.SetProperty("IntermediateOutputPath", Path.Combine("$(BaseIntermediateOutputPath)", "$(Configuration)"));
- mainGroup.SetProperty("ApiConfiguration", "Debug").Condition = " '$(Configuration)' != 'Release' ";
- mainGroup.SetProperty("ApiConfiguration", "Release").Condition = " '$(Configuration)' == 'Release' ";
-
- var toolsGroup = root.AddPropertyGroup();
- toolsGroup.Condition = " '$(Configuration)|$(Platform)' == 'Tools|AnyCPU' ";
- toolsGroup.AddProperty("DebugSymbols", "true");
- toolsGroup.AddProperty("DebugType", "portable");
- toolsGroup.AddProperty("Optimize", "false");
- toolsGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;TOOLS;");
- toolsGroup.AddProperty("ErrorReport", "prompt");
- toolsGroup.AddProperty("WarningLevel", "4");
- toolsGroup.AddProperty("ConsolePause", "false");
+ mainGroup.SetProperty("ApiConfiguration", "Debug").Condition = " '$(Configuration)' != 'ExportRelease' ";
+ mainGroup.SetProperty("ApiConfiguration", "Release").Condition = " '$(Configuration)' == 'ExportRelease' ";
+
+ var debugGroup = root.AddPropertyGroup();
+ debugGroup.Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ";
+ debugGroup.AddProperty("DebugSymbols", "true");
+ debugGroup.AddProperty("DebugType", "portable");
+ debugGroup.AddProperty("Optimize", "false");
+ debugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;TOOLS;");
+ debugGroup.AddProperty("ErrorReport", "prompt");
+ debugGroup.AddProperty("WarningLevel", "4");
+ debugGroup.AddProperty("ConsolePause", "false");
var coreApiRef = root.AddItem("Reference", CoreApiProjectName);
coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", CoreApiProjectName + ".dll"));
coreApiRef.AddMetadata("Private", "False");
var editorApiRef = root.AddItem("Reference", EditorApiProjectName);
- editorApiRef.Condition = " '$(Configuration)' == 'Tools' ";
+ editorApiRef.Condition = " '$(Configuration)' == 'Debug' ";
editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", EditorApiProjectName + ".dll"));
editorApiRef.AddMetadata("Private", "False");
@@ -103,24 +103,24 @@ namespace GodotTools.ProjectEditor
mainGroup.AddProperty("TargetFrameworkVersion", "v4.7");
mainGroup.AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString());
- var debugGroup = root.AddPropertyGroup();
- debugGroup.Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ";
- debugGroup.AddProperty("DebugSymbols", "true");
- debugGroup.AddProperty("DebugType", "portable");
- debugGroup.AddProperty("Optimize", "false");
- debugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;");
- debugGroup.AddProperty("ErrorReport", "prompt");
- debugGroup.AddProperty("WarningLevel", "4");
- debugGroup.AddProperty("ConsolePause", "false");
-
- var releaseGroup = root.AddPropertyGroup();
- releaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ";
- releaseGroup.AddProperty("DebugType", "portable");
- releaseGroup.AddProperty("Optimize", "true");
- releaseGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;");
- releaseGroup.AddProperty("ErrorReport", "prompt");
- releaseGroup.AddProperty("WarningLevel", "4");
- releaseGroup.AddProperty("ConsolePause", "false");
+ var exportDebugGroup = root.AddPropertyGroup();
+ exportDebugGroup.Condition = " '$(Configuration)|$(Platform)' == 'ExportDebug|AnyCPU' ";
+ exportDebugGroup.AddProperty("DebugSymbols", "true");
+ exportDebugGroup.AddProperty("DebugType", "portable");
+ exportDebugGroup.AddProperty("Optimize", "false");
+ exportDebugGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;DEBUG;");
+ exportDebugGroup.AddProperty("ErrorReport", "prompt");
+ exportDebugGroup.AddProperty("WarningLevel", "4");
+ exportDebugGroup.AddProperty("ConsolePause", "false");
+
+ var exportReleaseGroup = root.AddPropertyGroup();
+ exportReleaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'ExportRelease|AnyCPU' ";
+ exportReleaseGroup.AddProperty("DebugType", "portable");
+ exportReleaseGroup.AddProperty("Optimize", "true");
+ exportReleaseGroup.AddProperty("DefineConstants", "$(GodotDefineConstants);GODOT;");
+ exportReleaseGroup.AddProperty("ErrorReport", "prompt");
+ exportReleaseGroup.AddProperty("WarningLevel", "4");
+ exportReleaseGroup.AddProperty("ConsolePause", "false");
// References
var referenceGroup = root.AddItemGroup();
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 233aab45b3..f2ebef1a7d 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -3,13 +3,34 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Reflection;
using DotNet.Globbing;
using Microsoft.Build.Construction;
namespace GodotTools.ProjectEditor
{
+ public sealed class MSBuildProject
+ {
+ public ProjectRootElement Root { get; }
+
+ public bool HasUnsavedChanges { get; set; }
+
+ public void Save() => Root.Save();
+
+ public MSBuildProject(ProjectRootElement root)
+ {
+ Root = root;
+ }
+ }
+
public static class ProjectUtils
{
+ public static MSBuildProject Open(string path)
+ {
+ var root = ProjectRootElement.Open(path);
+ return root != null ? new MSBuildProject(root) : null;
+ }
+
public static void AddItemToProjectChecked(string projectPath, string itemType, string include)
{
var dir = Directory.GetParent(projectPath).FullName;
@@ -22,6 +43,78 @@ namespace GodotTools.ProjectEditor
root.Save();
}
+ public static void RenameItemInProjectChecked(string projectPath, string itemType, string oldInclude, string newInclude)
+ {
+ var dir = Directory.GetParent(projectPath).FullName;
+ var root = ProjectRootElement.Open(projectPath);
+ Debug.Assert(root != null);
+
+ var normalizedOldInclude = oldInclude.NormalizePath();
+ var normalizedNewInclude = newInclude.NormalizePath();
+
+ var item = root.FindItemOrNullAbs(itemType, normalizedOldInclude);
+
+ if (item == null)
+ return;
+
+ item.Include = normalizedNewInclude.RelativeToPath(dir).Replace("/", "\\");
+ root.Save();
+ }
+
+ public static void RemoveItemFromProjectChecked(string projectPath, string itemType, string include)
+ {
+ var root = ProjectRootElement.Open(projectPath);
+ Debug.Assert(root != null);
+
+ var normalizedInclude = include.NormalizePath();
+
+ if (root.RemoveItemChecked(itemType, normalizedInclude))
+ root.Save();
+ }
+
+ public static void RenameItemsToNewFolderInProjectChecked(string projectPath, string itemType, string oldFolder, string newFolder)
+ {
+ var dir = Directory.GetParent(projectPath).FullName;
+ var root = ProjectRootElement.Open(projectPath);
+ Debug.Assert(root != null);
+
+ bool dirty = false;
+
+ var oldFolderNormalized = oldFolder.NormalizePath();
+ var newFolderNormalized = newFolder.NormalizePath();
+ string absOldFolderNormalized = Path.GetFullPath(oldFolderNormalized).NormalizePath();
+ string absNewFolderNormalized = Path.GetFullPath(newFolderNormalized).NormalizePath();
+
+ foreach (var item in root.FindAllItemsInFolder(itemType, oldFolderNormalized))
+ {
+ string absPathNormalized = Path.GetFullPath(item.Include).NormalizePath();
+ string absNewIncludeNormalized = absNewFolderNormalized + absPathNormalized.Substring(absOldFolderNormalized.Length);
+ item.Include = absNewIncludeNormalized.RelativeToPath(dir).Replace("/", "\\");
+ dirty = true;
+ }
+
+ if (dirty)
+ root.Save();
+ }
+
+ public static void RemoveItemsInFolderFromProjectChecked(string projectPath, string itemType, string folder)
+ {
+ var root = ProjectRootElement.Open(projectPath);
+ Debug.Assert(root != null);
+
+ var folderNormalized = folder.NormalizePath();
+
+ var itemsToRemove = root.FindAllItemsInFolder(itemType, folderNormalized).ToList();
+
+ if (itemsToRemove.Count > 0)
+ {
+ foreach (var item in itemsToRemove)
+ item.Parent.RemoveChild(item);
+
+ root.Save();
+ }
+ }
+
private static string[] GetAllFilesRecursive(string rootDirectory, string mask)
{
string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories);
@@ -44,6 +137,7 @@ namespace GodotTools.ProjectEditor
globOptions.Evaluation.CaseInsensitive = false;
var root = ProjectRootElement.Open(projectPath);
+ Debug.Assert(root != null);
foreach (var itemGroup in root.ItemGroups)
{
@@ -75,45 +169,42 @@ namespace GodotTools.ProjectEditor
}
/// Simple function to make sure the Api assembly references are configured correctly
- public static void FixApiHintPath(string projectPath)
+ public static void FixApiHintPath(MSBuildProject project)
{
- var root = ProjectRootElement.Open(projectPath);
- Debug.Assert(root != null);
-
- bool dirty = false;
+ var root = project.Root;
void AddPropertyIfNotPresent(string name, string condition, string value)
{
if (root.PropertyGroups
- .Any(g => (g.Condition == string.Empty || g.Condition == condition) &&
+ .Any(g => (g.Condition == string.Empty || g.Condition.Trim() == condition) &&
g.Properties
.Any(p => p.Name == name &&
p.Value == value &&
- (p.Condition == condition || g.Condition == condition))))
+ (p.Condition.Trim() == condition || g.Condition.Trim() == condition))))
{
return;
}
- root.AddProperty(name, value).Condition = condition;
- dirty = true;
+ root.AddProperty(name, value).Condition = " " + condition + " ";
+ project.HasUnsavedChanges = true;
}
AddPropertyIfNotPresent(name: "ApiConfiguration",
- condition: " '$(Configuration)' != 'Release' ",
+ condition: "'$(Configuration)' != 'ExportRelease'",
value: "Debug");
AddPropertyIfNotPresent(name: "ApiConfiguration",
- condition: " '$(Configuration)' == 'Release' ",
+ condition: "'$(Configuration)' == 'ExportRelease'",
value: "Release");
void SetReferenceHintPath(string referenceName, string condition, string hintPath)
{
foreach (var itemGroup in root.ItemGroups.Where(g =>
- g.Condition == string.Empty || g.Condition == condition))
+ g.Condition.Trim() == string.Empty || g.Condition.Trim() == condition))
{
var references = itemGroup.Items.Where(item =>
item.ItemType == "Reference" &&
item.Include == referenceName &&
- (item.Condition == condition || itemGroup.Condition == condition));
+ (item.Condition.Trim() == condition || itemGroup.Condition.Trim() == condition));
var referencesWithHintPath = references.Where(reference =>
reference.Metadata.Any(m => m.Name == "HintPath"));
@@ -137,7 +228,7 @@ namespace GodotTools.ProjectEditor
}
referenceWithHintPath.AddMetadata("HintPath", hintPath);
- dirty = true;
+ project.HasUnsavedChanges = true;
return;
}
@@ -146,30 +237,119 @@ namespace GodotTools.ProjectEditor
{
// Found a Reference item without a HintPath
referenceWithoutHintPath.AddMetadata("HintPath", hintPath);
- dirty = true;
+ project.HasUnsavedChanges = true;
return;
}
}
// Found no Reference item at all. Add it.
- root.AddItem("Reference", referenceName).Condition = condition;
- dirty = true;
+ root.AddItem("Reference", referenceName).Condition = " " + condition + " ";
+ project.HasUnsavedChanges = true;
}
const string coreProjectName = "GodotSharp";
const string editorProjectName = "GodotSharpEditor";
const string coreCondition = "";
- const string editorCondition = " '$(Configuration)' == 'Tools' ";
+ const string editorCondition = "'$(Configuration)' == 'Debug'";
var coreHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{coreProjectName}.dll";
var editorHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{editorProjectName}.dll";
SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath);
SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath);
+ }
- if (dirty)
- root.Save();
+ public static void MigrateFromOldConfigNames(MSBuildProject project)
+ {
+ var root = project.Root;
+
+ bool hasGodotProjectGeneratorVersion = false;
+ bool foundOldConfiguration = false;
+
+ foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition == string.Empty))
+ {
+ if (!hasGodotProjectGeneratorVersion && propertyGroup.Properties.Any(p => p.Name == "GodotProjectGeneratorVersion"))
+ hasGodotProjectGeneratorVersion = true;
+
+ foreach (var configItem in propertyGroup.Properties
+ .Where(p => p.Condition.Trim() == "'$(Configuration)' == ''" && p.Value == "Tools"))
+ {
+ configItem.Value = "Debug";
+ foundOldConfiguration = true;
+ project.HasUnsavedChanges = true;
+ }
+ }
+
+ if (!hasGodotProjectGeneratorVersion)
+ {
+ root.PropertyGroups.First(g => g.Condition == string.Empty)?
+ .AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString());
+ project.HasUnsavedChanges = true;
+ }
+
+ if (!foundOldConfiguration)
+ {
+ var toolsConditions = new[]
+ {
+ "'$(Configuration)|$(Platform)' == 'Tools|AnyCPU'",
+ "'$(Configuration)|$(Platform)' != 'Tools|AnyCPU'",
+ "'$(Configuration)' == 'Tools'",
+ "'$(Configuration)' != 'Tools'"
+ };
+
+ foundOldConfiguration = root.PropertyGroups
+ .Any(g => toolsConditions.Any(c => c == g.Condition.Trim()));
+ }
+
+ if (foundOldConfiguration)
+ {
+ void MigrateConfigurationConditions(string oldConfiguration, string newConfiguration)
+ {
+ void MigrateConditions(string oldCondition, string newCondition)
+ {
+ foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition))
+ {
+ propertyGroup.Condition = " " + newCondition + " ";
+ project.HasUnsavedChanges = true;
+ }
+
+ foreach (var propertyGroup in root.PropertyGroups)
+ {
+ foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition))
+ {
+ prop.Condition = " " + newCondition + " ";
+ project.HasUnsavedChanges = true;
+ }
+ }
+
+ foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition))
+ {
+ itemGroup.Condition = " " + newCondition + " ";
+ project.HasUnsavedChanges = true;
+ }
+
+ foreach (var itemGroup in root.ItemGroups)
+ {
+ foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition))
+ {
+ item.Condition = " " + newCondition + " ";
+ project.HasUnsavedChanges = true;
+ }
+ }
+ }
+
+ foreach (var op in new[] {"==", "!="})
+ {
+ MigrateConditions($"'$(Configuration)|$(Platform)' {op} '{oldConfiguration}|AnyCPU'", $"'$(Configuration)|$(Platform)' {op} '{newConfiguration}|AnyCPU'");
+ MigrateConditions($"'$(Configuration)' {op} '{oldConfiguration}'", $"'$(Configuration)' {op} '{newConfiguration}'");
+ }
+ }
+
+ MigrateConfigurationConditions("Debug", "ExportDebug");
+ MigrateConfigurationConditions("Release", "ExportRelease");
+ MigrateConfigurationConditions("Tools", "Debug"); // Must be last
+ }
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs
index 09333850fc..3a0464c9bc 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
diff --git a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
index 4c76d2abf1..3cf495f025 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BottomPanel.cs
@@ -166,13 +166,13 @@ namespace GodotTools
Internal.GodotIs32Bits() ? "32" : "64"
};
- bool buildSuccess = BuildManager.BuildProjectBlocking("Tools", godotDefines);
+ bool buildSuccess = BuildManager.BuildProjectBlocking("Debug", godotDefines);
if (!buildSuccess)
return;
// Notify running game for hot-reload
- Internal.ScriptEditorDebuggerReloadScripts();
+ Internal.EditorDebuggerNodeReloadScripts();
// Hot-reload in the editor
GodotSharpEditor.Instance.GetNode<HotReloadAssemblyWatcher>("HotReloadAssemblyWatcher").RestartTimer();
@@ -205,9 +205,9 @@ namespace GodotTools
if (what == EditorSettings.NotificationEditorSettingsChanged)
{
var editorBaseControl = editorInterface.GetBaseControl();
- panelTabs.AddStyleboxOverride("panel", editorBaseControl.GetStylebox("DebuggerPanel", "EditorStyles"));
- panelTabs.AddStyleboxOverride("tab_fg", editorBaseControl.GetStylebox("DebuggerTabFG", "EditorStyles"));
- panelTabs.AddStyleboxOverride("tab_bg", editorBaseControl.GetStylebox("DebuggerTabBG", "EditorStyles"));
+ panelTabs.AddThemeStyleboxOverride("panel", editorBaseControl.GetThemeStylebox("DebuggerPanel", "EditorStyles"));
+ panelTabs.AddThemeStyleboxOverride("tab_fg", editorBaseControl.GetThemeStylebox("DebuggerTabFG", "EditorStyles"));
+ panelTabs.AddThemeStyleboxOverride("tab_bg", editorBaseControl.GetThemeStylebox("DebuggerTabBG", "EditorStyles"));
}
}
@@ -258,9 +258,9 @@ namespace GodotTools
RectMinSize = new Vector2(0, 228) * EditorScale,
SizeFlagsVertical = (int)SizeFlags.ExpandFill
};
- panelTabs.AddStyleboxOverride("panel", editorBaseControl.GetStylebox("DebuggerPanel", "EditorStyles"));
- panelTabs.AddStyleboxOverride("tab_fg", editorBaseControl.GetStylebox("DebuggerTabFG", "EditorStyles"));
- panelTabs.AddStyleboxOverride("tab_bg", editorBaseControl.GetStylebox("DebuggerTabBG", "EditorStyles"));
+ panelTabs.AddThemeStyleboxOverride("panel", editorBaseControl.GetThemeStylebox("DebuggerPanel", "EditorStyles"));
+ panelTabs.AddThemeStyleboxOverride("tab_fg", editorBaseControl.GetThemeStylebox("DebuggerTabFG", "EditorStyles"));
+ panelTabs.AddThemeStyleboxOverride("tab_bg", editorBaseControl.GetThemeStylebox("DebuggerTabBG", "EditorStyles"));
AddChild(panelTabs);
{
@@ -280,7 +280,7 @@ namespace GodotTools
Text = "Build Project".TTR(),
FocusMode = FocusModeEnum.None
};
- buildProjectBtn.Connect("pressed", this, nameof(BuildProjectPressed));
+ buildProjectBtn.PressedSignal += BuildProjectPressed;
toolBarHBox.AddChild(buildProjectBtn);
toolBarHBox.AddSpacer(begin: false);
@@ -293,7 +293,7 @@ namespace GodotTools
Visible = false,
FocusMode = FocusModeEnum.None
};
- warningsBtn.Connect("toggled", this, nameof(_WarningsToggled));
+ warningsBtn.Toggled += _WarningsToggled;
toolBarHBox.AddChild(warningsBtn);
errorsBtn = new ToolButton
@@ -304,7 +304,7 @@ namespace GodotTools
Visible = false,
FocusMode = FocusModeEnum.None
};
- errorsBtn.Connect("toggled", this, nameof(_ErrorsToggled));
+ errorsBtn.Toggled += _ErrorsToggled;
toolBarHBox.AddChild(errorsBtn);
toolBarHBox.AddSpacer(begin: false);
@@ -315,7 +315,7 @@ namespace GodotTools
FocusMode = FocusModeEnum.None,
Visible = false
};
- viewLogBtn.Connect("pressed", this, nameof(_ViewLogPressed));
+ viewLogBtn.PressedSignal += _ViewLogPressed;
toolBarHBox.AddChild(viewLogBtn);
var hsc = new HSplitContainer
@@ -326,8 +326,8 @@ namespace GodotTools
panelBuildsTab.AddChild(hsc);
buildTabsList = new ItemList { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill };
- buildTabsList.Connect("item_selected", this, nameof(_BuildTabsItemSelected));
- buildTabsList.Connect("nothing_selected", this, nameof(_BuildTabsNothingSelected));
+ buildTabsList.ItemSelected += _BuildTabsItemSelected;
+ buildTabsList.NothingSelected += _BuildTabsNothingSelected;
hsc.AddChild(buildTabsList);
buildTabs = new TabContainer
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index c3db52aa9e..af8d070cbd 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Godot;
+using GodotTools.Ides.Rider;
using GodotTools.Internals;
using Directory = System.IO.Directory;
using Environment = System.Environment;
@@ -54,6 +55,12 @@ namespace GodotTools.Build
return msbuildPath;
}
+ case BuildManager.BuildTool.JetBrainsMsBuild:
+ var editorPath = (string)editorSettings.GetSetting(RiderPathManager.EditorPathSettingName);
+ if (!File.Exists(editorPath))
+ throw new FileNotFoundException($"Cannot find Rider executable. Tried with path: {editorPath}");
+ var riderDir = new FileInfo(editorPath).Directory.Parent;
+ return Path.Combine(riderDir.FullName, @"tools\MSBuild\Current\Bin\MSBuild.exe");
default:
throw new IndexOutOfRangeException("Invalid build tool in editor settings");
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
index fa6bf4dafd..520e665595 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using GodotTools.Build;
+using GodotTools.Ides.Rider;
using GodotTools.Internals;
using GodotTools.Utils;
using static GodotTools.Internals.Globals;
@@ -16,6 +17,7 @@ namespace GodotTools
public const string PropNameMsbuildMono = "MSBuild (Mono)";
public const string PropNameMsbuildVs = "MSBuild (VS Build Tools)";
+ public const string PropNameMsbuildJetBrains = "MSBuild (JetBrains Rider)";
public const string MsBuildIssuesFileName = "msbuild_issues.csv";
public const string MsBuildLogFileName = "msbuild_log.txt";
@@ -23,7 +25,8 @@ namespace GodotTools
public enum BuildTool
{
MsBuildMono,
- MsBuildVs
+ MsBuildVs,
+ JetBrainsMsBuild
}
private static void RemoveOldIssuesFile(BuildInfo buildInfo)
@@ -163,7 +166,7 @@ namespace GodotTools
// Make sure the API assemblies are up to date before building the project.
// We may not have had the chance to update the release API assemblies, and the debug ones
// may have been deleted by the user at some point after they were loaded by the Godot editor.
- string apiAssembliesUpdateError = Internal.UpdateApiAssembliesFromPrebuilt(config == "Release" ? "Release" : "Debug");
+ string apiAssembliesUpdateError = Internal.UpdateApiAssembliesFromPrebuilt(config == "ExportRelease" ? "Release" : "Debug");
if (!string.IsNullOrEmpty(apiAssembliesUpdateError))
{
@@ -181,7 +184,7 @@ namespace GodotTools
var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, config);
// Add Godot defines
- string constants = buildTool == BuildTool.MsBuildVs ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
+ string constants = buildTool != BuildTool.MsBuildMono ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
foreach (var godotDefine in godotDefines)
constants += $"GODOT_{godotDefine.ToUpper().Replace("-", "_").Replace(" ", "_").Replace(";", "_")};";
@@ -189,7 +192,7 @@ namespace GodotTools
if (Internal.GodotIsRealTDouble())
constants += "GODOT_REAL_T_IS_DOUBLE;";
- constants += buildTool == BuildTool.MsBuildVs ? "\"" : "\\\"";
+ constants += buildTool != BuildTool.MsBuildMono ? "\"" : "\\\"";
buildInfo.CustomProperties.Add(constants);
@@ -239,16 +242,20 @@ namespace GodotTools
Internal.GodotIs32Bits() ? "32" : "64"
};
- return BuildProjectBlocking("Tools", godotDefines);
+ return BuildProjectBlocking("Debug", godotDefines);
}
public static void Initialize()
{
// Build tool settings
-
- EditorDef("mono/builds/build_tool", OS.IsWindows ? BuildTool.MsBuildVs : BuildTool.MsBuildMono);
-
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
+ var msbuild = BuildTool.MsBuildMono;
+ if (OS.IsWindows)
+ msbuild = RiderPathManager.IsExternalEditorSetToRider(editorSettings)
+ ? BuildTool.JetBrainsMsBuild
+ : BuildTool.MsBuildVs;
+
+ EditorDef("mono/builds/build_tool", msbuild);
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
@@ -256,7 +263,7 @@ namespace GodotTools
["name"] = "mono/builds/build_tool",
["hint"] = Godot.PropertyHint.Enum,
["hint_string"] = OS.IsWindows ?
- $"{PropNameMsbuildMono},{PropNameMsbuildVs}" :
+ $"{PropNameMsbuildMono},{PropNameMsbuildVs},{PropNameMsbuildJetBrains}" :
$"{PropNameMsbuildMono}"
});
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
index 727581daab..938c3d8be1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
@@ -41,17 +41,17 @@ namespace GodotTools
public bool ErrorsVisible { get; set; } = true;
public bool WarningsVisible { get; set; } = true;
- public Texture IconTexture
+ public Texture2D IconTexture
{
get
{
if (!BuildExited)
- return GetIcon("Stop", "EditorIcons");
+ return GetThemeIcon("Stop", "EditorIcons");
if (BuildResult == BuildResults.Error)
- return GetIcon("StatusError", "EditorIcons");
+ return GetThemeIcon("StatusError", "EditorIcons");
- return GetIcon("StatusSuccess", "EditorIcons");
+ return GetThemeIcon("StatusSuccess", "EditorIcons");
}
}
@@ -145,8 +145,8 @@ namespace GodotTools
{
issuesList.Clear();
- using (var warningIcon = GetIcon("Warning", "EditorIcons"))
- using (var errorIcon = GetIcon("Error", "EditorIcons"))
+ using (var warningIcon = GetThemeIcon("Warning", "EditorIcons"))
+ using (var errorIcon = GetThemeIcon("Error", "EditorIcons"))
{
for (int i = 0; i < issues.Count; i++)
{
@@ -251,7 +251,7 @@ namespace GodotTools
base._Ready();
issuesList = new ItemList { SizeFlagsVertical = (int)SizeFlags.ExpandFill };
- issuesList.Connect("item_activated", this, nameof(_IssueActivated));
+ issuesList.ItemActivated += _IssueActivated;
AddChild(issuesList);
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
index 9abfda4538..421729cc11 100644
--- a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
@@ -32,18 +32,6 @@ namespace GodotTools
ProjectUtils.AddItemToProjectChecked(projectPath, itemType, include);
}
- public static void FixApiHintPath(string projectPath)
- {
- try
- {
- ProjectUtils.FixApiHintPath(projectPath);
- }
- catch (Exception e)
- {
- GD.PushError(e.ToString());
- }
- }
-
private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private static ulong ConvertToTimestamp(this DateTime value)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
new file mode 100755
index 0000000000..f1765f7e19
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -0,0 +1,618 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using GodotTools.Internals;
+using Directory = GodotTools.Utils.Directory;
+using File = GodotTools.Utils.File;
+using OS = GodotTools.Utils.OS;
+using Path = System.IO.Path;
+
+namespace GodotTools.Export
+{
+ public struct AotOptions
+ {
+ public bool EnableLLVM;
+ public bool LLVMOnly;
+ public string LLVMPath;
+ public string LLVMOutputPath;
+
+ public bool FullAot;
+
+ private bool _useInterpreter;
+ public bool UseInterpreter { get => _useInterpreter && !LLVMOnly; set => _useInterpreter = value; }
+
+ public string[] ExtraAotOptions;
+ public string[] ExtraOptimizerOptions;
+
+ public string ToolchainPath;
+ }
+
+ public static class AotBuilder
+ {
+ public static void CompileAssemblies(ExportPlugin exporter, AotOptions aotOpts, string[] features, string platform, bool isDebug, string bclDir, string outputDir, string outputDataDir, IDictionary<string, string> assemblies)
+ {
+ // TODO: WASM
+
+ string aotTempDir = Path.Combine(Path.GetTempPath(), $"godot-aot-{Process.GetCurrentProcess().Id}");
+
+ if (!Directory.Exists(aotTempDir))
+ Directory.CreateDirectory(aotTempDir);
+
+ var assembliesPrepared = new Dictionary<string, string>();
+
+ foreach (var dependency in assemblies)
+ {
+ string assemblyName = dependency.Key;
+ string assemblyPath = dependency.Value;
+
+ string assemblyPathInBcl = Path.Combine(bclDir, assemblyName + ".dll");
+
+ if (File.Exists(assemblyPathInBcl))
+ {
+ // Don't create teporaries for assemblies from the BCL
+ assembliesPrepared.Add(assemblyName, assemblyPathInBcl);
+ }
+ else
+ {
+ string tempAssemblyPath = Path.Combine(aotTempDir, assemblyName + ".dll");
+ File.Copy(assemblyPath, tempAssemblyPath);
+ assembliesPrepared.Add(assemblyName, tempAssemblyPath);
+ }
+ }
+
+ if (platform == OS.Platforms.iOS)
+ {
+ var architectures = GetEnablediOSArchs(features).ToArray();
+ CompileAssembliesForiOS(exporter, isDebug, architectures, aotOpts, aotTempDir, assembliesPrepared, bclDir);
+ }
+ else if (platform == OS.Platforms.Android)
+ {
+ var abis = GetEnabledAndroidAbis(features).ToArray();
+ CompileAssembliesForAndroid(exporter, isDebug, abis, aotOpts, aotTempDir, assembliesPrepared, bclDir);
+ }
+ else
+ {
+ string bits = features.Contains("64") ? "64" : features.Contains("32") ? "32" : null;
+ CompileAssembliesForDesktop(exporter, platform, isDebug, bits, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir);
+ }
+ }
+
+ public static void CompileAssembliesForAndroid(ExportPlugin exporter, bool isDebug, string[] abis, AotOptions aotOpts, string aotTempDir, IDictionary<string, string> assemblies, string bclDir)
+ {
+
+ foreach (var assembly in assemblies)
+ {
+ string assemblyName = assembly.Key;
+ string assemblyPath = assembly.Value;
+
+ // Not sure if the 'lib' prefix is an Android thing or just Godot being picky,
+ // but we use '-aot-' as well just in case to avoid conflicts with other libs.
+ string outputFileName = "lib-aot-" + assemblyName + ".dll.so";
+
+ foreach (string abi in abis)
+ {
+ string aotAbiTempDir = Path.Combine(aotTempDir, abi);
+ string soFilePath = Path.Combine(aotAbiTempDir, outputFileName);
+
+ var compilerArgs = GetAotCompilerArgs(OS.Platforms.Android, isDebug, abi, aotOpts, assemblyPath, soFilePath);
+
+ // Make sure the output directory exists
+ Directory.CreateDirectory(aotAbiTempDir);
+
+ string compilerDirPath = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "aot-compilers", $"{OS.Platforms.Android}-{abi}");
+
+ ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
+
+ // The Godot exporter expects us to pass the abi in the tags parameter
+ exporter.AddSharedObject(soFilePath, tags: new[] { abi });
+ }
+ }
+ }
+
+ public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string bits, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir)
+ {
+ foreach (var assembly in assemblies)
+ {
+ string assemblyName = assembly.Key;
+ string assemblyPath = assembly.Value;
+
+ string outputFileExtension = platform == OS.Platforms.Windows ? ".dll" :
+ platform == OS.Platforms.OSX ? ".dylib" :
+ ".so";
+
+ string outputFileName = assemblyName + ".dll" + outputFileExtension;
+ string tempOutputFilePath = Path.Combine(aotTempDir, outputFileName);
+
+ var compilerArgs = GetAotCompilerArgs(platform, isDebug, bits, aotOpts, assemblyPath, tempOutputFilePath);
+
+ string compilerDirPath = GetMonoCrossDesktopDirName(platform, bits);
+
+ ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
+
+ if (platform == OS.Platforms.OSX)
+ {
+ exporter.AddSharedObject(tempOutputFilePath, tags: null);
+ }
+ else
+ {
+ string outputDataLibDir = Path.Combine(outputDataDir, "Mono", platform == OS.Platforms.Windows ? "bin" : "lib");
+ File.Copy(tempOutputFilePath, Path.Combine(outputDataLibDir, outputFileName));
+ }
+ }
+ }
+
+ public static void CompileAssembliesForiOS(ExportPlugin exporter, bool isDebug, string[] architectures, AotOptions aotOpts, string aotTempDir, IDictionary<string, string> assemblies, string bclDir)
+ {
+ var cppCode = new StringBuilder();
+ var aotModuleInfoSymbols = new List<string>(assemblies.Count);
+
+ // {arch: paths}
+ var objFilePathsForiOSArch = architectures.ToDictionary(arch => arch, arch => new List<string>(assemblies.Count));
+
+ foreach (var assembly in assemblies)
+ {
+ string assemblyName = assembly.Key;
+ string assemblyPath = assembly.Value;
+
+ string asmFileName = assemblyName + ".dll.S";
+ string objFileName = assemblyName + ".dll.o";
+
+ foreach (string arch in architectures)
+ {
+ string aotArchTempDir = Path.Combine(aotTempDir, arch);
+ string asmFilePath = Path.Combine(aotArchTempDir, asmFileName);
+
+ var compilerArgs = GetAotCompilerArgs(OS.Platforms.iOS, isDebug, arch, aotOpts, assemblyPath, asmFilePath);
+
+ // Make sure the output directory exists
+ Directory.CreateDirectory(aotArchTempDir);
+
+ string compilerDirPath = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "aot-compilers", $"{OS.Platforms.iOS}-{arch}");
+
+ ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
+
+ // Assembling
+ bool isSim = arch == "i386" || arch == "x86_64"; // Shouldn't really happen as we don't do AOT for the simulator
+ string versionMinName = isSim ? "iphonesimulator" : "iphoneos";
+ string iOSPlatformName = isSim ? "iPhoneSimulator" : "iPhoneOS";
+ const string versionMin = "10.0"; // TODO: Turn this hard-coded version into an exporter setting
+ string iOSSdkPath = Path.Combine(XcodeHelper.XcodePath,
+ $"Contents/Developer/Platforms/{iOSPlatformName}.platform/Developer/SDKs/{iOSPlatformName}.sdk");
+
+ string objFilePath = Path.Combine(aotArchTempDir, objFileName);
+
+ var clangArgs = new List<string>()
+ {
+ "-isysroot", iOSSdkPath,
+ "-Qunused-arguments",
+ $"-m{versionMinName}-version-min={versionMin}",
+ "-arch", arch,
+ "-c",
+ "-o", objFilePath,
+ "-x", "assembler"
+ };
+
+ if (isDebug)
+ clangArgs.Add("-DDEBUG");
+
+ clangArgs.Add(asmFilePath);
+
+ int clangExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("clang"), clangArgs);
+ if (clangExitCode != 0)
+ throw new Exception($"Command 'clang' exited with code: {clangExitCode}");
+
+ objFilePathsForiOSArch[arch].Add(objFilePath);
+ }
+
+ aotModuleInfoSymbols.Add($"mono_aot_module_{AssemblyNameToAotSymbol(assemblyName)}_info");
+ }
+
+ // Generate driver code
+ cppCode.AppendLine("#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)");
+ cppCode.AppendLine("#define IOS_DEVICE");
+ cppCode.AppendLine("#endif");
+
+ cppCode.AppendLine("#ifdef IOS_DEVICE");
+ cppCode.AppendLine("extern \"C\" {");
+ cppCode.AppendLine("// Mono API");
+ cppCode.AppendLine(@"
+typedef enum {
+MONO_AOT_MODE_NONE,
+MONO_AOT_MODE_NORMAL,
+MONO_AOT_MODE_HYBRID,
+MONO_AOT_MODE_FULL,
+MONO_AOT_MODE_LLVMONLY,
+MONO_AOT_MODE_INTERP,
+MONO_AOT_MODE_INTERP_LLVMONLY,
+MONO_AOT_MODE_LLVMONLY_INTERP,
+MONO_AOT_MODE_LAST = 1000,
+} MonoAotMode;");
+ cppCode.AppendLine("void mono_jit_set_aot_mode(MonoAotMode);");
+ cppCode.AppendLine("void mono_aot_register_module(void *);");
+
+ if (aotOpts.UseInterpreter)
+ {
+ cppCode.AppendLine("void mono_ee_interp_init(const char *);");
+ cppCode.AppendLine("void mono_icall_table_init();");
+ cppCode.AppendLine("void mono_marshal_ilgen_init();");
+ cppCode.AppendLine("void mono_method_builder_ilgen_init();");
+ cppCode.AppendLine("void mono_sgen_mono_ilgen_init();");
+ }
+
+ foreach (string symbol in aotModuleInfoSymbols)
+ cppCode.AppendLine($"extern void *{symbol};");
+
+ cppCode.AppendLine("void gd_mono_setup_aot() {");
+
+ foreach (string symbol in aotModuleInfoSymbols)
+ cppCode.AppendLine($"\tmono_aot_register_module({symbol});");
+
+ if (aotOpts.UseInterpreter)
+ {
+ cppCode.AppendLine("\tmono_icall_table_init();");
+ cppCode.AppendLine("\tmono_marshal_ilgen_init();");
+ cppCode.AppendLine("\tmono_method_builder_ilgen_init();");
+ cppCode.AppendLine("\tmono_sgen_mono_ilgen_init();");
+ cppCode.AppendLine("\tmono_ee_interp_init(0);");
+ }
+
+ string aotModeStr = null;
+
+ if (aotOpts.LLVMOnly)
+ {
+ aotModeStr = "MONO_AOT_MODE_LLVMONLY"; // --aot=llvmonly
+ }
+ else
+ {
+ if (aotOpts.UseInterpreter)
+ aotModeStr = "MONO_AOT_MODE_INTERP"; // --aot=interp or --aot=interp,full
+ else if (aotOpts.FullAot)
+ aotModeStr = "MONO_AOT_MODE_FULL"; // --aot=full
+ }
+
+ // One of the options above is always set for iOS
+ Debug.Assert(aotModeStr != null);
+
+ cppCode.AppendLine($"\tmono_jit_set_aot_mode({aotModeStr});");
+
+ cppCode.AppendLine("} // gd_mono_setup_aot");
+ cppCode.AppendLine("} // extern \"C\"");
+ cppCode.AppendLine("#endif // IOS_DEVICE");
+
+ // Add the driver code to the Xcode project
+ exporter.AddIosCppCode(cppCode.ToString());
+
+ // Archive the AOT object files into a static library
+
+ var arFilePathsForAllArchs = new List<string>();
+ string projectAssemblyName = GodotSharpEditor.ProjectAssemblyName;
+
+ foreach (var archPathsPair in objFilePathsForiOSArch)
+ {
+ string arch = archPathsPair.Key;
+ var objFilePaths = archPathsPair.Value;
+
+ string arOutputFilePath = Path.Combine(aotTempDir, $"lib-aot-{projectAssemblyName}.{arch}.a");
+
+ var arArgs = new List<string>()
+ {
+ "cr",
+ arOutputFilePath
+ };
+
+ foreach (string objFilePath in objFilePaths)
+ arArgs.Add(objFilePath);
+
+ int arExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("ar"), arArgs);
+ if (arExitCode != 0)
+ throw new Exception($"Command 'ar' exited with code: {arExitCode}");
+
+ arFilePathsForAllArchs.Add(arOutputFilePath);
+ }
+
+ // It's lipo time
+
+ string fatOutputFileName = $"lib-aot-{projectAssemblyName}.fat.a";
+ string fatOutputFilePath = Path.Combine(aotTempDir, fatOutputFileName);
+
+ var lipoArgs = new List<string>();
+ lipoArgs.Add("-create");
+ lipoArgs.AddRange(arFilePathsForAllArchs);
+ lipoArgs.Add("-output");
+ lipoArgs.Add(fatOutputFilePath);
+
+ int lipoExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("lipo"), lipoArgs);
+ if (lipoExitCode != 0)
+ throw new Exception($"Command 'lipo' exited with code: {lipoExitCode}");
+
+ // TODO: Add the AOT lib and interpreter libs as device only to supress warnings when targeting the simulator
+
+ // Add the fat AOT static library to the Xcode project
+ exporter.AddIosProjectStaticLib(fatOutputFilePath);
+
+ // Add the required Mono libraries to the Xcode project
+
+ string MonoLibFile(string libFileName) => libFileName + ".iphone.fat.a";
+
+ string MonoLibFromTemplate(string libFileName) =>
+ Path.Combine(Internal.FullTemplatesDir, "iphone-mono-libs", MonoLibFile(libFileName));
+
+ exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmonosgen-2.0"));
+
+ exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-native"));
+
+ if (aotOpts.UseInterpreter)
+ {
+ exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-ee-interp"));
+ exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-icall-table"));
+ exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-ilgen"));
+ }
+
+ // TODO: Turn into an exporter option
+ bool enableProfiling = false;
+ if (enableProfiling)
+ exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-profiler-log"));
+
+ // Add frameworks required by Mono to the Xcode project
+ exporter.AddIosFramework("libiconv.tbd");
+ exporter.AddIosFramework("GSS.framework");
+ exporter.AddIosFramework("CFNetwork.framework");
+
+ // Force load and export dynamic are needed for the linker to not strip required symbols.
+ // In theory we shouldn't be relying on this for P/Invoked functions (as is the case with
+ // functions in System.Native/libmono-native). Instead, we should use cecil to search for
+ // DllImports in assemblies and pass them to 'ld' as '-u/--undefined {pinvoke_symbol}'.
+ exporter.AddIosLinkerFlags("-rdynamic");
+ exporter.AddIosLinkerFlags($"-force_load \"$(SRCROOT)/{MonoLibFile("libmono-native")}\"");
+ }
+
+ /// Converts an assembly name to a valid symbol name in the same way the AOT compiler does
+ private static string AssemblyNameToAotSymbol(string assemblyName)
+ {
+ var builder = new StringBuilder();
+
+ foreach (var charByte in Encoding.UTF8.GetBytes(assemblyName))
+ {
+ char @char = (char)charByte;
+ builder.Append(Char.IsLetterOrDigit(@char) || @char == '_' ? @char : '_');
+ }
+
+ return builder.ToString();
+ }
+
+ private static IEnumerable<string> GetAotCompilerArgs(string platform, bool isDebug, string target, AotOptions aotOpts, string assemblyPath, string outputFilePath)
+ {
+ // TODO: LLVM
+
+ bool aotSoftDebug = isDebug && !aotOpts.EnableLLVM;
+ bool aotDwarfDebug = platform == OS.Platforms.iOS;
+
+ var aotOptions = new List<string>();
+ var optimizerOptions = new List<string>();
+
+ if (aotOpts.LLVMOnly)
+ {
+ aotOptions.Add("llvmonly");
+ }
+ else
+ {
+ // Can be both 'interp' and 'full'
+ if (aotOpts.UseInterpreter)
+ aotOptions.Add("interp");
+ if (aotOpts.FullAot)
+ aotOptions.Add("full");
+ }
+
+ aotOptions.Add(aotSoftDebug ? "soft-debug" : "nodebug");
+
+ if (aotDwarfDebug)
+ aotOptions.Add("dwarfdebug");
+
+ if (platform == OS.Platforms.Android)
+ {
+ string abi = target;
+
+ string androidToolchain = aotOpts.ToolchainPath;
+
+ if (string.IsNullOrEmpty(androidToolchain))
+ {
+ androidToolchain = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "android-toolchains", $"{abi}"); // TODO: $"{abi}-{apiLevel}{(clang?"clang":"")}"
+
+ if (!Directory.Exists(androidToolchain))
+ throw new FileNotFoundException("Missing android toolchain. Specify one in the AOT export settings.");
+ }
+ else if (!Directory.Exists(androidToolchain))
+ {
+ throw new FileNotFoundException("Android toolchain not found: " + androidToolchain);
+ }
+
+ var androidToolPrefixes = new Dictionary<string, string>
+ {
+ ["armeabi-v7a"] = "arm-linux-androideabi-",
+ ["arm64-v8a"] = "aarch64-linux-android-",
+ ["x86"] = "i686-linux-android-",
+ ["x86_64"] = "x86_64-linux-android-"
+ };
+
+ aotOptions.Add("tool-prefix=" + Path.Combine(androidToolchain, "bin", androidToolPrefixes[abi]));
+
+ string triple = GetAndroidTriple(abi);
+ aotOptions.Add($"mtriple={triple}");
+ }
+ else if (platform == OS.Platforms.iOS)
+ {
+ if (!aotOpts.LLVMOnly && !aotOpts.UseInterpreter)
+ optimizerOptions.Add("gsharedvt");
+
+ aotOptions.Add("static");
+
+ // I couldn't get the Mono cross-compiler to do assembling, so we'll have to do it ourselves
+ aotOptions.Add("asmonly");
+
+ aotOptions.Add("direct-icalls");
+
+ if (aotSoftDebug)
+ aotOptions.Add("no-direct-calls");
+
+ if (aotOpts.LLVMOnly || !aotOpts.UseInterpreter)
+ aotOptions.Add("direct-pinvoke");
+
+ string arch = target;
+ aotOptions.Add($"mtriple={arch}-ios");
+ }
+
+ aotOptions.Add($"outfile={outputFilePath}");
+
+ if (aotOpts.EnableLLVM)
+ {
+ aotOptions.Add($"llvm-path={aotOpts.LLVMPath}");
+ aotOptions.Add($"llvm-outfile={aotOpts.LLVMOutputPath}");
+ }
+
+ if (aotOpts.ExtraAotOptions.Length > 0)
+ aotOptions.AddRange(aotOpts.ExtraAotOptions);
+
+ if (aotOpts.ExtraOptimizerOptions.Length > 0)
+ optimizerOptions.AddRange(aotOpts.ExtraOptimizerOptions);
+
+ string EscapeOption(string option) => option.Contains(',') ? $"\"{option}\"" : option;
+ string OptionsToString(IEnumerable<string> options) => string.Join(",", options.Select(EscapeOption));
+
+ var runtimeArgs = new List<string>();
+
+ // The '--debug' runtime option is required when using the 'soft-debug' and 'dwarfdebug' AOT options
+ if (aotSoftDebug || aotDwarfDebug)
+ runtimeArgs.Add("--debug");
+
+ if (aotOpts.EnableLLVM)
+ runtimeArgs.Add("--llvm");
+
+ runtimeArgs.Add(aotOptions.Count > 0 ? $"--aot={OptionsToString(aotOptions)}" : "--aot");
+
+ if (optimizerOptions.Count > 0)
+ runtimeArgs.Add($"-O={OptionsToString(optimizerOptions)}");
+
+ runtimeArgs.Add(assemblyPath);
+
+ return runtimeArgs;
+ }
+
+ private static void ExecuteCompiler(string compiler, IEnumerable<string> compilerArgs, string bclDir)
+ {
+ // TODO: Once we move to .NET Standard 2.1 we can use ProcessStartInfo.ArgumentList instead
+ string CmdLineArgsToString(IEnumerable<string> args)
+ {
+ // Not perfect, but as long as we are careful...
+ return string.Join(" ", args.Select(arg => arg.Contains(" ") ? $@"""{arg}""" : arg));
+ }
+
+ using (var process = new Process())
+ {
+ process.StartInfo = new ProcessStartInfo(compiler, CmdLineArgsToString(compilerArgs))
+ {
+ UseShellExecute = false
+ };
+
+ process.StartInfo.EnvironmentVariables.Remove("MONO_ENV_OPTIONS");
+ process.StartInfo.EnvironmentVariables.Remove("MONO_THREADS_SUSPEND");
+ process.StartInfo.EnvironmentVariables.Add("MONO_PATH", bclDir);
+
+ Console.WriteLine($"Running: \"{process.StartInfo.FileName}\" {process.StartInfo.Arguments}");
+
+ if (!process.Start())
+ throw new Exception("Failed to start process for Mono AOT compiler");
+
+ process.WaitForExit();
+
+ if (process.ExitCode != 0)
+ throw new Exception($"Mono AOT compiler exited with code: {process.ExitCode}");
+ }
+ }
+
+ private static IEnumerable<string> GetEnablediOSArchs(string[] features)
+ {
+ var iosArchs = new[]
+ {
+ "armv7",
+ "arm64"
+ };
+
+ return iosArchs.Where(features.Contains);
+ }
+
+ private static IEnumerable<string> GetEnabledAndroidAbis(string[] features)
+ {
+ var androidAbis = new[]
+ {
+ "armeabi-v7a",
+ "arm64-v8a",
+ "x86",
+ "x86_64"
+ };
+
+ return androidAbis.Where(features.Contains);
+ }
+
+ private static string GetAndroidTriple(string abi)
+ {
+ var abiArchs = new Dictionary<string, string>
+ {
+ ["armeabi-v7a"] = "armv7",
+ ["arm64-v8a"] = "aarch64-v8a",
+ ["x86"] = "i686",
+ ["x86_64"] = "x86_64"
+ };
+
+ string arch = abiArchs[abi];
+
+ return $"{arch}-linux-android";
+ }
+
+ private static string GetMonoCrossDesktopDirName(string platform, string bits)
+ {
+ switch (platform)
+ {
+ case OS.Platforms.Windows:
+ case OS.Platforms.UWP:
+ {
+ string arch = bits == "64" ? "x86_64" : "i686";
+ return $"windows-{arch}";
+ }
+ case OS.Platforms.OSX:
+ {
+ Debug.Assert(bits == null || bits == "64");
+ string arch = "x86_64";
+ return $"{platform}-{arch}";
+ }
+ case OS.Platforms.X11:
+ case OS.Platforms.Server:
+ {
+ string arch = bits == "64" ? "x86_64" : "i686";
+ return $"linux-{arch}";
+ }
+ case OS.Platforms.Haiku:
+ {
+ string arch = bits == "64" ? "x86_64" : "i686";
+ return $"{platform}-{arch}";
+ }
+ default:
+ throw new NotSupportedException($"Platform not supported: {platform}");
+ }
+ }
+
+ // TODO: Replace this for a specific path for each platform
+ private static string FindCrossCompiler(string monoCrossBin)
+ {
+ string exeExt = OS.IsWindows ? ".exe" : string.Empty;
+
+ var files = new DirectoryInfo(monoCrossBin).GetFiles($"*mono-sgen{exeExt}", SearchOption.TopDirectoryOnly);
+ if (files.Length > 0)
+ return Path.Combine(monoCrossBin, files[0].Name);
+
+ throw new FileNotFoundException($"Cannot find the mono runtime executable in {monoCrossBin}");
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index 3e2a8c22a9..2ceb4888a2 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -29,15 +29,13 @@ namespace GodotTools.Export
All = CJK | MidEast | Other | Rare | West
}
- private void AddI18NAssemblies(Godot.Collections.Dictionary<string, string> assemblies, string platform)
+ private void AddI18NAssemblies(Godot.Collections.Dictionary<string, string> assemblies, string bclDir)
{
- var codesets = (I18NCodesets) ProjectSettings.GetSetting("mono/export/i18n_codesets");
+ var codesets = (I18NCodesets)ProjectSettings.GetSetting("mono/export/i18n_codesets");
if (codesets == I18NCodesets.None)
return;
- string bclDir = DeterminePlatformBclDir(platform) ?? typeof(object).Assembly.Location.GetBaseDir();
-
void AddI18NAssembly(string name) => assemblies.Add(name, Path.Combine(bclDir, $"{name}.dll"));
AddI18NAssembly("I18N");
@@ -73,6 +71,7 @@ namespace GodotTools.Export
GlobalDef("mono/export/aot/enabled", false);
GlobalDef("mono/export/aot/full_aot", false);
+ GlobalDef("mono/export/aot/use_interpreter", true);
// --aot or --aot=opt1,opt2 (use 'mono --aot=help AuxAssembly.dll' to list AOT options)
GlobalDef("mono/export/aot/extra_aot_options", new string[] { });
@@ -86,9 +85,11 @@ namespace GodotTools.Export
private void AddFile(string srcPath, string dstPath, bool remap = false)
{
+ // Add file to the PCK
AddFile(dstPath.Replace("\\", "/"), File.ReadAllBytes(srcPath), remap);
}
+ // With this method we can override how a file is exported in the PCK
public override void _ExportFile(string path, string type, string[] features)
{
base._ExportFile(path, type, features);
@@ -96,7 +97,7 @@ namespace GodotTools.Export
if (type != Internal.CSharpLanguageType)
return;
- if (Path.GetExtension(path) != $".{Internal.CSharpLanguageExtension}")
+ if (Path.GetExtension(path) != Internal.CSharpLanguageExtension)
throw new ArgumentException($"Resource of type {Internal.CSharpLanguageType} has an invalid file extension: {path}", nameof(path));
// TODO What if the source file is not part of the game's C# project
@@ -110,6 +111,8 @@ namespace GodotTools.Export
// Sadly, Godot prints errors when adding an empty file (nothing goes wrong, it's just noise).
// Because of this, we add a file which contains a line break.
AddFile(path, System.Text.Encoding.UTF8.GetBytes("\n"), remap: false);
+
+ // Tell the Godot exporter that we already took care of the file
Skip();
}
}
@@ -150,7 +153,7 @@ namespace GodotTools.Export
string outputDir = new FileInfo(path).Directory?.FullName ??
throw new FileNotFoundException("Base directory not found");
- string buildConfig = isDebug ? "Debug" : "Release";
+ string buildConfig = isDebug ? "ExportDebug" : "ExportRelease";
string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}");
CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);
@@ -165,18 +168,13 @@ namespace GodotTools.Export
// Add dependency assemblies
- var dependencies = new Godot.Collections.Dictionary<string, string>();
-
- var projectDllName = (string)ProjectSettings.GetSetting("application/config/name");
- if (projectDllName.Empty())
- {
- projectDllName = "UnnamedProject";
- }
+ var assemblies = new Godot.Collections.Dictionary<string, string>();
+ string projectDllName = GodotSharpEditor.ProjectAssemblyName;
string projectDllSrcDir = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig);
string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll");
- dependencies[projectDllName] = projectDllSrcPath;
+ assemblies[projectDllName] = projectDllSrcPath;
if (platform == OS.Platforms.Android)
{
@@ -186,13 +184,15 @@ namespace GodotTools.Export
if (!File.Exists(monoAndroidAssemblyPath))
throw new FileNotFoundException("Assembly not found: 'Mono.Android'", monoAndroidAssemblyPath);
- dependencies["Mono.Android"] = monoAndroidAssemblyPath;
+ assemblies["Mono.Android"] = monoAndroidAssemblyPath;
}
- var initialDependencies = dependencies.Duplicate();
- internal_GetExportedAssemblyDependencies(initialDependencies, buildConfig, DeterminePlatformBclDir(platform), dependencies);
+ string bclDir = DeterminePlatformBclDir(platform);
+
+ var initialAssemblies = assemblies.Duplicate();
+ internal_GetExportedAssemblyDependencies(initialAssemblies, buildConfig, bclDir, assemblies);
- AddI18NAssemblies(dependencies, platform);
+ AddI18NAssemblies(assemblies, bclDir);
string outputDataDir = null;
@@ -211,27 +211,62 @@ namespace GodotTools.Export
Directory.CreateDirectory(outputDataGameAssembliesDir);
}
- foreach (var dependency in dependencies)
+ foreach (var assembly in assemblies)
{
- string dependSrcPath = dependency.Value;
-
- if (assembliesInsidePck)
- {
- string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile());
- AddFile(dependSrcPath, dependDstPath);
- }
- else
+ void AddToAssembliesDir(string fileSrcPath)
{
- string dependDstPath = Path.Combine(outputDataDir, "Assemblies", dependSrcPath.GetFile());
- File.Copy(dependSrcPath, dependDstPath);
+ if (assembliesInsidePck)
+ {
+ string fileDstPath = Path.Combine(resAssembliesDir, fileSrcPath.GetFile());
+ AddFile(fileSrcPath, fileDstPath);
+ }
+ else
+ {
+ Debug.Assert(outputDataDir != null);
+ string fileDstPath = Path.Combine(outputDataDir, "Assemblies", fileSrcPath.GetFile());
+ File.Copy(fileSrcPath, fileDstPath);
+ }
}
+
+ string assemblySrcPath = assembly.Value;
+
+ string assemblyPathWithoutExtension = Path.ChangeExtension(assemblySrcPath, null);
+ string pdbSrcPath = assemblyPathWithoutExtension + ".pdb";
+
+ AddToAssembliesDir(assemblySrcPath);
+
+ if (File.Exists(pdbSrcPath))
+ AddToAssembliesDir(pdbSrcPath);
}
- // AOT
+ // AOT compilation
+ bool aotEnabled = platform == OS.Platforms.iOS || (bool)ProjectSettings.GetSetting("mono/export/aot/enabled");
- if ((bool)ProjectSettings.GetSetting("mono/export/aot/enabled"))
+ if (aotEnabled)
{
- AotCompileDependencies(features, platform, isDebug, outputDir, outputDataDir, dependencies);
+ string aotToolchainPath = null;
+
+ if (platform == OS.Platforms.Android)
+ aotToolchainPath = (string)ProjectSettings.GetSetting("mono/export/aot/android_toolchain_path");
+
+ if (aotToolchainPath == string.Empty)
+ aotToolchainPath = null; // Don't risk it being used as current working dir
+
+ // TODO: LLVM settings are hard-coded and disabled for now
+ var aotOpts = new AotOptions
+ {
+ EnableLLVM = false,
+ LLVMOnly = false,
+ LLVMPath = "",
+ LLVMOutputPath = "",
+ FullAot = platform == OS.Platforms.iOS || (bool)(ProjectSettings.GetSetting("mono/export/aot/full_aot") ?? false),
+ UseInterpreter = (bool)ProjectSettings.GetSetting("mono/export/aot/use_interpreter"),
+ ExtraAotOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_aot_options") ?? new string[] { },
+ ExtraOptimizerOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_optimizer_options") ?? new string[] { },
+ ToolchainPath = aotToolchainPath
+ };
+
+ AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, assemblies);
}
}
@@ -258,7 +293,8 @@ namespace GodotTools.Export
{
string target = isDebug ? "release_debug" : "release";
- // NOTE: Bits is ok for now as all platforms with a data directory have it, but that may change in the future.
+ // NOTE: Bits is ok for now as all platforms with a data directory only have one or two architectures.
+ // However, this may change in the future if we add arm linux or windows desktop templates.
string bits = features.Contains("64") ? "64" : "32";
string TemplateDirName() => $"data.mono.{platform}.{bits}.{target}";
@@ -284,7 +320,7 @@ namespace GodotTools.Export
if (!validTemplatePathFound)
throw new FileNotFoundException("Data template directory not found", templateDirPath);
- string outputDataDir = Path.Combine(outputDir, DataDirName);
+ string outputDataDir = Path.Combine(outputDir, DetermineDataDirNameForProject());
if (Directory.Exists(outputDataDir))
Directory.Delete(outputDataDir, recursive: true); // Clean first
@@ -304,333 +340,10 @@ namespace GodotTools.Export
return outputDataDir;
}
- private void AotCompileDependencies(string[] features, string platform, bool isDebug, string outputDir, string outputDataDir, IDictionary<string, string> dependencies)
- {
- // TODO: WASM
-
- string bclDir = DeterminePlatformBclDir(platform) ?? typeof(object).Assembly.Location.GetBaseDir();
-
- string aotTempDir = Path.Combine(Path.GetTempPath(), $"godot-aot-{Process.GetCurrentProcess().Id}");
-
- if (!Directory.Exists(aotTempDir))
- Directory.CreateDirectory(aotTempDir);
-
- var assemblies = new Dictionary<string, string>();
-
- foreach (var dependency in dependencies)
- {
- string assemblyName = dependency.Key;
- string assemblyPath = dependency.Value;
-
- string assemblyPathInBcl = Path.Combine(bclDir, assemblyName + ".dll");
-
- if (File.Exists(assemblyPathInBcl))
- {
- // Don't create teporaries for assemblies from the BCL
- assemblies.Add(assemblyName, assemblyPathInBcl);
- }
- else
- {
- string tempAssemblyPath = Path.Combine(aotTempDir, assemblyName + ".dll");
- File.Copy(assemblyPath, tempAssemblyPath);
- assemblies.Add(assemblyName, tempAssemblyPath);
- }
- }
-
- foreach (var assembly in assemblies)
- {
- string assemblyName = assembly.Key;
- string assemblyPath = assembly.Value;
-
- string sharedLibExtension = platform == OS.Platforms.Windows ? ".dll" :
- platform == OS.Platforms.OSX ? ".dylib" :
- platform == OS.Platforms.HTML5 ? ".wasm" :
- ".so";
-
- string outputFileName = assemblyName + ".dll" + sharedLibExtension;
-
- if (platform == OS.Platforms.Android)
- {
- // Not sure if the 'lib' prefix is an Android thing or just Godot being picky,
- // but we use '-aot-' as well just in case to avoid conflicts with other libs.
- outputFileName = "lib-aot-" + outputFileName;
- }
-
- string outputFilePath = null;
- string tempOutputFilePath;
-
- switch (platform)
- {
- case OS.Platforms.OSX:
- tempOutputFilePath = Path.Combine(aotTempDir, outputFileName);
- break;
- case OS.Platforms.Android:
- tempOutputFilePath = Path.Combine(aotTempDir, "%%ANDROID_ABI%%", outputFileName);
- break;
- case OS.Platforms.HTML5:
- tempOutputFilePath = Path.Combine(aotTempDir, outputFileName);
- outputFilePath = Path.Combine(outputDir, outputFileName);
- break;
- default:
- tempOutputFilePath = Path.Combine(aotTempDir, outputFileName);
- outputFilePath = Path.Combine(outputDataDir, "Mono", platform == OS.Platforms.Windows ? "bin" : "lib", outputFileName);
- break;
- }
-
- var data = new Dictionary<string, string>();
- var enabledAndroidAbis = platform == OS.Platforms.Android ? GetEnabledAndroidAbis(features).ToArray() : null;
-
- if (platform == OS.Platforms.Android)
- {
- Debug.Assert(enabledAndroidAbis != null);
-
- foreach (var abi in enabledAndroidAbis)
- {
- data["abi"] = abi;
- var outputFilePathForThisAbi = tempOutputFilePath.Replace("%%ANDROID_ABI%%", abi);
-
- AotCompileAssembly(platform, isDebug, data, assemblyPath, outputFilePathForThisAbi);
-
- AddSharedObject(outputFilePathForThisAbi, tags: new[] { abi });
- }
- }
- else
- {
- string bits = features.Contains("64") ? "64" : features.Contains("64") ? "32" : null;
-
- if (bits != null)
- data["bits"] = bits;
-
- AotCompileAssembly(platform, isDebug, data, assemblyPath, tempOutputFilePath);
-
- if (platform == OS.Platforms.OSX)
- {
- AddSharedObject(tempOutputFilePath, tags: null);
- }
- else
- {
- Debug.Assert(outputFilePath != null);
- File.Copy(tempOutputFilePath, outputFilePath);
- }
- }
- }
- }
-
- private static void AotCompileAssembly(string platform, bool isDebug, Dictionary<string, string> data, string assemblyPath, string outputFilePath)
- {
- // Make sure the output directory exists
- Directory.CreateDirectory(outputFilePath.GetBaseDir());
-
- string exeExt = OS.IsWindows ? ".exe" : string.Empty;
-
- string monoCrossDirName = DetermineMonoCrossDirName(platform, data);
- string monoCrossRoot = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "aot-compilers", monoCrossDirName);
- string monoCrossBin = Path.Combine(monoCrossRoot, "bin");
-
- string toolPrefix = DetermineToolPrefix(monoCrossBin);
- string monoExeName = System.IO.File.Exists(Path.Combine(monoCrossBin, $"{toolPrefix}mono{exeExt}")) ? "mono" : "mono-sgen";
-
- string compilerCommand = Path.Combine(monoCrossBin, $"{toolPrefix}{monoExeName}{exeExt}");
-
- bool fullAot = (bool)ProjectSettings.GetSetting("mono/export/aot/full_aot");
-
- string EscapeOption(string option) => option.Contains(',') ? $"\"{option}\"" : option;
- string OptionsToString(IEnumerable<string> options) => string.Join(",", options.Select(EscapeOption));
-
- var aotOptions = new List<string>();
- var optimizerOptions = new List<string>();
-
- if (fullAot)
- aotOptions.Add("full");
-
- aotOptions.Add(isDebug ? "soft-debug" : "nodebug");
-
- if (platform == OS.Platforms.Android)
- {
- string abi = data["abi"];
-
- string androidToolchain = (string)ProjectSettings.GetSetting("mono/export/aot/android_toolchain_path");
-
- if (string.IsNullOrEmpty(androidToolchain))
- {
- androidToolchain = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "android-toolchains", $"{abi}"); // TODO: $"{abi}-{apiLevel}{(clang?"clang":"")}"
-
- if (!Directory.Exists(androidToolchain))
- throw new FileNotFoundException("Missing android toolchain. Specify one in the AOT export settings.");
- }
- else if (!Directory.Exists(androidToolchain))
- {
- throw new FileNotFoundException("Android toolchain not found: " + androidToolchain);
- }
-
- var androidToolPrefixes = new Dictionary<string, string>
- {
- ["armeabi-v7a"] = "arm-linux-androideabi-",
- ["arm64-v8a"] = "aarch64-linux-android-",
- ["x86"] = "i686-linux-android-",
- ["x86_64"] = "x86_64-linux-android-"
- };
-
- aotOptions.Add("tool-prefix=" + Path.Combine(androidToolchain, "bin", androidToolPrefixes[abi]));
-
- string triple = GetAndroidTriple(abi);
- aotOptions.Add($"mtriple={triple}");
- }
-
- aotOptions.Add($"outfile={outputFilePath}");
-
- var extraAotOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_aot_options");
- var extraOptimizerOptions = (string[])ProjectSettings.GetSetting("mono/export/aot/extra_optimizer_options");
-
- if (extraAotOptions.Length > 0)
- aotOptions.AddRange(extraAotOptions);
-
- if (extraOptimizerOptions.Length > 0)
- optimizerOptions.AddRange(extraOptimizerOptions);
-
- var compilerArgs = new List<string>();
-
- if (isDebug)
- compilerArgs.Add("--debug"); // Required for --aot=soft-debug
-
- compilerArgs.Add(aotOptions.Count > 0 ? $"--aot={OptionsToString(aotOptions)}" : "--aot");
-
- if (optimizerOptions.Count > 0)
- compilerArgs.Add($"-O={OptionsToString(optimizerOptions)}");
-
- compilerArgs.Add(ProjectSettings.GlobalizePath(assemblyPath));
-
- // TODO: Once we move to .NET Standard 2.1 we can use ProcessStartInfo.ArgumentList instead
- string CmdLineArgsToString(IEnumerable<string> args)
- {
- // Not perfect, but as long as we are careful...
- return string.Join(" ", args.Select(arg => arg.Contains(" ") ? $@"""{arg}""" : arg));
- }
-
- using (var process = new Process())
- {
- process.StartInfo = new ProcessStartInfo(compilerCommand, CmdLineArgsToString(compilerArgs))
- {
- UseShellExecute = false
- };
-
- string platformBclDir = DeterminePlatformBclDir(platform);
- process.StartInfo.EnvironmentVariables.Add("MONO_PATH", string.IsNullOrEmpty(platformBclDir) ?
- typeof(object).Assembly.Location.GetBaseDir() :
- platformBclDir);
-
- Console.WriteLine($"Running: \"{process.StartInfo.FileName}\" {process.StartInfo.Arguments}");
-
- if (!process.Start())
- throw new Exception("Failed to start process for Mono AOT compiler");
-
- process.WaitForExit();
-
- if (process.ExitCode != 0)
- throw new Exception($"Mono AOT compiler exited with error code: {process.ExitCode}");
-
- if (!System.IO.File.Exists(outputFilePath))
- throw new Exception("Mono AOT compiler finished successfully but the output file is missing");
- }
- }
-
- private static string DetermineMonoCrossDirName(string platform, IReadOnlyDictionary<string, string> data)
- {
- switch (platform)
- {
- case OS.Platforms.Windows:
- case OS.Platforms.UWP:
- {
- string arch = data["bits"] == "64" ? "x86_64" : "i686";
- return $"windows-{arch}";
- }
- case OS.Platforms.OSX:
- {
- string arch = "x86_64";
- return $"{platform}-{arch}";
- }
- case OS.Platforms.X11:
- case OS.Platforms.Server:
- {
- string arch = data["bits"] == "64" ? "x86_64" : "i686";
- return $"linux-{arch}";
- }
- case OS.Platforms.Haiku:
- {
- string arch = data["bits"] == "64" ? "x86_64" : "i686";
- return $"{platform}-{arch}";
- }
- case OS.Platforms.Android:
- {
- string abi = data["abi"];
- return $"{platform}-{abi}";
- }
- case OS.Platforms.HTML5:
- return "wasm-wasm32";
- default:
- throw new NotSupportedException($"Platform not supported: {platform}");
- }
- }
-
- private static string DetermineToolPrefix(string monoCrossBin)
- {
- string exeExt = OS.IsWindows ? ".exe" : string.Empty;
-
- if (System.IO.File.Exists(Path.Combine(monoCrossBin, $"mono{exeExt}")))
- return string.Empty;
-
- if (System.IO.File.Exists(Path.Combine(monoCrossBin, $"mono-sgen{exeExt}" + exeExt)))
- return string.Empty;
-
- var files = new DirectoryInfo(monoCrossBin).GetFiles($"*mono{exeExt}" + exeExt, SearchOption.TopDirectoryOnly);
- if (files.Length > 0)
- {
- string fileName = files[0].Name;
- return fileName.Substring(0, fileName.Length - $"mono{exeExt}".Length);
- }
-
- files = new DirectoryInfo(monoCrossBin).GetFiles($"*mono-sgen{exeExt}" + exeExt, SearchOption.TopDirectoryOnly);
- if (files.Length > 0)
- {
- string fileName = files[0].Name;
- return fileName.Substring(0, fileName.Length - $"mono-sgen{exeExt}".Length);
- }
-
- throw new FileNotFoundException($"Cannot find the mono runtime executable in {monoCrossBin}");
- }
-
- private static IEnumerable<string> GetEnabledAndroidAbis(string[] features)
- {
- var androidAbis = new[]
- {
- "armeabi-v7a",
- "arm64-v8a",
- "x86",
- "x86_64"
- };
-
- return androidAbis.Where(features.Contains);
- }
-
- private static string GetAndroidTriple(string abi)
- {
- var abiArchs = new Dictionary<string, string>
- {
- ["armeabi-v7a"] = "armv7",
- ["arm64-v8a"] = "aarch64-v8a",
- ["x86"] = "i686",
- ["x86_64"] = "x86_64"
- };
-
- string arch = abiArchs[abi];
-
- return $"{arch}-linux-android";
- }
-
private static bool PlatformHasTemplateDir(string platform)
{
// OSX export templates are contained in a zip, so we place our custom template inside it and let Godot do the rest.
- return !new[] { OS.Platforms.OSX, OS.Platforms.Android, OS.Platforms.HTML5 }.Contains(platform);
+ return !new[] { OS.Platforms.OSX, OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5 }.Contains(platform);
}
private static string DeterminePlatformFromFeatures(IEnumerable<string> features)
@@ -665,7 +378,7 @@ namespace GodotTools.Export
if (PlatformRequiresCustomBcl(platform))
throw new FileNotFoundException($"Missing BCL (Base Class Library) for platform: {platform}");
- platformBclDir = null; // Use the one we're running on
+ platformBclDir = typeof(object).Assembly.Location.GetBaseDir(); // Use the one we're running on
}
}
@@ -678,7 +391,7 @@ namespace GodotTools.Export
/// </summary>
private static bool PlatformRequiresCustomBcl(string platform)
{
- if (new[] { OS.Platforms.Android, OS.Platforms.HTML5 }.Contains(platform))
+ if (new[] { OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5 }.Contains(platform))
return true;
// The 'net_4_x' BCL is not compatible between Windows and the other platforms.
@@ -707,6 +420,8 @@ namespace GodotTools.Export
return "net_4_x";
case OS.Platforms.Android:
return "monodroid";
+ case OS.Platforms.iOS:
+ return "monotouch";
case OS.Platforms.HTML5:
return "wasm";
default:
@@ -714,18 +429,15 @@ namespace GodotTools.Export
}
}
- private static string DataDirName
+ private static string DetermineDataDirNameForProject()
{
- get
- {
- var appName = (string)ProjectSettings.GetSetting("application/config/name");
- string appNameSafe = appName.ToSafeDirName(allowDirSeparator: false);
- return $"data_{appNameSafe}";
- }
+ var appName = (string)ProjectSettings.GetSetting("application/config/name");
+ string appNameSafe = appName.ToSafeDirName(allowDirSeparator: false);
+ return $"data_{appNameSafe}";
}
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialDependencies,
- string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencies);
+ private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialAssemblies,
+ string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencyAssemblies);
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
new file mode 100755
index 0000000000..219b7a698a
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
@@ -0,0 +1,93 @@
+using System;
+using System.IO;
+
+namespace GodotTools.Export
+{
+ public static class XcodeHelper
+ {
+ private static string _XcodePath = null;
+
+ public static string XcodePath
+ {
+ get
+ {
+ if (_XcodePath == null)
+ {
+ _XcodePath = FindXcode();
+
+ if (_XcodePath == null)
+ throw new Exception("Could not find Xcode");
+ }
+
+ return _XcodePath;
+ }
+ }
+
+ private static string FindSelectedXcode()
+ {
+ var outputWrapper = new Godot.Collections.Array();
+
+ int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, blocking: true, output: outputWrapper);
+
+ if (exitCode == 0)
+ {
+ string output = (string)outputWrapper[0];
+ return output.Trim();
+ }
+
+ Console.Error.WriteLine($"'xcode-select --print-path' exited with code: {exitCode}");
+
+ return null;
+ }
+
+ public static string FindXcode()
+ {
+ string selectedXcode = FindSelectedXcode();
+ if (selectedXcode != null)
+ {
+ if (Directory.Exists(Path.Combine(selectedXcode, "Contents", "Developer")))
+ return selectedXcode;
+
+ // The path already pointed to Contents/Developer
+ var dirInfo = new DirectoryInfo(selectedXcode);
+ if (dirInfo.Name != "Developer" || dirInfo.Parent.Name != "Contents")
+ {
+ Console.WriteLine(Path.GetDirectoryName(selectedXcode));
+ Console.WriteLine(System.IO.Directory.GetParent(selectedXcode).Name);
+ Console.Error.WriteLine("Unrecognized path for selected Xcode");
+ }
+ else
+ {
+ return System.IO.Path.GetFullPath($"{selectedXcode}/../..");
+ }
+ }
+ else
+ {
+ Console.Error.WriteLine("Could not find the selected Xcode; trying with a hint path");
+ }
+
+ const string XcodeHintPath = "/Applications/Xcode.app";
+
+ if (Directory.Exists(XcodeHintPath))
+ {
+ if (Directory.Exists(Path.Combine(XcodeHintPath, "Contents", "Developer")))
+ return XcodeHintPath;
+
+ Console.Error.WriteLine($"Found Xcode at '{XcodeHintPath}' but it's missing the 'Contents/Developer' sub-directory");
+ }
+
+ return null;
+ }
+
+ public static string FindXcodeTool(string toolName)
+ {
+ string XcodeDefaultToolchain = Path.Combine(XcodePath, "Contents", "Developer", "Toolchains", "XcodeDefault.xctoolchain");
+
+ string path = Path.Combine(XcodeDefaultToolchain, "usr", "bin", toolName);
+ if (File.Exists(path))
+ return path;
+
+ throw new FileNotFoundException($"Cannot find Xcode tool: {toolName}");
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 147bc95bb8..c070cb16d9 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -1,4 +1,5 @@
using Godot;
+using GodotTools.Core;
using GodotTools.Export;
using GodotTools.Utils;
using System;
@@ -13,6 +14,7 @@ using JetBrains.Annotations;
using static GodotTools.Internals.Globals;
using File = GodotTools.Utils.File;
using OS = GodotTools.Utils.OS;
+using Path = System.IO.Path;
namespace GodotTools
{
@@ -35,6 +37,17 @@ namespace GodotTools
public BottomPanel BottomPanel { get; private set; }
+ public static string ProjectAssemblyName
+ {
+ get
+ {
+ var projectAssemblyName = (string)ProjectSettings.GetSetting("application/config/name");
+ if (string.IsNullOrEmpty(projectAssemblyName))
+ projectAssemblyName = "UnnamedProject";
+ return projectAssemblyName;
+ }
+ }
+
private bool CreateProjectSolution()
{
using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 3))
@@ -44,9 +57,7 @@ namespace GodotTools
string resourceDir = ProjectSettings.GlobalizePath("res://");
string path = resourceDir;
- string name = (string)ProjectSettings.GetSetting("application/config/name");
- if (name.Empty())
- name = "UnnamedProject";
+ string name = ProjectAssemblyName;
string guid = CsProjOperations.GenerateGameProject(path, name);
@@ -61,7 +72,7 @@ namespace GodotTools
{
Guid = guid,
PathRelativeToSolution = name + ".csproj",
- Configs = new List<string> { "Debug", "Release", "Tools" }
+ Configs = new List<string> {"Debug", "ExportDebug", "ExportRelease"}
};
solution.AddNewProject(name, projectInfo);
@@ -118,19 +129,12 @@ namespace GodotTools
{
bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
aboutDialogCheckBox.Pressed = showOnStart;
- aboutDialog.PopupCenteredMinsize();
- }
-
- private void _ToggleAboutDialogOnStart(bool enabled)
- {
- bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
- if (showOnStart != enabled)
- editorSettings.SetSetting("mono/editor/show_info_on_start", enabled);
+ aboutDialog.PopupCentered();
}
- private void _MenuOptionPressed(MenuOptions id)
+ private void _MenuOptionPressed(int id)
{
- switch (id)
+ switch ((MenuOptions)id)
{
case MenuOptions.CreateSln:
CreateProjectSolution();
@@ -163,11 +167,41 @@ namespace GodotTools
bool showInfoDialog = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
if (showInfoDialog)
{
- aboutDialog.PopupExclusive = true;
+ aboutDialog.Exclusive = true;
_ShowAboutDialog();
// Once shown a first time, it can be seen again via the Mono menu - it doesn't have to be exclusive from that time on.
- aboutDialog.PopupExclusive = false;
+ aboutDialog.Exclusive = false;
}
+
+ var fileSystemDock = GetEditorInterface().GetFileSystemDock();
+
+ fileSystemDock.FilesMoved += (file, newFile) =>
+ {
+ if (Path.GetExtension(file) == Internal.CSharpLanguageExtension)
+ {
+ ProjectUtils.RenameItemInProjectChecked(GodotSharpDirs.ProjectCsProjPath, "Compile",
+ ProjectSettings.GlobalizePath(file), ProjectSettings.GlobalizePath(newFile));
+ }
+ };
+
+ fileSystemDock.FileRemoved += file =>
+ {
+ if (Path.GetExtension(file) == Internal.CSharpLanguageExtension)
+ ProjectUtils.RemoveItemFromProjectChecked(GodotSharpDirs.ProjectCsProjPath, "Compile",
+ ProjectSettings.GlobalizePath(file));
+ };
+
+ fileSystemDock.FolderMoved += (oldFolder, newFolder) =>
+ {
+ ProjectUtils.RenameItemsToNewFolderInProjectChecked(GodotSharpDirs.ProjectCsProjPath, "Compile",
+ ProjectSettings.GlobalizePath(oldFolder), ProjectSettings.GlobalizePath(newFolder));
+ };
+
+ fileSystemDock.FolderRemoved += oldFolder =>
+ {
+ ProjectUtils.RemoveItemsInFolderFromProjectChecked(GodotSharpDirs.ProjectCsProjPath, "Compile",
+ ProjectSettings.GlobalizePath(oldFolder));
+ };
}
}
@@ -179,9 +213,9 @@ namespace GodotTools
public void ShowErrorDialog(string message, string title = "Error")
{
- errorDialog.WindowTitle = title;
+ errorDialog.Title = title;
errorDialog.DialogText = message;
- errorDialog.PopupCenteredMinsize();
+ errorDialog.PopupCentered();
}
private static string _vsCodePath = string.Empty;
@@ -210,7 +244,7 @@ namespace GodotTools
string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
RiderPathManager.OpenFile(GodotSharpDirs.ProjectSlnPath, scriptPath, line);
return Error.Ok;
- }
+ }
case ExternalEditorId.MonoDevelop:
{
string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
@@ -346,11 +380,10 @@ namespace GodotTools
bottomPanelBtn = AddControlToBottomPanel(BottomPanel, "Mono".TTR());
- AddChild(new HotReloadAssemblyWatcher { Name = "HotReloadAssemblyWatcher" });
+ AddChild(new HotReloadAssemblyWatcher {Name = "HotReloadAssemblyWatcher"});
menuPopup = new PopupMenu();
menuPopup.Hide();
- menuPopup.SetAsToplevel(true);
AddToolSubmenuItem("Mono", menuPopup);
@@ -359,7 +392,7 @@ namespace GodotTools
menuPopup.AddItem("About C# support".TTR(), (int)MenuOptions.AboutCSharp);
aboutDialog = new AcceptDialog();
editorBaseControl.AddChild(aboutDialog);
- aboutDialog.WindowTitle = "Important: C# support is not feature-complete";
+ aboutDialog.Title = "Important: C# support is not feature-complete";
// We don't use DialogText as the default AcceptDialog Label doesn't play well with the TextureRect and CheckBox
// we'll add. Instead we add containers and a new autowrapped Label inside.
@@ -373,7 +406,7 @@ namespace GodotTools
aboutVBox.AddChild(aboutHBox);
var aboutIcon = new TextureRect();
- aboutIcon.Texture = aboutIcon.GetIcon("NodeWarning", "EditorIcons");
+ aboutIcon.Texture = aboutIcon.GetThemeIcon("NodeWarning", "EditorIcons");
aboutHBox.AddChild(aboutIcon);
var aboutLabel = new Label();
@@ -394,15 +427,48 @@ namespace GodotTools
EditorDef("mono/editor/show_info_on_start", true);
// CheckBox in main container
- aboutDialogCheckBox = new CheckBox { Text = "Show this warning when starting the editor" };
- aboutDialogCheckBox.Connect("toggled", this, nameof(_ToggleAboutDialogOnStart));
+ aboutDialogCheckBox = new CheckBox {Text = "Show this warning when starting the editor"};
+ aboutDialogCheckBox.Toggled += enabled =>
+ {
+ bool showOnStart = (bool)editorSettings.GetSetting("mono/editor/show_info_on_start");
+ if (showOnStart != enabled)
+ editorSettings.SetSetting("mono/editor/show_info_on_start", enabled);
+ };
aboutVBox.AddChild(aboutDialogCheckBox);
}
if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath))
{
- // Make sure the existing project has Api assembly references configured correctly
- CsProjOperations.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
+ try
+ {
+ // Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease
+ DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath);
+
+ var msbuildProject = ProjectUtils.Open(GodotSharpDirs.ProjectCsProjPath)
+ ?? throw new Exception("Cannot open C# project");
+
+ // NOTE: The order in which changes are made to the project is important
+
+ // Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease
+ ProjectUtils.MigrateFromOldConfigNames(msbuildProject);
+
+ // Apply the other fixes only after configurations have been migrated
+
+ // Make sure the existing project has Api assembly references configured correctly
+ ProjectUtils.FixApiHintPath(msbuildProject);
+
+ if (msbuildProject.HasUnsavedChanges)
+ {
+ // Save a copy of the project before replacing it
+ FileUtils.SaveBackupCopy(GodotSharpDirs.ProjectCsProjPath);
+
+ msbuildProject.Save();
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PushError(e.ToString());
+ }
}
else
{
@@ -410,7 +476,7 @@ namespace GodotTools
menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln);
}
- menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed));
+ menuPopup.IdPressed += _MenuOptionPressed;
var buildButton = new ToolButton
{
@@ -418,7 +484,7 @@ namespace GodotTools
HintTooltip = "Build solution",
FocusMode = Control.FocusModeEnum.None
};
- buildButton.Connect("pressed", this, nameof(_BuildSolutionPressed));
+ buildButton.PressedSignal += _BuildSolutionPressed;
AddControlToContainer(CustomControlContainer.Toolbar, buildButton);
// External editor settings
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
index 379dfd9f7d..ac9379adf8 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
@@ -51,7 +51,9 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Build\MsBuildFinder.cs" />
+ <Compile Include="Export\AotBuilder.cs" />
<Compile Include="Export\ExportPlugin.cs" />
+ <Compile Include="Export\XcodeHelper.cs" />
<Compile Include="ExternalEditorId.cs" />
<Compile Include="Ides\GodotIdeManager.cs" />
<Compile Include="Ides\GodotIdeServer.cs" />
diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
index 0ed567afd1..ae05710f4f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
@@ -10,7 +10,7 @@ namespace GodotTools
public override void _Notification(int what)
{
- if (what == MainLoop.NotificationWmFocusIn)
+ if (what == Node.NotificationWmFocusIn)
{
RestartTimer();
@@ -40,7 +40,7 @@ namespace GodotTools
OneShot = false,
WaitTime = (float)EditorDef("mono/assembly_watch_interval_sec", 0.5)
};
- watchTimer.Connect("timeout", this, nameof(TimerTimeout));
+ watchTimer.Timeout += TimerTimeout;
AddChild(watchTimer);
watchTimer.Start();
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
index 9038333d38..e3a4fa7b45 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
@@ -11,6 +11,10 @@ using Environment = System.Environment;
using File = System.IO.File;
using Path = System.IO.Path;
using OS = GodotTools.Utils.OS;
+// ReSharper disable UnassignedField.Local
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnassignedField.Global
+// ReSharper disable MemberHidesStaticFromOuterClass
namespace GodotTools.Ides.Rider
{
@@ -131,28 +135,45 @@ namespace GodotTools.Ides.Rider
if (OS.IsWindows)
{
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
- return Path.Combine(localAppData, @"JetBrains\Toolbox\apps\Rider");
+ return GetToolboxRiderRootPath(localAppData);
}
if (OS.IsOSX)
{
var home = Environment.GetEnvironmentVariable("HOME");
- if (!string.IsNullOrEmpty(home))
- {
- return Path.Combine(home, @"Library/Application Support/JetBrains/Toolbox/apps/Rider");
- }
+ if (string.IsNullOrEmpty(home))
+ return string.Empty;
+ var localAppData = Path.Combine(home, @"Library/Application Support");
+ return GetToolboxRiderRootPath(localAppData);
}
if (OS.IsUnixLike())
{
var home = Environment.GetEnvironmentVariable("HOME");
- if (!string.IsNullOrEmpty(home))
- {
- return Path.Combine(home, @".local/share/JetBrains/Toolbox/apps/Rider");
- }
+ if (string.IsNullOrEmpty(home))
+ return string.Empty;
+ var localAppData = Path.Combine(home, @".local/share");
+ return GetToolboxRiderRootPath(localAppData);
}
- throw new Exception("Unexpected OS.");
+ return string.Empty;
+ }
+
+
+ private static string GetToolboxRiderRootPath(string localAppData)
+ {
+ var toolboxPath = Path.Combine(localAppData, @"JetBrains/Toolbox");
+ var settingsJson = Path.Combine(toolboxPath, ".settings.json");
+
+ if (File.Exists(settingsJson))
+ {
+ var path = SettingsJson.GetInstallLocationFromJson(File.ReadAllText(settingsJson));
+ if (!string.IsNullOrEmpty(path))
+ toolboxPath = path;
+ }
+
+ var toolboxRiderRootPath = Path.Combine(toolboxPath, @"apps/Rider");
+ return toolboxRiderRootPath;
}
internal static ProductInfo GetBuildVersion(string path)
@@ -197,20 +218,29 @@ namespace GodotTools.Ides.Rider
private static void CollectPathsFromRegistry(string registryKey, List<string> installPaths)
{
+ using (var key = Registry.CurrentUser.OpenSubKey(registryKey))
+ {
+ CollectPathsFromRegistry(installPaths, key);
+ }
using (var key = Registry.LocalMachine.OpenSubKey(registryKey))
{
- if (key == null) return;
- foreach (var subkeyName in key.GetSubKeyNames().Where(a => a.Contains("Rider")))
+ CollectPathsFromRegistry(installPaths, key);
+ }
+ }
+
+ private static void CollectPathsFromRegistry(List<string> installPaths, RegistryKey key)
+ {
+ if (key == null) return;
+ foreach (var subkeyName in key.GetSubKeyNames().Where(a => a.Contains("Rider")))
+ {
+ using (var subkey = key.OpenSubKey(subkeyName))
{
- using (var subkey = key.OpenSubKey(subkeyName))
- {
- var folderObject = subkey?.GetValue("InstallLocation");
- if (folderObject == null) continue;
- var folder = folderObject.ToString();
- var possiblePath = Path.Combine(folder, @"bin\rider64.exe");
- if (File.Exists(possiblePath))
- installPaths.Add(possiblePath);
- }
+ var folderObject = subkey?.GetValue("InstallLocation");
+ if (folderObject == null) continue;
+ var folder = folderObject.ToString();
+ var possiblePath = Path.Combine(folder, @"bin\rider64.exe");
+ if (File.Exists(possiblePath))
+ installPaths.Add(possiblePath);
}
}
}
@@ -226,8 +256,8 @@ namespace GodotTools.Ides.Rider
{
try
{
- // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D
- var historyFile = Path.Combine(channelDir, ".history.json");
+ // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D
+ var historyFile = Path.Combine(channelDir, ".history.json");
if (File.Exists(historyFile))
{
var json = File.ReadAllText(historyFile);
@@ -255,14 +285,14 @@ namespace GodotTools.Ides.Rider
}
}
- // changes in toolbox json files format may brake the logic above, so return all found Rider installations
- return Directory.GetDirectories(channelDir)
- .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir));
+ // changes in toolbox json files format may brake the logic above, so return all found Rider installations
+ return Directory.GetDirectories(channelDir)
+ .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir));
}
catch (Exception e)
{
- // do not write to Debug.Log, just log it.
- Logger.Warn($"Failed to get RiderPath from {channelDir}", e);
+ // do not write to Debug.Log, just log it.
+ Logger.Warn($"Failed to get RiderPath from {channelDir}", e);
}
return new string[0];
@@ -289,6 +319,27 @@ namespace GodotTools.Ides.Rider
#pragma warning disable 0649
[Serializable]
+ class SettingsJson
+ {
+ public string install_location;
+
+ [CanBeNull]
+ public static string GetInstallLocationFromJson(string json)
+ {
+ try
+ {
+ return JsonConvert.DeserializeObject<SettingsJson>(json).install_location;
+ }
+ catch (Exception)
+ {
+ Logger.Warn($"Failed to get install_location from json {json}");
+ }
+
+ return null;
+ }
+ }
+
+ [Serializable]
class ToolboxHistory
{
public List<ItemNode> history;
@@ -372,7 +423,6 @@ namespace GodotTools.Ides.Rider
[Serializable]
class ActiveApplication
{
- // ReSharper disable once InconsistentNaming
public List<string> builds;
}
@@ -380,6 +430,7 @@ namespace GodotTools.Ides.Rider
public struct RiderInfo
{
+ // ReSharper disable once NotAccessedField.Global
public bool IsToolbox;
public string Presentation;
public Version BuildNumber;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
index 558a242bf9..16f91a0925 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -9,13 +9,13 @@ namespace GodotTools.Ides.Rider
{
public static class RiderPathManager
{
- private static readonly string editorPathSettingName = "mono/editor/editor_path_optional";
+ public static readonly string EditorPathSettingName = "mono/editor/editor_path_optional";
private static string GetRiderPathFromSettings()
{
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- if (editorSettings.HasSetting(editorPathSettingName))
- return (string)editorSettings.GetSetting(editorPathSettingName);
+ if (editorSettings.HasSetting(EditorPathSettingName))
+ return (string)editorSettings.GetSetting(EditorPathSettingName);
return null;
}
@@ -25,22 +25,22 @@ namespace GodotTools.Ides.Rider
var editor = (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor");
if (editor == ExternalEditorId.Rider)
{
- if (!editorSettings.HasSetting(editorPathSettingName))
+ if (!editorSettings.HasSetting(EditorPathSettingName))
{
- Globals.EditorDef(editorPathSettingName, "Optional");
+ Globals.EditorDef(EditorPathSettingName, "Optional");
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
["type"] = Variant.Type.String,
- ["name"] = editorPathSettingName,
+ ["name"] = EditorPathSettingName,
["hint"] = PropertyHint.File,
["hint_string"] = ""
});
}
- var riderPath = (string)editorSettings.GetSetting(editorPathSettingName);
+ var riderPath = (string)editorSettings.GetSetting(EditorPathSettingName);
if (IsRiderAndExists(riderPath))
{
- Globals.EditorDef(editorPathSettingName, riderPath);
+ Globals.EditorDef(EditorPathSettingName, riderPath);
return;
}
@@ -50,17 +50,20 @@ namespace GodotTools.Ides.Rider
return;
var newPath = paths.Last().Path;
- Globals.EditorDef(editorPathSettingName, newPath);
- editorSettings.SetSetting(editorPathSettingName, newPath);
+ Globals.EditorDef(EditorPathSettingName, newPath);
+ editorSettings.SetSetting(EditorPathSettingName, newPath);
}
}
- private static bool IsRider(string path)
+ public static bool IsExternalEditorSetToRider(EditorSettings editorSettings)
+ {
+ return editorSettings.HasSetting(EditorPathSettingName) && IsRider((string) editorSettings.GetSetting(EditorPathSettingName));
+ }
+
+ public static bool IsRider(string path)
{
if (string.IsNullOrEmpty(path))
- {
return false;
- }
var fileInfo = new FileInfo(path);
var filename = fileInfo.Name.ToLowerInvariant();
@@ -81,8 +84,8 @@ namespace GodotTools.Ides.Rider
return null;
var newPath = paths.Last().Path;
- editorSettings.SetSetting(editorPathSettingName, newPath);
- Globals.EditorDef(editorPathSettingName, newPath);
+ editorSettings.SetSetting(EditorPathSettingName, newPath);
+ Globals.EditorDef(EditorPathSettingName, newPath);
return newPath;
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index de361ba844..026a7db89c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -8,7 +8,7 @@ namespace GodotTools.Internals
public static class Internal
{
public const string CSharpLanguageType = "CSharpScript";
- public const string CSharpLanguageExtension = "cs";
+ public const string CSharpLanguageExtension = ".cs";
public static string UpdateApiAssembliesFromPrebuilt(string config) =>
internal_UpdateApiAssembliesFromPrebuilt(config);
@@ -34,7 +34,7 @@ namespace GodotTools.Internals
public static void ReloadAssemblies(bool softReload) => internal_ReloadAssemblies(softReload);
- public static void ScriptEditorDebuggerReloadScripts() => internal_ScriptEditorDebuggerReloadScripts();
+ public static void EditorDebuggerNodeReloadScripts() => internal_EditorDebuggerNodeReloadScripts();
public static bool ScriptEditorEdit(Resource resource, int line, int col, bool grabFocus = true) =>
internal_ScriptEditorEdit(resource, line, col, grabFocus);
@@ -88,7 +88,7 @@ namespace GodotTools.Internals
private static extern void internal_ReloadAssemblies(bool softReload);
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void internal_ScriptEditorDebuggerReloadScripts();
+ private static extern void internal_EditorDebuggerNodeReloadScripts();
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool internal_ScriptEditorEdit(Resource resource, int line, int col, bool grabFocus);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index 279e67b3eb..b057ac12c6 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
+using JetBrains.Annotations;
namespace GodotTools.Utils
{
@@ -26,6 +27,7 @@ namespace GodotTools.Utils
public const string UWP = "UWP";
public const string Haiku = "Haiku";
public const string Android = "Android";
+ public const string iOS = "iOS";
public const string HTML5 = "HTML5";
}
@@ -33,11 +35,12 @@ namespace GodotTools.Utils
{
public const string Windows = "windows";
public const string OSX = "osx";
- public const string X11 = "x11";
+ public const string X11 = "linuxbsd";
public const string Server = "server";
public const string UWP = "uwp";
public const string Haiku = "haiku";
public const string Android = "android";
+ public const string iOS = "iphone";
public const string HTML5 = "javascript";
}
@@ -50,6 +53,7 @@ namespace GodotTools.Utils
[Names.UWP] = Platforms.UWP,
[Names.Haiku] = Platforms.Haiku,
[Names.Android] = Platforms.Android,
+ [Names.iOS] = Platforms.iOS,
[Names.HTML5] = Platforms.HTML5
};
@@ -65,6 +69,7 @@ namespace GodotTools.Utils
private static readonly Lazy<bool> _isUWP = new Lazy<bool>(() => IsOS(Names.UWP));
private static readonly Lazy<bool> _isHaiku = new Lazy<bool>(() => IsOS(Names.Haiku));
private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android));
+ private static readonly Lazy<bool> _isiOS = new Lazy<bool>(() => IsOS(Names.iOS));
private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5));
public static bool IsWindows => _isWindows.Value || IsUWP;
@@ -74,10 +79,11 @@ namespace GodotTools.Utils
public static bool IsUWP => _isUWP.Value;
public static bool IsHaiku => _isHaiku.Value;
public static bool IsAndroid => _isAndroid.Value;
+ public static bool IsiOS => _isiOS.Value;
public static bool IsHTML5 => _isHTML5.Value;
private static bool? _isUnixCache;
- private static readonly string[] UnixLikePlatforms = { Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android };
+ private static readonly string[] UnixLikePlatforms = { Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android, Names.iOS };
public static bool IsUnixLike()
{
@@ -91,12 +97,12 @@ namespace GodotTools.Utils
public static char PathSep => IsWindows ? ';' : ':';
- public static string PathWhich(string name)
+ public static string PathWhich([NotNull] string name)
{
return IsWindows ? PathWhichWindows(name) : PathWhichUnix(name);
}
- private static string PathWhichWindows(string name)
+ private static string PathWhichWindows([NotNull] string name)
{
string[] windowsExts = Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) ?? new string[] { };
string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep);
@@ -121,7 +127,7 @@ namespace GodotTools.Utils
select path + ext).FirstOrDefault(File.Exists);
}
- private static string PathWhichUnix(string name)
+ private static string PathWhichUnix([NotNull] string name)
{
string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep);
@@ -163,5 +169,33 @@ namespace GodotTools.Utils
User32Dll.AllowSetForegroundWindow(process.Id); // allows application to focus itself
}
}
+
+ public static int ExecuteCommand(string command, IEnumerable<string> arguments)
+ {
+ // TODO: Once we move to .NET Standard 2.1 we can use ProcessStartInfo.ArgumentList instead
+ string CmdLineArgsToString(IEnumerable<string> args)
+ {
+ // Not perfect, but as long as we are careful...
+ return string.Join(" ", args.Select(arg => arg.Contains(" ") ? $@"""{arg}""" : arg));
+ }
+
+ var startInfo = new ProcessStartInfo(command, CmdLineArgsToString(arguments));
+
+ Console.WriteLine($"Executing: \"{startInfo.FileName}\" {startInfo.Arguments}");
+
+ // Print the output
+ startInfo.RedirectStandardOutput = false;
+ startInfo.RedirectStandardError = false;
+
+ startInfo.UseShellExecute = false;
+
+ using (var process = new Process { StartInfo = startInfo })
+ {
+ process.Start();
+ process.WaitForExit();
+
+ return process.ExitCode;
+ }
+ }
}
}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 34f01ce3c6..ee92a6234a 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -76,7 +76,7 @@
#define GLUE_HEADER_FILE "glue_header.h"
#define ICALL_PREFIX "godot_icall_"
#define SINGLETON_ICALL_SUFFIX "_get_singleton"
-#define ICALL_GET_METHODBIND ICALL_PREFIX "Object_ClassDB_get_method"
+#define ICALL_GET_METHODBIND "__ClassDB_get_method"
#define C_LOCAL_RET "ret"
#define C_LOCAL_VARARG_RET "vararg_ret"
@@ -95,6 +95,10 @@
#define C_METHOD_MONOSTR_FROM_GODOT C_NS_MONOMARSHAL "::mono_string_from_godot"
#define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type
#define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array"
+#define C_METHOD_MANAGED_TO_CALLABLE C_NS_MONOMARSHAL "::managed_to_callable"
+#define C_METHOD_MANAGED_FROM_CALLABLE C_NS_MONOMARSHAL "::callable_to_managed"
+#define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable"
+#define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info"
#define BINDINGS_GENERATOR_VERSION UINT32_C(11)
@@ -407,7 +411,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append("\"/>");
} else {
// Try to find as global enum constant
- const EnumInterface *target_ienum = NULL;
+ const EnumInterface *target_ienum = nullptr;
for (const List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) {
target_ienum = &E->get();
@@ -445,7 +449,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append("\"/>");
} else {
// Try to find as enum constant in the current class
- const EnumInterface *target_ienum = NULL;
+ const EnumInterface *target_ienum = nullptr;
for (const List<EnumInterface>::Element *E = target_itype->enums.front(); E; E = E->next()) {
target_ienum = &E->get();
@@ -503,24 +507,24 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append("<c>");
xml_output.append(tag);
xml_output.append("</c>");
- } else if (tag == "PoolByteArray") {
- xml_output.append("<see cref=\"byte\"/>");
- } else if (tag == "PoolIntArray") {
- xml_output.append("<see cref=\"int\"/>");
- } else if (tag == "PoolRealArray") {
-#ifdef REAL_T_IS_DOUBLE
- xml_output.append("<see cref=\"double\"/>");
-#else
- xml_output.append("<see cref=\"float\"/>");
-#endif
- } else if (tag == "PoolStringArray") {
- xml_output.append("<see cref=\"string\"/>");
- } else if (tag == "PoolVector2Array") {
- xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Vector2\"/>");
- } else if (tag == "PoolVector3Array") {
- xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Vector3\"/>");
- } else if (tag == "PoolColorArray") {
- xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Color\"/>");
+ } else if (tag == "PackedByteArray") {
+ xml_output.append("<see cref=\"T:byte[]\"/>");
+ } else if (tag == "PackedInt32Array") {
+ xml_output.append("<see cref=\"T:int[]\"/>");
+ } else if (tag == "PackedInt64Array") {
+ xml_output.append("<see cref=\"T:long[]\"/>");
+ } else if (tag == "PackedFloat32Array") {
+ xml_output.append("<see cref=\"T:float[]\"/>");
+ } else if (tag == "PackedFloat64Array") {
+ xml_output.append("<see cref=\"T:double[]\"/>");
+ } else if (tag == "PackedStringArray") {
+ xml_output.append("<see cref=\"T:string[]\"/>");
+ } else if (tag == "PackedVector2Array") {
+ xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Vector2[]\"/>");
+ } else if (tag == "PackedVector3Array") {
+ xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Vector3[]\"/>");
+ } else if (tag == "PackedColorArray") {
+ xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Color[]\"/>");
} else {
const TypeInterface *target_itype = _get_type_or_null(TypeReference(tag));
@@ -778,7 +782,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
const ConstantInterface &iconstant = E->get();
if (iconstant.const_doc && iconstant.const_doc->description.size()) {
- String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), NULL);
+ String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), nullptr);
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
if (summary_lines.size()) {
@@ -839,7 +843,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
const ConstantInterface &iconstant = F->get();
if (iconstant.const_doc && iconstant.const_doc->description.size()) {
- String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), NULL);
+ String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), nullptr);
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
if (summary_lines.size()) {
@@ -932,7 +936,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
"using System.Runtime.CompilerServices;\n"
"\n");
cs_icalls_content.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
- cs_icalls_content.append(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 OPEN_BLOCK);
+ cs_icalls_content.append(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 "{");
cs_icalls_content.append(MEMBER_BEGIN "internal static ulong godot_api_hash = ");
cs_icalls_content.append(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + ";\n");
@@ -944,7 +948,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
#define ADD_INTERNAL_CALL(m_icall) \
if (!m_icall.editor_only) { \
cs_icalls_content.append(MEMBER_BEGIN "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \
- cs_icalls_content.append(INDENT2 "internal extern static "); \
+ cs_icalls_content.append(INDENT2 "internal static extern "); \
cs_icalls_content.append(m_icall.im_type_out + " "); \
cs_icalls_content.append(m_icall.name + "("); \
cs_icalls_content.append(m_icall.im_sig + ");\n"); \
@@ -1046,7 +1050,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
#define ADD_INTERNAL_CALL(m_icall) \
if (m_icall.editor_only) { \
cs_icalls_content.append(INDENT2 "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \
- cs_icalls_content.append(INDENT2 "internal extern static "); \
+ cs_icalls_content.append(INDENT2 "internal static extern "); \
cs_icalls_content.append(m_icall.im_type_out + " "); \
cs_icalls_content.append(m_icall.name + "("); \
cs_icalls_content.append(m_icall.im_sig + ");\n"); \
@@ -1312,7 +1316,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(itype.proxy_name);
output.append(").Name);\n" INDENT4 "return singleton;\n" INDENT3 "}\n" INDENT2 "}\n");
- output.append(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
+ output.append(MEMBER_BEGIN "private static StringName " BINDINGS_NATIVE_NAME_FIELD " = \"");
output.append(itype.name);
output.append("\";\n");
@@ -1324,7 +1328,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
} else if (is_derived_type) {
// Add member fields
- output.append(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
+ output.append(MEMBER_BEGIN "private static StringName " BINDINGS_NATIVE_NAME_FIELD " = \"");
output.append(itype.name);
output.append("\";\n");
@@ -1363,6 +1367,13 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
"Failed to generate method '" + imethod.name + "' for class '" + itype.name + "'.");
}
+ for (const List<SignalInterface>::Element *E = itype.signals_.front(); E; E = E->next()) {
+ const SignalInterface &isignal = E->get();
+ Error method_err = _generate_cs_signal(itype, isignal, output);
+ ERR_FAIL_COND_V_MSG(method_err != OK, method_err,
+ "Failed to generate signal '" + isignal.name + "' for class '" + itype.name + "'.");
+ }
+
if (itype.is_singleton) {
InternalCall singleton_icall = InternalCall(itype.api_type, ICALL_PREFIX + itype.name + SINGLETON_ICALL_SUFFIX, "IntPtr");
@@ -1395,7 +1406,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
const TypeInterface *current_type = &p_itype;
while (!setter && current_type->base_name != StringName()) {
OrderedHashMap<StringName, TypeInterface>::Element base_match = obj_types.find(current_type->base_name);
- ERR_FAIL_COND_V(!base_match, ERR_BUG);
+ ERR_FAIL_COND_V_MSG(!base_match, ERR_BUG, "Type not found '" + current_type->base_name + "'. Inherited by '" + current_type->name + "'.");
current_type = &base_match.get();
setter = current_type->find_method_by_name(p_iprop.setter);
}
@@ -1406,7 +1417,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
current_type = &p_itype;
while (!getter && current_type->base_name != StringName()) {
OrderedHashMap<StringName, TypeInterface>::Element base_match = obj_types.find(current_type->base_name);
- ERR_FAIL_COND_V(!base_match, ERR_BUG);
+ ERR_FAIL_COND_V_MSG(!base_match, ERR_BUG, "Type not found '" + current_type->base_name + "'. Inherited by '" + current_type->name + "'.");
current_type = &base_match.get();
getter = current_type->find_method_by_name(p_iprop.getter);
}
@@ -1424,7 +1435,16 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
}
if (getter && setter) {
- ERR_FAIL_COND_V(getter->return_type.cname != setter->arguments.back()->get().type.cname, ERR_BUG);
+ const ArgumentInterface &setter_first_arg = setter->arguments.back()->get();
+ if (getter->return_type.cname != setter_first_arg.type.cname) {
+ // Special case for Node::set_name
+ bool whitelisted = getter->return_type.cname == name_cache.type_StringName &&
+ setter_first_arg.type.cname == name_cache.type_String;
+
+ ERR_FAIL_COND_V_MSG(!whitelisted, ERR_BUG,
+ "Return type from getter doesn't match first argument of setter for property: '" +
+ p_itype.name + "." + String(p_iprop.cname) + "'.");
+ }
}
const TypeReference &proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
@@ -1474,7 +1494,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
if (idx_arg.type.cname != name_cache.type_int) {
// Assume the index parameter is an enum
const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type);
- CRASH_COND(idx_arg_type == NULL);
+ CRASH_COND(idx_arg_type == nullptr);
p_output.append("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index));
} else {
p_output.append(itos(p_iprop.index));
@@ -1502,7 +1522,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
if (idx_arg.type.cname != name_cache.type_int) {
// Assume the index parameter is an enum
const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type);
- CRASH_COND(idx_arg_type == NULL);
+ CRASH_COND(idx_arg_type == nullptr);
p_output.append("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index) + ", ");
} else {
p_output.append(itos(p_iprop.index) + ", ");
@@ -1525,7 +1545,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type);
- String method_bind_field = "method_bind_" + itos(p_method_bind_count);
+ String method_bind_field = "__method_bind_" + itos(p_method_bind_count);
String arguments_sig;
String cs_in_statements;
@@ -1611,8 +1631,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
// Generate method
{
if (!p_imethod.is_virtual && !p_imethod.requires_object_call) {
- p_output.append(MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN "private static IntPtr ");
- p_output.append(method_bind_field + " = Object." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \"");
+ p_output.append(MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN "private static readonly IntPtr ");
+ p_output.append(method_bind_field);
+ p_output.append(" = Object." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \"");
p_output.append(p_imethod.name);
p_output.append("\");\n");
}
@@ -1726,6 +1747,106 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
return OK;
}
+Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output) {
+ String arguments_sig;
+
+ // Retrieve information from the arguments
+ for (const List<ArgumentInterface>::Element *F = p_isignal.arguments.front(); F; F = F->next()) {
+ const ArgumentInterface &iarg = F->get();
+ const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
+
+ // Add the current arguments to the signature
+
+ if (F != p_isignal.arguments.front())
+ arguments_sig += ", ";
+
+ arguments_sig += arg_type->cs_type;
+ arguments_sig += " ";
+ arguments_sig += iarg.name;
+ }
+
+ // Generate signal
+ {
+ if (p_isignal.method_doc && p_isignal.method_doc->description.size()) {
+ String xml_summary = bbcode_to_xml(fix_doc_description(p_isignal.method_doc->description), &p_itype);
+ Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
+
+ if (summary_lines.size()) {
+ p_output.append(MEMBER_BEGIN "/// <summary>\n");
+
+ for (int i = 0; i < summary_lines.size(); i++) {
+ p_output.append(INDENT2 "/// ");
+ p_output.append(summary_lines[i]);
+ p_output.append("\n");
+ }
+
+ p_output.append(INDENT2 "/// </summary>");
+ }
+ }
+
+ if (p_isignal.is_deprecated) {
+ if (p_isignal.deprecation_message.empty())
+ WARN_PRINT("An empty deprecation message is discouraged. Signal: '" + p_isignal.proxy_name + "'.");
+
+ p_output.append(MEMBER_BEGIN "[Obsolete(\"");
+ p_output.append(p_isignal.deprecation_message);
+ p_output.append("\")]");
+ }
+
+ String delegate_name = p_isignal.proxy_name;
+ delegate_name += "Handler"; // Delegate name is [SignalName]Handler
+
+ // Generate delegate
+ p_output.append(MEMBER_BEGIN "public delegate void ");
+ p_output.append(delegate_name);
+ p_output.append("(");
+ p_output.append(arguments_sig);
+ p_output.append(");\n");
+
+ // TODO:
+ // Could we assume the StringName instance of signal name will never be freed (it's stored in ClassDB) before the managed world is unloaded?
+ // If so, we could store the pointer we get from `data_unique_pointer()` instead of allocating StringName here.
+
+ // Cached signal name (StringName)
+ p_output.append(MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN "private static StringName __signal_name_");
+ p_output.append(p_isignal.name);
+ p_output.append(" = \"");
+ p_output.append(p_isignal.name);
+ p_output.append("\";\n");
+
+ // Generate event
+ p_output.append(MEMBER_BEGIN "[Signal]" MEMBER_BEGIN "public ");
+
+ if (p_itype.is_singleton)
+ p_output.append("static ");
+
+ p_output.append("event ");
+ p_output.append(delegate_name);
+ p_output.append(" ");
+ p_output.append(p_isignal.proxy_name);
+ p_output.append("\n" OPEN_BLOCK_L2);
+
+ if (p_itype.is_singleton)
+ p_output.append("add => Singleton.Connect(__signal_name_");
+ else
+ p_output.append("add => Connect(__signal_name_");
+
+ p_output.append(p_isignal.name);
+ p_output.append(", new Callable(value));\n");
+
+ if (p_itype.is_singleton)
+ p_output.append(INDENT3 "remove => Singleton.Disconnect(__signal_name_");
+ else
+ p_output.append(INDENT3 "remove => Disconnect(__signal_name_");
+
+ p_output.append(p_isignal.name);
+ p_output.append(", new Callable(value));\n");
+ p_output.append(CLOSE_BLOCK_L2);
+ }
+
+ return OK;
+}
+
Error BindingsGenerator::generate_glue(const String &p_output_dir) {
ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED);
@@ -2000,7 +2121,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
if (return_type->is_object_type) {
ptrcall_return_type = return_type->is_reference ? "Ref<Reference>" : return_type->c_type;
- initialization = return_type->is_reference ? "" : " = NULL";
+ initialization = return_type->is_reference ? "" : " = nullptr";
} else {
ptrcall_return_type = return_type->c_type;
}
@@ -2009,10 +2130,10 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
p_output.append(" " C_LOCAL_RET);
p_output.append(initialization + ";\n");
- String fail_ret = return_type->c_type_out.ends_with("*") && !return_type->ret_as_byref_arg ? "NULL" : return_type->c_type_out + "()";
+ String fail_ret = return_type->c_type_out.ends_with("*") && !return_type->ret_as_byref_arg ? "nullptr" : return_type->c_type_out + "()";
if (return_type->ret_as_byref_arg) {
- p_output.append("\tif (" CS_PARAM_INSTANCE " == NULL) { *arg_ret = ");
+ p_output.append("\tif (" CS_PARAM_INSTANCE " == nullptr) { *arg_ret = ");
p_output.append(fail_ret);
p_output.append("; ERR_FAIL_MSG(\"Parameter ' arg_ret ' is null.\"); }\n");
} else {
@@ -2054,7 +2175,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
}
if (p_imethod.is_vararg) {
- p_output.append("\tVariant::CallError vcall_error;\n\t");
+ p_output.append("\tCallable::CallError vcall_error;\n\t");
if (!ret_void) {
// See the comment on the C_LOCAL_VARARG_RET declaration
@@ -2066,7 +2187,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
}
p_output.append(CS_PARAM_METHODBIND "->call(" CS_PARAM_INSTANCE ", ");
- p_output.append(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ".ptr()" : "NULL");
+ p_output.append(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ".ptr()" : "nullptr");
p_output.append(", total_length, vcall_error);\n");
if (!ret_void) {
@@ -2077,8 +2198,8 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
}
} else {
p_output.append("\t" CS_PARAM_METHODBIND "->ptrcall(" CS_PARAM_INSTANCE ", ");
- p_output.append(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ", " : "NULL, ");
- p_output.append(!ret_void ? "&" C_LOCAL_RET ");\n" : "NULL);\n");
+ p_output.append(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ", " : "nullptr, ");
+ p_output.append(!ret_void ? "&" C_LOCAL_RET ");\n" : "nullptr);\n");
}
if (!ret_void) {
@@ -2120,11 +2241,11 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_null(con
// Enum not found. Most likely because none of its constants were bound, so it's empty. That's fine. Use int instead.
const Map<StringName, TypeInterface>::Element *int_match = builtin_types.find(name_cache.type_int);
- ERR_FAIL_NULL_V(int_match, NULL);
+ ERR_FAIL_NULL_V(int_match, nullptr);
return &int_match->get();
}
- return NULL;
+ return nullptr;
}
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placeholder(const TypeReference &p_typeref) {
@@ -2262,7 +2383,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
const PropertyInfo &property = E->get();
- if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_CATEGORY)
+ if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY)
continue;
PropertyInterface iprop;
@@ -2291,7 +2412,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
iprop.proxy_name = iprop.proxy_name.replace("/", "__"); // Some members have a slash...
- iprop.prop_doc = NULL;
+ iprop.prop_doc = nullptr;
for (int i = 0; i < itype.class_doc->properties.size(); i++) {
const DocData::PropertyDoc &prop_doc = itype.class_doc->properties[i];
@@ -2336,7 +2457,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
PropertyInfo return_info = method_info.return_val;
- MethodBind *m = imethod.is_virtual ? NULL : ClassDB::get_method(type_cname, method_info.name);
+ MethodBind *m = imethod.is_virtual ? nullptr : ClassDB::get_method(type_cname, method_info.name);
imethod.is_vararg = m && m->is_vararg();
@@ -2383,7 +2504,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
} else {
if (return_info.type == Variant::INT) {
imethod.return_type.cname = _get_int_type_name_from_meta(m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE);
- } else if (return_info.type == Variant::REAL) {
+ } else if (return_info.type == Variant::FLOAT) {
imethod.return_type.cname = _get_float_type_name_from_meta(m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE);
} else {
imethod.return_type.cname = Variant::get_type_name(return_info.type);
@@ -2410,7 +2531,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
} else {
if (arginfo.type == Variant::INT) {
iarg.type.cname = _get_int_type_name_from_meta(m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE);
- } else if (arginfo.type == Variant::REAL) {
+ } else if (arginfo.type == Variant::FLOAT) {
iarg.type.cname = _get_float_type_name_from_meta(m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE);
} else {
iarg.type.cname = Variant::get_type_name(arginfo.type);
@@ -2479,13 +2600,92 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
}
}
+ // Populate signals
+
+ const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map;
+ const StringName *k = nullptr;
+
+ while ((k = signal_map.next(k))) {
+ SignalInterface isignal;
+
+ const MethodInfo &method_info = signal_map.get(*k);
+
+ isignal.name = method_info.name;
+ isignal.cname = method_info.name;
+
+ int argc = method_info.arguments.size();
+
+ for (int i = 0; i < argc; i++) {
+ PropertyInfo arginfo = method_info.arguments[i];
+
+ String orig_arg_name = arginfo.name;
+
+ ArgumentInterface iarg;
+ iarg.name = orig_arg_name;
+
+ if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ iarg.type.cname = arginfo.class_name;
+ iarg.type.is_enum = true;
+ } else if (arginfo.class_name != StringName()) {
+ iarg.type.cname = arginfo.class_name;
+ } else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ iarg.type.cname = arginfo.hint_string;
+ } else if (arginfo.type == Variant::NIL) {
+ iarg.type.cname = name_cache.type_Variant;
+ } else {
+ if (arginfo.type == Variant::INT) {
+ iarg.type.cname = _get_int_type_name_from_meta(GodotTypeInfo::METADATA_NONE);
+ } else if (arginfo.type == Variant::FLOAT) {
+ iarg.type.cname = _get_float_type_name_from_meta(GodotTypeInfo::METADATA_NONE);
+ } else {
+ iarg.type.cname = Variant::get_type_name(arginfo.type);
+ }
+ }
+
+ iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
+
+ isignal.add_argument(iarg);
+ }
+
+ isignal.proxy_name = escape_csharp_keyword(snake_to_pascal_case(isignal.name));
+
+ // Prevent the signal and its enclosing type from sharing the same name
+ if (isignal.proxy_name == itype.proxy_name) {
+ _log("Name of signal '%s' is ambiguous with the name of its enclosing class '%s'. Renaming signal to '%s_'\n",
+ isignal.proxy_name.utf8().get_data(), itype.proxy_name.utf8().get_data(), isignal.proxy_name.utf8().get_data());
+
+ isignal.proxy_name += "_";
+ }
+
+ if (itype.find_property_by_proxy_name(isignal.proxy_name) || itype.find_method_by_proxy_name(isignal.proxy_name)) {
+ // ClassDB allows signal names that conflict with method or property names.
+ // While registering a signal with a conflicting name is considered wrong,
+ // it may still happen and it may take some time until someone fixes the name.
+ // We can't allow the bindings to be in a broken state while we wait for a fix;
+ // that's why we must handle this possibility by renaming the signal.
+ isignal.proxy_name += "Signal";
+ }
+
+ if (itype.class_doc) {
+ for (int i = 0; i < itype.class_doc->signals.size(); i++) {
+ const DocData::MethodDoc &signal_doc = itype.class_doc->signals[i];
+ if (signal_doc.name == isignal.name) {
+ isignal.method_doc = &signal_doc;
+ break;
+ }
+ }
+ }
+
+ itype.signals_.push_back(isignal);
+ }
+
// Populate enums and constants
List<String> constants;
ClassDB::get_integer_constant_list(type_cname, &constants, true);
- const HashMap<StringName, List<StringName> > &enum_map = class_info->enum_map;
- const StringName *k = NULL;
+ const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
+ k = nullptr;
while ((k = enum_map.next(k))) {
StringName enum_proxy_cname = *k;
@@ -2507,7 +2707,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value);
- iconstant.const_doc = NULL;
+ iconstant.const_doc = nullptr;
for (int i = 0; i < itype.class_doc->constants.size(); i++) {
const DocData::ConstantDoc &const_doc = itype.class_doc->constants[i];
@@ -2542,7 +2742,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value);
- iconstant.const_doc = NULL;
+ iconstant.const_doc = nullptr;
for (int i = 0; i < itype.class_doc->constants.size(); i++) {
const DocData::ConstantDoc &const_doc = itype.class_doc->constants[i];
@@ -2581,14 +2781,21 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "(%s)" + r_iarg.default_argument;
}
break;
- case Variant::REAL:
+ case Variant::FLOAT:
#ifndef REAL_T_IS_DOUBLE
r_iarg.default_argument += "f";
#endif
break;
case Variant::STRING:
+ case Variant::STRING_NAME:
case Variant::NODE_PATH:
- r_iarg.default_argument = "\"" + r_iarg.default_argument + "\"";
+ if (r_iarg.type.cname == name_cache.type_StringName || r_iarg.type.cname == name_cache.type_NodePath) {
+ r_iarg.default_argument = "(%s)\"" + r_iarg.default_argument + "\"";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
+ } else {
+ CRASH_COND(r_iarg.type.cname != name_cache.type_String);
+ r_iarg.default_argument = "\"" + r_iarg.default_argument + "\"";
+ }
break;
case Variant::TRANSFORM:
if (p_val.operator Transform() == Transform())
@@ -2603,8 +2810,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
break;
case Variant::VECTOR2:
+ case Variant::VECTOR2I:
case Variant::RECT2:
+ case Variant::RECT2I:
case Variant::VECTOR3:
+ case Variant::VECTOR3I:
r_iarg.default_argument = "new %s" + r_iarg.default_argument;
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
break;
@@ -2628,13 +2838,15 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "null";
break;
case Variant::ARRAY:
- case Variant::POOL_BYTE_ARRAY:
- case Variant::POOL_INT_ARRAY:
- case Variant::POOL_REAL_ARRAY:
- case Variant::POOL_STRING_ARRAY:
- case Variant::POOL_VECTOR2_ARRAY:
- case Variant::POOL_VECTOR3_ARRAY:
- case Variant::POOL_COLOR_ARRAY:
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY:
+ case Variant::PACKED_COLOR_ARRAY:
r_iarg.default_argument = "new %s {}";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
break;
@@ -2644,8 +2856,13 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = Variant::get_type_name(p_val.get_type()) + ".Identity";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
break;
- default: {
- }
+ case Variant::CALLABLE:
+ case Variant::SIGNAL:
+ CRASH_NOW_MSG("Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value.");
+ break;
+ default:
+ CRASH_NOW_MSG("Unexpected Variant type: " + itos(p_val.get_type()));
+ break;
}
if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type.cname == name_cache.type_Variant && r_iarg.default_argument != "null")
@@ -2670,16 +2887,19 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.c_type_out = "GDMonoMarshal::M_" #m_type; \
itype.cs_in = "ref %s"; \
/* in cs_out, im_type_out (%3) includes the 'out ' part */ \
- itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;"; \
+ itype.cs_out = "%0(%1, %3 argRet); return argRet;"; \
itype.im_type_out = "out " + itype.cs_type; \
itype.ret_as_byref_arg = true; \
builtin_types.insert(itype.cname, itype); \
}
INSERT_STRUCT_TYPE(Vector2)
+ INSERT_STRUCT_TYPE(Vector2i)
INSERT_STRUCT_TYPE(Rect2)
+ INSERT_STRUCT_TYPE(Rect2i)
INSERT_STRUCT_TYPE(Transform2D)
INSERT_STRUCT_TYPE(Vector3)
+ INSERT_STRUCT_TYPE(Vector3i)
INSERT_STRUCT_TYPE(Basis)
INSERT_STRUCT_TYPE(Quat)
INSERT_STRUCT_TYPE(Transform)
@@ -2747,7 +2967,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.im_type_out = "out " + itype.name;
itype.cs_in = "ref %0";
/* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;";
+ itype.cs_out = "%0(%1, %3 argRet); return argRet;";
itype.ret_as_byref_arg = true;
builtin_types.insert(itype.cname, itype);
@@ -2764,7 +2984,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.im_type_out = "out " + itype.name;
itype.cs_in = "ref %0";
/* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;";
+ itype.cs_out = "%0(%1, %3 argRet); return argRet;";
itype.ret_as_byref_arg = true;
builtin_types.insert(itype.cname, itype);
}
@@ -2790,7 +3010,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.im_type_out = "out " + itype.proxy_name;
itype.cs_in = "ref %0";
/* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;";
+ itype.cs_out = "%0(%1, %3 argRet); return argRet;";
itype.ret_as_byref_arg = true;
builtin_types.insert(itype.cname, itype);
@@ -2812,7 +3032,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.im_type_out = "out " + itype.proxy_name;
itype.cs_in = "ref %0";
/* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return (%2)argRet;";
+ itype.cs_out = "%0(%1, %3 argRet); return argRet;";
itype.ret_as_byref_arg = true;
builtin_types.insert(itype.cname, itype);
}
@@ -2833,6 +3053,24 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.im_type_out = itype.proxy_name;
builtin_types.insert(itype.cname, itype);
+ // StringName
+ itype = TypeInterface();
+ itype.name = "StringName";
+ itype.cname = itype.name;
+ itype.proxy_name = "StringName";
+ itype.c_in = "\t%0 %1_in = %1 ? *%1 : StringName();\n";
+ itype.c_out = "\treturn memnew(StringName(%1));\n";
+ itype.c_arg_in = "&%s_in";
+ itype.c_type = itype.name;
+ itype.c_type_in = itype.c_type + "*";
+ itype.c_type_out = itype.c_type + "*";
+ itype.cs_type = itype.proxy_name;
+ itype.cs_in = "StringName." CS_SMETHOD_GETINSTANCE "(%0)";
+ itype.cs_out = "return new %2(%0(%1));";
+ itype.im_type_in = "IntPtr";
+ itype.im_type_out = "IntPtr";
+ builtin_types.insert(itype.cname, itype);
+
// NodePath
itype = TypeInterface();
itype.name = "NodePath";
@@ -2881,6 +3119,40 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.im_type_out = itype.proxy_name;
builtin_types.insert(itype.cname, itype);
+ // Callable
+ itype = TypeInterface::create_value_type(String("Callable"));
+ itype.c_in = "\t%0 %1_in = " C_METHOD_MANAGED_TO_CALLABLE "(*%1);\n";
+ itype.c_out = "\t*%3 = " C_METHOD_MANAGED_FROM_CALLABLE "(%1);\n";
+ itype.c_arg_in = "&%s_in";
+ itype.c_type_in = "GDMonoMarshal::M_Callable*";
+ itype.c_type_out = "GDMonoMarshal::M_Callable";
+ itype.cs_in = "ref %s";
+ /* in cs_out, im_type_out (%3) includes the 'out ' part */
+ itype.cs_out = "%0(%1, %3 argRet); return argRet;";
+ itype.im_type_out = "out " + itype.cs_type;
+ itype.ret_as_byref_arg = true;
+ builtin_types.insert(itype.cname, itype);
+
+ // Signal
+ itype = TypeInterface();
+ itype.name = "Signal";
+ itype.cname = itype.name;
+ itype.proxy_name = "SignalInfo";
+ itype.c_in = "\t%0 %1_in = " C_METHOD_MANAGED_TO_SIGNAL "(*%1);\n";
+ itype.c_out = "\t*%3 = " C_METHOD_MANAGED_FROM_SIGNAL "(%1);\n";
+ itype.c_arg_in = "&%s_in";
+ itype.c_type = itype.name;
+ itype.c_type_in = "GDMonoMarshal::M_SignalInfo*";
+ itype.c_type_out = "GDMonoMarshal::M_SignalInfo";
+ itype.cs_in = "ref %s";
+ /* in cs_out, im_type_out (%3) includes the 'out ' part */
+ itype.cs_out = "%0(%1, %3 argRet); return argRet;";
+ itype.cs_type = itype.proxy_name;
+ itype.im_type_in = "ref " + itype.cs_type;
+ itype.im_type_out = "out " + itype.cs_type;
+ itype.ret_as_byref_arg = true;
+ builtin_types.insert(itype.cname, itype);
+
// VarArg (fictitious type to represent variable arguments)
itype = TypeInterface();
itype.name = "VarArg";
@@ -2914,20 +3186,18 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
#define INSERT_ARRAY(m_type, m_proxy_t) INSERT_ARRAY_FULL(m_type, m_type, m_proxy_t)
- INSERT_ARRAY(PoolIntArray, int);
- INSERT_ARRAY_FULL(PoolByteArray, PoolByteArray, byte);
+ INSERT_ARRAY(PackedInt32Array, int);
+ INSERT_ARRAY(PackedInt64Array, long);
+ INSERT_ARRAY_FULL(PackedByteArray, PackedByteArray, byte);
-#ifdef REAL_T_IS_DOUBLE
- INSERT_ARRAY(PoolRealArray, double);
-#else
- INSERT_ARRAY(PoolRealArray, float);
-#endif
+ INSERT_ARRAY(PackedFloat32Array, float);
+ INSERT_ARRAY(PackedFloat64Array, double);
- INSERT_ARRAY(PoolStringArray, string);
+ INSERT_ARRAY(PackedStringArray, string);
- INSERT_ARRAY(PoolColorArray, Color);
- INSERT_ARRAY(PoolVector2Array, Vector2);
- INSERT_ARRAY(PoolVector3Array, Vector3);
+ INSERT_ARRAY(PackedColorArray, Color);
+ INSERT_ARRAY(PackedVector2Array, Vector2);
+ INSERT_ARRAY(PackedVector3Array, Vector3);
#undef INSERT_ARRAY
@@ -2992,7 +3262,7 @@ void BindingsGenerator::_populate_global_constants() {
String constant_name = GlobalConstants::get_global_constant_name(i);
- const DocData::ConstantDoc *const_doc = NULL;
+ const DocData::ConstantDoc *const_doc = nullptr;
for (int j = 0; j < global_scope_doc.constants.size(); j++) {
const DocData::ConstantDoc &curr_const_doc = global_scope_doc.constants[j];
@@ -3050,7 +3320,10 @@ void BindingsGenerator::_populate_global_constants() {
// HARDCODED
List<StringName> hardcoded_enums;
+ hardcoded_enums.push_back("Vector2.Axis");
+ hardcoded_enums.push_back("Vector2i.Axis");
hardcoded_enums.push_back("Vector3.Axis");
+ hardcoded_enums.push_back("Vector3i.Axis");
for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) {
// These enums are not generated and must be written manually (e.g.: Vector3.Axis)
// Here, we assume core types do not begin with underscore
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index d3a8937313..7c87c688db 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -33,7 +33,7 @@
#include "core/class_db.h"
#include "core/string_builder.h"
-#include "editor/doc/doc_data.h"
+#include "editor/doc_data.h"
#include "editor/editor_help.h"
#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
@@ -107,9 +107,15 @@ class BindingsGenerator {
TypeReference type;
String name;
- String default_argument;
DefaultParamMode def_param_mode;
+ /**
+ * Determines the expression for the parameter default value.
+ * Formatting elements:
+ * %0 or %s: [cs_type] of the argument type
+ */
+ String default_argument;
+
ArgumentInterface() {
def_param_mode = CONSTANT;
}
@@ -170,7 +176,33 @@ class BindingsGenerator {
is_virtual = false;
requires_object_call = false;
is_internal = false;
- method_doc = NULL;
+ method_doc = nullptr;
+ is_deprecated = false;
+ }
+ };
+
+ struct SignalInterface {
+ String name;
+ StringName cname;
+
+ /**
+ * Name of the C# method
+ */
+ String proxy_name;
+
+ List<ArgumentInterface> arguments;
+
+ const DocData::MethodDoc *method_doc;
+
+ bool is_deprecated;
+ String deprecation_message;
+
+ void add_argument(const ArgumentInterface &argument) {
+ arguments.push_back(argument);
+ }
+
+ SignalInterface() {
+ method_doc = nullptr;
is_deprecated = false;
}
};
@@ -336,6 +368,7 @@ class BindingsGenerator {
List<EnumInterface> enums;
List<PropertyInterface> properties;
List<MethodInterface> methods;
+ List<SignalInterface> signals_;
const MethodInterface *find_method_by_name(const StringName &p_cname) const {
for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) {
@@ -343,7 +376,7 @@ class BindingsGenerator {
return &E->get();
}
- return NULL;
+ return nullptr;
}
const PropertyInterface *find_property_by_name(const StringName &p_cname) const {
@@ -352,7 +385,7 @@ class BindingsGenerator {
return &E->get();
}
- return NULL;
+ return nullptr;
}
const PropertyInterface *find_property_by_proxy_name(const String &p_proxy_name) const {
@@ -361,7 +394,16 @@ class BindingsGenerator {
return &E->get();
}
- return NULL;
+ return nullptr;
+ }
+
+ const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const {
+ for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) {
+ if (E->get().proxy_name == p_proxy_name)
+ return &E->get();
+ }
+
+ return nullptr;
}
private:
@@ -456,7 +498,7 @@ class BindingsGenerator {
c_arg_in = "%s";
- class_doc = NULL;
+ class_doc = nullptr;
}
};
@@ -510,7 +552,7 @@ class BindingsGenerator {
List<InternalCall> core_custom_icalls;
List<InternalCall> editor_custom_icalls;
- Map<StringName, List<StringName> > blacklisted_methods;
+ Map<StringName, List<StringName>> blacklisted_methods;
void _initialize_blacklisted_methods();
@@ -524,6 +566,8 @@ class BindingsGenerator {
StringName type_Reference;
StringName type_RID;
StringName type_String;
+ StringName type_StringName;
+ StringName type_NodePath;
StringName type_at_GlobalScope;
StringName enum_Error;
@@ -548,6 +592,8 @@ class BindingsGenerator {
type_Reference = StaticCString::create("Reference");
type_RID = StaticCString::create("RID");
type_String = StaticCString::create("String");
+ type_StringName = StaticCString::create("StringName");
+ type_NodePath = StaticCString::create("NodePath");
type_at_GlobalScope = StaticCString::create("@GlobalScope");
enum_Error = StaticCString::create("Error");
@@ -576,7 +622,7 @@ class BindingsGenerator {
if (it->get().name == p_name) return it;
it = it->next();
}
- return NULL;
+ return nullptr;
}
const ConstantInterface *find_constant_by_name(const String &p_name, const List<ConstantInterface> &p_constants) const {
@@ -585,7 +631,7 @@ class BindingsGenerator {
return &E->get();
}
- return NULL;
+ return nullptr;
}
inline String get_unique_sig(const TypeInterface &p_type) {
@@ -623,6 +669,7 @@ class BindingsGenerator {
Error _generate_cs_property(const TypeInterface &p_itype, const PropertyInterface &p_iprop, StringBuilder &p_output);
Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output);
+ Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output);
void _generate_global_constants(StringBuilder &p_output);
diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp
index 872f45ba91..e5c2d023d3 100644
--- a/modules/mono/editor/csharp_project.cpp
+++ b/modules/mono/editor/csharp_project.cpp
@@ -57,8 +57,8 @@ void add_item(const String &p_project_path, const String &p_item_type, const Str
Variant item_type = p_item_type;
Variant include = p_include;
const Variant *args[3] = { &project_path, &item_type, &include };
- MonoException *exc = NULL;
- klass->get_method("AddItemToProjectChecked", 3)->invoke(NULL, args, &exc);
+ MonoException *exc = nullptr;
+ klass->get_method("AddItemToProjectChecked", 3)->invoke(nullptr, args, &exc);
if (exc) {
GDMonoUtils::debug_print_unhandled_exception(exc);
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index c8d20e80be..c3e7e67ae9 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -36,10 +36,10 @@
#include "core/os/os.h"
#include "core/version.h"
+#include "editor/debugger/editor_debugger_node.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/plugins/script_editor_plugin.h"
-#include "editor/script_editor_debugger.h"
#include "main/main.h"
#include "../csharp_script.h"
@@ -95,7 +95,7 @@ MonoString *godot_icall_GodotSharpDirs_MonoSolutionsDir() {
#ifdef TOOLS_ENABLED
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_mono_solutions_dir());
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -103,7 +103,7 @@ MonoString *godot_icall_GodotSharpDirs_BuildLogsDirs() {
#ifdef TOOLS_ENABLED
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_build_logs_dir());
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -111,7 +111,7 @@ MonoString *godot_icall_GodotSharpDirs_ProjectSlnPath() {
#ifdef TOOLS_ENABLED
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_project_sln_path());
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -119,7 +119,7 @@ MonoString *godot_icall_GodotSharpDirs_ProjectCsProjPath() {
#ifdef TOOLS_ENABLED
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_project_csproj_path());
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -127,7 +127,7 @@ MonoString *godot_icall_GodotSharpDirs_DataEditorToolsDir() {
#ifdef TOOLS_ENABLED
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_editor_tools_dir());
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -135,7 +135,7 @@ MonoString *godot_icall_GodotSharpDirs_DataEditorPrebuiltApiDir() {
#ifdef TOOLS_ENABLED
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_editor_prebuilt_api_dir());
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -151,7 +151,7 @@ MonoString *godot_icall_GodotSharpDirs_DataMonoBinDir() {
#ifdef WINDOWS_ENABLED
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_mono_bin_dir());
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -202,7 +202,7 @@ uint32_t godot_icall_BindingsGenerator_CsGlueVersion() {
}
int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObject *p_classes, MonoString **r_error_str) {
- *r_error_str = NULL;
+ *r_error_str = nullptr;
String filepath = GDMonoMarshal::mono_string_to_godot(p_filepath);
@@ -231,14 +231,14 @@ int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObje
return err;
}
-uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_dependencies,
- MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_dependencies) {
- Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_dependencies);
+uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies,
+ MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) {
+ Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies);
String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config);
String custom_bcl_dir = GDMonoMarshal::mono_string_to_godot(p_custom_bcl_dir);
- Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies);
+ Dictionary assembly_dependencies = GDMonoMarshal::mono_object_to_variant(r_assembly_dependencies);
- return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, dependencies);
+ return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, assembly_dependencies);
}
MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) {
@@ -305,8 +305,8 @@ void godot_icall_Internal_ReloadAssemblies(MonoBoolean p_soft_reload) {
#endif
}
-void godot_icall_Internal_ScriptEditorDebuggerReloadScripts() {
- ScriptEditor::get_singleton()->get_debugger()->reload_scripts();
+void godot_icall_Internal_EditorDebuggerNodeReloadScripts() {
+ EditorDebuggerNode::get_singleton()->reload_scripts();
}
MonoBoolean godot_icall_Internal_ScriptEditorEdit(MonoObject *p_resource, int32_t p_line, int32_t p_col, MonoBoolean p_grab_focus) {
@@ -335,7 +335,7 @@ MonoString *godot_icall_Internal_MonoWindowsInstallRoot() {
String install_root_dir = GDMono::get_singleton()->get_mono_reg_info().install_root_dir;
return GDMonoMarshal::mono_string_from_godot(install_root_dir);
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -348,9 +348,9 @@ void godot_icall_Internal_EditorRunStop() {
}
void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() {
- ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
- if (sed) {
- sed->reload_scripts();
+ EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
+ if (ed) {
+ ed->reload_scripts();
}
}
@@ -446,7 +446,7 @@ void register_editor_internal_calls() {
mono_add_internal_call("GodotTools.Internals.Internal::internal_GetEditorApiHash", (void *)godot_icall_Internal_GetEditorApiHash);
mono_add_internal_call("GodotTools.Internals.Internal::internal_IsAssembliesReloadingNeeded", (void *)godot_icall_Internal_IsAssembliesReloadingNeeded);
mono_add_internal_call("GodotTools.Internals.Internal::internal_ReloadAssemblies", (void *)godot_icall_Internal_ReloadAssemblies);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebuggerReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebuggerReloadScripts);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorDebuggerNodeReloadScripts", (void *)godot_icall_Internal_EditorDebuggerNodeReloadScripts);
mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", (void *)godot_icall_Internal_ScriptEditorEdit);
mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", (void *)godot_icall_Internal_EditorNodeShowScriptScreen);
mono_add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", (void *)godot_icall_Internal_GetScriptsMetadataOrNothing);
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index ce0b6ad0e6..4126da16be 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -50,16 +50,16 @@ String get_assemblyref_name(MonoImage *p_image, int index) {
return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME]));
}
-Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) {
+Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) {
MonoImage *image = p_assembly->get_image();
for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) {
String ref_name = get_assemblyref_name(image, i);
- if (r_dependencies.has(ref_name))
+ if (r_assembly_dependencies.has(ref_name))
continue;
- GDMonoAssembly *ref_assembly = NULL;
+ GDMonoAssembly *ref_assembly = nullptr;
String path;
bool has_extension = ref_name.ends_with(".dll") || ref_name.ends_with(".exe");
@@ -70,21 +70,21 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
path = search_dir.plus_file(ref_name);
if (FileAccess::exists(path)) {
GDMono::get_singleton()->load_assembly_from(ref_name.get_basename(), path, &ref_assembly, true);
- if (ref_assembly != NULL)
+ if (ref_assembly != nullptr)
break;
}
} else {
path = search_dir.plus_file(ref_name + ".dll");
if (FileAccess::exists(path)) {
GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true);
- if (ref_assembly != NULL)
+ if (ref_assembly != nullptr)
break;
}
path = search_dir.plus_file(ref_name + ".exe");
if (FileAccess::exists(path)) {
GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true);
- if (ref_assembly != NULL)
+ if (ref_assembly != nullptr)
break;
}
}
@@ -92,17 +92,18 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
- r_dependencies[ref_name] = ref_assembly->get_path();
+ // Use the path we got from the search. Don't try to get the path from the loaded assembly as we can't trust it will be from the selected BCL dir.
+ r_assembly_dependencies[ref_name] = path;
- Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
+ Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_assembly_dependencies);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
}
return OK;
}
-Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
- const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) {
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
+ const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_assembly_dependencies) {
MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport");
ERR_FAIL_NULL_V(export_domain, FAILED);
_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);
@@ -112,16 +113,16 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencie
Vector<String> search_dirs;
GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir);
- for (const Variant *key = p_initial_dependencies.next(); key; key = p_initial_dependencies.next(key)) {
+ for (const Variant *key = p_initial_assemblies.next(); key; key = p_initial_assemblies.next(key)) {
String assembly_name = *key;
- String assembly_path = p_initial_dependencies[*key];
+ String assembly_path = p_initial_assemblies[*key];
- GDMonoAssembly *assembly = NULL;
+ GDMonoAssembly *assembly = nullptr;
bool load_success = GDMono::get_singleton()->load_assembly_from(assembly_name, assembly_path, &assembly, /* refonly: */ true);
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
- Error err = get_assembly_dependencies(assembly, search_dirs, r_dependencies);
+ Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies);
if (err != OK)
return err;
}
diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h
index 36138f81b7..9ab57755de 100644
--- a/modules/mono/editor/godotsharp_export.h
+++ b/modules/mono/editor/godotsharp_export.h
@@ -41,8 +41,8 @@ namespace GodotSharpExport {
Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies);
-Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
- const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies);
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
+ const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_assembly_dependencies);
} // namespace GodotSharpExport
diff --git a/modules/mono/glue/GodotSharp/GodotSharp.sln b/modules/mono/glue/GodotSharp/GodotSharp.sln
index a496e36da3..4896d0a07d 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp.sln
+++ b/modules/mono/glue/GodotSharp/GodotSharp.sln
@@ -8,8 +8,6 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index aba1065498..a963810d63 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -15,10 +15,7 @@ namespace Godot.Collections
public override bool IsInvalid
{
- get
- {
- return handle == IntPtr.Zero;
- }
+ get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
@@ -43,7 +40,8 @@ namespace Godot.Collections
if (collection == null)
throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'");
- MarshalUtils.EnumerableToArray(collection, GetPtr());
+ foreach (object element in collection)
+ Add(element);
}
internal Array(ArraySafeHandle handle)
@@ -272,14 +270,8 @@ namespace Godot.Collections
public T this[int index]
{
- get
- {
- return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass);
- }
- set
- {
- objectArray[index] = value;
- }
+ get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); }
+ set { objectArray[index] = value; }
}
public int IndexOf(T item)
@@ -301,18 +293,12 @@ namespace Godot.Collections
public int Count
{
- get
- {
- return objectArray.Count;
- }
+ get { return objectArray.Count; }
}
public bool IsReadOnly
{
- get
- {
- return objectArray.IsReadOnly;
- }
+ get { return objectArray.IsReadOnly; }
}
public void Add(T item)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
index 1bf6d5199a..8fc430b6bc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs
@@ -6,18 +6,12 @@ namespace Godot
public class RemoteAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
- public class SyncAttribute : Attribute {}
-
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public class MasterAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public class PuppetAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
- public class SlaveAttribute : Attribute {}
-
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public class RemoteSyncAttribute : Attribute {}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
index 3957387be9..39d5782db8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
@@ -2,7 +2,7 @@ using System;
namespace Godot
{
- [AttributeUsage(AttributeTargets.Delegate)]
+ [AttributeUsage(AttributeTargets.Delegate | AttributeTargets.Event)]
public class SignalAttribute : Attribute
{
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index d38589013e..baf470a0cc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -93,11 +93,15 @@ namespace Godot
}
}
- public Vector3 this[int columnIndex]
+ /// <summary>
+ /// Access whole columns in the form of Vector3.
+ /// </summary>
+ /// <param name="column">Which column vector.</param>
+ public Vector3 this[int column]
{
get
{
- switch (columnIndex)
+ switch (column)
{
case 0:
return Column0;
@@ -111,7 +115,7 @@ namespace Godot
}
set
{
- switch (columnIndex)
+ switch (column)
{
case 0:
Column0 = value;
@@ -128,50 +132,22 @@ namespace Godot
}
}
- public real_t this[int columnIndex, int rowIndex]
+ /// <summary>
+ /// Access matrix elements in column-major order.
+ /// </summary>
+ /// <param name="column">Which column, the matrix horizontal position.</param>
+ /// <param name="row">Which row, the matrix vertical position.</param>
+ public real_t this[int column, int row]
{
get
{
- switch (columnIndex)
- {
- case 0:
- return Column0[rowIndex];
- case 1:
- return Column1[rowIndex];
- case 2:
- return Column2[rowIndex];
- default:
- throw new IndexOutOfRangeException();
- }
+ return this[column][row];
}
set
{
- switch (columnIndex)
- {
- case 0:
- {
- var column0 = Column0;
- column0[rowIndex] = value;
- Column0 = column0;
- return;
- }
- case 1:
- {
- var column1 = Column1;
- column1[rowIndex] = value;
- Column1 = column1;
- return;
- }
- case 2:
- {
- var column2 = Column2;
- column2[rowIndex] = value;
- Column2 = column2;
- return;
- }
- default:
- throw new IndexOutOfRangeException();
- }
+ Vector3 columnVector = this[column];
+ columnVector[row] = value;
+ this[column] = columnVector;
}
}
@@ -290,12 +266,6 @@ namespace Godot
this[index] = value;
}
- [Obsolete("GetAxis is deprecated. Use GetColumn instead.")]
- public Vector3 GetAxis(int axis)
- {
- return new Vector3(this.Row0[axis], this.Row1[axis], this.Row2[axis]);
- }
-
public int GetOrthogonalIndex()
{
var orth = this;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
new file mode 100644
index 0000000000..c85cc1884c
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Godot
+{
+ public struct Callable
+ {
+ private readonly Object _target;
+ private readonly StringName _method;
+ private readonly Delegate _delegate;
+
+ public Object Target => _target;
+ public StringName Method => _method;
+ public Delegate Delegate => _delegate;
+
+ public static implicit operator Callable(Delegate @delegate) => new Callable(@delegate);
+
+ public Callable(Object target, StringName method)
+ {
+ _target = target;
+ _method = method;
+ _delegate = null;
+ }
+
+ public Callable(Delegate @delegate)
+ {
+ _target = null;
+ _method = null;
+ _delegate = @delegate;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index 0462ef1125..1d1a49945f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -318,9 +318,9 @@ namespace Godot
return res;
}
- public int ToAbgr32()
+ public uint ToAbgr32()
{
- int c = (byte)Math.Round(a * 255);
+ uint c = (byte)Math.Round(a * 255);
c <<= 8;
c |= (byte)Math.Round(b * 255);
c <<= 8;
@@ -331,9 +331,9 @@ namespace Godot
return c;
}
- public long ToAbgr64()
+ public ulong ToAbgr64()
{
- long c = (ushort)Math.Round(a * 65535);
+ ulong c = (ushort)Math.Round(a * 65535);
c <<= 16;
c |= (ushort)Math.Round(b * 65535);
c <<= 16;
@@ -344,9 +344,9 @@ namespace Godot
return c;
}
- public int ToArgb32()
+ public uint ToArgb32()
{
- int c = (byte)Math.Round(a * 255);
+ uint c = (byte)Math.Round(a * 255);
c <<= 8;
c |= (byte)Math.Round(r * 255);
c <<= 8;
@@ -357,9 +357,9 @@ namespace Godot
return c;
}
- public long ToArgb64()
+ public ulong ToArgb64()
{
- long c = (ushort)Math.Round(a * 65535);
+ ulong c = (ushort)Math.Round(a * 65535);
c <<= 16;
c |= (ushort)Math.Round(r * 65535);
c <<= 16;
@@ -370,9 +370,9 @@ namespace Godot
return c;
}
- public int ToRgba32()
+ public uint ToRgba32()
{
- int c = (byte)Math.Round(r * 255);
+ uint c = (byte)Math.Round(r * 255);
c <<= 8;
c |= (byte)Math.Round(g * 255);
c <<= 8;
@@ -383,9 +383,9 @@ namespace Godot
return c;
}
- public long ToRgba64()
+ public ulong ToRgba64()
{
- long c = (ushort)Math.Round(r * 65535);
+ ulong c = (ushort)Math.Round(r * 65535);
c <<= 16;
c |= (ushort)Math.Round(g * 65535);
c <<= 16;
@@ -419,7 +419,7 @@ namespace Godot
this.a = a;
}
- public Color(int rgba)
+ public Color(uint rgba)
{
a = (rgba & 0xFF) / 255.0f;
rgba >>= 8;
@@ -430,7 +430,7 @@ namespace Godot
r = (rgba & 0xFF) / 255.0f;
}
- public Color(long rgba)
+ public Color(ulong rgba)
{
a = (rgba & 0xFFFF) / 65535.0f;
rgba >>= 16;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
new file mode 100644
index 0000000000..785e87a043
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
@@ -0,0 +1,395 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace Godot
+{
+ internal static class DelegateUtils
+ {
+ private enum TargetKind : uint
+ {
+ Static,
+ GodotObject,
+ CompilerGenerated
+ }
+
+ internal static bool TrySerializeDelegate(Delegate @delegate, Collections.Array serializedData)
+ {
+ if (@delegate is MulticastDelegate multicastDelegate)
+ {
+ bool someDelegatesSerialized = false;
+
+ Delegate[] invocationList = multicastDelegate.GetInvocationList();
+
+ if (invocationList.Length > 1)
+ {
+ var multiCastData = new Collections.Array();
+
+ foreach (Delegate oneDelegate in invocationList)
+ someDelegatesSerialized |= TrySerializeDelegate(oneDelegate, multiCastData);
+
+ if (!someDelegatesSerialized)
+ return false;
+
+ serializedData.Add(multiCastData);
+ return true;
+ }
+ }
+
+ if (TrySerializeSingleDelegate(@delegate, out byte[] buffer))
+ {
+ serializedData.Add(buffer);
+ return true;
+ }
+
+ return false;
+ }
+
+ private static bool TrySerializeSingleDelegate(Delegate @delegate, out byte[] buffer)
+ {
+ buffer = null;
+
+ object target = @delegate.Target;
+
+ switch (target)
+ {
+ case null:
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new BinaryWriter(stream))
+ {
+ writer.Write((ulong) TargetKind.Static);
+
+ SerializeType(writer, @delegate.GetType());
+
+ if (!TrySerializeMethodInfo(writer, @delegate.Method))
+ return false;
+
+ buffer = stream.ToArray();
+ return true;
+ }
+ }
+ case Godot.Object godotObject:
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new BinaryWriter(stream))
+ {
+ writer.Write((ulong) TargetKind.GodotObject);
+ writer.Write((ulong) godotObject.GetInstanceId());
+
+ SerializeType(writer, @delegate.GetType());
+
+ if (!TrySerializeMethodInfo(writer, @delegate.Method))
+ return false;
+
+ buffer = stream.ToArray();
+ return true;
+ }
+ }
+ default:
+ {
+ Type targetType = target.GetType();
+
+ if (targetType.GetCustomAttribute(typeof(CompilerGeneratedAttribute), true) != null)
+ {
+ // Compiler generated. Probably a closure. Try to serialize it.
+
+ using (var stream = new MemoryStream())
+ using (var writer = new BinaryWriter(stream))
+ {
+ writer.Write((ulong) TargetKind.CompilerGenerated);
+ SerializeType(writer, targetType);
+
+ SerializeType(writer, @delegate.GetType());
+
+ if (!TrySerializeMethodInfo(writer, @delegate.Method))
+ return false;
+
+ FieldInfo[] fields = targetType.GetFields(BindingFlags.Instance | BindingFlags.Public);
+
+ writer.Write(fields.Length);
+
+ foreach (FieldInfo field in fields)
+ {
+ Type fieldType = field.GetType();
+
+ Variant.Type variantType = GD.TypeToVariantType(fieldType);
+
+ if (variantType == Variant.Type.Nil)
+ return false;
+
+ writer.Write(field.Name);
+ byte[] valueBuffer = GD.Var2Bytes(field.GetValue(target));
+ writer.Write(valueBuffer.Length);
+ writer.Write(valueBuffer);
+ }
+
+ buffer = stream.ToArray();
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+ }
+
+ private static bool TrySerializeMethodInfo(BinaryWriter writer, MethodInfo methodInfo)
+ {
+ if (methodInfo == null)
+ return false;
+
+ SerializeType(writer, methodInfo.DeclaringType);
+
+ writer.Write(methodInfo.Name);
+
+ int flags = 0;
+
+ if (methodInfo.IsPublic)
+ flags |= (int) BindingFlags.Public;
+ else
+ flags |= (int) BindingFlags.NonPublic;
+
+ if (methodInfo.IsStatic)
+ flags |= (int) BindingFlags.Static;
+ else
+ flags |= (int) BindingFlags.Instance;
+
+ writer.Write(flags);
+
+ Type returnType = methodInfo.ReturnType;
+ bool hasReturn = methodInfo.ReturnType != typeof(void);
+
+ writer.Write(hasReturn);
+ if (hasReturn)
+ SerializeType(writer, returnType);
+
+ ParameterInfo[] parameters = methodInfo.GetParameters();
+
+ writer.Write(parameters.Length);
+
+ if (parameters.Length > 0)
+ {
+ for (int i = 0; i < parameters.Length; i++)
+ SerializeType(writer, parameters[i].ParameterType);
+ }
+
+ return true;
+ }
+
+ private static void SerializeType(BinaryWriter writer, Type type)
+ {
+ if (type == null)
+ {
+ int genericArgumentsCount = -1;
+ writer.Write(genericArgumentsCount);
+ }
+ else if (type.IsGenericType)
+ {
+ Type genericTypeDef = type.GetGenericTypeDefinition();
+ Type[] genericArgs = type.GetGenericArguments();
+
+ int genericArgumentsCount = genericArgs.Length;
+ writer.Write(genericArgumentsCount);
+
+ string assemblyQualifiedName = genericTypeDef.AssemblyQualifiedName;
+ Debug.Assert(assemblyQualifiedName != null);
+ writer.Write(assemblyQualifiedName);
+
+ for (int i = 0; i < genericArgs.Length; i++)
+ SerializeType(writer, genericArgs[i]);
+ }
+ else
+ {
+ int genericArgumentsCount = 0;
+ writer.Write(genericArgumentsCount);
+
+ string assemblyQualifiedName = type.AssemblyQualifiedName;
+ Debug.Assert(assemblyQualifiedName != null);
+ writer.Write(assemblyQualifiedName);
+ }
+ }
+
+ private static bool TryDeserializeDelegate(Collections.Array serializedData, out Delegate @delegate)
+ {
+ if (serializedData.Count == 1)
+ {
+ object elem = serializedData[0];
+
+ if (elem is Collections.Array multiCastData)
+ return TryDeserializeDelegate(multiCastData, out @delegate);
+
+ return TryDeserializeSingleDelegate((byte[])elem, out @delegate);
+ }
+
+ @delegate = null;
+
+ var delegates = new List<Delegate>(serializedData.Count);
+
+ foreach (object elem in serializedData)
+ {
+ if (elem is Collections.Array multiCastData)
+ {
+ if (TryDeserializeDelegate(multiCastData, out Delegate oneDelegate))
+ delegates.Add(oneDelegate);
+ }
+ else
+ {
+ if (TryDeserializeSingleDelegate((byte[]) elem, out Delegate oneDelegate))
+ delegates.Add(oneDelegate);
+ }
+ }
+
+ if (delegates.Count <= 0)
+ return false;
+
+ @delegate = delegates.Count == 1 ? delegates[0] : Delegate.Combine(delegates.ToArray());
+ return true;
+ }
+
+ private static bool TryDeserializeSingleDelegate(byte[] buffer, out Delegate @delegate)
+ {
+ @delegate = null;
+
+ using (var stream = new MemoryStream(buffer, writable: false))
+ using (var reader = new BinaryReader(stream))
+ {
+ var targetKind = (TargetKind) reader.ReadUInt64();
+
+ switch (targetKind)
+ {
+ case TargetKind.Static:
+ {
+ Type delegateType = DeserializeType(reader);
+ if (delegateType == null)
+ return false;
+
+ if (!TryDeserializeMethodInfo(reader, out MethodInfo methodInfo))
+ return false;
+
+ @delegate = Delegate.CreateDelegate(delegateType, null, methodInfo);
+ return true;
+ }
+ case TargetKind.GodotObject:
+ {
+ ulong objectId = reader.ReadUInt64();
+ Godot.Object godotObject = GD.InstanceFromId(objectId);
+ if (godotObject == null)
+ return false;
+
+ Type delegateType = DeserializeType(reader);
+ if (delegateType == null)
+ return false;
+
+ if (!TryDeserializeMethodInfo(reader, out MethodInfo methodInfo))
+ return false;
+
+ @delegate = Delegate.CreateDelegate(delegateType, godotObject, methodInfo);
+ return true;
+ }
+ case TargetKind.CompilerGenerated:
+ {
+ Type targetType = DeserializeType(reader);
+ if (targetType == null)
+ return false;
+
+ Type delegateType = DeserializeType(reader);
+ if (delegateType == null)
+ return false;
+
+ if (!TryDeserializeMethodInfo(reader, out MethodInfo methodInfo))
+ return false;
+
+ int fieldCount = reader.ReadInt32();
+
+ object recreatedTarget = Activator.CreateInstance(targetType);
+
+ for (int i = 0; i < fieldCount; i++)
+ {
+ string name = reader.ReadString();
+ int valueBufferLength = reader.ReadInt32();
+ byte[] valueBuffer = reader.ReadBytes(valueBufferLength);
+
+ FieldInfo fieldInfo = targetType.GetField(name, BindingFlags.Instance | BindingFlags.Public);
+ fieldInfo?.SetValue(recreatedTarget, GD.Bytes2Var(valueBuffer));
+ }
+
+ @delegate = Delegate.CreateDelegate(delegateType, recreatedTarget, methodInfo);
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+ }
+
+ private static bool TryDeserializeMethodInfo(BinaryReader reader, out MethodInfo methodInfo)
+ {
+ methodInfo = null;
+
+ Type declaringType = DeserializeType(reader);
+
+ string methodName = reader.ReadString();
+
+ int flags = reader.ReadInt32();
+
+ bool hasReturn = reader.ReadBoolean();
+ Type returnType = hasReturn ? DeserializeType(reader) : typeof(void);
+
+ int parametersCount = reader.ReadInt32();
+
+ if (parametersCount > 0)
+ {
+ var parameterTypes = new Type[parametersCount];
+
+ for (int i = 0; i < parametersCount; i++)
+ {
+ Type parameterType = DeserializeType(reader);
+ if (parameterType == null)
+ return false;
+ parameterTypes[i] = parameterType;
+ }
+
+ methodInfo = declaringType.GetMethod(methodName, (BindingFlags) flags, null, parameterTypes, null);
+ return methodInfo != null && methodInfo.ReturnType == returnType;
+ }
+
+ methodInfo = declaringType.GetMethod(methodName, (BindingFlags) flags);
+ return methodInfo != null && methodInfo.ReturnType == returnType;
+ }
+
+ private static Type DeserializeType(BinaryReader reader)
+ {
+ int genericArgumentsCount = reader.ReadInt32();
+
+ if (genericArgumentsCount == -1)
+ return null;
+
+ string assemblyQualifiedName = reader.ReadString();
+ var type = Type.GetType(assemblyQualifiedName);
+
+ if (type == null)
+ return null; // Type not found
+
+ if (genericArgumentsCount != 0)
+ {
+ var genericArgumentTypes = new Type[genericArgumentsCount];
+
+ for (int i = 0; i < genericArgumentsCount; i++)
+ {
+ Type genericArgumentType = DeserializeType(reader);
+ if (genericArgumentType == null)
+ return null;
+ genericArgumentTypes[i] = genericArgumentType;
+ }
+
+ type = type.MakeGenericType(genericArgumentTypes);
+ }
+
+ return type;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index d72109de92..213fc181c1 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -15,10 +15,7 @@ namespace Godot.Collections
public override bool IsInvalid
{
- get
- {
- return handle == IntPtr.Zero;
- }
+ get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
@@ -45,7 +42,8 @@ namespace Godot.Collections
if (dictionary == null)
throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'");
- MarshalUtils.IDictionaryToDictionary(dictionary, GetPtr());
+ foreach (DictionaryEntry entry in dictionary)
+ Add(entry.Key, entry.Value);
}
internal Dictionary(DictionarySafeHandle handle)
@@ -330,14 +328,8 @@ namespace Godot.Collections
public TValue this[TKey key]
{
- get
- {
- return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass);
- }
- set
- {
- objectDict[key] = value;
- }
+ get { return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); }
+ set { objectDict[key] = value; }
}
public ICollection<TKey> Keys
@@ -385,18 +377,12 @@ namespace Godot.Collections
public int Count
{
- get
- {
- return objectDict.Count;
- }
+ get { return objectDict.Count; }
}
public bool IsReadOnly
{
- get
- {
- return objectDict.IsReadOnly;
- }
+ get { return objectDict.IsReadOnly; }
}
public void Add(KeyValuePair<TKey, TValue> item)
@@ -440,7 +426,8 @@ namespace Godot.Collections
public bool Remove(KeyValuePair<TKey, TValue> item)
{
- return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); ;
+ return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value);
+ ;
}
// IEnumerable<KeyValuePair<TKey, TValue>>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs
index a0f105d55e..c4c911b863 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DynamicObject.cs
@@ -23,7 +23,7 @@ namespace Godot
/// <example>
/// This sample shows how to use <see cref="Godot.DynamicGodotObject"/> to dynamically access the engine members of a <see cref="Godot.Object"/>.
/// <code>
- /// dynamic sprite = GetNode("Sprite").DynamicGodotObject;
+ /// dynamic sprite = GetNode("Sprite2D").DynamicGodotObject;
/// sprite.add_child(this);
///
/// if ((sprite.hframes * sprite.vframes) &gt; 0)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
index 684d160b57..5f64c09a89 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
@@ -2,9 +2,9 @@ namespace Godot
{
public static partial class ResourceLoader
{
- public static T Load<T>(string path) where T : class
+ public static T Load<T>(string path, string typeHint = null, bool noCache = false) where T : class
{
- return (T)(object)Load(path);
+ return (T)(object)Load(path, typeHint, noCache);
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 19962d418a..9384da0e48 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -5,6 +5,7 @@ using System.Runtime.CompilerServices;
using real_t = System.Double;
#else
using real_t = System.Single;
+
#endif
// TODO: Add comments describing what this class does. It is not obvious.
@@ -13,9 +14,9 @@ namespace Godot
{
public static partial class GD
{
- public static object Bytes2Var(byte[] bytes, bool allow_objects = false)
+ public static object Bytes2Var(byte[] bytes, bool allowObjects = false)
{
- return godot_icall_GD_bytes2var(bytes, allow_objects);
+ return godot_icall_GD_bytes2var(bytes, allowObjects);
}
public static object Convert(object what, Variant.Type type)
@@ -25,7 +26,7 @@ namespace Godot
public static real_t Db2Linear(real_t db)
{
- return (real_t)Math.Exp(db * 0.11512925464970228420089957273422);
+ return (real_t) Math.Exp(db * 0.11512925464970228420089957273422);
}
public static real_t DecTime(real_t value, real_t amount, real_t step)
@@ -38,11 +39,11 @@ namespace Godot
return val * sgn;
}
- public static FuncRef FuncRef(Object instance, string funcname)
+ public static FuncRef FuncRef(Object instance, StringName funcName)
{
var ret = new FuncRef();
ret.SetInstance(instance);
- ret.SetFunction(funcname);
+ ret.SetFunction(funcName);
return ret;
}
@@ -58,7 +59,7 @@ namespace Godot
public static real_t Linear2Db(real_t linear)
{
- return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321);
+ return (real_t) (Math.Log(linear) * 8.6858896380650365530225783783321);
}
public static Resource Load(string path)
@@ -83,7 +84,7 @@ namespace Godot
public static void Print(params object[] what)
{
- godot_icall_GD_print(Array.ConvertAll(what, x => x.ToString()));
+ godot_icall_GD_print(Array.ConvertAll(what, x => x?.ToString()));
}
public static void PrintStack()
@@ -181,14 +182,14 @@ namespace Godot
return godot_icall_GD_str2var(str);
}
- public static bool TypeExists(string type)
+ public static bool TypeExists(StringName type)
{
- return godot_icall_GD_type_exists(type);
+ return godot_icall_GD_type_exists(StringName.GetPtr(type));
}
- public static byte[] Var2Bytes(object var, bool full_objects = false)
+ public static byte[] Var2Bytes(object var, bool fullObjects = false)
{
- return godot_icall_GD_var2bytes(var, full_objects);
+ return godot_icall_GD_var2bytes(var, fullObjects);
}
public static string Var2Str(object var)
@@ -196,8 +197,13 @@ namespace Godot
return godot_icall_GD_var2str(var);
}
+ public static Variant.Type TypeToVariantType(Type type)
+ {
+ return godot_icall_TypeToVariantType(type);
+ }
+
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_GD_bytes2var(byte[] bytes, bool allow_objects);
+ internal extern static object godot_icall_GD_bytes2var(byte[] bytes, bool allowObjects);
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static object godot_icall_GD_convert(object what, Variant.Type type);
@@ -206,7 +212,7 @@ namespace Godot
internal extern static int godot_icall_GD_hash(object var);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static Object godot_icall_GD_instance_from_id(ulong instance_id);
+ internal extern static Object godot_icall_GD_instance_from_id(ulong instanceId);
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_GD_print(object[] what);
@@ -249,10 +255,10 @@ namespace Godot
internal extern static object godot_icall_GD_str2var(string str);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_GD_type_exists(string type);
+ internal extern static bool godot_icall_GD_type_exists(IntPtr type);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static byte[] godot_icall_GD_var2bytes(object what, bool full_objects);
+ internal extern static byte[] godot_icall_GD_var2bytes(object what, bool fullObjects);
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static string godot_icall_GD_var2str(object var);
@@ -262,5 +268,8 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_GD_pushwarning(string type);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern Variant.Type godot_icall_TypeToVariantType(Type type);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
index a1d63a62ef..c59d083080 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
@@ -16,10 +16,8 @@ namespace Godot
/// <exception cref="System.InvalidOperationException">
/// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
/// </exception>
- static bool TypeIsGenericArray(Type type)
- {
- return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>);
- }
+ static bool TypeIsGenericArray(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>);
/// <summary>
/// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
@@ -28,10 +26,20 @@ namespace Godot
/// <exception cref="System.InvalidOperationException">
/// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
/// </exception>
- static bool TypeIsGenericDictionary(Type type)
- {
- return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>);
- }
+ static bool TypeIsGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>);
+
+ static bool TypeIsSystemGenericList(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>);
+
+ static bool TypeIsSystemGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.Dictionary<,>);
+
+ static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
+
+ static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>);
+
+ static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
static void ArrayGetElementType(Type arrayType, out Type elementType)
{
@@ -45,105 +53,6 @@ namespace Godot
valueType = genericArgs[1];
}
- static bool GenericIEnumerableIsAssignableFromType(Type type)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- return true;
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- return true;
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- return false;
-
- return GenericIEnumerableIsAssignableFromType(baseType);
- }
-
- static bool GenericIDictionaryIsAssignableFromType(Type type)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- return true;
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- return true;
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- return false;
-
- return GenericIDictionaryIsAssignableFromType(baseType);
- }
-
- static bool GenericIEnumerableIsAssignableFromType(Type type, out Type elementType)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- {
- elementType = type.GetGenericArguments()[0];
- return true;
- }
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- {
- elementType = interfaceType.GetGenericArguments()[0];
- return true;
- }
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- {
- elementType = null;
- return false;
- }
-
- return GenericIEnumerableIsAssignableFromType(baseType, out elementType);
- }
-
- static bool GenericIDictionaryIsAssignableFromType(Type type, out Type keyType, out Type valueType)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- {
- var genericArgs = type.GetGenericArguments();
- keyType = genericArgs[0];
- valueType = genericArgs[1];
- return true;
- }
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- {
- var genericArgs = interfaceType.GetGenericArguments();
- keyType = genericArgs[0];
- valueType = genericArgs[1];
- return true;
- }
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- {
- keyType = null;
- valueType = null;
- return false;
- }
-
- return GenericIDictionaryIsAssignableFromType(baseType, out keyType, out valueType);
- }
-
static Type MakeGenericArrayType(Type elemType)
{
return typeof(Godot.Collections.Array<>).MakeGenericType(elemType);
@@ -153,60 +62,5 @@ namespace Godot
{
return typeof(Godot.Collections.Dictionary<,>).MakeGenericType(keyType, valueType);
}
-
- // TODO Add support for IEnumerable<T> and IDictionary<TKey, TValue>
- // TODO: EnumerableToArray and IDictionaryToDictionary can be optimized
-
- internal static void EnumerableToArray(IEnumerable enumerable, IntPtr godotArrayPtr)
- {
- if (enumerable is ICollection collection)
- {
- int count = collection.Count;
-
- object[] tempArray = new object[count];
- collection.CopyTo(tempArray, 0);
-
- for (int i = 0; i < count; i++)
- {
- Array.godot_icall_Array_Add(godotArrayPtr, tempArray[i]);
- }
- }
- else
- {
- foreach (object element in enumerable)
- {
- Array.godot_icall_Array_Add(godotArrayPtr, element);
- }
- }
- }
-
- internal static void IDictionaryToDictionary(IDictionary dictionary, IntPtr godotDictionaryPtr)
- {
- foreach (DictionaryEntry entry in dictionary)
- {
- Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, entry.Key, entry.Value);
- }
- }
-
- internal static void GenericIDictionaryToDictionary(object dictionary, IntPtr godotDictionaryPtr)
- {
-#if DEBUG
- if (!GenericIDictionaryIsAssignableFromType(dictionary.GetType()))
- throw new InvalidOperationException("The type does not implement IDictionary<,>");
-#endif
-
- // TODO: Can we optimize this?
-
- var keys = ((IEnumerable)dictionary.GetType().GetProperty("Keys").GetValue(dictionary)).GetEnumerator();
- var values = ((IEnumerable)dictionary.GetType().GetProperty("Values").GetValue(dictionary)).GetEnumerator();
-
- while (keys.MoveNext() && values.MoveNext())
- {
- object key = keys.Current;
- object value = values.Current;
-
- Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, key, value);
- }
- }
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index ddfed180b5..4f7aa99df8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -130,7 +130,7 @@ namespace Godot
public static real_t InverseLerp(real_t from, real_t to, real_t weight)
{
- return (weight - from) / (to - from);
+ return (weight - from) / (to - from);
}
public static bool IsEqualApprox(real_t a, real_t b)
@@ -151,12 +151,12 @@ namespace Godot
public static bool IsInf(real_t s)
{
- return real_t.IsInfinity(s);
+ return real_t.IsInfinity(s);
}
public static bool IsNaN(real_t s)
{
- return real_t.IsNaN(s);
+ return real_t.IsNaN(s);
}
public static bool IsZeroApprox(real_t s)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
index 8c5872ba5a..4ecc55f94e 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
@@ -7,7 +7,7 @@ namespace Godot
{
private bool disposed = false;
- internal IntPtr ptr;
+ private IntPtr ptr;
internal static IntPtr GetPtr(NodePath instance)
{
@@ -50,104 +50,93 @@ namespace Godot
this.ptr = ptr;
}
- public IntPtr NativeInstance
- {
- get { return ptr; }
- }
-
public NodePath() : this(string.Empty) {}
public NodePath(string path)
{
- this.ptr = godot_icall_NodePath_Ctor(path);
+ ptr = godot_icall_NodePath_Ctor(path);
}
- public static implicit operator NodePath(string from)
- {
- return new NodePath(from);
- }
+ public static implicit operator NodePath(string from) => new NodePath(from);
- public static implicit operator string(NodePath from)
- {
- return godot_icall_NodePath_operator_String(NodePath.GetPtr(from));
- }
+ public static implicit operator string(NodePath from) => from.ToString();
public override string ToString()
{
- return (string)this;
+ return godot_icall_NodePath_operator_String(GetPtr(this));
}
public NodePath GetAsPropertyPath()
{
- return new NodePath(godot_icall_NodePath_get_as_property_path(NodePath.GetPtr(this)));
+ return new NodePath(godot_icall_NodePath_get_as_property_path(GetPtr(this)));
}
public string GetConcatenatedSubnames()
{
- return godot_icall_NodePath_get_concatenated_subnames(NodePath.GetPtr(this));
+ return godot_icall_NodePath_get_concatenated_subnames(GetPtr(this));
}
public string GetName(int idx)
{
- return godot_icall_NodePath_get_name(NodePath.GetPtr(this), idx);
+ return godot_icall_NodePath_get_name(GetPtr(this), idx);
}
public int GetNameCount()
{
- return godot_icall_NodePath_get_name_count(NodePath.GetPtr(this));
+ return godot_icall_NodePath_get_name_count(GetPtr(this));
}
public string GetSubname(int idx)
{
- return godot_icall_NodePath_get_subname(NodePath.GetPtr(this), idx);
+ return godot_icall_NodePath_get_subname(GetPtr(this), idx);
}
public int GetSubnameCount()
{
- return godot_icall_NodePath_get_subname_count(NodePath.GetPtr(this));
+ return godot_icall_NodePath_get_subname_count(GetPtr(this));
}
public bool IsAbsolute()
{
- return godot_icall_NodePath_is_absolute(NodePath.GetPtr(this));
+ return godot_icall_NodePath_is_absolute(GetPtr(this));
}
public bool IsEmpty()
{
- return godot_icall_NodePath_is_empty(NodePath.GetPtr(this));
+ return godot_icall_NodePath_is_empty(GetPtr(this));
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_NodePath_Ctor(string path);
+ private static extern IntPtr godot_icall_NodePath_Ctor(string path);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_NodePath_Dtor(IntPtr ptr);
+ private static extern void godot_icall_NodePath_Dtor(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_NodePath_operator_String(IntPtr ptr);
+ private static extern string godot_icall_NodePath_operator_String(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_NodePath_get_as_property_path(IntPtr ptr);
+ private static extern IntPtr godot_icall_NodePath_get_as_property_path(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_NodePath_get_concatenated_subnames(IntPtr ptr);
+ private static extern string godot_icall_NodePath_get_concatenated_subnames(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_NodePath_get_name(IntPtr ptr, int arg1);
+ private static extern string godot_icall_NodePath_get_name(IntPtr ptr, int arg1);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_NodePath_get_name_count(IntPtr ptr);
+ private static extern int godot_icall_NodePath_get_name_count(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_NodePath_get_subname(IntPtr ptr, int arg1);
+ private static extern string godot_icall_NodePath_get_subname(IntPtr ptr, int arg1);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_NodePath_get_subname_count(IntPtr ptr);
+ private static extern int godot_icall_NodePath_get_subname_count(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_NodePath_is_absolute(IntPtr ptr);
+ private static extern bool godot_icall_NodePath_is_absolute(IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_NodePath_is_empty(IntPtr ptr);
+ private static extern bool godot_icall_NodePath_is_empty(IntPtr ptr);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
index de80f7fddc..42610c5ef7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
@@ -7,7 +7,7 @@ namespace Godot
{
private bool disposed = false;
- private const string nativeName = "Object";
+ private static StringName nativeName = "Object";
internal IntPtr ptr;
internal bool memoryOwn;
@@ -15,7 +15,14 @@ namespace Godot
public Object() : this(false)
{
if (ptr == IntPtr.Zero)
+ {
ptr = godot_icall_Object_Ctor(this);
+ }
+ else
+ {
+ // This is called inside godot_icall_Object_Ctor, so we must call it as well in this case.
+ godot_icall_Object_ConnectEventSignals(ptr);
+ }
}
internal Object(bool memoryOwn)
@@ -101,7 +108,7 @@ namespace Godot
/// }
/// </code>
/// </example>
- public SignalAwaiter ToSignal(Object source, string signal)
+ public SignalAwaiter ToSignal(Object source, StringName signal)
{
return new SignalAwaiter(source, signal, this);
}
@@ -111,20 +118,28 @@ namespace Godot
/// </summary>
public dynamic DynamicObject => new DynamicGodotObject(this);
+ internal static IntPtr __ClassDB_get_method(StringName type, string method)
+ {
+ return godot_icall_Object_ClassDB_get_method(StringName.GetPtr(type), method);
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern IntPtr godot_icall_Object_Ctor(Object obj);
+
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Object_Ctor(Object obj);
+ internal static extern void godot_icall_Object_Disposed(Object obj, IntPtr ptr);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Object_Disposed(Object obj, IntPtr ptr);
+ internal static extern void godot_icall_Reference_Disposed(Object obj, IntPtr ptr, bool isFinalizer);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Reference_Disposed(Object obj, IntPtr ptr, bool isFinalizer);
+ internal static extern void godot_icall_Object_ConnectEventSignals(IntPtr obj);
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static string godot_icall_Object_ToString(IntPtr ptr);
+ internal static extern string godot_icall_Object_ToString(IntPtr ptr);
// Used by the generated API
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Object_ClassDB_get_method(string type, string method);
+ internal static extern IntPtr godot_icall_Object_ClassDB_get_method(IntPtr type, string method);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs
index 6702634c51..bbc617ea6e 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs
@@ -104,33 +104,6 @@ namespace Godot
return this / Length;
}
- [Obsolete("Set is deprecated. Use the Quat(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
- public void Set(real_t x, real_t y, real_t z, real_t w)
- {
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- }
-
- [Obsolete("Set is deprecated. Use the Quat(" + nameof(Quat) + ") constructor instead.", error: true)]
- public void Set(Quat q)
- {
- this = q;
- }
-
- [Obsolete("SetAxisAngle is deprecated. Use the Quat(" + nameof(Vector3) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
- public void SetAxisAngle(Vector3 axis, real_t angle)
- {
- this = new Quat(axis, angle);
- }
-
- [Obsolete("SetEuler is deprecated. Use the Quat(" + nameof(Vector3) + ") constructor instead.", error: true)]
- public void SetEuler(Vector3 eulerYXZ)
- {
- this = new Quat(eulerYXZ);
- }
-
public Quat Slerp(Quat b, real_t t)
{
#if DEBUG
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
new file mode 100644
index 0000000000..bc2cad8713
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
@@ -0,0 +1,262 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Godot
+{
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Rect2i : IEquatable<Rect2i>
+ {
+ private Vector2i _position;
+ private Vector2i _size;
+
+ public Vector2i Position
+ {
+ get { return _position; }
+ set { _position = value; }
+ }
+
+ public Vector2i Size
+ {
+ get { return _size; }
+ set { _size = value; }
+ }
+
+ public Vector2i End
+ {
+ get { return _position + _size; }
+ set { _size = value - _position; }
+ }
+
+ public int Area
+ {
+ get { return GetArea(); }
+ }
+
+ public Rect2i Abs()
+ {
+ Vector2i end = End;
+ Vector2i topLeft = new Vector2i(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y));
+ return new Rect2i(topLeft, _size.Abs());
+ }
+
+ public Rect2i Clip(Rect2i b)
+ {
+ var newRect = b;
+
+ if (!Intersects(newRect))
+ return new Rect2i();
+
+ newRect._position.x = Mathf.Max(b._position.x, _position.x);
+ newRect._position.y = Mathf.Max(b._position.y, _position.y);
+
+ Vector2i bEnd = b._position + b._size;
+ Vector2i end = _position + _size;
+
+ newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x;
+ newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y;
+
+ return newRect;
+ }
+
+ public bool Encloses(Rect2i b)
+ {
+ return b._position.x >= _position.x && b._position.y >= _position.y &&
+ b._position.x + b._size.x < _position.x + _size.x &&
+ b._position.y + b._size.y < _position.y + _size.y;
+ }
+
+ public Rect2i Expand(Vector2i to)
+ {
+ var expanded = this;
+
+ Vector2i begin = expanded._position;
+ Vector2i end = expanded._position + expanded._size;
+
+ if (to.x < begin.x)
+ begin.x = to.x;
+ if (to.y < begin.y)
+ begin.y = to.y;
+
+ if (to.x > end.x)
+ end.x = to.x;
+ if (to.y > end.y)
+ end.y = to.y;
+
+ expanded._position = begin;
+ expanded._size = end - begin;
+
+ return expanded;
+ }
+
+ public int GetArea()
+ {
+ return _size.x * _size.y;
+ }
+
+ public Rect2i Grow(int by)
+ {
+ var g = this;
+
+ g._position.x -= by;
+ g._position.y -= by;
+ g._size.x += by * 2;
+ g._size.y += by * 2;
+
+ return g;
+ }
+
+ public Rect2i GrowIndividual(int left, int top, int right, int bottom)
+ {
+ var g = this;
+
+ g._position.x -= left;
+ g._position.y -= top;
+ g._size.x += left + right;
+ g._size.y += top + bottom;
+
+ return g;
+ }
+
+ public Rect2i GrowMargin(Margin margin, int by)
+ {
+ var g = this;
+
+ g.GrowIndividual(Margin.Left == margin ? by : 0,
+ Margin.Top == margin ? by : 0,
+ Margin.Right == margin ? by : 0,
+ Margin.Bottom == margin ? by : 0);
+
+ return g;
+ }
+
+ public bool HasNoArea()
+ {
+ return _size.x <= 0 || _size.y <= 0;
+ }
+
+ public bool HasPoint(Vector2i point)
+ {
+ if (point.x < _position.x)
+ return false;
+ if (point.y < _position.y)
+ return false;
+
+ if (point.x >= _position.x + _size.x)
+ return false;
+ if (point.y >= _position.y + _size.y)
+ return false;
+
+ return true;
+ }
+
+ public bool Intersects(Rect2i b)
+ {
+ if (_position.x >= b._position.x + b._size.x)
+ return false;
+ if (_position.x + _size.x <= b._position.x)
+ return false;
+ if (_position.y >= b._position.y + b._size.y)
+ return false;
+ if (_position.y + _size.y <= b._position.y)
+ return false;
+
+ return true;
+ }
+
+ public Rect2i Merge(Rect2i b)
+ {
+ Rect2i newRect;
+
+ newRect._position.x = Mathf.Min(b._position.x, _position.x);
+ newRect._position.y = Mathf.Min(b._position.y, _position.y);
+
+ newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x);
+ newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y);
+
+ newRect._size = newRect._size - newRect._position; // Make relative again
+
+ return newRect;
+ }
+
+ // Constructors
+ public Rect2i(Vector2i position, Vector2i size)
+ {
+ _position = position;
+ _size = size;
+ }
+ public Rect2i(Vector2i position, int width, int height)
+ {
+ _position = position;
+ _size = new Vector2i(width, height);
+ }
+ public Rect2i(int x, int y, Vector2i size)
+ {
+ _position = new Vector2i(x, y);
+ _size = size;
+ }
+ public Rect2i(int x, int y, int width, int height)
+ {
+ _position = new Vector2i(x, y);
+ _size = new Vector2i(width, height);
+ }
+
+ public static bool operator ==(Rect2i left, Rect2i right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Rect2i left, Rect2i right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static implicit operator Rect2(Rect2i value)
+ {
+ return new Rect2(value._position, value._size);
+ }
+
+ public static explicit operator Rect2i(Rect2 value)
+ {
+ return new Rect2i((Vector2i)value.Position, (Vector2i)value.Size);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Rect2i)
+ {
+ return Equals((Rect2i)obj);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Rect2i other)
+ {
+ return _position.Equals(other._position) && _size.Equals(other._size);
+ }
+
+ public override int GetHashCode()
+ {
+ return _position.GetHashCode() ^ _size.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0}, {1}", new object[]
+ {
+ _position.ToString(),
+ _size.ToString()
+ });
+ }
+
+ public string ToString(string format)
+ {
+ return String.Format("{0}, {1}", new object[]
+ {
+ _position.ToString(format),
+ _size.ToString(format)
+ });
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
index 9483b6ffb4..4dc630238b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
@@ -9,13 +9,13 @@ namespace Godot
private object[] result;
private Action action;
- public SignalAwaiter(Object source, string signal, Object target)
+ public SignalAwaiter(Object source, StringName signal, Object target)
{
- godot_icall_SignalAwaiter_connect(Object.GetPtr(source), signal, Object.GetPtr(target), this);
+ godot_icall_SignalAwaiter_connect(Object.GetPtr(source), StringName.GetPtr(signal), Object.GetPtr(target), this);
}
[MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static Error godot_icall_SignalAwaiter_connect(IntPtr source, string signal, IntPtr target, SignalAwaiter awaiter);
+ internal extern static Error godot_icall_SignalAwaiter_connect(IntPtr source, IntPtr signal, IntPtr target, SignalAwaiter awaiter);
public bool IsCompleted
{
@@ -50,11 +50,5 @@ namespace Godot
action();
}
}
-
- internal void FailureCallback()
- {
- action = null;
- completed = true;
- }
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
new file mode 100644
index 0000000000..dc92de7a61
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
@@ -0,0 +1,17 @@
+namespace Godot
+{
+ public struct SignalInfo
+ {
+ private readonly Object _owner;
+ private readonly StringName _signalName;
+
+ public Object Owner => _owner;
+ public StringName Name => _signalName;
+
+ public SignalInfo(Object owner, StringName name)
+ {
+ _owner = owner;
+ _signalName = name;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index b926037e5a..099eacd7dd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -264,7 +264,8 @@ namespace Godot
instanceIndex++;
toIndex++;
}
- } else
+ }
+ else
{
while (true)
{
@@ -474,7 +475,7 @@ namespace Godot
int source = 0;
int target = 0;
- while (instance[source] != 0 && text[target] != 0)
+ while (source < len && target < text.Length)
{
bool match;
@@ -491,7 +492,7 @@ namespace Godot
if (match)
{
source++;
- if (instance[source] == 0)
+ if (source >= len)
return true;
}
@@ -980,7 +981,7 @@ namespace Godot
}
// <summary>
- // Convert the String (which is a character array) to PoolByteArray (which is an array of bytes). The conversion is speeded up in comparison to to_utf8() with the assumption that all the characters the String contains are only ASCII characters.
+ // Convert the String (which is a character array) to PackedByteArray (which is an array of bytes). The conversion is speeded up in comparison to to_utf8() with the assumption that all the characters the String contains are only ASCII characters.
// </summary>
public static byte[] ToAscii(this string instance)
{
@@ -1020,7 +1021,7 @@ namespace Godot
}
// <summary>
- // Convert the String (which is an array of characters) to PoolByteArray (which is an array of bytes). The conversion is a bit slower than to_ascii(), but supports all UTF-8 characters. Therefore, you should prefer this function over to_ascii().
+ // Convert the String (which is an array of characters) to PackedByteArray (which is an array of bytes). The conversion is a bit slower than to_ascii(), but supports all UTF-8 characters. Therefore, you should prefer this function over to_ascii().
// </summary>
public static byte[] ToUTF8(this string instance)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
new file mode 100644
index 0000000000..7700b6d4ed
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Godot
+{
+ public sealed partial class StringName : IDisposable
+ {
+ private IntPtr ptr;
+
+ internal static IntPtr GetPtr(StringName instance)
+ {
+ if (instance == null)
+ throw new NullReferenceException($"The instance of type {nameof(StringName)} is null.");
+
+ if (instance.ptr == IntPtr.Zero)
+ throw new ObjectDisposedException(instance.GetType().FullName);
+
+ return instance.ptr;
+ }
+
+ ~StringName()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (ptr != IntPtr.Zero)
+ {
+ godot_icall_StringName_Dtor(ptr);
+ ptr = IntPtr.Zero;
+ }
+ }
+
+ internal StringName(IntPtr ptr)
+ {
+ this.ptr = ptr;
+ }
+
+ public StringName()
+ {
+ ptr = IntPtr.Zero;
+ }
+
+ public StringName(string path)
+ {
+ ptr = path == null ? IntPtr.Zero : godot_icall_StringName_Ctor(path);
+ }
+
+ public static implicit operator StringName(string from) => new StringName(from);
+
+ public static implicit operator string(StringName from) => from.ToString();
+
+ public override string ToString()
+ {
+ return ptr == IntPtr.Zero ? string.Empty : godot_icall_StringName_operator_String(GetPtr(this));
+ }
+
+ public bool IsEmpty()
+ {
+ return ptr == IntPtr.Zero || godot_icall_StringName_is_empty(GetPtr(this));
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern IntPtr godot_icall_StringName_Ctor(string path);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void godot_icall_StringName_Dtor(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern string godot_icall_StringName_operator_String(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern bool godot_icall_StringName_is_empty(IntPtr ptr);
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs
index 0b84050f07..aa8815d1aa 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs
@@ -15,6 +15,76 @@ namespace Godot
public Basis basis;
public Vector3 origin;
+ /// <summary>
+ /// Access whole columns in the form of Vector3. The fourth column is the origin vector.
+ /// </summary>
+ /// <param name="column">Which column vector.</param>
+ public Vector3 this[int column]
+ {
+ get
+ {
+ switch (column)
+ {
+ case 0:
+ return basis.Column0;
+ case 1:
+ return basis.Column1;
+ case 2:
+ return basis.Column2;
+ case 3:
+ return origin;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ set
+ {
+ switch (column)
+ {
+ case 0:
+ basis.Column0 = value;
+ return;
+ case 1:
+ basis.Column1 = value;
+ return;
+ case 2:
+ basis.Column2 = value;
+ return;
+ case 3:
+ origin = value;
+ return;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Access matrix elements in column-major order. The fourth column is the origin vector.
+ /// </summary>
+ /// <param name="column">Which column, the matrix horizontal position.</param>
+ /// <param name="row">Which row, the matrix vertical position.</param>
+ public real_t this[int column, int row]
+ {
+ get
+ {
+ if (column == 3)
+ {
+ return origin[row];
+ }
+ return basis[column, row];
+ }
+ set
+ {
+ if (column == 3)
+ {
+ origin[row] = value;
+ return;
+ }
+ basis[column, row] = value;
+ }
+ }
+
public Transform AffineInverse()
{
Basis basisInv = basis.Inverse();
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index 77ea3e5830..e72a44809a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -54,11 +54,15 @@ namespace Godot
}
}
- public Vector2 this[int rowIndex]
+ /// <summary>
+ /// Access whole columns in the form of Vector2. The third column is the origin vector.
+ /// </summary>
+ /// <param name="column">Which column vector.</param>
+ public Vector2 this[int column]
{
get
{
- switch (rowIndex)
+ switch (column)
{
case 0:
return x;
@@ -72,7 +76,7 @@ namespace Godot
}
set
{
- switch (rowIndex)
+ switch (column)
{
case 0:
x = value;
@@ -89,38 +93,22 @@ namespace Godot
}
}
- public real_t this[int rowIndex, int columnIndex]
+ /// <summary>
+ /// Access matrix elements in column-major order. The third column is the origin vector.
+ /// </summary>
+ /// <param name="column">Which column, the matrix horizontal position.</param>
+ /// <param name="row">Which row, the matrix vertical position.</param>
+ public real_t this[int column, int row]
{
get
{
- switch (rowIndex)
- {
- case 0:
- return x[columnIndex];
- case 1:
- return y[columnIndex];
- case 2:
- return origin[columnIndex];
- default:
- throw new IndexOutOfRangeException();
- }
+ return this[column][row];
}
set
{
- switch (rowIndex)
- {
- case 0:
- x[columnIndex] = value;
- return;
- case 1:
- y[columnIndex] = value;
- return;
- case 2:
- origin[columnIndex] = value;
- return;
- default:
- throw new IndexOutOfRangeException();
- }
+ Vector2 columnVector = this[column];
+ columnVector[row] = value;
+ this[column] = columnVector;
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index f92453f546..f7b13198f8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -76,11 +76,6 @@ namespace Godot
}
}
- public real_t Cross(Vector2 b)
- {
- return x * b.y - y * b.x;
- }
-
public Vector2 Abs()
{
return new Vector2(Mathf.Abs(x), Mathf.Abs(y));
@@ -130,6 +125,11 @@ namespace Godot
return v;
}
+ public real_t Cross(Vector2 b)
+ {
+ return x * b.y - y * b.x;
+ }
+
public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t t)
{
var p0 = preA;
@@ -234,7 +234,7 @@ namespace Godot
public Vector2 Reflect(Vector2 n)
{
- return 2.0f * n * Dot(n) - this;
+ return 2 * Dot(n) * n - this;
}
public Vector2 Rotated(real_t phi)
@@ -248,19 +248,6 @@ namespace Godot
return new Vector2(Mathf.Round(x), Mathf.Round(y));
}
- [Obsolete("Set is deprecated. Use the Vector2(" + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
- public void Set(real_t x, real_t y)
- {
- this.x = x;
- this.y = y;
- }
- [Obsolete("Set is deprecated. Use the Vector2(" + nameof(Vector2) + ") constructor instead.", error: true)]
- public void Set(Vector2 v)
- {
- x = v.x;
- y = v.y;
- }
-
public Vector2 Sign()
{
Vector2 v;
@@ -365,18 +352,18 @@ namespace Godot
return left;
}
- public static Vector2 operator /(Vector2 vec, real_t scale)
+ public static Vector2 operator /(Vector2 vec, real_t divisor)
{
- vec.x /= scale;
- vec.y /= scale;
+ vec.x /= divisor;
+ vec.y /= divisor;
return vec;
}
- public static Vector2 operator /(Vector2 left, Vector2 right)
+ public static Vector2 operator /(Vector2 vec, Vector2 divisorv)
{
- left.x /= right.x;
- left.y /= right.y;
- return left;
+ vec.x /= divisorv.x;
+ vec.y /= divisorv.y;
+ return vec;
}
public static Vector2 operator %(Vector2 vec, real_t divisor)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
new file mode 100644
index 0000000000..7dc22d7918
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -0,0 +1,380 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+namespace Godot
+{
+ /// <summary>
+ /// 2-element structure that can be used to represent 2D grid coordinates or pairs of integers.
+ /// </summary>
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Vector2i : IEquatable<Vector2i>
+ {
+ public enum Axis
+ {
+ X = 0,
+ Y
+ }
+
+ public int x;
+ public int y;
+
+ public int this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return x;
+ case 1:
+ return y;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ set
+ {
+ switch (index)
+ {
+ case 0:
+ x = value;
+ return;
+ case 1:
+ y = value;
+ return;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+
+ public Vector2i Abs()
+ {
+ return new Vector2i(Mathf.Abs(x), Mathf.Abs(y));
+ }
+
+ public real_t Angle()
+ {
+ return Mathf.Atan2(y, x);
+ }
+
+ public real_t AngleTo(Vector2i to)
+ {
+ return Mathf.Atan2(Cross(to), Dot(to));
+ }
+
+ public real_t AngleToPoint(Vector2i to)
+ {
+ return Mathf.Atan2(y - to.y, x - to.x);
+ }
+
+ public real_t Aspect()
+ {
+ return x / (real_t)y;
+ }
+
+ public Vector2i Bounce(Vector2i n)
+ {
+ return -Reflect(n);
+ }
+
+ public int Cross(Vector2i b)
+ {
+ return x * b.y - y * b.x;
+ }
+
+ public int DistanceSquaredTo(Vector2i b)
+ {
+ return (b - this).LengthSquared();
+ }
+
+ public real_t DistanceTo(Vector2i b)
+ {
+ return (b - this).Length();
+ }
+
+ public int Dot(Vector2i b)
+ {
+ return x * b.x + y * b.y;
+ }
+
+ public real_t Length()
+ {
+ int x2 = x * x;
+ int y2 = y * y;
+
+ return Mathf.Sqrt(x2 + y2);
+ }
+
+ public int LengthSquared()
+ {
+ int x2 = x * x;
+ int y2 = y * y;
+
+ return x2 + y2;
+ }
+
+ public Axis MaxAxis()
+ {
+ return x < y ? Axis.Y : Axis.X;
+ }
+
+ public Axis MinAxis()
+ {
+ return x > y ? Axis.Y : Axis.X;
+ }
+
+ public Vector2i PosMod(int mod)
+ {
+ Vector2i v = this;
+ v.x = Mathf.PosMod(v.x, mod);
+ v.y = Mathf.PosMod(v.y, mod);
+ return v;
+ }
+
+ public Vector2i PosMod(Vector2i modv)
+ {
+ Vector2i v = this;
+ v.x = Mathf.PosMod(v.x, modv.x);
+ v.y = Mathf.PosMod(v.y, modv.y);
+ return v;
+ }
+
+ public Vector2i Reflect(Vector2i n)
+ {
+ return 2 * Dot(n) * n - this;
+ }
+
+ public Vector2i Sign()
+ {
+ Vector2i v = this;
+ v.x = Mathf.Sign(v.x);
+ v.y = Mathf.Sign(v.y);
+ return v;
+ }
+
+ public Vector2i Tangent()
+ {
+ return new Vector2i(y, -x);
+ }
+
+ // Constants
+ private static readonly Vector2i _zero = new Vector2i(0, 0);
+ private static readonly Vector2i _one = new Vector2i(1, 1);
+
+ private static readonly Vector2i _up = new Vector2i(0, -1);
+ private static readonly Vector2i _down = new Vector2i(0, 1);
+ private static readonly Vector2i _right = new Vector2i(1, 0);
+ private static readonly Vector2i _left = new Vector2i(-1, 0);
+
+ public static Vector2i Zero { get { return _zero; } }
+ public static Vector2i One { get { return _one; } }
+
+ public static Vector2i Up { get { return _up; } }
+ public static Vector2i Down { get { return _down; } }
+ public static Vector2i Right { get { return _right; } }
+ public static Vector2i Left { get { return _left; } }
+
+ // Constructors
+ public Vector2i(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+ public Vector2i(Vector2i vi)
+ {
+ this.x = vi.x;
+ this.y = vi.y;
+ }
+ public Vector2i(Vector2 v)
+ {
+ this.x = Mathf.RoundToInt(v.x);
+ this.y = Mathf.RoundToInt(v.y);
+ }
+
+ public static Vector2i operator +(Vector2i left, Vector2i right)
+ {
+ left.x += right.x;
+ left.y += right.y;
+ return left;
+ }
+
+ public static Vector2i operator -(Vector2i left, Vector2i right)
+ {
+ left.x -= right.x;
+ left.y -= right.y;
+ return left;
+ }
+
+ public static Vector2i operator -(Vector2i vec)
+ {
+ vec.x = -vec.x;
+ vec.y = -vec.y;
+ return vec;
+ }
+
+ public static Vector2i operator *(Vector2i vec, int scale)
+ {
+ vec.x *= scale;
+ vec.y *= scale;
+ return vec;
+ }
+
+ public static Vector2i operator *(int scale, Vector2i vec)
+ {
+ vec.x *= scale;
+ vec.y *= scale;
+ return vec;
+ }
+
+ public static Vector2i operator *(Vector2i left, Vector2i right)
+ {
+ left.x *= right.x;
+ left.y *= right.y;
+ return left;
+ }
+
+ public static Vector2i operator /(Vector2i vec, int divisor)
+ {
+ vec.x /= divisor;
+ vec.y /= divisor;
+ return vec;
+ }
+
+ public static Vector2i operator /(Vector2i vec, Vector2i divisorv)
+ {
+ vec.x /= divisorv.x;
+ vec.y /= divisorv.y;
+ return vec;
+ }
+
+ public static Vector2i operator %(Vector2i vec, int divisor)
+ {
+ vec.x %= divisor;
+ vec.y %= divisor;
+ return vec;
+ }
+
+ public static Vector2i operator %(Vector2i vec, Vector2i divisorv)
+ {
+ vec.x %= divisorv.x;
+ vec.y %= divisorv.y;
+ return vec;
+ }
+
+ public static Vector2i operator &(Vector2i vec, int and)
+ {
+ vec.x &= and;
+ vec.y &= and;
+ return vec;
+ }
+
+ public static Vector2i operator &(Vector2i vec, Vector2i andv)
+ {
+ vec.x &= andv.x;
+ vec.y &= andv.y;
+ return vec;
+ }
+
+ public static bool operator ==(Vector2i left, Vector2i right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Vector2i left, Vector2i right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static bool operator <(Vector2i left, Vector2i right)
+ {
+ if (left.x.Equals(right.x))
+ {
+ return left.y < right.y;
+ }
+ return left.x < right.x;
+ }
+
+ public static bool operator >(Vector2i left, Vector2i right)
+ {
+ if (left.x.Equals(right.x))
+ {
+ return left.y > right.y;
+ }
+ return left.x > right.x;
+ }
+
+ public static bool operator <=(Vector2i left, Vector2i right)
+ {
+ if (left.x.Equals(right.x))
+ {
+ return left.y <= right.y;
+ }
+ return left.x <= right.x;
+ }
+
+ public static bool operator >=(Vector2i left, Vector2i right)
+ {
+ if (left.x.Equals(right.x))
+ {
+ return left.y >= right.y;
+ }
+ return left.x >= right.x;
+ }
+
+ public static implicit operator Vector2(Vector2i value)
+ {
+ return new Vector2(value.x, value.y);
+ }
+
+ public static explicit operator Vector2i(Vector2 value)
+ {
+ return new Vector2i(value);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Vector2i)
+ {
+ return Equals((Vector2i)obj);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Vector2i other)
+ {
+ return x == other.x && y == other.y;
+ }
+
+ public override int GetHashCode()
+ {
+ return y.GetHashCode() ^ x.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format("({0}, {1})", new object[]
+ {
+ this.x.ToString(),
+ this.y.ToString()
+ });
+ }
+
+ public string ToString(string format)
+ {
+ return String.Format("({0}, {1})", new object[]
+ {
+ this.x.ToString(format),
+ this.y.ToString(format)
+ });
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index fded34002d..a43836e985 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -270,21 +270,6 @@ namespace Godot
return new Basis(axis, phi).Xform(this);
}
- [Obsolete("Set is deprecated. Use the Vector3(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
- public void Set(real_t x, real_t y, real_t z)
- {
- this.x = x;
- this.y = y;
- this.z = z;
- }
- [Obsolete("Set is deprecated. Use the Vector3(" + nameof(Vector3) + ") constructor instead.", error: true)]
- public void Set(Vector3 v)
- {
- x = v.x;
- y = v.y;
- z = v.z;
- }
-
public Vector3 Sign()
{
Vector3 v;
@@ -415,20 +400,20 @@ namespace Godot
return left;
}
- public static Vector3 operator /(Vector3 vec, real_t scale)
+ public static Vector3 operator /(Vector3 vec, real_t divisor)
{
- vec.x /= scale;
- vec.y /= scale;
- vec.z /= scale;
+ vec.x /= divisor;
+ vec.y /= divisor;
+ vec.z /= divisor;
return vec;
}
- public static Vector3 operator /(Vector3 left, Vector3 right)
+ public static Vector3 operator /(Vector3 vec, Vector3 divisorv)
{
- left.x /= right.x;
- left.y /= right.y;
- left.z /= right.z;
- return left;
+ vec.x /= divisorv.x;
+ vec.y /= divisorv.y;
+ vec.z /= divisorv.z;
+ return vec;
}
public static Vector3 operator %(Vector3 vec, real_t divisor)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
new file mode 100644
index 0000000000..c17f900131
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -0,0 +1,402 @@
+using System;
+using System.Runtime.InteropServices;
+
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
+
+namespace Godot
+{
+ /// <summary>
+ /// 3-element structure that can be used to represent 3D grid coordinates or sets of integers.
+ /// </summary>
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Vector3i : IEquatable<Vector3i>
+ {
+ public enum Axis
+ {
+ X = 0,
+ Y,
+ Z
+ }
+
+ public int x;
+ public int y;
+ public int z;
+
+ public int this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return x;
+ case 1:
+ return y;
+ case 2:
+ return z;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ set
+ {
+ switch (index)
+ {
+ case 0:
+ x = value;
+ return;
+ case 1:
+ y = value;
+ return;
+ case 2:
+ z = value;
+ return;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+
+ public Vector3i Abs()
+ {
+ Vector3i v = this;
+ if (v.x < 0)
+ {
+ v.x = -v.x;
+ }
+ if (v.y < 0)
+ {
+ v.y = -v.y;
+ }
+ if (v.z < 0)
+ {
+ v.z = -v.z;
+ }
+ return v;
+ }
+
+ public int DistanceSquaredTo(Vector3i b)
+ {
+ return (b - this).LengthSquared();
+ }
+
+ public real_t DistanceTo(Vector3i b)
+ {
+ return (b - this).Length();
+ }
+
+ public int Dot(Vector3i b)
+ {
+ return x * b.x + y * b.y + z * b.z;
+ }
+
+ public real_t Length()
+ {
+ int x2 = x * x;
+ int y2 = y * y;
+ int z2 = z * z;
+
+ return Mathf.Sqrt(x2 + y2 + z2);
+ }
+
+ public int LengthSquared()
+ {
+ int x2 = x * x;
+ int y2 = y * y;
+ int z2 = z * z;
+
+ return x2 + y2 + z2;
+ }
+
+ public Axis MaxAxis()
+ {
+ return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X);
+ }
+
+ public Axis MinAxis()
+ {
+ return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z);
+ }
+
+ public Vector3i PosMod(int mod)
+ {
+ Vector3i v = this;
+ v.x = Mathf.PosMod(v.x, mod);
+ v.y = Mathf.PosMod(v.y, mod);
+ v.z = Mathf.PosMod(v.z, mod);
+ return v;
+ }
+
+ public Vector3i PosMod(Vector3i modv)
+ {
+ Vector3i v = this;
+ v.x = Mathf.PosMod(v.x, modv.x);
+ v.y = Mathf.PosMod(v.y, modv.y);
+ v.z = Mathf.PosMod(v.z, modv.z);
+ return v;
+ }
+
+ public Vector3i Sign()
+ {
+ Vector3i v = this;
+ v.x = Mathf.Sign(v.x);
+ v.y = Mathf.Sign(v.y);
+ v.z = Mathf.Sign(v.z);
+ return v;
+ }
+
+ // Constants
+ private static readonly Vector3i _zero = new Vector3i(0, 0, 0);
+ private static readonly Vector3i _one = new Vector3i(1, 1, 1);
+
+ private static readonly Vector3i _up = new Vector3i(0, 1, 0);
+ private static readonly Vector3i _down = new Vector3i(0, -1, 0);
+ private static readonly Vector3i _right = new Vector3i(1, 0, 0);
+ private static readonly Vector3i _left = new Vector3i(-1, 0, 0);
+ private static readonly Vector3i _forward = new Vector3i(0, 0, -1);
+ private static readonly Vector3i _back = new Vector3i(0, 0, 1);
+
+ public static Vector3i Zero { get { return _zero; } }
+ public static Vector3i One { get { return _one; } }
+
+ public static Vector3i Up { get { return _up; } }
+ public static Vector3i Down { get { return _down; } }
+ public static Vector3i Right { get { return _right; } }
+ public static Vector3i Left { get { return _left; } }
+ public static Vector3i Forward { get { return _forward; } }
+ public static Vector3i Back { get { return _back; } }
+
+ // Constructors
+ public Vector3i(int x, int y, int z)
+ {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+ public Vector3i(Vector3i vi)
+ {
+ this.x = vi.x;
+ this.y = vi.y;
+ this.z = vi.z;
+ }
+ public Vector3i(Vector3 v)
+ {
+ this.x = Mathf.RoundToInt(v.x);
+ this.y = Mathf.RoundToInt(v.y);
+ this.z = Mathf.RoundToInt(v.z);
+ }
+
+ public static Vector3i operator +(Vector3i left, Vector3i right)
+ {
+ left.x += right.x;
+ left.y += right.y;
+ left.z += right.z;
+ return left;
+ }
+
+ public static Vector3i operator -(Vector3i left, Vector3i right)
+ {
+ left.x -= right.x;
+ left.y -= right.y;
+ left.z -= right.z;
+ return left;
+ }
+
+ public static Vector3i operator -(Vector3i vec)
+ {
+ vec.x = -vec.x;
+ vec.y = -vec.y;
+ vec.z = -vec.z;
+ return vec;
+ }
+
+ public static Vector3i operator *(Vector3i vec, int scale)
+ {
+ vec.x *= scale;
+ vec.y *= scale;
+ vec.z *= scale;
+ return vec;
+ }
+
+ public static Vector3i operator *(int scale, Vector3i vec)
+ {
+ vec.x *= scale;
+ vec.y *= scale;
+ vec.z *= scale;
+ return vec;
+ }
+
+ public static Vector3i operator *(Vector3i left, Vector3i right)
+ {
+ left.x *= right.x;
+ left.y *= right.y;
+ left.z *= right.z;
+ return left;
+ }
+
+ public static Vector3i operator /(Vector3i vec, int divisor)
+ {
+ vec.x /= divisor;
+ vec.y /= divisor;
+ vec.z /= divisor;
+ return vec;
+ }
+
+ public static Vector3i operator /(Vector3i vec, Vector3i divisorv)
+ {
+ vec.x /= divisorv.x;
+ vec.y /= divisorv.y;
+ vec.z /= divisorv.z;
+ return vec;
+ }
+
+ public static Vector3i operator %(Vector3i vec, int divisor)
+ {
+ vec.x %= divisor;
+ vec.y %= divisor;
+ vec.z %= divisor;
+ return vec;
+ }
+
+ public static Vector3i operator %(Vector3i vec, Vector3i divisorv)
+ {
+ vec.x %= divisorv.x;
+ vec.y %= divisorv.y;
+ vec.z %= divisorv.z;
+ return vec;
+ }
+
+ public static Vector3i operator &(Vector3i vec, int and)
+ {
+ vec.x &= and;
+ vec.y &= and;
+ vec.z &= and;
+ return vec;
+ }
+
+ public static Vector3i operator &(Vector3i vec, Vector3i andv)
+ {
+ vec.x &= andv.x;
+ vec.y &= andv.y;
+ vec.z &= andv.z;
+ return vec;
+ }
+
+ public static bool operator ==(Vector3i left, Vector3i right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Vector3i left, Vector3i right)
+ {
+ return !left.Equals(right);
+ }
+
+ public static bool operator <(Vector3i left, Vector3i right)
+ {
+ if (left.x == right.x)
+ {
+ if (left.y == right.y)
+ return left.z < right.z;
+ else
+ return left.y < right.y;
+ }
+
+ return left.x < right.x;
+ }
+
+ public static bool operator >(Vector3i left, Vector3i right)
+ {
+ if (left.x == right.x)
+ {
+ if (left.y == right.y)
+ return left.z > right.z;
+ else
+ return left.y > right.y;
+ }
+
+ return left.x > right.x;
+ }
+
+ public static bool operator <=(Vector3i left, Vector3i right)
+ {
+ if (left.x == right.x)
+ {
+ if (left.y == right.y)
+ return left.z <= right.z;
+ else
+ return left.y < right.y;
+ }
+
+ return left.x < right.x;
+ }
+
+ public static bool operator >=(Vector3i left, Vector3i right)
+ {
+ if (left.x == right.x)
+ {
+ if (left.y == right.y)
+ return left.z >= right.z;
+ else
+ return left.y > right.y;
+ }
+
+ return left.x > right.x;
+ }
+
+ public static implicit operator Vector3(Vector3i value)
+ {
+ return new Vector3(value.x, value.y, value.z);
+ }
+
+ public static explicit operator Vector3i(Vector3 value)
+ {
+ return new Vector3i(value);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Vector3i)
+ {
+ return Equals((Vector3i)obj);
+ }
+
+ return false;
+ }
+
+ public bool Equals(Vector3i other)
+ {
+ return x == other.x && y == other.y && z == other.z;
+ }
+
+ public override int GetHashCode()
+ {
+ return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return String.Format("({0}, {1}, {2})", new object[]
+ {
+ this.x.ToString(),
+ this.y.ToString(),
+ this.z.ToString()
+ });
+ }
+
+ public string ToString(string format)
+ {
+ return String.Format("({0}, {1}, {2})", new object[]
+ {
+ this.x.ToString(format),
+ this.y.ToString(format),
+ this.z.ToString(format)
+ });
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index 5419cd06e6..ba0bbd7630 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -41,9 +41,11 @@
<Compile Include="Core\Attributes\SignalAttribute.cs" />
<Compile Include="Core\Attributes\ToolAttribute.cs" />
<Compile Include="Core\Basis.cs" />
+ <Compile Include="Core\Callable.cs" />
<Compile Include="Core\Color.cs" />
<Compile Include="Core\Colors.cs" />
<Compile Include="Core\DebuggingUtils.cs" />
+ <Compile Include="Core\DelegateUtils.cs" />
<Compile Include="Core\Dictionary.cs" />
<Compile Include="Core\Dispatcher.cs" />
<Compile Include="Core\DynamicObject.cs" />
@@ -65,13 +67,18 @@
<Compile Include="Core\Plane.cs" />
<Compile Include="Core\Quat.cs" />
<Compile Include="Core\Rect2.cs" />
+ <Compile Include="Core\Rect2i.cs" />
<Compile Include="Core\RID.cs" />
+ <Compile Include="Core\SignalInfo.cs" />
<Compile Include="Core\SignalAwaiter.cs" />
<Compile Include="Core\StringExtensions.cs" />
+ <Compile Include="Core\StringName.cs" />
<Compile Include="Core\Transform.cs" />
<Compile Include="Core\Transform2D.cs" />
<Compile Include="Core\Vector2.cs" />
+ <Compile Include="Core\Vector2i.cs" />
<Compile Include="Core\Vector3.cs" />
+ <Compile Include="Core\Vector3i.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<!--
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
index 02246b2f2f..f370883320 100644
--- a/modules/mono/glue/base_object_glue.cpp
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -51,7 +51,7 @@ Object *godot_icall_Object_Ctor(MonoObject *p_obj) {
void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_ptr == NULL);
+ CRASH_COND(p_ptr == nullptr);
#endif
if (p_ptr->get_script_instance()) {
@@ -59,7 +59,7 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
if (cs_instance) {
if (!cs_instance->is_destructing_script_instance()) {
cs_instance->mono_object_disposed(p_obj);
- p_ptr->set_script_instance(NULL);
+ p_ptr->set_script_instance(nullptr);
}
return;
}
@@ -70,8 +70,8 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
if (data) {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
if (script_binding.inited) {
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
- if (gchandle.is_valid()) {
+ MonoGCHandleData &gchandle = script_binding.gchandle;
+ if (!gchandle.is_released()) {
CSharpLanguage::release_script_gchandle(p_obj, gchandle);
}
}
@@ -80,7 +80,7 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_ptr == NULL);
+ CRASH_COND(p_ptr == nullptr);
// This is only called with Reference derived classes
CRASH_COND(!Object::cast_to<Reference>(p_ptr));
#endif
@@ -99,7 +99,7 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea
if (delete_owner) {
memdelete(ref);
} else if (remove_script_instance) {
- ref->set_script_instance(NULL);
+ ref->set_script_instance(nullptr);
}
}
return;
@@ -117,8 +117,8 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea
if (data) {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
if (script_binding.inited) {
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
- if (gchandle.is_valid()) {
+ MonoGCHandleData &gchandle = script_binding.gchandle;
+ if (!gchandle.is_released()) {
CSharpLanguage::release_script_gchandle(p_obj, gchandle);
}
}
@@ -126,37 +126,44 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea
}
}
-MethodBind *godot_icall_Object_ClassDB_get_method(MonoString *p_type, MonoString *p_method) {
- StringName type(GDMonoMarshal::mono_string_to_godot(p_type));
+void godot_icall_Object_ConnectEventSignals(Object *p_ptr) {
+ CSharpInstance *csharp_instance = CAST_CSHARP_INSTANCE(p_ptr->get_script_instance());
+ if (csharp_instance) {
+ csharp_instance->connect_event_signals();
+ }
+}
+
+MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method) {
+ StringName type = p_type ? *p_type : StringName();
StringName method(GDMonoMarshal::mono_string_to_godot(p_method));
return ClassDB::get_method(type, method);
}
-MonoObject *godot_icall_Object_weakref(Object *p_obj) {
- if (!p_obj)
- return NULL;
+MonoObject *godot_icall_Object_weakref(Object *p_ptr) {
+ if (!p_ptr)
+ return nullptr;
Ref<WeakRef> wref;
- Reference *ref = Object::cast_to<Reference>(p_obj);
+ Reference *ref = Object::cast_to<Reference>(p_ptr);
if (ref) {
REF r = ref;
if (!r.is_valid())
- return NULL;
+ return nullptr;
wref.instance();
wref->set_ref(r);
} else {
wref.instance();
- wref->set_obj(p_obj);
+ wref->set_obj(p_ptr);
}
return GDMonoUtils::unmanaged_get_managed(wref.ptr());
}
-Error godot_icall_SignalAwaiter_connect(Object *p_source, MonoString *p_signal, Object *p_target, MonoObject *p_awaiter) {
- String signal = GDMonoMarshal::mono_string_to_godot(p_signal);
- return SignalAwaiterUtils::connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
+Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter) {
+ StringName signal = p_signal ? *p_signal : StringName();
+ return gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
}
MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
@@ -189,12 +196,12 @@ MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoStrin
args.set(i, &arg_store.get(i));
}
- Variant::CallError error;
+ Callable::CallError error;
Variant result = p_ptr->call(StringName(name), args.ptr(), argc, error);
*r_result = GDMonoMarshal::variant_to_mono_object(result);
- return error.error == Variant::CallError::CALL_OK;
+ return error.error == Callable::CallError::CALL_OK;
}
MonoBoolean godot_icall_DynamicGodotObject_GetMember(Object *p_ptr, MonoString *p_name, MonoObject **r_result) {
@@ -223,14 +230,9 @@ MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString *
MonoString *godot_icall_Object_ToString(Object *p_ptr) {
#ifdef DEBUG_ENABLED
// Cannot happen in C#; would get an ObjectDisposedException instead.
- CRASH_COND(p_ptr == NULL);
-
- if (ScriptDebugger::get_singleton() && !Object::cast_to<Reference>(p_ptr)) { // Only if debugging!
- // Cannot happen either in C#; the handle is nullified when the object is destroyed
- CRASH_COND(!ObjectDB::instance_validate(p_ptr));
- }
+ CRASH_COND(p_ptr == nullptr);
#endif
-
+ // Can't call 'Object::to_string()' here, as that can end up calling 'ToString' again resulting in an endless circular loop.
String result = "[" + p_ptr->get_class() + ":" + itos(p_ptr->get_instance_id()) + "]";
return GDMonoMarshal::mono_string_from_godot(result);
}
diff --git a/modules/mono/glue/base_object_glue.h b/modules/mono/glue/base_object_glue.h
index 22532dcff9..67769f3061 100644
--- a/modules/mono/glue/base_object_glue.h
+++ b/modules/mono/glue/base_object_glue.h
@@ -44,11 +44,13 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr);
void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer);
-MethodBind *godot_icall_Object_ClassDB_get_method(MonoString *p_type, MonoString *p_method);
+void godot_icall_Object_ConnectEventSignals(Object *p_ptr);
-MonoObject *godot_icall_Object_weakref(Object *p_obj);
+MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method);
-Error godot_icall_SignalAwaiter_connect(Object *p_source, MonoString *p_signal, Object *p_target, MonoObject *p_awaiter);
+MonoObject *godot_icall_Object_weakref(Object *p_ptr);
+
+Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter);
// DynamicGodotObject
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index b7fa7fcab2..4e3dc9c4ea 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -49,7 +49,7 @@ void godot_icall_Array_Dtor(Array *ptr) {
MonoObject *godot_icall_Array_At(Array *ptr, int index) {
if (index < 0 || index >= ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
- return NULL;
+ return nullptr;
}
return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index));
}
@@ -57,7 +57,7 @@ MonoObject *godot_icall_Array_At(Array *ptr, int index) {
MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class) {
if (index < 0 || index >= ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
- return NULL;
+ return nullptr;
}
return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index), ManagedType(type_encoding, type_class));
}
@@ -162,28 +162,28 @@ void godot_icall_Dictionary_Dtor(Dictionary *ptr) {
MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key) {
Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
- if (ret == NULL) {
+ if (ret == nullptr) {
MonoObject *exc = mono_object_new(mono_domain_get(), CACHED_CLASS(KeyNotFoundException)->get_mono_ptr());
#ifdef DEBUG_ENABLED
CRASH_COND(!exc);
#endif
GDMonoUtils::runtime_object_init(exc, CACHED_CLASS(KeyNotFoundException));
GDMonoUtils::set_pending_exception((MonoException *)exc);
- return NULL;
+ return nullptr;
}
return GDMonoMarshal::variant_to_mono_object(ret);
}
MonoObject *godot_icall_Dictionary_GetValue_Generic(Dictionary *ptr, MonoObject *key, uint32_t type_encoding, GDMonoClass *type_class) {
Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
- if (ret == NULL) {
+ if (ret == nullptr) {
MonoObject *exc = mono_object_new(mono_domain_get(), CACHED_CLASS(KeyNotFoundException)->get_mono_ptr());
#ifdef DEBUG_ENABLED
CRASH_COND(!exc);
#endif
GDMonoUtils::runtime_object_init(exc, CACHED_CLASS(KeyNotFoundException));
GDMonoUtils::set_pending_exception((MonoException *)exc);
- return NULL;
+ return nullptr;
}
return GDMonoMarshal::variant_to_mono_object(ret, ManagedType(type_encoding, type_class));
}
@@ -207,7 +207,7 @@ int godot_icall_Dictionary_Count(Dictionary *ptr) {
void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value) {
Variant varKey = GDMonoMarshal::mono_object_to_variant(key);
Variant *ret = ptr->getptr(varKey);
- if (ret != NULL) {
+ if (ret != nullptr) {
GDMonoUtils::set_pending_exception(mono_get_exception_argument("key", "An element with the same key already exists"));
return;
}
@@ -221,7 +221,7 @@ void godot_icall_Dictionary_Clear(Dictionary *ptr) {
MonoBoolean godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, MonoObject *value) {
// no dupes
Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
- return ret != NULL && *ret == GDMonoMarshal::mono_object_to_variant(value);
+ return ret != nullptr && *ret == GDMonoMarshal::mono_object_to_variant(value);
}
MonoBoolean godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key) {
@@ -241,7 +241,7 @@ MonoBoolean godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, Mono
// no dupes
Variant *ret = ptr->getptr(varKey);
- if (ret != NULL && *ret == GDMonoMarshal::mono_object_to_variant(value)) {
+ if (ret != nullptr && *ret == GDMonoMarshal::mono_object_to_variant(value)) {
ptr->erase(varKey);
return true;
}
@@ -251,8 +251,8 @@ MonoBoolean godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, Mono
MonoBoolean godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoObject **value) {
Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
- if (ret == NULL) {
- *value = NULL;
+ if (ret == nullptr) {
+ *value = nullptr;
return false;
}
*value = GDMonoMarshal::variant_to_mono_object(ret);
@@ -261,8 +261,8 @@ MonoBoolean godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key,
MonoBoolean godot_icall_Dictionary_TryGetValue_Generic(Dictionary *ptr, MonoObject *key, MonoObject **value, uint32_t type_encoding, GDMonoClass *type_class) {
Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
- if (ret == NULL) {
- *value = NULL;
+ if (ret == nullptr) {
+ *value = nullptr;
return false;
}
*value = GDMonoMarshal::variant_to_mono_object(ret, ManagedType(type_encoding, type_class));
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index 17483c4457..2da39a916a 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -44,9 +44,8 @@
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects) {
Variant ret;
- PoolByteArray varr = GDMonoMarshal::mono_array_to_PoolByteArray(p_bytes);
- PoolByteArray::Read r = varr.read();
- Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, p_allow_objects);
+ PackedByteArray varr = GDMonoMarshal::mono_array_to_PackedByteArray(p_bytes);
+ Error err = decode_variant(ret, varr.ptr(), varr.size(), nullptr, p_allow_objects);
if (err != OK) {
ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
}
@@ -56,9 +55,9 @@ MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_obj
MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type) {
Variant what = GDMonoMarshal::mono_object_to_variant(p_what);
const Variant *args[1] = { &what };
- Variant::CallError ce;
+ Callable::CallError ce;
Variant ret = Variant::construct(Variant::Type(p_type), args, 1, ce);
- ERR_FAIL_COND_V(ce.error != Variant::CallError::CALL_OK, NULL);
+ ERR_FAIL_COND_V(ce.error != Callable::CallError::CALL_OK, nullptr);
return GDMonoMarshal::variant_to_mono_object(ret);
}
@@ -67,7 +66,7 @@ int godot_icall_GD_hash(MonoObject *p_var) {
}
MonoObject *godot_icall_GD_instance_from_id(uint64_t p_instance_id) {
- return GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(p_instance_id));
+ return GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(ObjectID(p_instance_id)));
}
void godot_icall_GD_print(MonoArray *p_what) {
@@ -77,7 +76,7 @@ void godot_icall_GD_print(MonoArray *p_what) {
for (int i = 0; i < length; i++) {
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
if (exc) {
@@ -99,7 +98,7 @@ void godot_icall_GD_printerr(MonoArray *p_what) {
for (int i = 0; i < length; i++) {
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
if (exc) {
@@ -120,7 +119,7 @@ void godot_icall_GD_printraw(MonoArray *p_what) {
for (int i = 0; i < length; i++) {
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
if (exc) {
@@ -141,7 +140,7 @@ void godot_icall_GD_prints(MonoArray *p_what) {
for (int i = 0; i < length; i++) {
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
if (exc) {
@@ -165,7 +164,7 @@ void godot_icall_GD_printt(MonoArray *p_what) {
for (int i = 0; i < length; i++) {
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
if (exc) {
@@ -242,8 +241,9 @@ MonoObject *godot_icall_GD_str2var(MonoString *p_str) {
return GDMonoMarshal::variant_to_mono_object(ret);
}
-MonoBoolean godot_icall_GD_type_exists(MonoString *p_type) {
- return ClassDB::class_exists(GDMonoMarshal::mono_string_to_godot(p_type));
+MonoBoolean godot_icall_GD_type_exists(StringName *p_type) {
+ StringName type = p_type ? *p_type : StringName();
+ return ClassDB::class_exists(type);
}
void godot_icall_GD_pusherror(MonoString *p_str) {
@@ -257,18 +257,15 @@ void godot_icall_GD_pushwarning(MonoString *p_str) {
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects) {
Variant var = GDMonoMarshal::mono_object_to_variant(p_var);
- PoolByteArray barr;
+ PackedByteArray barr;
int len;
- Error err = encode_variant(var, NULL, len, p_full_objects);
- ERR_FAIL_COND_V_MSG(err != OK, NULL, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
+ Error err = encode_variant(var, nullptr, len, p_full_objects);
+ ERR_FAIL_COND_V_MSG(err != OK, nullptr, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
barr.resize(len);
- {
- PoolByteArray::Write w = barr.write();
- encode_variant(var, w.ptr(), len, p_full_objects);
- }
+ encode_variant(var, barr.ptrw(), len, p_full_objects);
- return GDMonoMarshal::PoolByteArray_to_mono_array(barr);
+ return GDMonoMarshal::PackedByteArray_to_mono_array(barr);
}
MonoString *godot_icall_GD_var2str(MonoObject *p_var) {
@@ -277,6 +274,10 @@ MonoString *godot_icall_GD_var2str(MonoObject *p_var) {
return GDMonoMarshal::mono_string_from_godot(vars);
}
+uint32_t godot_icall_TypeToVariantType(MonoReflectionType *p_refl_type) {
+ return (uint32_t)GDMonoMarshal::managed_to_variant_type(ManagedType::from_reftype(p_refl_type));
+}
+
MonoObject *godot_icall_DefaultGodotTaskScheduler() {
return GDMonoCache::cached_data.task_scheduler_handle->get_target();
}
@@ -304,6 +305,7 @@ void godot_register_gd_icalls() {
mono_add_internal_call("Godot.GD::godot_icall_GD_type_exists", (void *)godot_icall_GD_type_exists);
mono_add_internal_call("Godot.GD::godot_icall_GD_var2bytes", (void *)godot_icall_GD_var2bytes);
mono_add_internal_call("Godot.GD::godot_icall_GD_var2str", (void *)godot_icall_GD_var2str);
+ mono_add_internal_call("Godot.GD::godot_icall_TypeToVariantType", (void *)godot_icall_TypeToVariantType);
// Dispatcher
mono_add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", (void *)godot_icall_DefaultGodotTaskScheduler);
diff --git a/modules/mono/glue/gd_glue.h b/modules/mono/glue/gd_glue.h
index f00e2efc5d..3ad6058205 100644
--- a/modules/mono/glue/gd_glue.h
+++ b/modules/mono/glue/gd_glue.h
@@ -69,7 +69,7 @@ MonoString *godot_icall_GD_str(MonoArray *p_what);
MonoObject *godot_icall_GD_str2var(MonoString *p_str);
-MonoBoolean godot_icall_GD_type_exists(MonoString *p_type);
+MonoBoolean godot_icall_GD_type_exists(StringName *p_type);
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects);
diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h
index 758b71f719..ee99a300b9 100644
--- a/modules/mono/glue/glue_header.h
+++ b/modules/mono/glue/glue_header.h
@@ -36,6 +36,7 @@
#include "nodepath_glue.h"
#include "rid_glue.h"
#include "string_glue.h"
+#include "string_name_glue.h"
/**
* Registers internal calls that were not generated. This function is called
@@ -44,6 +45,7 @@
void godot_register_glue_header_icalls() {
godot_register_collections_icalls();
godot_register_gd_icalls();
+ godot_register_string_name_icalls();
godot_register_nodepath_icalls();
godot_register_object_icalls();
godot_register_rid_icalls();
@@ -68,7 +70,7 @@ void godot_register_glue_header_icalls() {
#include "../mono_gd/gd_mono_utils.h"
#define GODOTSHARP_INSTANCE_OBJECT(m_instance, m_type) \
- static ClassDB::ClassInfo *ci = NULL; \
+ static ClassDB::ClassInfo *ci = nullptr; \
if (!ci) { \
ci = ClassDB::classes.getptr(m_type); \
} \
diff --git a/modules/mono/glue/string_name_glue.cpp b/modules/mono/glue/string_name_glue.cpp
new file mode 100644
index 0000000000..81006e5849
--- /dev/null
+++ b/modules/mono/glue/string_name_glue.cpp
@@ -0,0 +1,61 @@
+/*************************************************************************/
+/* string_name_glue.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "string_name_glue.h"
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/ustring.h"
+
+StringName *godot_icall_StringName_Ctor(MonoString *p_path) {
+ return memnew(StringName(GDMonoMarshal::mono_string_to_godot(p_path)));
+}
+
+void godot_icall_StringName_Dtor(StringName *p_ptr) {
+ ERR_FAIL_NULL(p_ptr);
+ memdelete(p_ptr);
+}
+
+MonoString *godot_icall_StringName_operator_String(StringName *p_np) {
+ return GDMonoMarshal::mono_string_from_godot(p_np->operator String());
+}
+
+MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) {
+ return (MonoBoolean)(p_ptr == StringName());
+}
+
+void godot_register_string_name_icalls() {
+ mono_add_internal_call("Godot.StringName::godot_icall_StringName_Ctor", (void *)godot_icall_StringName_Ctor);
+ mono_add_internal_call("Godot.StringName::godot_icall_StringName_Dtor", (void *)godot_icall_StringName_Dtor);
+ mono_add_internal_call("Godot.StringName::godot_icall_StringName_operator_String", (void *)godot_icall_StringName_operator_String);
+ mono_add_internal_call("Godot.StringName::godot_icall_StringName_is_empty", (void *)godot_icall_StringName_is_empty);
+}
+
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/string_name_glue.h b/modules/mono/glue/string_name_glue.h
new file mode 100644
index 0000000000..88354ddd84
--- /dev/null
+++ b/modules/mono/glue/string_name_glue.h
@@ -0,0 +1,54 @@
+/*************************************************************************/
+/* string_name_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 STRING_NAME_GLUE_H
+#define STRING_NAME_GLUE_H
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/string_name.h"
+
+#include "../mono_gd/gd_mono_marshal.h"
+
+StringName *godot_icall_StringName_Ctor(MonoString *p_path);
+
+void godot_icall_StringName_Dtor(StringName *p_ptr);
+
+MonoString *godot_icall_StringName_operator_String(StringName *p_np);
+
+MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr);
+
+// Register internal calls
+
+void godot_register_string_name_icalls();
+
+#endif // MONO_GLUE_ENABLED
+
+#endif // STRING_NAME_GLUE_H
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 47eb432490..d596163926 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -40,7 +40,7 @@
#endif
#ifdef ANDROID_ENABLED
-#include "mono_gd/gd_mono_android.h"
+#include "mono_gd/support/android_support.h"
#endif
#include "mono_gd/gd_mono.h"
@@ -49,13 +49,13 @@ namespace GodotSharpDirs {
String _get_expected_build_config() {
#ifdef TOOLS_ENABLED
- return "Tools";
+ return "Debug";
#else
#ifdef DEBUG_ENABLED
- return "Debug";
+ return "ExportDebug";
#else
- return "Release";
+ return "ExportRelease";
#endif
#endif
@@ -169,7 +169,7 @@ private:
data_mono_etc_dir = data_mono_root_dir.plus_file("etc");
#ifdef ANDROID_ENABLED
- data_mono_lib_dir = GDMonoAndroid::get_app_native_lib_dir();
+ data_mono_lib_dir = gdmono::android::support::get_app_native_lib_dir();
#else
data_mono_lib_dir = data_mono_root_dir.plus_file("lib");
#endif
@@ -206,7 +206,7 @@ private:
data_mono_etc_dir = data_mono_root_dir.plus_file("etc");
#ifdef ANDROID_ENABLED
- data_mono_lib_dir = GDMonoAndroid::get_app_native_lib_dir();
+ data_mono_lib_dir = gdmono::android::support::get_app_native_lib_dir();
#else
data_mono_lib_dir = data_mono_root_dir.plus_file("lib");
data_game_assemblies_dir = data_dir_root.plus_file("Assemblies");
diff --git a/modules/mono/icons/icon_c_sharp_script.svg b/modules/mono/icons/CSharpScript.svg
index 69664ca553..69664ca553 100644
--- a/modules/mono/icons/icon_c_sharp_script.svg
+++ b/modules/mono/icons/CSharpScript.svg
diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp
new file mode 100644
index 0000000000..dfd78a8244
--- /dev/null
+++ b/modules/mono/managed_callable.cpp
@@ -0,0 +1,145 @@
+/*************************************************************************/
+/* managed_callable.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "managed_callable.h"
+
+#include "csharp_script.h"
+#include "mono_gd/gd_mono_marshal.h"
+#include "mono_gd/gd_mono_utils.h"
+
+#ifdef GD_MONO_HOT_RELOAD
+SelfList<ManagedCallable>::List ManagedCallable::instances;
+Map<ManagedCallable *, Array> ManagedCallable::instances_pending_reload;
+Mutex ManagedCallable::instances_mutex;
+#endif
+
+bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) {
+ const ManagedCallable *a = static_cast<const ManagedCallable *>(p_a);
+ const ManagedCallable *b = static_cast<const ManagedCallable *>(p_b);
+
+ MonoDelegate *delegate_a = (MonoDelegate *)a->delegate_handle.get_target();
+ MonoDelegate *delegate_b = (MonoDelegate *)b->delegate_handle.get_target();
+
+ if (!delegate_a || !delegate_b) {
+ if (!delegate_a && !delegate_b)
+ return true;
+ return false;
+ }
+
+ // Call Delegate's 'Equals'
+ return GDMonoUtils::mono_delegate_equal(delegate_a, delegate_b);
+}
+
+bool ManagedCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
+ if (compare_equal(p_a, p_b))
+ return false;
+ return p_a < p_b;
+}
+
+uint32_t ManagedCallable::hash() const {
+ // hmm
+ uint32_t hash = delegate_invoke->get_name().hash();
+ return hash_djb2_one_64(delegate_handle.handle, hash);
+}
+
+String ManagedCallable::get_as_text() const {
+ return "Delegate::Invoke";
+}
+
+CallableCustom::CompareEqualFunc ManagedCallable::get_compare_equal_func() const {
+ return compare_equal_func_ptr;
+}
+
+CallableCustom::CompareLessFunc ManagedCallable::get_compare_less_func() const {
+ return compare_less_func_ptr;
+}
+
+ObjectID ManagedCallable::get_object() const {
+ return CSharpLanguage::get_singleton()->get_managed_callable_middleman()->get_instance_id();
+}
+
+void ManagedCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
+ r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; // Can't find anything better
+ r_return_value = Variant();
+
+#ifdef GD_MONO_HOT_RELOAD
+ // Lost during hot-reload
+ ERR_FAIL_NULL(delegate_invoke);
+ ERR_FAIL_COND(delegate_handle.is_released());
+#endif
+
+ ERR_FAIL_COND(delegate_invoke->get_parameters_count() < p_argcount);
+
+ MonoObject *delegate = delegate_handle.get_target();
+
+ MonoException *exc = nullptr;
+ MonoObject *ret = delegate_invoke->invoke(delegate, p_arguments, &exc);
+
+ if (exc) {
+ GDMonoUtils::set_pending_exception(exc);
+ } else {
+ r_return_value = GDMonoMarshal::mono_object_to_variant(ret);
+ r_call_error.error = Callable::CallError::CALL_OK;
+ }
+}
+
+void ManagedCallable::set_delegate(MonoDelegate *p_delegate) {
+ delegate_handle = MonoGCHandleData::new_strong_handle((MonoObject *)p_delegate);
+ MonoMethod *delegate_invoke_raw = mono_get_delegate_invoke(mono_object_get_class((MonoObject *)p_delegate));
+ const StringName &delegate_invoke_name = CSharpLanguage::get_singleton()->get_string_names().delegate_invoke_method_name;
+ delegate_invoke = memnew(GDMonoMethod(delegate_invoke_name, delegate_invoke_raw)); // TODO: Use pooling for this GDMonoMethod instances
+}
+
+ManagedCallable::ManagedCallable(MonoDelegate *p_delegate) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(p_delegate == nullptr);
+#endif
+
+ set_delegate(p_delegate);
+
+#ifdef GD_MONO_HOT_RELOAD
+ {
+ MutexLock lock(instances_mutex);
+ instances.add(&self_instance);
+ }
+#endif
+}
+
+ManagedCallable::~ManagedCallable() {
+#ifdef GD_MONO_HOT_RELOAD
+ {
+ MutexLock lock(instances_mutex);
+ instances.remove(&self_instance);
+ instances_pending_reload.erase(this);
+ }
+#endif
+
+ delegate_handle.release();
+}
diff --git a/modules/mono/utils/thread_local.cpp b/modules/mono/managed_callable.h
index 4f10e3fb85..4f71e14a2f 100644
--- a/modules/mono/utils/thread_local.cpp
+++ b/modules/mono/managed_callable.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* thread_local.cpp */
+/* managed_callable.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,80 +28,50 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "thread_local.h"
+#ifndef MANAGED_CALLABLE_H
+#define MANAGED_CALLABLE_H
-#ifdef WINDOWS_ENABLED
-#include <windows.h>
-#else
-#include <pthread.h>
-#endif
-
-#include "core/os/memory.h"
-#include "core/print_string.h"
+#include <mono/metadata/object.h>
-struct ThreadLocalStorage::Impl {
+#include "core/callable.h"
+#include "core/os/mutex.h"
+#include "core/self_list.h"
-#ifdef WINDOWS_ENABLED
- DWORD dwFlsIndex;
-#else
- pthread_key_t key;
-#endif
-
- void *get_value() const {
-#ifdef WINDOWS_ENABLED
- return FlsGetValue(dwFlsIndex);
-#else
- return pthread_getspecific(key);
-#endif
- }
+#include "mono_gc_handle.h"
+#include "mono_gd/gd_mono_method.h"
- void set_value(void *p_value) const {
-#ifdef WINDOWS_ENABLED
- FlsSetValue(dwFlsIndex, p_value);
-#else
- pthread_setspecific(key, p_value);
-#endif
- }
+class ManagedCallable : public CallableCustom {
+ friend class CSharpLanguage;
+ MonoGCHandleData delegate_handle;
+ GDMonoMethod *delegate_invoke;
-#ifdef WINDOWS_ENABLED
-#define _CALLBACK_FUNC_ __stdcall
-#else
-#define _CALLBACK_FUNC_
+#ifdef GD_MONO_HOT_RELOAD
+ SelfList<ManagedCallable> self_instance = this;
+ static SelfList<ManagedCallable>::List instances;
+ static Map<ManagedCallable *, Array> instances_pending_reload;
+ static Mutex instances_mutex;
#endif
- Impl(void(_CALLBACK_FUNC_ *p_destr_callback_func)(void *)) {
-#ifdef WINDOWS_ENABLED
- dwFlsIndex = FlsAlloc(p_destr_callback_func);
- ERR_FAIL_COND(dwFlsIndex == FLS_OUT_OF_INDEXES);
-#else
- pthread_key_create(&key, p_destr_callback_func);
-#endif
- }
+public:
+ uint32_t hash() const override;
+ String get_as_text() const override;
+ CompareEqualFunc get_compare_equal_func() const override;
+ CompareLessFunc get_compare_less_func() const override;
+ ObjectID get_object() const override;
+ void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
- ~Impl() {
-#ifdef WINDOWS_ENABLED
- FlsFree(dwFlsIndex);
-#else
- pthread_key_delete(key);
-#endif
- }
-};
+ _FORCE_INLINE_ MonoDelegate *get_delegate() { return (MonoDelegate *)delegate_handle.get_target(); }
-void *ThreadLocalStorage::get_value() const {
- return pimpl->get_value();
-}
+ void set_delegate(MonoDelegate *p_delegate);
-void ThreadLocalStorage::set_value(void *p_value) const {
- pimpl->set_value(p_value);
-}
+ static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b);
+ static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b);
-void ThreadLocalStorage::alloc(void(_CALLBACK_FUNC_ *p_destr_callback)(void *)) {
- pimpl = memnew(ThreadLocalStorage::Impl(p_destr_callback));
-}
+ static constexpr CompareEqualFunc compare_equal_func_ptr = &ManagedCallable::compare_equal;
+ static constexpr CompareEqualFunc compare_less_func_ptr = &ManagedCallable::compare_less;
-#undef _CALLBACK_FUNC_
+ ManagedCallable(MonoDelegate *p_delegate);
+ ~ManagedCallable();
+};
-void ThreadLocalStorage::free() {
- memdelete(pimpl);
- pimpl = NULL;
-}
+#endif // MANAGED_CALLABLE_H
diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp
index feeea848ee..e362d5affb 100644
--- a/modules/mono/mono_gc_handle.cpp
+++ b/modules/mono/mono_gc_handle.cpp
@@ -32,56 +32,35 @@
#include "mono_gd/gd_mono.h"
-uint32_t MonoGCHandle::new_strong_handle(MonoObject *p_object) {
-
- return mono_gchandle_new(p_object, /* pinned: */ false);
-}
-
-uint32_t MonoGCHandle::new_strong_handle_pinned(MonoObject *p_object) {
-
- return mono_gchandle_new(p_object, /* pinned: */ true);
-}
-
-uint32_t MonoGCHandle::new_weak_handle(MonoObject *p_object) {
-
- return mono_gchandle_new_weakref(p_object, /* track_resurrection: */ false);
-}
-
-void MonoGCHandle::free_handle(uint32_t p_gchandle) {
+void MonoGCHandleData::release() {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(handle && GDMono::get_singleton() == nullptr);
+#endif
- mono_gchandle_free(p_gchandle);
+ if (handle && GDMono::get_singleton()->is_runtime_initialized()) {
+ GDMonoUtils::free_gchandle(handle);
+ handle = 0;
+ }
}
-Ref<MonoGCHandle> MonoGCHandle::create_strong(MonoObject *p_object) {
-
- return memnew(MonoGCHandle(new_strong_handle(p_object), STRONG_HANDLE));
+MonoGCHandleData MonoGCHandleData::new_strong_handle(MonoObject *p_object) {
+ return MonoGCHandleData(GDMonoUtils::new_strong_gchandle(p_object), gdmono::GCHandleType::STRONG_HANDLE);
}
-Ref<MonoGCHandle> MonoGCHandle::create_weak(MonoObject *p_object) {
-
- return memnew(MonoGCHandle(new_weak_handle(p_object), WEAK_HANDLE));
+MonoGCHandleData MonoGCHandleData::new_strong_handle_pinned(MonoObject *p_object) {
+ return MonoGCHandleData(GDMonoUtils::new_strong_gchandle_pinned(p_object), gdmono::GCHandleType::STRONG_HANDLE);
}
-void MonoGCHandle::release() {
-
-#ifdef DEBUG_ENABLED
- CRASH_COND(!released && GDMono::get_singleton() == NULL);
-#endif
-
- if (!released && GDMono::get_singleton()->is_runtime_initialized()) {
- free_handle(handle);
- released = true;
- }
+MonoGCHandleData MonoGCHandleData::new_weak_handle(MonoObject *p_object) {
+ return MonoGCHandleData(GDMonoUtils::new_weak_gchandle(p_object), gdmono::GCHandleType::WEAK_HANDLE);
}
-MonoGCHandle::MonoGCHandle(uint32_t p_handle, HandleType p_handle_type) {
+Ref<MonoGCHandleRef> MonoGCHandleRef::create_strong(MonoObject *p_object) {
- released = false;
- weak = p_handle_type == WEAK_HANDLE;
- handle = p_handle;
+ return memnew(MonoGCHandleRef(MonoGCHandleData::new_strong_handle(p_object)));
}
-MonoGCHandle::~MonoGCHandle() {
+Ref<MonoGCHandleRef> MonoGCHandleRef::create_weak(MonoObject *p_object) {
- release();
+ return memnew(MonoGCHandleRef(MonoGCHandleData::new_weak_handle(p_object)));
}
diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h
index 37fc7d8a17..fbcb405b0d 100644
--- a/modules/mono/mono_gc_handle.h
+++ b/modules/mono/mono_gc_handle.h
@@ -35,42 +35,79 @@
#include "core/reference.h"
-class MonoGCHandle : public Reference {
+namespace gdmono {
- GDCLASS(MonoGCHandle, Reference);
+enum class GCHandleType : char {
+ NIL,
+ STRONG_HANDLE,
+ WEAK_HANDLE
+};
+
+}
- bool released;
- bool weak;
+// Manual release of the GC handle must be done when using this struct
+struct MonoGCHandleData {
uint32_t handle;
+ gdmono::GCHandleType type;
-public:
- enum HandleType {
- STRONG_HANDLE,
- WEAK_HANDLE
- };
+ _FORCE_INLINE_ bool is_released() const { return !handle; }
+ _FORCE_INLINE_ bool is_weak() const { return type == gdmono::GCHandleType::WEAK_HANDLE; }
- static uint32_t new_strong_handle(MonoObject *p_object);
- static uint32_t new_strong_handle_pinned(MonoObject *p_object);
- static uint32_t new_weak_handle(MonoObject *p_object);
- static void free_handle(uint32_t p_gchandle);
+ _FORCE_INLINE_ MonoObject *get_target() const { return handle ? mono_gchandle_get_target(handle) : nullptr; }
- static Ref<MonoGCHandle> create_strong(MonoObject *p_object);
- static Ref<MonoGCHandle> create_weak(MonoObject *p_object);
+ void release();
- _FORCE_INLINE_ bool is_released() { return released; }
- _FORCE_INLINE_ bool is_weak() { return weak; }
+ MonoGCHandleData &operator=(const MonoGCHandleData &p_other) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!is_released());
+#endif
+ handle = p_other.handle;
+ type = p_other.type;
+ return *this;
+ }
- _FORCE_INLINE_ MonoObject *get_target() const { return released ? NULL : mono_gchandle_get_target(handle); }
+ MonoGCHandleData(const MonoGCHandleData &) = default;
- _FORCE_INLINE_ void set_handle(uint32_t p_handle, HandleType p_handle_type) {
- released = false;
- weak = p_handle_type == WEAK_HANDLE;
- handle = p_handle;
+ MonoGCHandleData() :
+ handle(0),
+ type(gdmono::GCHandleType::NIL) {
}
- void release();
- MonoGCHandle(uint32_t p_handle, HandleType p_handle_type);
- ~MonoGCHandle();
+ MonoGCHandleData(uint32_t p_handle, gdmono::GCHandleType p_type) :
+ handle(p_handle),
+ type(p_type) {
+ }
+
+ static MonoGCHandleData new_strong_handle(MonoObject *p_object);
+ static MonoGCHandleData new_strong_handle_pinned(MonoObject *p_object);
+ static MonoGCHandleData new_weak_handle(MonoObject *p_object);
+};
+
+class MonoGCHandleRef : public Reference {
+
+ GDCLASS(MonoGCHandleRef, Reference);
+
+ MonoGCHandleData data;
+
+public:
+ static Ref<MonoGCHandleRef> create_strong(MonoObject *p_object);
+ static Ref<MonoGCHandleRef> create_weak(MonoObject *p_object);
+
+ _FORCE_INLINE_ bool is_released() const { return data.is_released(); }
+ _FORCE_INLINE_ bool is_weak() const { return data.is_weak(); }
+
+ _FORCE_INLINE_ MonoObject *get_target() const { return data.get_target(); }
+
+ void release() { data.release(); }
+
+ _FORCE_INLINE_ void set_handle(uint32_t p_handle, gdmono::GCHandleType p_handle_type) {
+ data = MonoGCHandleData(p_handle, p_handle_type);
+ }
+
+ MonoGCHandleRef(const MonoGCHandleData &p_gc_handle_data) :
+ data(p_gc_handle_data) {
+ }
+ ~MonoGCHandleRef() { release(); }
};
#endif // CSHARP_GC_HANDLE_H
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 895393537f..3298c5da4c 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -37,6 +37,7 @@
#include <mono/metadata/mono-gc.h>
#include <mono/metadata/profiler.h>
+#include "core/debugger/engine_debugger.h"
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
@@ -57,14 +58,25 @@
#ifdef ANDROID_ENABLED
#include "android_mono_config.h"
-#include "gd_mono_android.h"
+#include "support/android_support.h"
+#elif defined(IPHONE_ENABLED)
+#include "support/ios_support.h"
+#endif
+
+#if defined(TOOL_ENABLED) && defined(GD_MONO_SINGLE_APPDOMAIN)
+// This will no longer be the case if we replace appdomains with AssemblyLoadContext
+#error "Editor build requires support for multiple appdomains"
+#endif
+
+#if defined(GD_MONO_HOT_RELOAD) && defined(GD_MONO_SINGLE_APPDOMAIN)
+#error "Hot reloading requires multiple appdomains"
#endif
// TODO:
// This has turn into a gigantic mess. There's too much going on here. Too much #ifdef as well.
// It's just painful to read... It needs to be re-structured. Please, clean this up, future me.
-GDMono *GDMono::singleton = NULL;
+GDMono *GDMono::singleton = nullptr;
namespace {
@@ -117,12 +129,8 @@ void gd_mono_profiler_init() {
}
}
-#if defined(DEBUG_ENABLED)
-
void gd_mono_debug_init() {
- mono_debug_init(MONO_DEBUG_FORMAT_MONO);
-
CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8();
#ifdef TOOLS_ENABLED
@@ -147,6 +155,10 @@ void gd_mono_debug_init() {
return; // Exported games don't use the project settings to setup the debugger agent
#endif
+ // Debugging enabled
+
+ mono_debug_init(MONO_DEBUG_FORMAT_MONO);
+
// --debugger-agent=help
const char *options[] = {
"--soft-breakpoints",
@@ -155,7 +167,6 @@ void gd_mono_debug_init() {
mono_jit_parse_options(2, (char **)options);
}
-#endif // defined(DEBUG_ENABLED)
#endif // !defined(JAVASCRIPT_ENABLED)
#if defined(JAVASCRIPT_ENABLED)
@@ -163,6 +174,7 @@ MonoDomain *gd_initialize_mono_runtime() {
const char *vfs_prefix = "managed";
int enable_debugging = 0;
+ // TODO: Provide a way to enable debugging on WASM release builds.
#ifdef DEBUG_ENABLED
enable_debugging = 1;
#endif
@@ -173,11 +185,16 @@ MonoDomain *gd_initialize_mono_runtime() {
}
#else
MonoDomain *gd_initialize_mono_runtime() {
-#ifdef DEBUG_ENABLED
gd_mono_debug_init();
+
+#if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED)
+ // I don't know whether this actually matters or not
+ const char *runtime_version = "mobile";
+#else
+ const char *runtime_version = "v4.0.30319";
#endif
- return mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319");
+ return mono_jit_init_version("GodotEngine.RootDomain", runtime_version);
}
#endif
@@ -313,14 +330,22 @@ void GDMono::initialize() {
determine_mono_dirs(assembly_rootdir, config_dir);
// Leak if we call mono_set_dirs more than once
- mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : NULL,
- config_dir.length() ? config_dir.utf8().get_data() : NULL);
+ mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : nullptr,
+ config_dir.length() ? config_dir.utf8().get_data() : nullptr);
add_mono_shared_libs_dir_to_path();
#endif
+#ifdef ANDROID_ENABLED
+ mono_config_parse_memory(get_godot_android_mono_config().utf8().get_data());
+#else
+ mono_config_parse(nullptr);
+#endif
+
#if defined(ANDROID_ENABLED)
- GDMonoAndroid::initialize();
+ gdmono::android::support::initialize();
+#elif defined(IPHONE_ENABLED)
+ gdmono::ios::support::initialize();
#endif
GDMonoAssembly::initialize();
@@ -329,13 +354,7 @@ void GDMono::initialize() {
gd_mono_profiler_init();
#endif
-#ifdef ANDROID_ENABLED
- mono_config_parse_memory(get_godot_android_mono_config().utf8().get_data());
-#else
- mono_config_parse(NULL);
-#endif
-
- mono_install_unhandled_exception_hook(&unhandled_exception_hook, NULL);
+ mono_install_unhandled_exception_hook(&unhandled_exception_hook, nullptr);
#ifndef TOOLS_ENABLED
// Exported games that don't use C# must still work. They likely don't ship with mscorlib.
@@ -354,7 +373,7 @@ void GDMono::initialize() {
#endif
// NOTE: Internal calls must be registered after the Mono runtime initialization.
- // Otherwise registration fails with the error: 'assertion 'hash != NULL' failed'.
+ // Otherwise registration fails with the error: 'assertion 'hash != nullptr' failed'.
root_domain = gd_initialize_mono_runtime();
ERR_FAIL_NULL_MSG(root_domain, "Mono: Failed to initialize runtime.");
@@ -370,15 +389,19 @@ void GDMono::initialize() {
print_verbose("Mono: Runtime initialized");
#if defined(ANDROID_ENABLED)
- GDMonoAndroid::register_internal_calls();
+ gdmono::android::support::register_internal_calls();
#endif
// mscorlib assembly MUST be present at initialization
bool corlib_loaded = _load_corlib_assembly();
ERR_FAIL_COND_MSG(!corlib_loaded, "Mono: Failed to load mscorlib assembly.");
+#ifndef GD_MONO_SINGLE_APPDOMAIN
Error domain_load_err = _load_scripts_domain();
ERR_FAIL_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
+#else
+ scripts_domain = root_domain;
+#endif
_register_internal_calls();
@@ -490,11 +513,15 @@ void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) {
assemblies[p_domain_id][p_assembly->get_name()] = p_assembly;
}
-GDMonoAssembly **GDMono::get_loaded_assembly(const String &p_name) {
+GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) {
+
+ if (p_name == "mscorlib")
+ return get_corlib_assembly();
MonoDomain *domain = mono_domain_get();
uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0;
- return assemblies[domain_id].getptr(p_name);
+ GDMonoAssembly **result = assemblies[domain_id].getptr(p_name);
+ return result ? *result : nullptr;
}
bool GDMono::load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly) {
@@ -516,7 +543,7 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo
print_verbose("Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...");
MonoImageOpenStatus status = MONO_IMAGE_OK;
- MonoAssembly *assembly = mono_assembly_load_full(p_aname, NULL, &status, p_refonly);
+ MonoAssembly *assembly = mono_assembly_load_full(p_aname, nullptr, &status, p_refonly);
if (!assembly)
return false;
@@ -527,7 +554,7 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo
GDMonoAssembly **stored_assembly = assemblies[domain_id].getptr(p_name);
- ERR_FAIL_COND_V(stored_assembly == NULL, false);
+ ERR_FAIL_COND_V(stored_assembly == nullptr, false);
ERR_FAIL_COND_V((*stored_assembly)->get_assembly() != assembly, false);
*r_assembly = *stored_assembly;
@@ -548,14 +575,6 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo
if (!assembly)
return false;
-#ifdef DEBUG_ENABLED
- uint32_t domain_id = mono_domain_get_id(mono_domain_get());
- GDMonoAssembly **stored_assembly = assemblies[domain_id].getptr(p_name);
-
- ERR_FAIL_COND_V(stored_assembly == NULL, false);
- ERR_FAIL_COND_V(*stored_assembly != assembly, false);
-#endif
-
*r_assembly = assembly;
print_verbose("Mono: Assembly " + p_name + (p_refonly ? " (refonly)" : "") + " loaded from path: " + (*r_assembly)->get_path());
@@ -575,15 +594,15 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo
if (nativecalls_klass) {
GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash");
if (api_hash_field)
- api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(NULL));
+ api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(nullptr));
GDMonoField *binds_ver_field = nativecalls_klass->get_field("bindings_version");
if (binds_ver_field)
- api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(NULL));
+ api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(nullptr));
GDMonoField *cs_glue_ver_field = nativecalls_klass->get_field("cs_glue_version");
if (cs_glue_ver_field)
- api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(NULL));
+ api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(nullptr));
}
return api_assembly_version;
@@ -714,7 +733,7 @@ bool GDMono::_temp_domain_load_are_assemblies_out_of_sync(const String &p_config
GDMono::LoadedApiAssembly temp_editor_api_assembly;
if (!_try_load_api_assemblies(temp_core_api_assembly, temp_editor_api_assembly,
- p_config, /* refonly: */ true, /* loaded_callback: */ NULL)) {
+ p_config, /* refonly: */ true, /* loaded_callback: */ nullptr)) {
return temp_core_api_assembly.out_of_sync || temp_editor_api_assembly.out_of_sync;
}
@@ -893,8 +912,8 @@ void GDMono::_load_api_assemblies() {
bool api_assemblies_loaded = _try_load_api_assemblies_preset();
+#if defined(TOOLS_ENABLED) && !defined(GD_MONO_SINGLE_APPDOMAIN)
if (!api_assemblies_loaded) {
-#ifdef TOOLS_ENABLED
// The API assemblies are out of sync or some other error happened. Fine, try one more time, but
// this time update them from the prebuilt assemblies directory before trying to load them again.
@@ -915,8 +934,8 @@ void GDMono::_load_api_assemblies() {
// 4. Try loading the updated assemblies
api_assemblies_loaded = _try_load_api_assemblies_preset();
-#endif
}
+#endif
if (!api_assemblies_loaded) {
// welp... too bad
@@ -981,8 +1000,8 @@ void GDMono::_install_trace_listener() {
GDMonoClass *debug_utils = get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, "DebuggingUtils");
GDMonoMethod *install_func = debug_utils->get_method("InstallTraceListener");
- MonoException *exc = NULL;
- install_func->invoke_raw(NULL, NULL, &exc);
+ MonoException *exc = nullptr;
+ install_func->invoke_raw(nullptr, nullptr, &exc);
if (exc) {
GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_PRINT("Failed to install 'System.Diagnostics.Trace' listener.");
@@ -990,9 +1009,10 @@ void GDMono::_install_trace_listener() {
#endif
}
+#ifndef GD_MONO_SINGLE_APPDOMAIN
Error GDMono::_load_scripts_domain() {
- ERR_FAIL_COND_V(scripts_domain != NULL, ERR_BUG);
+ ERR_FAIL_COND_V(scripts_domain != nullptr, ERR_BUG);
print_verbose("Mono: Loading scripts domain...");
@@ -1009,7 +1029,7 @@ Error GDMono::_unload_scripts_domain() {
ERR_FAIL_NULL_V(scripts_domain, ERR_BUG);
- print_verbose("Mono: Unloading scripts domain...");
+ print_verbose("Mono: Finalizing scripts domain...");
if (mono_domain_get() != root_domain)
mono_domain_set(root_domain, true);
@@ -1028,21 +1048,23 @@ Error GDMono::_unload_scripts_domain() {
_domain_assemblies_cleanup(mono_domain_get_id(scripts_domain));
- core_api_assembly.assembly = NULL;
+ core_api_assembly.assembly = nullptr;
#ifdef TOOLS_ENABLED
- editor_api_assembly.assembly = NULL;
+ editor_api_assembly.assembly = nullptr;
#endif
- project_assembly = NULL;
+ project_assembly = nullptr;
#ifdef TOOLS_ENABLED
- tools_assembly = NULL;
- tools_project_editor_assembly = NULL;
+ tools_assembly = nullptr;
+ tools_project_editor_assembly = nullptr;
#endif
MonoDomain *domain = scripts_domain;
- scripts_domain = NULL;
+ scripts_domain = nullptr;
+
+ print_verbose("Mono: Unloading scripts domain...");
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
mono_domain_try_unload(domain, (MonoObject **)&exc);
if (exc) {
@@ -1053,6 +1075,7 @@ Error GDMono::_unload_scripts_domain() {
return OK;
}
+#endif
#ifdef GD_MONO_HOT_RELOAD
Error GDMono::reload_scripts_domain() {
@@ -1091,9 +1114,10 @@ Error GDMono::reload_scripts_domain() {
}
#endif
+#ifndef GD_MONO_SINGLE_APPDOMAIN
Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
- CRASH_COND(p_domain == NULL);
+ CRASH_COND(p_domain == nullptr);
CRASH_COND(p_domain == GDMono::get_singleton()->get_scripts_domain()); // Should use _unload_scripts_domain() instead
String domain_name = mono_domain_get_friendly_name(p_domain);
@@ -1111,7 +1135,7 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
_domain_assemblies_cleanup(mono_domain_get_id(p_domain));
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
mono_domain_try_unload(p_domain, (MonoObject **)&exc);
if (exc) {
@@ -1122,6 +1146,7 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
return OK;
}
+#endif
GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
@@ -1133,7 +1158,7 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
uint32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
- const String *k = NULL;
+ const String *k = nullptr;
while ((k = domain_assemblies.next(k))) {
GDMonoAssembly *assembly = domain_assemblies.get(*k);
if (assembly->get_image() == image) {
@@ -1144,30 +1169,34 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
}
}
- return NULL;
+ return nullptr;
}
GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) {
+ GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name);
+ if (klass)
+ return klass;
+
uint32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
- const String *k = NULL;
+ const String *k = nullptr;
while ((k = domain_assemblies.next(k))) {
GDMonoAssembly *assembly = domain_assemblies.get(*k);
- GDMonoClass *klass = assembly->get_class(p_namespace, p_name);
+ klass = assembly->get_class(p_namespace, p_name);
if (klass)
return klass;
}
- return NULL;
+ return nullptr;
}
void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id];
- const String *k = NULL;
+ const String *k = nullptr;
while ((k = domain_assemblies.next(k))) {
memdelete(domain_assemblies.get(*k));
}
@@ -1183,8 +1212,8 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) {
#ifdef DEBUG_ENABLED
GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc);
- if (ScriptDebugger::get_singleton())
- ScriptDebugger::get_singleton()->idle_poll();
+ if (EngineDebugger::is_active())
+ EngineDebugger::get_singleton()->poll_events(false);
#endif
exit(mono_environment_exitcode_get());
@@ -1201,14 +1230,14 @@ GDMono::GDMono() {
runtime_initialized = false;
finalizing_scripts_domain = false;
- root_domain = NULL;
- scripts_domain = NULL;
+ root_domain = nullptr;
+ scripts_domain = nullptr;
- corlib_assembly = NULL;
- project_assembly = NULL;
+ corlib_assembly = nullptr;
+ project_assembly = nullptr;
#ifdef TOOLS_ENABLED
- tools_assembly = NULL;
- tools_project_editor_assembly = NULL;
+ tools_assembly = nullptr;
+ tools_project_editor_assembly = nullptr;
#endif
api_core_hash = 0;
@@ -1222,18 +1251,50 @@ GDMono::GDMono() {
GDMono::~GDMono() {
if (is_runtime_initialized()) {
+#ifndef GD_MONO_SINGLE_APPDOMAIN
if (scripts_domain) {
Error err = _unload_scripts_domain();
if (err != OK) {
ERR_PRINT("Mono: Failed to unload scripts domain.");
}
}
+#else
+ CRASH_COND(scripts_domain != root_domain);
+
+ print_verbose("Mono: Finalizing scripts domain...");
+
+ if (mono_domain_get() != root_domain)
+ mono_domain_set(root_domain, true);
+
+ finalizing_scripts_domain = true;
+
+ if (!mono_domain_finalize(root_domain, 2000)) {
+ ERR_PRINT("Mono: Domain finalization timeout.");
+ }
- const uint32_t *k = NULL;
+ finalizing_scripts_domain = false;
+
+ mono_gc_collect(mono_gc_max_generation());
+
+ GDMonoCache::clear_godot_api_cache();
+
+ _domain_assemblies_cleanup(mono_domain_get_id(root_domain));
+
+ core_api_assembly.assembly = nullptr;
+
+ project_assembly = nullptr;
+
+ root_domain = nullptr;
+ scripts_domain = nullptr;
+
+ // Leave the rest to 'mono_jit_cleanup'
+#endif
+
+ const uint32_t *k = nullptr;
while ((k = assemblies.next(k))) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies.get(*k);
- const String *kk = NULL;
+ const String *kk = nullptr;
while ((kk = domain_assemblies.next(kk))) {
memdelete(domain_assemblies.get(*kk));
}
@@ -1244,22 +1305,22 @@ GDMono::~GDMono() {
mono_jit_cleanup(root_domain);
-#if defined(ANDROID_ENABLED)
- GDMonoAndroid::cleanup();
-#endif
-
print_verbose("Mono: Finalized");
runtime_initialized = false;
}
+#if defined(ANDROID_ENABLED)
+ gdmono::android::support::cleanup();
+#endif
+
if (gdmono_log)
memdelete(gdmono_log);
- singleton = NULL;
+ singleton = nullptr;
}
-_GodotSharp *_GodotSharp::singleton = NULL;
+_GodotSharp *_GodotSharp::singleton = nullptr;
void _GodotSharp::attach_thread() {
@@ -1287,7 +1348,7 @@ int32_t _GodotSharp::get_scripts_domain_id() {
bool _GodotSharp::is_scripts_domain_loaded() {
- return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != NULL;
+ return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr;
}
bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) {
@@ -1326,7 +1387,10 @@ bool _GodotSharp::is_runtime_initialized() {
void _GodotSharp::_reload_assemblies(bool p_soft_reload) {
#ifdef GD_MONO_HOT_RELOAD
- CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
+ // This method may be called more than once with `call_deferred`, so we need to check
+ // again if reloading is needed to avoid reloading multiple times unnecessarily.
+ if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed())
+ CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
#endif
}
@@ -1352,5 +1416,5 @@ _GodotSharp::_GodotSharp() {
_GodotSharp::~_GodotSharp() {
- singleton = NULL;
+ singleton = nullptr;
}
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 306fa15f12..4898833e8e 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -91,7 +91,7 @@ public:
bool out_of_sync;
LoadedApiAssembly() :
- assembly(NULL),
+ assembly(nullptr),
out_of_sync(false) {
}
};
@@ -105,7 +105,7 @@ private:
MonoDomain *root_domain;
MonoDomain *scripts_domain;
- HashMap<uint32_t, HashMap<String, GDMonoAssembly *> > assemblies;
+ HashMap<uint32_t, HashMap<String, GDMonoAssembly *>> assemblies;
GDMonoAssembly *corlib_assembly;
GDMonoAssembly *project_assembly;
@@ -144,8 +144,10 @@ private:
void _register_internal_calls();
+#ifndef GD_MONO_SINGLE_APPDOMAIN
Error _load_scripts_domain();
Error _unload_scripts_domain();
+#endif
void _domain_assemblies_cleanup(uint32_t p_domain_id);
@@ -198,18 +200,18 @@ public:
#ifdef TOOLS_ENABLED
bool copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const String &p_config);
- String update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync = NULL, const bool *p_editor_api_out_of_sync = NULL);
+ String update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync = nullptr, const bool *p_editor_api_out_of_sync = nullptr);
#endif
static GDMono *get_singleton() { return singleton; }
- GD_NORETURN static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data);
+ [[noreturn]] static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data);
UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; }
// Do not use these, unless you know what you're doing
void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly);
- GDMonoAssembly **get_loaded_assembly(const String &p_name);
+ GDMonoAssembly *get_loaded_assembly(const String &p_name);
_FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; }
@@ -263,7 +265,7 @@ public:
this->prev_domain = prev_domain;
mono_domain_set(p_domain, false);
} else {
- this->prev_domain = NULL;
+ this->prev_domain = nullptr;
}
}
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 6cf5377e2c..0f211eebc6 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -42,9 +42,6 @@
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
-bool GDMonoAssembly::no_search = false;
-bool GDMonoAssembly::in_preload = false;
-
Vector<String> GDMonoAssembly::search_dirs;
void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config, const String &p_custom_bcl_dir) {
@@ -78,7 +75,7 @@ void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const Strin
if (p_custom_config.empty()) {
r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir());
} else {
- String api_config = p_custom_config == "Release" ? "Release" : "Debug";
+ String api_config = p_custom_config == "ExportRelease" ? "Release" : "Debug";
r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_base_dir().plus_file(api_config));
}
@@ -94,19 +91,30 @@ void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const Strin
#endif
}
+// This is how these assembly loading hooks work:
+//
+// - The 'search' hook checks if the assembly has already been loaded, to avoid loading again.
+// - The 'preload' hook does the actual loading and is only called if the
+// 'search' hook didn't find the assembly in the list of loaded assemblies.
+// - The 'load' hook is called after the assembly has been loaded. Its job is to add the
+// assembly to the list of loaded assemblies so that the 'search' hook can look it up.
+
void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, void *user_data) {
- if (no_search)
- return;
-
- // If our search and preload hooks fail to load the assembly themselves, the mono runtime still might.
- // Just do Assembly.LoadFrom("/Full/Path/On/Disk.dll");
- // In this case, we wouldn't have the assembly known in GDMono, which causes crashes
- // if any class inside the assembly is looked up by Godot.
- // And causing a lookup like that is as easy as throwing an exception defined in it...
- // No, we can't make the assembly load hooks smart enough because they get passed a MonoAssemblyName* only,
- // not the disk path passed to say Assembly.LoadFrom().
- _wrap_mono_assembly(assembly);
+ String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly)));
+
+ MonoImage *image = mono_assembly_get_image(assembly);
+
+ GDMonoAssembly *gdassembly = memnew(GDMonoAssembly(name, image, assembly));
+
+#ifdef GD_MONO_HOT_RELOAD
+ const char *path = mono_image_get_filename(image);
+ if (FileAccess::exists(path))
+ gdassembly->modified_time = FileAccess::get_modified_time(path);
+#endif
+
+ MonoDomain *domain = mono_domain_get();
+ GDMono::get_singleton()->add_assembly(domain ? mono_domain_get_id(domain) : 0, gdassembly);
}
MonoAssembly *GDMonoAssembly::assembly_search_hook(MonoAssemblyName *aname, void *user_data) {
@@ -132,71 +140,24 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d
String name = String::utf8(mono_assembly_name_get_name(aname));
bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
- if (no_search)
- return NULL;
-
- GDMonoAssembly **loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
+ GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
if (loaded_asm)
- return (*loaded_asm)->get_assembly();
-
- no_search = true; // Avoid the recursion madness
-
- GDMonoAssembly *res = _load_assembly_search(name, search_dirs, refonly);
+ return loaded_asm->get_assembly();
- no_search = false;
-
- return res ? res->get_assembly() : NULL;
+ return nullptr;
}
-static _THREAD_LOCAL_(MonoImage *) image_corlib_loading = NULL;
-
MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, void *user_data, bool refonly) {
(void)user_data; // UNUSED
- {
- // If we find the assembly here, we load it with 'mono_assembly_load_from_full',
- // which in turn invokes load hooks before returning the MonoAssembly to us.
- // One of the load hooks is 'load_aot_module'. This hook can end up calling preload hooks
- // again for the same assembly in certain in certain circumstances (the 'do_load_image' part).
- // If this is the case and we return NULL due to the no_search condition below,
- // it will result in an internal crash later on. Therefore we need to return the assembly we didn't
- // get yet from 'mono_assembly_load_from_full'. Luckily we have the image, which already got it.
- // This must be done here. If done in search hooks, it would cause 'mono_assembly_load_from_full'
- // to think another MonoAssembly for this assembly was already loaded, making it delete its own,
- // when in fact both pointers were the same... This hooks thing is confusing.
- if (image_corlib_loading) {
- return mono_image_get_assembly(image_corlib_loading);
- }
- }
-
- if (no_search)
- return NULL;
-
- no_search = true;
- in_preload = true;
-
String name = String::utf8(mono_assembly_name_get_name(aname));
- bool has_extension = name.ends_with(".dll");
-
- GDMonoAssembly *res = NULL;
- if (has_extension ? name == "mscorlib.dll" : name == "mscorlib") {
- GDMonoAssembly **stored_assembly = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
- if (stored_assembly)
- return (*stored_assembly)->get_assembly();
-
- res = _load_assembly_search("mscorlib.dll", search_dirs, refonly);
- }
-
- no_search = false;
- in_preload = false;
-
- return res ? res->get_assembly() : NULL;
+ return _load_assembly_search(name, search_dirs, refonly);
}
-GDMonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly) {
+MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly) {
- GDMonoAssembly *res = NULL;
+ MonoAssembly *res = nullptr;
String path;
bool has_extension = p_name.ends_with(".dll") || p_name.ends_with(".exe");
@@ -207,28 +168,28 @@ GDMonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, cons
if (has_extension) {
path = search_dir.plus_file(p_name);
if (FileAccess::exists(path)) {
- res = _load_assembly_from(p_name.get_basename(), path, p_refonly);
- if (res != NULL)
+ res = _real_load_assembly_from(path, p_refonly);
+ if (res != nullptr)
return res;
}
} else {
path = search_dir.plus_file(p_name + ".dll");
if (FileAccess::exists(path)) {
- res = _load_assembly_from(p_name, path, p_refonly);
- if (res != NULL)
+ res = _real_load_assembly_from(path, p_refonly);
+ if (res != nullptr)
return res;
}
path = search_dir.plus_file(p_name + ".exe");
if (FileAccess::exists(path)) {
- res = _load_assembly_from(p_name, path, p_refonly);
- if (res != NULL)
+ res = _real_load_assembly_from(path, p_refonly);
+ if (res != nullptr)
return res;
}
}
}
- return NULL;
+ return nullptr;
}
String GDMonoAssembly::find_assembly(const String &p_name) {
@@ -258,91 +219,50 @@ String GDMonoAssembly::find_assembly(const String &p_name) {
return String();
}
-GDMonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly) {
-
- GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path));
-
- Error err = assembly->load(p_refonly);
-
- if (err != OK) {
- memdelete(assembly);
- ERR_FAIL_V(NULL);
- }
-
- MonoDomain *domain = mono_domain_get();
- GDMono::get_singleton()->add_assembly(domain ? mono_domain_get_id(domain) : 0, assembly);
-
- return assembly;
-}
-
-void GDMonoAssembly::_wrap_mono_assembly(MonoAssembly *assembly) {
- String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly)));
-
- MonoImage *image = mono_assembly_get_image(assembly);
-
- GDMonoAssembly *gdassembly = memnew(GDMonoAssembly(name, mono_image_get_filename(image)));
- Error err = gdassembly->wrapper_for_image(image);
-
- if (err != OK) {
- memdelete(gdassembly);
- ERR_FAIL();
- }
-
- MonoDomain *domain = mono_domain_get();
- GDMono::get_singleton()->add_assembly(domain ? mono_domain_get_id(domain) : 0, gdassembly);
-}
-
void GDMonoAssembly::initialize() {
fill_search_dirs(search_dirs);
- mono_install_assembly_search_hook(&assembly_search_hook, NULL);
- mono_install_assembly_refonly_search_hook(&assembly_refonly_search_hook, NULL);
- mono_install_assembly_preload_hook(&assembly_preload_hook, NULL);
- mono_install_assembly_refonly_preload_hook(&assembly_refonly_preload_hook, NULL);
- mono_install_assembly_load_hook(&assembly_load_hook, NULL);
+ mono_install_assembly_search_hook(&assembly_search_hook, nullptr);
+ mono_install_assembly_refonly_search_hook(&assembly_refonly_search_hook, nullptr);
+ mono_install_assembly_preload_hook(&assembly_preload_hook, nullptr);
+ mono_install_assembly_refonly_preload_hook(&assembly_refonly_preload_hook, nullptr);
+ mono_install_assembly_load_hook(&assembly_load_hook, nullptr);
}
-Error GDMonoAssembly::load(bool p_refonly) {
-
- ERR_FAIL_COND_V(loaded, ERR_FILE_ALREADY_IN_USE);
-
- refonly = p_refonly;
-
- uint64_t last_modified_time = FileAccess::get_modified_time(path);
+MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, bool p_refonly) {
- Vector<uint8_t> data = FileAccess::get_file_as_array(path);
- ERR_FAIL_COND_V(data.empty(), ERR_FILE_CANT_READ);
+ Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
+ ERR_FAIL_COND_V_MSG(data.empty(), nullptr, "Could read the assembly in the specified location");
String image_filename;
#ifdef ANDROID_ENABLED
- if (path.begins_with("res://")) {
- image_filename = path.substr(6, path.length());
+ if (p_path.begins_with("res://")) {
+ image_filename = p_path.substr(6, p_path.length());
} else {
- image_filename = ProjectSettings::get_singleton()->globalize_path(path);
+ image_filename = ProjectSettings::get_singleton()->globalize_path(p_path);
}
#else
// FIXME: globalize_path does not work on exported games
- image_filename = ProjectSettings::get_singleton()->globalize_path(path);
+ image_filename = ProjectSettings::get_singleton()->globalize_path(p_path);
#endif
MonoImageOpenStatus status = MONO_IMAGE_OK;
- image = mono_image_open_from_data_with_name(
+ MonoImage *image = mono_image_open_from_data_with_name(
(char *)&data[0], data.size(),
- true, &status, refonly,
- image_filename.utf8().get_data());
+ true, &status, p_refonly,
+ image_filename.utf8());
- ERR_FAIL_COND_V(status != MONO_IMAGE_OK, ERR_FILE_CANT_OPEN);
- ERR_FAIL_NULL_V(image, ERR_FILE_CANT_OPEN);
+ ERR_FAIL_COND_V_MSG(status != MONO_IMAGE_OK || !image, nullptr, "Failed to open assembly image from the loaded data");
#ifdef DEBUG_ENABLED
Vector<uint8_t> pdb_data;
- String pdb_path(path + ".pdb");
+ String pdb_path(p_path + ".pdb");
if (!FileAccess::exists(pdb_path)) {
- pdb_path = path.get_basename() + ".pdb"; // without .dll
+ pdb_path = p_path.get_basename() + ".pdb"; // without .dll
if (!FileAccess::exists(pdb_path))
goto no_pdb;
@@ -357,44 +277,34 @@ no_pdb:
#endif
- bool is_corlib_preload = in_preload && name == "mscorlib";
+ bool need_manual_load_hook = mono_image_get_assembly(image) != nullptr; // Re-using an existing image with an assembly loaded
- if (is_corlib_preload)
- image_corlib_loading = image;
+ status = MONO_IMAGE_OK;
- assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, refonly);
+ MonoAssembly *assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, p_refonly);
- if (is_corlib_preload)
- image_corlib_loading = NULL;
+ ERR_FAIL_COND_V_MSG(status != MONO_IMAGE_OK || !assembly, nullptr, "Failed to load assembly for image");
- ERR_FAIL_COND_V(status != MONO_IMAGE_OK || assembly == NULL, ERR_FILE_CANT_OPEN);
+ if (need_manual_load_hook) {
+ // For some reason if an assembly survived domain reloading (maybe because it's referenced somewhere else),
+ // the mono internal search hook don't detect it, yet mono_image_open_from_data_with_name re-uses the image
+ // and assembly, and mono_assembly_load_from_full doesn't call the load hook. We need to call it manually.
+ String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly)));
+ bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
+ GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
+ if (!loaded_asm)
+ assembly_load_hook(assembly, nullptr);
+ }
// Decrement refcount which was previously incremented by mono_image_open_from_data_with_name
mono_image_close(image);
- loaded = true;
- modified_time = last_modified_time;
-
- return OK;
-}
-
-Error GDMonoAssembly::wrapper_for_image(MonoImage *p_image) {
-
- ERR_FAIL_COND_V(loaded, ERR_FILE_ALREADY_IN_USE);
-
- assembly = mono_image_get_assembly(p_image);
- ERR_FAIL_NULL_V(assembly, FAILED);
-
- image = p_image;
-
- loaded = true;
-
- return OK;
+ return assembly;
}
void GDMonoAssembly::unload() {
- ERR_FAIL_COND(!loaded);
+ ERR_FAIL_NULL(image); // Should not be called if already unloaded
for (Map<MonoClass *, GDMonoClass *>::Element *E = cached_raw.front(); E; E = E->next()) {
memdelete(E->value());
@@ -403,14 +313,17 @@ void GDMonoAssembly::unload() {
cached_classes.clear();
cached_raw.clear();
- assembly = NULL;
- image = NULL;
- loaded = false;
+ assembly = nullptr;
+ image = nullptr;
+}
+
+String GDMonoAssembly::get_path() const {
+ return String::utf8(mono_image_get_filename(image));
}
GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const StringName &p_name) {
- ERR_FAIL_COND_V(!loaded, NULL);
+ ERR_FAIL_NULL_V(image, nullptr);
ClassKey key(p_namespace, p_name);
@@ -422,7 +335,7 @@ GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const Stri
MonoClass *mono_class = mono_class_from_name(image, String(p_namespace).utf8(), String(p_name).utf8());
if (!mono_class)
- return NULL;
+ return nullptr;
GDMonoClass *wrapped_class = memnew(GDMonoClass(p_namespace, p_name, mono_class, this));
@@ -434,7 +347,7 @@ GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const Stri
GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
- ERR_FAIL_COND_V(!loaded, NULL);
+ ERR_FAIL_NULL_V(image, nullptr);
Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class);
@@ -454,7 +367,7 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) {
- GDMonoClass *match = NULL;
+ GDMonoClass *match = nullptr;
if (gdobject_class_cache_updated) {
Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class);
@@ -486,7 +399,7 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
GDMonoClass *current_nested = nested_classes.front()->get();
nested_classes.pop_back();
- void *iter = NULL;
+ void *iter = nullptr;
while (true) {
MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter);
@@ -514,32 +427,38 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) {
- GDMonoAssembly **loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name);
- if (loaded_asm)
- return *loaded_asm;
-#ifdef DEBUG_ENABLED
- CRASH_COND(!FileAccess::exists(p_path));
-#endif
- no_search = true;
- GDMonoAssembly *res = _load_assembly_from(p_name, p_path, p_refonly);
- no_search = false;
- return res;
-}
+ if (p_name == "mscorlib" || p_name == "mscorlib.dll")
+ return GDMono::get_singleton()->get_corlib_assembly();
-GDMonoAssembly::GDMonoAssembly(const String &p_name, const String &p_path) {
+ // We need to manually call the search hook in this case, as it won't be called in the next step
+ MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8());
+ MonoAssembly *assembly = mono_assembly_invoke_search_hook(aname);
+ mono_assembly_name_free(aname);
+ mono_free(aname);
+
+ if (!assembly) {
+ assembly = _real_load_assembly_from(p_path, p_refonly);
+ ERR_FAIL_NULL_V(assembly, nullptr);
+ }
- loaded = false;
- gdobject_class_cache_updated = false;
- name = p_name;
- path = p_path;
- refonly = false;
- modified_time = 0;
- assembly = NULL;
- image = NULL;
+ GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name);
+ ERR_FAIL_NULL_V_MSG(loaded_asm, nullptr, "Loaded assembly missing from table. Did we not receive the load hook?");
+
+ return loaded_asm;
+}
+
+GDMonoAssembly::GDMonoAssembly(const String &p_name, MonoImage *p_image, MonoAssembly *p_assembly) :
+ name(p_name),
+ image(p_image),
+ assembly(p_assembly),
+#ifdef GD_MONO_HOT_RELOAD
+ modified_time(0),
+#endif
+ gdobject_class_cache_updated(false) {
}
GDMonoAssembly::~GDMonoAssembly() {
- if (loaded)
+ if (image)
unload();
}
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index 4740e10339..43c8225b74 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -68,24 +68,20 @@ class GDMonoAssembly {
StringName class_name;
};
- MonoAssembly *assembly;
+ String name;
MonoImage *image;
+ MonoAssembly *assembly;
- bool refonly;
- bool loaded;
-
- String name;
- String path;
+#ifdef GD_MONO_HOT_RELOAD
uint64_t modified_time;
-
- HashMap<ClassKey, GDMonoClass *, ClassKey::Hasher> cached_classes;
- Map<MonoClass *, GDMonoClass *> cached_raw;
+#endif
bool gdobject_class_cache_updated;
Map<StringName, GDMonoClass *> gdobject_class_cache;
- static bool no_search;
- static bool in_preload;
+ HashMap<ClassKey, GDMonoClass *, ClassKey::Hasher> cached_classes;
+ Map<MonoClass *, GDMonoClass *> cached_raw;
+
static Vector<String> search_dirs;
static void assembly_load_hook(MonoAssembly *assembly, void *user_data);
@@ -97,25 +93,24 @@ class GDMonoAssembly {
static MonoAssembly *_search_hook(MonoAssemblyName *aname, void *user_data, bool refonly);
static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly);
- static GDMonoAssembly *_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly);
- static GDMonoAssembly *_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly);
- static void _wrap_mono_assembly(MonoAssembly *assembly);
+ static MonoAssembly *_real_load_assembly_from(const String &p_path, bool p_refonly);
+ static MonoAssembly *_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly);
friend class GDMono;
static void initialize();
public:
- Error load(bool p_refonly);
- Error wrapper_for_image(MonoImage *p_image);
void unload();
- _FORCE_INLINE_ bool is_refonly() const { return refonly; }
- _FORCE_INLINE_ bool is_loaded() const { return loaded; }
_FORCE_INLINE_ MonoImage *get_image() const { return image; }
_FORCE_INLINE_ MonoAssembly *get_assembly() const { return assembly; }
_FORCE_INLINE_ String get_name() const { return name; }
- _FORCE_INLINE_ String get_path() const { return path; }
+
+#ifdef GD_MONO_HOT_RELOAD
_FORCE_INLINE_ uint64_t get_modified_time() const { return modified_time; }
+#endif
+
+ String get_path() const;
GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_name);
GDMonoClass *get_class(MonoClass *p_mono_class);
@@ -128,7 +123,7 @@ public:
static GDMonoAssembly *load_from(const String &p_name, const String &p_path, bool p_refonly);
- GDMonoAssembly(const String &p_name, const String &p_path = String());
+ GDMonoAssembly(const String &p_name, MonoImage *p_image, MonoAssembly *p_assembly);
~GDMonoAssembly();
};
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index f1f6524cd2..5ddf18d544 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -40,11 +40,11 @@ namespace GDMonoCache {
CachedData cached_data;
-#define CACHE_AND_CHECK(m_var, m_val) \
- { \
- CRASH_COND(m_var != NULL); \
- m_var = m_val; \
- ERR_FAIL_COND_MSG(m_var == NULL, "Mono Cache: Member " #m_var " is null."); \
+#define CACHE_AND_CHECK(m_var, m_val) \
+ { \
+ CRASH_COND(m_var != nullptr); \
+ m_var = m_val; \
+ ERR_FAIL_COND_MSG(m_var == nullptr, "Mono Cache: Member " #m_var " is null."); \
}
#define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(cached_data.class_##m_class, m_val)
@@ -54,12 +54,12 @@ CachedData cached_data;
#define CACHE_METHOD_AND_CHECK(m_class, m_method, m_val) CACHE_AND_CHECK(cached_data.method_##m_class##_##m_method, m_val)
#define CACHE_PROPERTY_AND_CHECK(m_class, m_property, m_val) CACHE_AND_CHECK(cached_data.property_##m_class##_##m_property, m_val)
-#define CACHE_METHOD_THUNK_AND_CHECK_IMPL(m_var, m_val) \
- { \
- CRASH_COND(!m_var.is_null()); \
- ERR_FAIL_COND_MSG(m_val == NULL, "Mono Cache: Method for member " #m_var " is null."); \
- m_var.set_from_method(m_val); \
- ERR_FAIL_COND_MSG(m_var.is_null(), "Mono Cache: Member " #m_var " is null."); \
+#define CACHE_METHOD_THUNK_AND_CHECK_IMPL(m_var, m_val) \
+ { \
+ CRASH_COND(!m_var.is_null()); \
+ ERR_FAIL_COND_MSG(m_val == nullptr, "Mono Cache: Method for member " #m_var " is null."); \
+ m_var.set_from_method(m_val); \
+ ERR_FAIL_COND_MSG(m_var.is_null(), "Mono Cache: Member " #m_var " is null."); \
}
#define CACHE_METHOD_THUNK_AND_CHECK(m_class, m_method, m_val) CACHE_METHOD_THUNK_AND_CHECK_IMPL(cached_data.methodthunk_##m_class##_##m_method, m_val)
@@ -68,119 +68,125 @@ void CachedData::clear_corlib_cache() {
corlib_cache_updated = false;
- class_MonoObject = NULL;
- class_bool = NULL;
- class_int8_t = NULL;
- class_int16_t = NULL;
- class_int32_t = NULL;
- class_int64_t = NULL;
- class_uint8_t = NULL;
- class_uint16_t = NULL;
- class_uint32_t = NULL;
- class_uint64_t = NULL;
- class_float = NULL;
- class_double = NULL;
- class_String = NULL;
- class_IntPtr = NULL;
-
- class_System_Collections_IEnumerable = NULL;
- class_System_Collections_IDictionary = NULL;
+ class_MonoObject = nullptr;
+ class_bool = nullptr;
+ class_int8_t = nullptr;
+ class_int16_t = nullptr;
+ class_int32_t = nullptr;
+ class_int64_t = nullptr;
+ class_uint8_t = nullptr;
+ class_uint16_t = nullptr;
+ class_uint32_t = nullptr;
+ class_uint64_t = nullptr;
+ class_float = nullptr;
+ class_double = nullptr;
+ class_String = nullptr;
+ class_IntPtr = nullptr;
+
+ class_System_Collections_IEnumerable = nullptr;
+ class_System_Collections_ICollection = nullptr;
+ class_System_Collections_IDictionary = nullptr;
#ifdef DEBUG_ENABLED
- class_System_Diagnostics_StackTrace = NULL;
+ class_System_Diagnostics_StackTrace = nullptr;
methodthunk_System_Diagnostics_StackTrace_GetFrames.nullify();
- method_System_Diagnostics_StackTrace_ctor_bool = NULL;
- method_System_Diagnostics_StackTrace_ctor_Exception_bool = NULL;
+ method_System_Diagnostics_StackTrace_ctor_bool = nullptr;
+ method_System_Diagnostics_StackTrace_ctor_Exception_bool = nullptr;
#endif
- class_KeyNotFoundException = NULL;
+ class_KeyNotFoundException = nullptr;
}
void CachedData::clear_godot_api_cache() {
godot_api_cache_updated = false;
- rawclass_Dictionary = NULL;
-
- class_Vector2 = NULL;
- class_Rect2 = NULL;
- class_Transform2D = NULL;
- class_Vector3 = NULL;
- class_Basis = NULL;
- class_Quat = NULL;
- class_Transform = NULL;
- class_AABB = NULL;
- class_Color = NULL;
- class_Plane = NULL;
- class_NodePath = NULL;
- class_RID = NULL;
- class_GodotObject = NULL;
- class_GodotResource = NULL;
- class_Node = NULL;
- class_Control = NULL;
- class_Spatial = NULL;
- class_WeakRef = NULL;
- class_Array = NULL;
- class_Dictionary = NULL;
- class_MarshalUtils = NULL;
- class_ISerializationListener = NULL;
+ rawclass_Dictionary = nullptr;
+
+ class_Vector2 = nullptr;
+ class_Vector2i = nullptr;
+ class_Rect2 = nullptr;
+ class_Rect2i = nullptr;
+ class_Transform2D = nullptr;
+ class_Vector3 = nullptr;
+ class_Vector3i = nullptr;
+ class_Basis = nullptr;
+ class_Quat = nullptr;
+ class_Transform = nullptr;
+ class_AABB = nullptr;
+ class_Color = nullptr;
+ class_Plane = nullptr;
+ class_StringName = nullptr;
+ class_NodePath = nullptr;
+ class_RID = nullptr;
+ class_GodotObject = nullptr;
+ class_GodotResource = nullptr;
+ class_Node = nullptr;
+ class_Control = nullptr;
+ class_Node3D = nullptr;
+ class_WeakRef = nullptr;
+ class_Callable = nullptr;
+ class_SignalInfo = nullptr;
+ class_Array = nullptr;
+ class_Dictionary = nullptr;
+ class_MarshalUtils = nullptr;
+ class_ISerializationListener = nullptr;
#ifdef DEBUG_ENABLED
- class_DebuggingUtils = NULL;
+ class_DebuggingUtils = nullptr;
methodthunk_DebuggingUtils_GetStackFrameInfo.nullify();
#endif
- class_ExportAttribute = NULL;
- field_ExportAttribute_hint = NULL;
- field_ExportAttribute_hintString = NULL;
- class_SignalAttribute = NULL;
- class_ToolAttribute = NULL;
- class_RemoteAttribute = NULL;
- class_SyncAttribute = NULL;
- class_MasterAttribute = NULL;
- class_PuppetAttribute = NULL;
- class_SlaveAttribute = NULL;
- class_RemoteSyncAttribute = NULL;
- class_MasterSyncAttribute = NULL;
- class_PuppetSyncAttribute = NULL;
- class_GodotMethodAttribute = NULL;
- field_GodotMethodAttribute_methodName = NULL;
-
- field_GodotObject_ptr = NULL;
- field_NodePath_ptr = NULL;
- field_Image_ptr = NULL;
- field_RID_ptr = NULL;
+ class_ExportAttribute = nullptr;
+ field_ExportAttribute_hint = nullptr;
+ field_ExportAttribute_hintString = nullptr;
+ class_SignalAttribute = nullptr;
+ class_ToolAttribute = nullptr;
+ class_RemoteAttribute = nullptr;
+ class_MasterAttribute = nullptr;
+ class_PuppetAttribute = nullptr;
+ class_RemoteSyncAttribute = nullptr;
+ class_MasterSyncAttribute = nullptr;
+ class_PuppetSyncAttribute = nullptr;
+ class_GodotMethodAttribute = nullptr;
+ field_GodotMethodAttribute_methodName = nullptr;
+
+ field_GodotObject_ptr = nullptr;
+ field_StringName_ptr = nullptr;
+ field_NodePath_ptr = nullptr;
+ field_Image_ptr = nullptr;
+ field_RID_ptr = nullptr;
methodthunk_GodotObject_Dispose.nullify();
methodthunk_Array_GetPtr.nullify();
methodthunk_Dictionary_GetPtr.nullify();
methodthunk_SignalAwaiter_SignalCallback.nullify();
- methodthunk_SignalAwaiter_FailureCallback.nullify();
methodthunk_GodotTaskScheduler_Activate.nullify();
+ methodthunk_Delegate_Equals.nullify();
+
+ methodthunk_DelegateUtils_TrySerializeDelegate.nullify();
+ methodthunk_DelegateUtils_TryDeserializeDelegate.nullify();
+
// Start of MarshalUtils methods
methodthunk_MarshalUtils_TypeIsGenericArray.nullify();
methodthunk_MarshalUtils_TypeIsGenericDictionary.nullify();
+ methodthunk_MarshalUtils_TypeIsSystemGenericList.nullify();
+ methodthunk_MarshalUtils_TypeIsSystemGenericDictionary.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericIEnumerable.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericICollection.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify();
methodthunk_MarshalUtils_ArrayGetElementType.nullify();
methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify();
- methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType.nullify();
- methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info.nullify();
-
methodthunk_MarshalUtils_MakeGenericArrayType.nullify();
methodthunk_MarshalUtils_MakeGenericDictionaryType.nullify();
- methodthunk_MarshalUtils_EnumerableToArray.nullify();
- methodthunk_MarshalUtils_IDictionaryToDictionary.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryToDictionary.nullify();
-
// End of MarshalUtils methods
- task_scheduler_handle = Ref<MonoGCHandle>();
+ task_scheduler_handle = Ref<MonoGCHandleRef>();
}
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
@@ -204,6 +210,7 @@ void update_corlib_cache() {
CACHE_CLASS_AND_CHECK(IntPtr, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_intptr_class()));
CACHE_CLASS_AND_CHECK(System_Collections_IEnumerable, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IEnumerable"));
+ CACHE_CLASS_AND_CHECK(System_Collections_ICollection, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "ICollection"));
CACHE_CLASS_AND_CHECK(System_Collections_IDictionary, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IDictionary"));
#ifdef DEBUG_ENABLED
@@ -213,6 +220,8 @@ void update_corlib_cache() {
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true));
#endif
+ CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", 1));
+
CACHE_CLASS_AND_CHECK(KeyNotFoundException, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections.Generic", "KeyNotFoundException"));
cached_data.corlib_cache_updated = true;
@@ -221,23 +230,29 @@ void update_corlib_cache() {
void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(Vector2, GODOT_API_CLASS(Vector2));
+ CACHE_CLASS_AND_CHECK(Vector2i, GODOT_API_CLASS(Vector2i));
CACHE_CLASS_AND_CHECK(Rect2, GODOT_API_CLASS(Rect2));
+ CACHE_CLASS_AND_CHECK(Rect2i, GODOT_API_CLASS(Rect2i));
CACHE_CLASS_AND_CHECK(Transform2D, GODOT_API_CLASS(Transform2D));
CACHE_CLASS_AND_CHECK(Vector3, GODOT_API_CLASS(Vector3));
+ CACHE_CLASS_AND_CHECK(Vector3i, GODOT_API_CLASS(Vector3i));
CACHE_CLASS_AND_CHECK(Basis, GODOT_API_CLASS(Basis));
CACHE_CLASS_AND_CHECK(Quat, GODOT_API_CLASS(Quat));
CACHE_CLASS_AND_CHECK(Transform, GODOT_API_CLASS(Transform));
CACHE_CLASS_AND_CHECK(AABB, GODOT_API_CLASS(AABB));
CACHE_CLASS_AND_CHECK(Color, GODOT_API_CLASS(Color));
CACHE_CLASS_AND_CHECK(Plane, GODOT_API_CLASS(Plane));
+ CACHE_CLASS_AND_CHECK(StringName, GODOT_API_CLASS(StringName));
CACHE_CLASS_AND_CHECK(NodePath, GODOT_API_CLASS(NodePath));
CACHE_CLASS_AND_CHECK(RID, GODOT_API_CLASS(RID));
CACHE_CLASS_AND_CHECK(GodotObject, GODOT_API_CLASS(Object));
CACHE_CLASS_AND_CHECK(GodotResource, GODOT_API_CLASS(Resource));
CACHE_CLASS_AND_CHECK(Node, GODOT_API_CLASS(Node));
CACHE_CLASS_AND_CHECK(Control, GODOT_API_CLASS(Control));
- CACHE_CLASS_AND_CHECK(Spatial, GODOT_API_CLASS(Spatial));
+ CACHE_CLASS_AND_CHECK(Node3D, GODOT_API_CLASS(Node3D));
CACHE_CLASS_AND_CHECK(WeakRef, GODOT_API_CLASS(WeakRef));
+ CACHE_CLASS_AND_CHECK(Callable, GODOT_API_CLASS(Callable));
+ CACHE_CLASS_AND_CHECK(SignalInfo, GODOT_API_CLASS(SignalInfo));
CACHE_CLASS_AND_CHECK(Array, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Array));
CACHE_CLASS_AND_CHECK(Dictionary, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary));
CACHE_CLASS_AND_CHECK(MarshalUtils, GODOT_API_CLASS(MarshalUtils));
@@ -254,10 +269,8 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute));
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute));
- CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute));
CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute));
CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute));
- CACHE_CLASS_AND_CHECK(SlaveAttribute, GODOT_API_CLASS(SlaveAttribute));
CACHE_CLASS_AND_CHECK(RemoteSyncAttribute, GODOT_API_CLASS(RemoteSyncAttribute));
CACHE_CLASS_AND_CHECK(MasterSyncAttribute, GODOT_API_CLASS(MasterSyncAttribute));
CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute));
@@ -265,6 +278,7 @@ void update_godot_api_cache() {
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
CACHE_FIELD_AND_CHECK(GodotObject, ptr, CACHED_CLASS(GodotObject)->get_field(BINDINGS_PTR_FIELD));
+ CACHE_FIELD_AND_CHECK(StringName, ptr, CACHED_CLASS(StringName)->get_field(BINDINGS_PTR_FIELD));
CACHE_FIELD_AND_CHECK(NodePath, ptr, CACHED_CLASS(NodePath)->get_field(BINDINGS_PTR_FIELD));
CACHE_FIELD_AND_CHECK(RID, ptr, CACHED_CLASS(RID)->get_field(BINDINGS_PTR_FIELD));
@@ -272,29 +286,27 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(Array, GetPtr, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Array)->get_method("GetPtr", 0));
CACHE_METHOD_THUNK_AND_CHECK(Dictionary, GetPtr, GODOT_API_NS_CLASS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary)->get_method("GetPtr", 0));
CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1));
- CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, GODOT_API_CLASS(SignalAwaiter)->get_method("FailureCallback", 0));
CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0));
+ CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TrySerializeDelegate, GODOT_API_CLASS(DelegateUtils)->get_method("TrySerializeDelegate", 2));
+ CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TryDeserializeDelegate, GODOT_API_CLASS(DelegateUtils)->get_method("TryDeserializeDelegate", 2));
+
// Start of MarshalUtils methods
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericArray, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericArray", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericDictionary", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericList, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericList", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericDictionary", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIEnumerable, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIEnumerable", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 1));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 1));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 3));
-
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericArrayType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericArrayType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericDictionaryType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericDictionaryType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, EnumerableToArray, GODOT_API_CLASS(MarshalUtils)->get_method("EnumerableToArray", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("IDictionaryToDictionary", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryToDictionary", 2));
-
// End of MarshalUtils methods
#ifdef DEBUG_ENABLED
@@ -304,7 +316,7 @@ void update_godot_api_cache() {
// TODO Move to CSharpLanguage::init() and do handle disposal
MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr());
GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler));
- cached_data.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler);
+ cached_data.task_scheduler_handle = MonoGCHandleRef::create_strong(task_scheduler);
cached_data.godot_api_cache_updated = true;
}
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index 1dc6b70479..3cf2bd6ce5 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -58,6 +58,7 @@ struct CachedData {
GDMonoClass *class_IntPtr; // System.IntPtr
GDMonoClass *class_System_Collections_IEnumerable;
+ GDMonoClass *class_System_Collections_ICollection;
GDMonoClass *class_System_Collections_IDictionary;
#ifdef DEBUG_ENABLED
@@ -73,23 +74,29 @@ struct CachedData {
// -----------------------------------------------
GDMonoClass *class_Vector2;
+ GDMonoClass *class_Vector2i;
GDMonoClass *class_Rect2;
+ GDMonoClass *class_Rect2i;
GDMonoClass *class_Transform2D;
GDMonoClass *class_Vector3;
+ GDMonoClass *class_Vector3i;
GDMonoClass *class_Basis;
GDMonoClass *class_Quat;
GDMonoClass *class_Transform;
GDMonoClass *class_AABB;
GDMonoClass *class_Color;
GDMonoClass *class_Plane;
+ GDMonoClass *class_StringName;
GDMonoClass *class_NodePath;
GDMonoClass *class_RID;
GDMonoClass *class_GodotObject;
GDMonoClass *class_GodotResource;
GDMonoClass *class_Node;
GDMonoClass *class_Control;
- GDMonoClass *class_Spatial;
+ GDMonoClass *class_Node3D;
GDMonoClass *class_WeakRef;
+ GDMonoClass *class_Callable;
+ GDMonoClass *class_SignalInfo;
GDMonoClass *class_Array;
GDMonoClass *class_Dictionary;
GDMonoClass *class_MarshalUtils;
@@ -106,17 +113,16 @@ struct CachedData {
GDMonoClass *class_SignalAttribute;
GDMonoClass *class_ToolAttribute;
GDMonoClass *class_RemoteAttribute;
- GDMonoClass *class_SyncAttribute;
+ GDMonoClass *class_MasterAttribute;
+ GDMonoClass *class_PuppetAttribute;
GDMonoClass *class_RemoteSyncAttribute;
GDMonoClass *class_MasterSyncAttribute;
GDMonoClass *class_PuppetSyncAttribute;
- GDMonoClass *class_MasterAttribute;
- GDMonoClass *class_PuppetAttribute;
- GDMonoClass *class_SlaveAttribute;
GDMonoClass *class_GodotMethodAttribute;
GDMonoField *field_GodotMethodAttribute_methodName;
GDMonoField *field_GodotObject_ptr;
+ GDMonoField *field_StringName_ptr;
GDMonoField *field_NodePath_ptr;
GDMonoField *field_Image_ptr;
GDMonoField *field_RID_ptr;
@@ -125,32 +131,32 @@ struct CachedData {
GDMonoMethodThunkR<Array *, MonoObject *> methodthunk_Array_GetPtr;
GDMonoMethodThunkR<Dictionary *, MonoObject *> methodthunk_Dictionary_GetPtr;
GDMonoMethodThunk<MonoObject *, MonoArray *> methodthunk_SignalAwaiter_SignalCallback;
- GDMonoMethodThunk<MonoObject *> methodthunk_SignalAwaiter_FailureCallback;
GDMonoMethodThunk<MonoObject *> methodthunk_GodotTaskScheduler_Activate;
+ GDMonoMethodThunkR<MonoBoolean, MonoObject *, MonoObject *> methodthunk_Delegate_Equals;
+
+ GDMonoMethodThunkR<MonoBoolean, MonoDelegate *, MonoObject *> methodthunk_DelegateUtils_TrySerializeDelegate;
+ GDMonoMethodThunkR<MonoBoolean, MonoObject *, MonoDelegate **> methodthunk_DelegateUtils_TryDeserializeDelegate;
+
// Start of MarshalUtils methods
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericArray;
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericDictionary;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericList;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericDictionary;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIEnumerable;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary;
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType;
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info;
-
GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericArrayType;
GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericDictionaryType;
- GDMonoMethodThunk<MonoObject *, Array *> methodthunk_MarshalUtils_EnumerableToArray;
- GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_IDictionaryToDictionary;
- GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_GenericIDictionaryToDictionary;
-
// End of MarshalUtils methods
- Ref<MonoGCHandle> task_scheduler_handle;
+ Ref<MonoGCHandleRef> task_scheduler_handle;
bool corlib_cache_updated;
bool godot_api_cache_updated;
@@ -177,14 +183,6 @@ inline void clear_godot_api_cache() {
cached_data.clear_godot_api_cache();
}
-_FORCE_INLINE_ bool tools_godot_api_check() {
-#ifdef TOOLS_ENABLED
- return cached_data.godot_api_cache_updated;
-#else
- return true; // Assume it's updated if this was called, otherwise it's a bug
-#endif
-}
-
} // namespace GDMonoCache
#define CACHED_CLASS(m_class) (GDMonoCache::cached_data.class_##m_class)
@@ -195,10 +193,4 @@ _FORCE_INLINE_ bool tools_godot_api_check() {
#define CACHED_METHOD_THUNK(m_class, m_method) (GDMonoCache::cached_data.methodthunk_##m_class##_##m_method)
#define CACHED_PROPERTY(m_class, m_property) (GDMonoCache::cached_data.property_##m_class##_##m_property)
-#ifdef REAL_T_IS_DOUBLE
-#define REAL_T_MONOCLASS CACHED_CLASS_RAW(double)
-#else
-#define REAL_T_MONOCLASS CACHED_CLASS_RAW(float)
-#endif
-
#endif // GD_MONO_CACHE_H
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index 648f5f6c6b..2c65f7e3a0 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -31,6 +31,7 @@
#include "gd_mono_class.h"
#include <mono/metadata/attrdefs.h>
+#include <mono/metadata/debug-helpers.h>
#include "gd_mono_assembly.h"
#include "gd_mono_cache.h"
@@ -40,7 +41,7 @@ String GDMonoClass::get_full_name(MonoClass *p_mono_class) {
// mono_type_get_full_name is not exposed to embedders, but this seems to do the job
MonoReflectionType *type_obj = mono_type_get_object(mono_domain_get(), get_mono_type(p_mono_class));
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoString *str = GDMonoUtils::object_to_string((MonoObject *)type_obj, &exc);
UNHANDLED_EXCEPTION(exc);
@@ -55,7 +56,11 @@ String GDMonoClass::get_full_name() const {
return get_full_name(mono_class);
}
-MonoType *GDMonoClass::get_mono_type() {
+String GDMonoClass::get_type_desc() const {
+ return GDMonoUtils::get_type_desc(get_mono_type());
+}
+
+MonoType *GDMonoClass::get_mono_type() const {
// Careful, you cannot compare two MonoType*.
// There is mono_metadata_type_equal, how is this different from comparing two MonoClass*?
return get_mono_type(mono_class);
@@ -76,12 +81,12 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
GDMonoClass *GDMonoClass::get_parent_class() {
MonoClass *parent_mono_class = mono_class_get_parent(mono_class);
- return parent_mono_class ? GDMono::get_singleton()->get_class(parent_mono_class) : NULL;
+ return parent_mono_class ? GDMono::get_singleton()->get_class(parent_mono_class) : nullptr;
}
GDMonoClass *GDMonoClass::get_nesting_class() {
MonoClass *nesting_type = mono_class_get_nesting_type(mono_class);
- return nesting_type ? GDMono::get_singleton()->get_class(nesting_type) : NULL;
+ return nesting_type ? GDMono::get_singleton()->get_class(nesting_type) : nullptr;
}
#ifdef TOOLS_ENABLED
@@ -92,9 +97,9 @@ Vector<MonoClassField *> GDMonoClass::get_enum_fields() {
Vector<MonoClassField *> enum_fields;
- void *iter = NULL;
- MonoClassField *raw_field = NULL;
- while ((raw_field = mono_class_get_fields(get_mono_ptr(), &iter)) != NULL) {
+ void *iter = nullptr;
+ MonoClassField *raw_field = nullptr;
+ while ((raw_field = mono_class_get_fields(get_mono_ptr(), &iter)) != nullptr) {
uint32_t field_flags = mono_field_get_flags(raw_field);
// Enums have an instance field named value__ which holds the value of the enum.
@@ -126,21 +131,21 @@ bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) {
MonoObject *GDMonoClass::get_attribute(GDMonoClass *p_attr_class) {
#ifdef DEBUG_ENABLED
- ERR_FAIL_NULL_V(p_attr_class, NULL);
+ ERR_FAIL_NULL_V(p_attr_class, nullptr);
#endif
if (!attrs_fetched)
fetch_attributes();
if (!attributes)
- return NULL;
+ return nullptr;
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
void GDMonoClass::fetch_attributes() {
- ERR_FAIL_COND(attributes != NULL);
+ ERR_FAIL_COND(attributes != nullptr);
attributes = mono_custom_attrs_from_class(get_mono_ptr());
attrs_fetched = true;
@@ -153,9 +158,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
if (methods_fetched)
return;
- void *iter = NULL;
- MonoMethod *raw_method = NULL;
- while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != NULL) {
+ void *iter = nullptr;
+ MonoMethod *raw_method = nullptr;
+ while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) {
StringName name = mono_method_get_name(raw_method);
// get_method implicitly fetches methods and adds them to this->methods
@@ -198,7 +203,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
}
#endif
- uint32_t flags = mono_method_get_flags(method->mono_method, NULL);
+ uint32_t flags = mono_method_get_flags(method->mono_method, nullptr);
if (!(flags & MONO_METHOD_ATTR_VIRTUAL))
continue;
@@ -242,21 +247,21 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p_name) {
- ERR_FAIL_COND_V(!methods_fetched, NULL);
+ ERR_FAIL_COND_V(!methods_fetched, nullptr);
- const MethodKey *k = NULL;
+ const MethodKey *k = nullptr;
while ((k = methods.next(k))) {
if (k->name == p_name)
return methods.get(*k);
}
- return NULL;
+ return nullptr;
}
bool GDMonoClass::has_fetched_method_unknown_params(const StringName &p_name) {
- return get_fetched_method_unknown_params(p_name) != NULL;
+ return get_fetched_method_unknown_params(p_name) != nullptr;
}
bool GDMonoClass::implements_interface(GDMonoClass *p_interface) {
@@ -264,6 +269,12 @@ bool GDMonoClass::implements_interface(GDMonoClass *p_interface) {
return mono_class_implements_interface(mono_class, p_interface->get_mono_ptr());
}
+bool GDMonoClass::has_public_parameterless_ctor() {
+
+ GDMonoMethod *ctor = get_method(".ctor", 0);
+ return ctor && ctor->get_visibility() == IMonoClassMember::PUBLIC;
+}
+
GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) {
MethodKey key = MethodKey(p_name, p_params_count);
@@ -274,7 +285,7 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_cou
return *match;
if (methods_fetched)
- return NULL;
+ return nullptr;
MonoMethod *raw_method = mono_class_get_method_from_name(mono_class, String(p_name).utf8().get_data(), p_params_count);
@@ -285,7 +296,7 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_cou
return method;
}
- return NULL;
+ return nullptr;
}
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) {
@@ -307,7 +318,7 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count) {
- ERR_FAIL_NULL_V(p_raw_method, NULL);
+ ERR_FAIL_NULL_V(p_raw_method, nullptr);
MethodKey key = MethodKey(p_name, p_params_count);
@@ -328,7 +339,10 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo
MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class);
mono_method_desc_free(desc);
- ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, NULL);
+ if (!method)
+ return nullptr;
+
+ ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr);
return get_method(method);
}
@@ -341,7 +355,7 @@ GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
return result->value();
if (fields_fetched)
- return NULL;
+ return nullptr;
MonoClassField *raw_field = mono_class_get_field_from_name(mono_class, String(p_name).utf8().get_data());
@@ -352,7 +366,7 @@ GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
return field;
}
- return NULL;
+ return nullptr;
}
const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
@@ -360,9 +374,9 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
if (fields_fetched)
return fields_list;
- void *iter = NULL;
- MonoClassField *raw_field = NULL;
- while ((raw_field = mono_class_get_fields(mono_class, &iter)) != NULL) {
+ void *iter = nullptr;
+ MonoClassField *raw_field = nullptr;
+ while ((raw_field = mono_class_get_fields(mono_class, &iter)) != nullptr) {
StringName name = mono_field_get_name(raw_field);
Map<StringName, GDMonoField *>::Element *match = fields.find(name);
@@ -389,7 +403,7 @@ GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
return result->value();
if (properties_fetched)
- return NULL;
+ return nullptr;
MonoProperty *raw_property = mono_class_get_property_from_name(mono_class, String(p_name).utf8().get_data());
@@ -400,7 +414,7 @@ GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
return property;
}
- return NULL;
+ return nullptr;
}
const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
@@ -408,9 +422,9 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
if (properties_fetched)
return properties_list;
- void *iter = NULL;
- MonoProperty *raw_property = NULL;
- while ((raw_property = mono_class_get_properties(mono_class, &iter)) != NULL) {
+ void *iter = nullptr;
+ MonoProperty *raw_property = nullptr;
+ while ((raw_property = mono_class_get_properties(mono_class, &iter)) != nullptr) {
StringName name = mono_property_get_name(raw_property);
Map<StringName, GDMonoProperty *>::Element *match = properties.find(name);
@@ -433,9 +447,9 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
if (delegates_fetched)
return delegates_list;
- void *iter = NULL;
- MonoClass *raw_class = NULL;
- while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != NULL) {
+ void *iter = nullptr;
+ MonoClass *raw_class = nullptr;
+ while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) {
if (mono_class_is_delegate(raw_class)) {
StringName name = mono_class_get_name(raw_class);
@@ -459,9 +473,9 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() {
if (!method_list_fetched) {
- void *iter = NULL;
- MonoMethod *raw_method = NULL;
- while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != NULL) {
+ void *iter = nullptr;
+ MonoMethod *raw_method = nullptr;
+ while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) {
method_list.push_back(memnew(GDMonoMethod(mono_method_get_name(raw_method), raw_method)));
}
@@ -479,7 +493,7 @@ GDMonoClass::GDMonoClass(const StringName &p_namespace, const StringName &p_name
assembly = p_assembly;
attrs_fetched = false;
- attributes = NULL;
+ attributes = nullptr;
methods_fetched = false;
method_list_fetched = false;
@@ -512,7 +526,7 @@ GDMonoClass::~GDMonoClass() {
Vector<GDMonoMethod *> deleted_methods;
deleted_methods.resize(methods.size());
- const MethodKey *k = NULL;
+ const MethodKey *k = nullptr;
while ((k = methods.next(k))) {
GDMonoMethod *method = methods.get(*k);
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index 0c9a8cdafe..9237aae057 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -31,8 +31,6 @@
#ifndef GD_MONO_CLASS_H
#define GD_MONO_CLASS_H
-#include <mono/metadata/debug-helpers.h>
-
#include "core/map.h"
#include "core/ustring.h"
@@ -107,7 +105,8 @@ public:
static MonoType *get_mono_type(MonoClass *p_mono_class);
String get_full_name() const;
- MonoType *get_mono_type();
+ String get_type_desc() const;
+ MonoType *get_mono_type() const;
uint32_t get_flags() const;
bool is_static() const;
@@ -137,6 +136,7 @@ public:
void fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base);
bool implements_interface(GDMonoClass *p_interface);
+ bool has_public_parameterless_ctor();
GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0);
GDMonoMethod *get_method(MonoMethod *p_raw_method);
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index 178647b968..e76cb84d43 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -37,6 +37,10 @@
#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"
+void GDMonoField::set_value(MonoObject *p_object, MonoObject *p_value) {
+ mono_field_set_value(p_object, mono_field, p_value);
+}
+
void GDMonoField::set_value_raw(MonoObject *p_object, void *p_ptr) {
mono_field_set_value(p_object, mono_field, &p_ptr);
}
@@ -112,7 +116,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
case MONO_TYPE_STRING: {
if (p_value.get_type() == Variant::NIL) {
// Otherwise, Variant -> String would return the string "Null"
- MonoString *mono_string = NULL;
+ MonoString *mono_string = nullptr;
mono_field_set_value(p_object, mono_field, mono_string);
} else {
MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
@@ -128,11 +132,21 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
+ if (tclass == CACHED_CLASS(Vector2i)) {
+ SET_FROM_STRUCT(Vector2i);
+ break;
+ }
+
if (tclass == CACHED_CLASS(Rect2)) {
SET_FROM_STRUCT(Rect2);
break;
}
+ if (tclass == CACHED_CLASS(Rect2i)) {
+ SET_FROM_STRUCT(Rect2i);
+ break;
+ }
+
if (tclass == CACHED_CLASS(Transform2D)) {
SET_FROM_STRUCT(Transform2D);
break;
@@ -143,6 +157,11 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
+ if (tclass == CACHED_CLASS(Vector3i)) {
+ SET_FROM_STRUCT(Vector3i);
+ break;
+ }
+
if (tclass == CACHED_CLASS(Basis)) {
SET_FROM_STRUCT(Basis);
break;
@@ -173,6 +192,18 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
+ if (tclass == CACHED_CLASS(Callable)) {
+ GDMonoMarshal::M_Callable val = GDMonoMarshal::callable_to_managed(p_value.operator Callable());
+ mono_field_set_value(p_object, mono_field, &val);
+ break;
+ }
+
+ if (tclass == CACHED_CLASS(SignalInfo)) {
+ GDMonoMarshal::M_SignalInfo val = GDMonoMarshal::signal_info_to_managed(p_value.operator Signal());
+ mono_field_set_value(p_object, mono_field, &val);
+ break;
+ }
+
if (mono_class_is_enum(tclass->get_mono_ptr())) {
MonoType *enum_basetype = mono_class_enum_basetype(tclass->get_mono_ptr());
switch (mono_type_get_type(enum_basetype)) {
@@ -247,37 +278,54 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
}
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
- SET_FROM_ARRAY(PoolByteArray);
+ SET_FROM_ARRAY(PackedByteArray);
break;
}
if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
- SET_FROM_ARRAY(PoolIntArray);
+ SET_FROM_ARRAY(PackedInt32Array);
+ break;
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
+ SET_FROM_ARRAY(PackedInt64Array);
break;
}
- if (array_type->eklass == REAL_T_MONOCLASS) {
- SET_FROM_ARRAY(PoolRealArray);
+ if (array_type->eklass == CACHED_CLASS_RAW(float)) {
+ SET_FROM_ARRAY(PackedFloat32Array);
+ break;
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(double)) {
+ SET_FROM_ARRAY(PackedFloat64Array);
break;
}
if (array_type->eklass == CACHED_CLASS_RAW(String)) {
- SET_FROM_ARRAY(PoolStringArray);
+ SET_FROM_ARRAY(PackedStringArray);
break;
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
- SET_FROM_ARRAY(PoolVector2Array);
+ SET_FROM_ARRAY(PackedVector2Array);
break;
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
- SET_FROM_ARRAY(PoolVector3Array);
+ SET_FROM_ARRAY(PackedVector3Array);
break;
}
if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
- SET_FROM_ARRAY(PoolColorArray);
+ SET_FROM_ARRAY(PackedColorArray);
+ break;
+ }
+
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
+ MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class);
+ mono_field_set_value(p_object, mono_field, managed);
break;
}
@@ -294,6 +342,12 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
+ if (CACHED_CLASS(StringName) == type_class) {
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName());
+ mono_field_set_value(p_object, mono_field, managed);
+ break;
+ }
+
if (CACHED_CLASS(NodePath) == type_class) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
mono_field_set_value(p_object, mono_field, managed);
@@ -306,56 +360,22 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Dictionary or IDictionary
+ if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Array or ICollection or IEnumerable
+ if (CACHED_CLASS(Array) == type_class ||
+ type_class == CACHED_CLASS(System_Collections_ICollection) ||
+ type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
mono_field_set_value(p_object, mono_field, managed);
break;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- } else {
- MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
- }
-
ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
} break;
@@ -370,7 +390,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
int32_t val = p_value.operator signed int();
mono_field_set_value(p_object, mono_field, &val);
} break;
- case Variant::REAL: {
+ case Variant::FLOAT: {
#ifdef REAL_T_IS_DOUBLE
double val = p_value.operator double();
mono_field_set_value(p_object, mono_field, &val);
@@ -386,12 +406,21 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
case Variant::VECTOR2: {
SET_FROM_STRUCT(Vector2);
} break;
+ case Variant::VECTOR2I: {
+ SET_FROM_STRUCT(Vector2i);
+ } break;
case Variant::RECT2: {
SET_FROM_STRUCT(Rect2);
} break;
+ case Variant::RECT2I: {
+ SET_FROM_STRUCT(Rect2i);
+ } break;
case Variant::VECTOR3: {
SET_FROM_STRUCT(Vector3);
} break;
+ case Variant::VECTOR3I: {
+ SET_FROM_STRUCT(Vector3i);
+ } break;
case Variant::TRANSFORM2D: {
SET_FROM_STRUCT(Transform2D);
} break;
@@ -413,6 +442,10 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
case Variant::COLOR: {
SET_FROM_STRUCT(Color);
} break;
+ case Variant::STRING_NAME: {
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName());
+ mono_field_set_value(p_object, mono_field, managed);
+ } break;
case Variant::NODE_PATH: {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
mono_field_set_value(p_object, mono_field, managed);
@@ -424,8 +457,15 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
case Variant::OBJECT: {
MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
mono_field_set_value(p_object, mono_field, managed);
- break;
- }
+ } break;
+ case Variant::CALLABLE: {
+ GDMonoMarshal::M_Callable val = GDMonoMarshal::callable_to_managed(p_value.operator Callable());
+ mono_field_set_value(p_object, mono_field, &val);
+ } break;
+ case Variant::SIGNAL: {
+ GDMonoMarshal::M_SignalInfo val = GDMonoMarshal::signal_info_to_managed(p_value.operator Signal());
+ mono_field_set_value(p_object, mono_field, &val);
+ } break;
case Variant::DICTIONARY: {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
mono_field_set_value(p_object, mono_field, managed);
@@ -434,26 +474,32 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
mono_field_set_value(p_object, mono_field, managed);
} break;
- case Variant::POOL_BYTE_ARRAY: {
- SET_FROM_ARRAY(PoolByteArray);
+ case Variant::PACKED_BYTE_ARRAY: {
+ SET_FROM_ARRAY(PackedByteArray);
+ } break;
+ case Variant::PACKED_INT32_ARRAY: {
+ SET_FROM_ARRAY(PackedInt32Array);
} break;
- case Variant::POOL_INT_ARRAY: {
- SET_FROM_ARRAY(PoolIntArray);
+ case Variant::PACKED_INT64_ARRAY: {
+ SET_FROM_ARRAY(PackedInt64Array);
} break;
- case Variant::POOL_REAL_ARRAY: {
- SET_FROM_ARRAY(PoolRealArray);
+ case Variant::PACKED_FLOAT32_ARRAY: {
+ SET_FROM_ARRAY(PackedFloat32Array);
} break;
- case Variant::POOL_STRING_ARRAY: {
- SET_FROM_ARRAY(PoolStringArray);
+ case Variant::PACKED_FLOAT64_ARRAY: {
+ SET_FROM_ARRAY(PackedFloat64Array);
} break;
- case Variant::POOL_VECTOR2_ARRAY: {
- SET_FROM_ARRAY(PoolVector2Array);
+ case Variant::PACKED_STRING_ARRAY: {
+ SET_FROM_ARRAY(PackedStringArray);
} break;
- case Variant::POOL_VECTOR3_ARRAY: {
- SET_FROM_ARRAY(PoolVector3Array);
+ case Variant::PACKED_VECTOR2_ARRAY: {
+ SET_FROM_ARRAY(PackedVector2Array);
} break;
- case Variant::POOL_COLOR_ARRAY: {
- SET_FROM_ARRAY(PoolColorArray);
+ case Variant::PACKED_VECTOR3_ARRAY: {
+ SET_FROM_ARRAY(PackedVector3Array);
+ } break;
+ case Variant::PACKED_COLOR_ARRAY: {
+ SET_FROM_ARRAY(PackedColorArray);
} break;
default: break;
}
@@ -462,52 +508,62 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(),
+ type.type_class, key_reftype, value_reftype);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(),
+ type.type_class, elem_reftype);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ MonoReflectionType *key_reftype;
+ MonoReflectionType *value_reftype;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
+
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- } else {
- MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
+ MonoReflectionType *elem_reftype;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
+
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class);
+ mono_field_set_value(p_object, mono_field, managed);
+ break;
}
} break;
@@ -550,19 +606,19 @@ bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) {
}
MonoObject *GDMonoField::get_attribute(GDMonoClass *p_attr_class) {
- ERR_FAIL_NULL_V(p_attr_class, NULL);
+ ERR_FAIL_NULL_V(p_attr_class, nullptr);
if (!attrs_fetched)
fetch_attributes();
if (!attributes)
- return NULL;
+ return nullptr;
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
void GDMonoField::fetch_attributes() {
- ERR_FAIL_COND(attributes != NULL);
+ ERR_FAIL_COND(attributes != nullptr);
attributes = mono_custom_attrs_from_field(owner->get_mono_ptr(), mono_field);
attrs_fetched = true;
}
@@ -598,7 +654,7 @@ GDMonoField::GDMonoField(MonoClassField *p_mono_field, GDMonoClass *p_owner) {
type.type_class = GDMono::get_singleton()->get_class(field_type_class);
attrs_fetched = false;
- attributes = NULL;
+ attributes = nullptr;
}
GDMonoField::~GDMonoField() {
diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h
index 76ee0963c4..61f2c8f071 100644
--- a/modules/mono/mono_gd/gd_mono_field.h
+++ b/modules/mono/mono_gd/gd_mono_field.h
@@ -47,21 +47,22 @@ class GDMonoField : public IMonoClassMember {
MonoCustomAttrInfo *attributes;
public:
- virtual GDMonoClass *get_enclosing_class() const GD_FINAL { return owner; }
+ virtual GDMonoClass *get_enclosing_class() const final { return owner; }
- virtual MemberType get_member_type() const GD_FINAL { return MEMBER_TYPE_FIELD; }
+ virtual MemberType get_member_type() const final { return MEMBER_TYPE_FIELD; }
- virtual StringName get_name() const GD_FINAL { return name; }
+ virtual StringName get_name() const final { return name; }
- virtual bool is_static() GD_FINAL;
- virtual Visibility get_visibility() GD_FINAL;
+ virtual bool is_static() final;
+ virtual Visibility get_visibility() final;
- virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL;
- virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL;
+ virtual bool has_attribute(GDMonoClass *p_attr_class) final;
+ virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) final;
void fetch_attributes();
_FORCE_INLINE_ ManagedType get_type() const { return type; }
+ void set_value(MonoObject *p_object, MonoObject *p_value);
void set_value_raw(MonoObject *p_object, void *p_ptr);
void set_value_from_variant(MonoObject *p_object, const Variant &p_value);
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index 75aa77c7b0..1898785699 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -33,11 +33,13 @@
#include "../csharp_script.h"
#include "../mono_gc_handle.h"
#include "../utils/macros.h"
-#include "../utils/thread_local.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"
+#include "core/debugger/engine_debugger.h"
+#include "core/debugger/script_debugger.h"
+
#include <mono/metadata/exception.h>
namespace GDMonoInternals {
@@ -59,7 +61,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
GDMonoClass *native = GDMonoUtils::get_class_native_base(klass);
- CRASH_COND(native == NULL);
+ CRASH_COND(native == nullptr);
if (native == klass) {
// If it's just a wrapper Godot class and not a custom inheriting class, then attach a
@@ -73,7 +75,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
script_binding.inited = true;
script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass);
script_binding.wrapper_class = klass;
- script_binding.gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed);
+ script_binding.gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed);
script_binding.owner = unmanaged;
if (ref) {
@@ -99,15 +101,17 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
return;
}
- Ref<MonoGCHandle> gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed);
+ MonoGCHandleData gchandle = ref ? MonoGCHandleData::new_weak_handle(managed) : MonoGCHandleData::new_strong_handle(managed);
Ref<CSharpScript> script = CSharpScript::create_for_managed_type(klass, native);
CRASH_COND(script.is_null());
- ScriptInstance *si = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
+ CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
+
+ unmanaged->set_script_and_instance(script, csharp_instance);
- unmanaged->set_script_and_instance(script.get_ref_ptr(), si);
+ csharp_instance->connect_event_signals();
}
void unhandled_exception(MonoException *p_exc) {
@@ -115,13 +119,13 @@ void unhandled_exception(MonoException *p_exc) {
if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) {
// Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
- GDMono::unhandled_exception_hook((MonoObject *)p_exc, NULL);
+ GDMono::unhandled_exception_hook((MonoObject *)p_exc, nullptr);
GD_UNREACHABLE();
} else {
#ifdef DEBUG_ENABLED
GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc);
- if (ScriptDebugger::get_singleton())
- ScriptDebugger::get_singleton()->idle_poll();
+ if (EngineDebugger::is_active())
+ EngineDebugger::get_singleton()->poll_events(false);
#endif
}
}
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index 76828a66e0..ca16c2b76a 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -46,13 +46,13 @@ static CharString get_default_log_level() {
#endif
}
-GDMonoLog *GDMonoLog::singleton = NULL;
+GDMonoLog *GDMonoLog::singleton = nullptr;
-#if !defined(JAVASCRIPT_ENABLED)
+#ifdef GD_MONO_LOG_ENABLED
static int get_log_level_id(const char *p_log_level) {
- const char *valid_log_levels[] = { "error", "critical", "warning", "message", "info", "debug", NULL };
+ const char *valid_log_levels[] = { "error", "critical", "warning", "message", "info", "debug", nullptr };
int i = 0;
while (valid_log_levels[i]) {
@@ -191,7 +191,7 @@ GDMonoLog::GDMonoLog() {
GDMonoLog::~GDMonoLog() {
- singleton = NULL;
+ singleton = nullptr;
if (log_file) {
log_file->close();
@@ -213,7 +213,7 @@ GDMonoLog::GDMonoLog() {
GDMonoLog::~GDMonoLog() {
- singleton = NULL;
+ singleton = nullptr;
}
#endif // !defined(JAVASCRIPT_ENABLED)
diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h
index ecf4c78b1a..1fc21f7df5 100644
--- a/modules/mono/mono_gd/gd_mono_log.h
+++ b/modules/mono/mono_gd/gd_mono_log.h
@@ -35,13 +35,18 @@
#include "core/typedefs.h"
-#if !defined(JAVASCRIPT_ENABLED)
+#if !defined(JAVASCRIPT_ENABLED) && !defined(IPHONE_ENABLED)
+// We have custom mono log callbacks for WASM and iOS
+#define GD_MONO_LOG_ENABLED
+#endif
+
+#ifdef GD_MONO_LOG_ENABLED
#include "core/os/file_access.h"
#endif
class GDMonoLog {
-#if !defined(JAVASCRIPT_ENABLED)
+#ifdef GD_MONO_LOG_ENABLED
int log_level_id;
FileAccess *log_file;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 19d627218e..91ee07388b 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -30,13 +30,14 @@
#include "gd_mono_marshal.h"
+#include "../signal_awaiter_utils.h"
#include "gd_mono.h"
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
namespace GDMonoMarshal {
-Variant::Type managed_to_variant_type(const ManagedType &p_type) {
+Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant) {
switch (p_type.type_encoding) {
case MONO_TYPE_BOOLEAN:
return Variant::BOOL;
@@ -60,9 +61,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
return Variant::INT;
case MONO_TYPE_R4:
- return Variant::REAL;
+ return Variant::FLOAT;
case MONO_TYPE_R8:
- return Variant::REAL;
+ return Variant::FLOAT;
case MONO_TYPE_STRING: {
return Variant::STRING;
@@ -74,15 +75,24 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
if (vtclass == CACHED_CLASS(Vector2))
return Variant::VECTOR2;
+ if (vtclass == CACHED_CLASS(Vector2i))
+ return Variant::VECTOR2I;
+
if (vtclass == CACHED_CLASS(Rect2))
return Variant::RECT2;
+ if (vtclass == CACHED_CLASS(Rect2i))
+ return Variant::RECT2I;
+
if (vtclass == CACHED_CLASS(Transform2D))
return Variant::TRANSFORM2D;
if (vtclass == CACHED_CLASS(Vector3))
return Variant::VECTOR3;
+ if (vtclass == CACHED_CLASS(Vector3i))
+ return Variant::VECTOR3I;
+
if (vtclass == CACHED_CLASS(Basis))
return Variant::BASIS;
@@ -101,6 +111,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
if (vtclass == CACHED_CLASS(Plane))
return Variant::PLANE;
+ if (vtclass == CACHED_CLASS(Callable))
+ return Variant::CALLABLE;
+
+ if (vtclass == CACHED_CLASS(SignalInfo))
+ return Variant::SIGNAL;
+
if (mono_class_is_enum(vtclass->get_mono_ptr()))
return Variant::INT;
} break;
@@ -113,25 +129,35 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
return Variant::ARRAY;
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
- return Variant::POOL_BYTE_ARRAY;
+ return Variant::PACKED_BYTE_ARRAY;
if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
- return Variant::POOL_INT_ARRAY;
+ return Variant::PACKED_INT32_ARRAY;
+
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t))
+ return Variant::PACKED_INT64_ARRAY;
+
+ if (array_type->eklass == CACHED_CLASS_RAW(float))
+ return Variant::PACKED_FLOAT32_ARRAY;
- if (array_type->eklass == REAL_T_MONOCLASS)
- return Variant::POOL_REAL_ARRAY;
+ if (array_type->eklass == CACHED_CLASS_RAW(double))
+ return Variant::PACKED_FLOAT64_ARRAY;
if (array_type->eklass == CACHED_CLASS_RAW(String))
- return Variant::POOL_STRING_ARRAY;
+ return Variant::PACKED_STRING_ARRAY;
if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
- return Variant::POOL_VECTOR2_ARRAY;
+ return Variant::PACKED_VECTOR2_ARRAY;
if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
- return Variant::POOL_VECTOR3_ARRAY;
+ return Variant::PACKED_VECTOR3_ARRAY;
if (array_type->eklass == CACHED_CLASS_RAW(Color))
- return Variant::POOL_COLOR_ARRAY;
+ return Variant::PACKED_COLOR_ARRAY;
+
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return Variant::ARRAY;
} break;
case MONO_TYPE_CLASS: {
@@ -142,6 +168,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
return Variant::OBJECT;
}
+ if (CACHED_CLASS(StringName) == type_class) {
+ return Variant::STRING_NAME;
+ }
+
if (CACHED_CLASS(NodePath) == type_class) {
return Variant::NODE_PATH;
}
@@ -158,51 +188,54 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
return Variant::ARRAY;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return Variant::DICTIONARY;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
+ // IDictionary
+ if (p_type.type_class == CACHED_CLASS(System_Collections_IDictionary)) {
return Variant::DICTIONARY;
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
+ // ICollection or IEnumerable
+ if (p_type.type_class == CACHED_CLASS(System_Collections_ICollection) ||
+ p_type.type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
return Variant::ARRAY;
}
+ } break;
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- return Variant::ARRAY;
- }
+ case MONO_TYPE_OBJECT: {
+ if (r_nil_is_variant)
+ *r_nil_is_variant = true;
+ return Variant::NIL;
} break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
return Variant::DICTIONARY;
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
return Variant::ARRAY;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype))
- return Variant::DICTIONARY;
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
return Variant::DICTIONARY;
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype))
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
return Variant::ARRAY;
+ }
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ return Variant::DICTIONARY;
+ }
+
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
return Variant::ARRAY;
}
} break;
@@ -211,16 +244,29 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
} break;
}
+ if (r_nil_is_variant)
+ *r_nil_is_variant = false;
+
// Unknown
return Variant::NIL;
}
bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) {
switch (p_array_type.type_encoding) {
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY: {
+ MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type());
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ r_elem_type = ManagedType::from_class(array_type_class);
+ return true;
+ } break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type());
- if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype)) {
+ if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_system_generic_list(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_icollection(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_ienumerable(array_reftype)) {
MonoReflectionType *elem_reftype;
GDMonoUtils::Marshal::array_get_element_type(array_reftype, &elem_reftype);
@@ -228,12 +274,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
r_elem_type = ManagedType::from_reftype(elem_reftype);
return true;
}
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(array_reftype, &elem_reftype)) {
- r_elem_type = ManagedType::from_reftype(elem_reftype);
- return true;
- }
} break;
default: {
} break;
@@ -247,7 +287,9 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma
case MONO_TYPE_GENERICINST: {
MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type());
- if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype)) {
+ if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) ||
+ GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) {
MonoReflectionType *key_reftype;
MonoReflectionType *value_reftype;
@@ -257,13 +299,6 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma
r_value_type = ManagedType::from_reftype(value_reftype);
return true;
}
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(dict_reftype, &key_reftype, &value_reftype)) {
- r_key_type = ManagedType::from_reftype(key_reftype);
- r_value_type = ManagedType::from_reftype(value_reftype);
- return true;
- }
} break;
default: {
} break;
@@ -375,7 +410,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
case MONO_TYPE_STRING: {
if (p_var->get_type() == Variant::NIL)
- return NULL; // Otherwise, Variant -> String would return the string "Null"
+ return nullptr; // Otherwise, Variant -> String would return the string "Null"
return (MonoObject *)mono_string_from_godot(p_var->operator String());
} break;
@@ -387,11 +422,21 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from);
}
+ if (vtclass == CACHED_CLASS(Vector2i)) {
+ GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from);
+ }
+
if (vtclass == CACHED_CLASS(Rect2)) {
GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from);
}
+ if (vtclass == CACHED_CLASS(Rect2i)) {
+ GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from);
+ }
+
if (vtclass == CACHED_CLASS(Transform2D)) {
GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from);
@@ -402,6 +447,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from);
}
+ if (vtclass == CACHED_CLASS(Vector3i)) {
+ GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from);
+ }
+
if (vtclass == CACHED_CLASS(Basis)) {
GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var->operator ::Basis());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from);
@@ -432,6 +482,16 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from);
}
+ if (vtclass == CACHED_CLASS(Callable)) {
+ GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var->operator Callable());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Callable), &from);
+ }
+
+ if (vtclass == CACHED_CLASS(SignalInfo)) {
+ GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var->operator Signal());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(SignalInfo), &from);
+ }
+
if (mono_class_is_enum(vtclass->get_mono_ptr())) {
MonoType *enum_basetype = mono_class_enum_basetype(vtclass->get_mono_ptr());
MonoClass *enum_baseclass = mono_class_from_mono_type(enum_basetype);
@@ -477,7 +537,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return BOX_ENUM(enum_baseclass, val);
}
default: {
- ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
}
}
}
@@ -491,27 +551,37 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return (MonoObject *)Array_to_mono_array(p_var->operator Array());
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
- return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray());
+ return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray());
if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
- return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray());
+ return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array());
+
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t))
+ return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array());
+
+ if (array_type->eklass == CACHED_CLASS_RAW(float))
+ return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array());
- if (array_type->eklass == REAL_T_MONOCLASS)
- return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray());
+ if (array_type->eklass == CACHED_CLASS_RAW(double))
+ return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array());
if (array_type->eklass == CACHED_CLASS_RAW(String))
- return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray());
+ return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray());
if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
- return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array());
+ return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array());
if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
- return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array());
+ return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array());
if (array_type->eklass == CACHED_CLASS_RAW(Color))
- return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
+ return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
- ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed array of unmarshallable element type.");
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);
+
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
case MONO_TYPE_CLASS: {
@@ -522,6 +592,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
}
+ if (CACHED_CLASS(StringName) == type_class) {
+ return GDMonoUtils::create_managed_from(p_var->operator StringName());
+ }
+
if (CACHED_CLASS(NodePath) == type_class) {
return GDMonoUtils::create_managed_from(p_var->operator NodePath());
}
@@ -530,41 +604,17 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return GDMonoUtils::create_managed_from(p_var->operator RID());
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Dictionary or IDictionary
+ if (CACHED_CLASS(Dictionary) == type_class || CACHED_CLASS(System_Collections_IDictionary) == type_class) {
return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Array or ICollection or IEnumerable
+ if (CACHED_CLASS(Array) == type_class ||
+ CACHED_CLASS(System_Collections_ICollection) == type_class ||
+ CACHED_CLASS(System_Collections_IEnumerable) == type_class) {
return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
}
-
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
- }
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- } else {
- return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array());
- }
- }
} break;
case MONO_TYPE_OBJECT: {
// Variant
@@ -577,7 +627,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
int32_t val = p_var->operator signed int();
return BOX_INT32(val);
}
- case Variant::REAL: {
+ case Variant::FLOAT: {
#ifdef REAL_T_IS_DOUBLE
double val = p_var->operator double();
return BOX_DOUBLE(val);
@@ -592,14 +642,26 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var->operator ::Vector2());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from);
}
+ case Variant::VECTOR2I: {
+ GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from);
+ }
case Variant::RECT2: {
GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from);
}
+ case Variant::RECT2I: {
+ GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from);
+ }
case Variant::VECTOR3: {
GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var->operator ::Vector3());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from);
}
+ case Variant::VECTOR3I: {
+ GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from);
+ }
case Variant::TRANSFORM2D: {
GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from);
@@ -628,76 +690,100 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var->operator ::Color());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from);
}
+ case Variant::STRING_NAME:
+ return GDMonoUtils::create_managed_from(p_var->operator StringName());
case Variant::NODE_PATH:
return GDMonoUtils::create_managed_from(p_var->operator NodePath());
case Variant::_RID:
return GDMonoUtils::create_managed_from(p_var->operator RID());
case Variant::OBJECT:
return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
+ case Variant::CALLABLE: {
+ GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var->operator Callable());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Callable), &from);
+ }
+ case Variant::SIGNAL: {
+ GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var->operator Signal());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(SignalInfo), &from);
+ }
case Variant::DICTIONARY:
return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
case Variant::ARRAY:
return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- case Variant::POOL_BYTE_ARRAY:
- return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray());
- case Variant::POOL_INT_ARRAY:
- return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray());
- case Variant::POOL_REAL_ARRAY:
- return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray());
- case Variant::POOL_STRING_ARRAY:
- return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray());
- case Variant::POOL_VECTOR2_ARRAY:
- return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array());
- case Variant::POOL_VECTOR3_ARRAY:
- return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array());
- case Variant::POOL_COLOR_ARRAY:
- return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
+ case Variant::PACKED_BYTE_ARRAY:
+ return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray());
+ case Variant::PACKED_INT32_ARRAY:
+ return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array());
+ case Variant::PACKED_INT64_ARRAY:
+ return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array());
+ case Variant::PACKED_FLOAT32_ARRAY:
+ return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array());
+ case Variant::PACKED_FLOAT64_ARRAY:
+ return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array());
+ case Variant::PACKED_STRING_ARRAY:
+ return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray());
+ case Variant::PACKED_VECTOR2_ARRAY:
+ return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array());
+ case Variant::PACKED_VECTOR3_ARRAY:
+ return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array());
+ case Variant::PACKED_COLOR_ARRAY:
+ return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
default:
- return NULL;
+ return nullptr;
}
break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class);
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class);
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ return Dictionary_to_system_generic_dict(p_var->operator Dictionary(), p_type.type_class, key_reftype, value_reftype);
}
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ return Array_to_system_generic_list(p_var->operator Array(), p_type.type_class, elem_reftype);
}
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ MonoReflectionType *key_reftype;
+ MonoReflectionType *value_reftype;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), godot_dict_class);
}
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- } else {
- return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array());
- }
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
+ MonoReflectionType *elem_reftype;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var->operator Array(), godot_array_class);
}
} break;
} break;
}
- ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to an unmarshallable managed type. Name: '" +
- p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + ".");
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to an unmarshallable managed type. Name: '" +
+ p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + ".");
}
Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type, bool p_fail_with_err = true) {
@@ -735,7 +821,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return unbox<double>(p_obj);
case MONO_TYPE_STRING: {
- if (p_obj == NULL)
+ if (p_obj == nullptr)
return Variant(); // NIL
return mono_string_to_godot_not_null((MonoString *)p_obj);
} break;
@@ -744,34 +830,49 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
GDMonoClass *vtclass = p_type.type_class;
if (vtclass == CACHED_CLASS(Vector2))
- return MARSHALLED_IN(Vector2, (GDMonoMarshal::M_Vector2 *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj));
+
+ if (vtclass == CACHED_CLASS(Vector2i))
+ return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj));
if (vtclass == CACHED_CLASS(Rect2))
- return MARSHALLED_IN(Rect2, (GDMonoMarshal::M_Rect2 *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj));
+
+ if (vtclass == CACHED_CLASS(Rect2i))
+ return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj));
if (vtclass == CACHED_CLASS(Transform2D))
- return MARSHALLED_IN(Transform2D, (GDMonoMarshal::M_Transform2D *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj));
if (vtclass == CACHED_CLASS(Vector3))
- return MARSHALLED_IN(Vector3, (GDMonoMarshal::M_Vector3 *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj));
+
+ if (vtclass == CACHED_CLASS(Vector3i))
+ return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj));
if (vtclass == CACHED_CLASS(Basis))
- return MARSHALLED_IN(Basis, (GDMonoMarshal::M_Basis *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj));
if (vtclass == CACHED_CLASS(Quat))
- return MARSHALLED_IN(Quat, (GDMonoMarshal::M_Quat *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj));
if (vtclass == CACHED_CLASS(Transform))
- return MARSHALLED_IN(Transform, (GDMonoMarshal::M_Transform *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj));
if (vtclass == CACHED_CLASS(AABB))
- return MARSHALLED_IN(AABB, (GDMonoMarshal::M_AABB *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(AABB, unbox_addr<GDMonoMarshal::M_AABB>(p_obj));
if (vtclass == CACHED_CLASS(Color))
- return MARSHALLED_IN(Color, (GDMonoMarshal::M_Color *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Color, unbox_addr<GDMonoMarshal::M_Color>(p_obj));
if (vtclass == CACHED_CLASS(Plane))
- return MARSHALLED_IN(Plane, (GDMonoMarshal::M_Plane *)mono_object_unbox(p_obj));
+ return MARSHALLED_IN(Plane, unbox_addr<GDMonoMarshal::M_Plane>(p_obj));
+
+ if (vtclass == CACHED_CLASS(Callable))
+ return managed_to_callable(unbox<GDMonoMarshal::M_Callable>(p_obj));
+
+ if (vtclass == CACHED_CLASS(SignalInfo))
+ return managed_to_signal_info(unbox<GDMonoMarshal::M_SignalInfo>(p_obj));
if (mono_class_is_enum(vtclass->get_mono_ptr()))
return unbox<int32_t>(p_obj);
@@ -785,25 +886,35 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return mono_array_to_Array((MonoArray *)p_obj);
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
- return mono_array_to_PoolByteArray((MonoArray *)p_obj);
+ return mono_array_to_PackedByteArray((MonoArray *)p_obj);
if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
- return mono_array_to_PoolIntArray((MonoArray *)p_obj);
+ return mono_array_to_PackedInt32Array((MonoArray *)p_obj);
+
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t))
+ return mono_array_to_PackedInt64Array((MonoArray *)p_obj);
- if (array_type->eklass == REAL_T_MONOCLASS)
- return mono_array_to_PoolRealArray((MonoArray *)p_obj);
+ if (array_type->eklass == CACHED_CLASS_RAW(float))
+ return mono_array_to_PackedFloat32Array((MonoArray *)p_obj);
+
+ if (array_type->eklass == CACHED_CLASS_RAW(double))
+ return mono_array_to_PackedFloat64Array((MonoArray *)p_obj);
if (array_type->eklass == CACHED_CLASS_RAW(String))
- return mono_array_to_PoolStringArray((MonoArray *)p_obj);
+ return mono_array_to_PackedStringArray((MonoArray *)p_obj);
if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
- return mono_array_to_PoolVector2Array((MonoArray *)p_obj);
+ return mono_array_to_PackedVector2Array((MonoArray *)p_obj);
if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
- return mono_array_to_PoolVector3Array((MonoArray *)p_obj);
+ return mono_array_to_PackedVector3Array((MonoArray *)p_obj);
if (array_type->eklass == CACHED_CLASS_RAW(Color))
- return mono_array_to_PoolColorArray((MonoArray *)p_obj);
+ return mono_array_to_PackedColorArray((MonoArray *)p_obj);
+
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return mono_array_to_Array((MonoArray *)p_obj);
if (p_fail_with_err) {
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
@@ -818,13 +929,18 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
// GodotObject
if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj));
- if (ptr != NULL) {
+ if (ptr != nullptr) {
Reference *ref = Object::cast_to<Reference>(ptr);
return ref ? Variant(Ref<Reference>(ref)) : Variant(ptr);
}
return Variant();
}
+ if (CACHED_CLASS(StringName) == type_class) {
+ StringName *ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_obj));
+ return ptr ? Variant(*ptr) : Variant();
+ }
+
if (CACHED_CLASS(NodePath) == type_class) {
NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj));
return ptr ? Variant(*ptr) : Variant();
@@ -835,74 +951,55 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return ptr ? Variant(*ptr) : Variant();
}
- if (CACHED_CLASS(Array) == type_class) {
- MonoException *exc = NULL;
- Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc);
- UNHANDLED_EXCEPTION(exc);
- return ptr ? Variant(*ptr) : Variant();
- }
-
+ // Godot.Collections.Dictionary
if (CACHED_CLASS(Dictionary) == type_class) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc);
UNHANDLED_EXCEPTION(exc);
return ptr ? Variant(*ptr) : Variant();
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
- }
-
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
+ // Godot.Collections.Array
+ if (CACHED_CLASS(Array) == type_class) {
+ MonoException *exc = nullptr;
+ Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc);
+ UNHANDLED_EXCEPTION(exc);
+ return ptr ? Variant(*ptr) : Variant();
}
} break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
UNHANDLED_EXCEPTION(exc);
return *unbox<Dictionary *>(ret);
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
UNHANDLED_EXCEPTION(exc);
return *unbox<Array *>(ret);
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
- }
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ return system_generic_dict_to_Dictionary(p_obj, p_type.type_class, key_reftype, value_reftype);
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
- }
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype);
}
} break;
}
@@ -942,9 +1039,9 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj));
Variant var = GDMonoMarshal::mono_object_to_variant_no_err(p_obj, type);
- if (var.get_type() == Variant::NIL && p_obj != NULL) {
+ if (var.get_type() == Variant::NIL && p_obj != nullptr) {
// Cannot convert MonoObject* to Variant; fallback to 'ToString()'.
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc);
if (exc) {
@@ -959,10 +1056,97 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
}
}
+MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) {
+ String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) +
+ ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)";
+ GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(ctor == nullptr);
+
+ MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(mono_object, nullptr);
+
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype);
+ MonoObject *godot_dict = GDMonoUtils::create_managed_from(p_dict, godot_dict_class);
+
+ void *ctor_args[1] = { godot_dict };
+
+ MonoException *exc = nullptr;
+ ctor->invoke_raw(mono_object, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_object;
+}
+
+Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) {
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype);
+ String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) +
+ ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)";
+ GDMonoMethod *godot_dict_ctor = godot_dict_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(godot_dict_ctor == nullptr);
+
+ MonoObject *godot_dict = mono_object_new(mono_domain_get(), godot_dict_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(godot_dict, Dictionary());
+
+ void *ctor_args[1] = { p_obj };
+
+ MonoException *exc = nullptr;
+ godot_dict_ctor->invoke_raw(godot_dict, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ exc = nullptr;
+ MonoObject *ret = godot_dict_class->get_method("GetPtr")->invoke(godot_dict, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return *unbox<Dictionary *>(ret);
+}
+
+MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) {
+ GDMonoClass *elem_class = ManagedType::from_reftype(p_elem_reftype).type_class;
+
+ String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + elem_class->get_type_desc() + ">)";
+ GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(ctor == nullptr);
+
+ MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(mono_object, nullptr);
+
+ void *ctor_args[1] = { Array_to_mono_array(p_array, elem_class) };
+
+ MonoException *exc = nullptr;
+ ctor->invoke_raw(mono_object, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_object;
+}
+
+Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) {
+ GDMonoMethod *to_array = p_class->get_method("ToArray", 0);
+ CRASH_COND(to_array == nullptr);
+
+ MonoException *exc = nullptr;
+ MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_array_to_Array(mono_array);
+}
+
MonoArray *Array_to_mono_array(const Array &p_array) {
- MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_array.size());
+ int length = p_array.size();
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), length);
+
+ for (int i = 0; i < length; i++) {
+ MonoObject *boxed = variant_to_mono_object(p_array[i]);
+ mono_array_setref(ret, i, boxed);
+ }
+
+ return ret;
+}
- for (int i = 0; i < p_array.size(); i++) {
+MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) {
+ int length = p_array.size();
+ MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length);
+
+ for (int i = 0; i < length; i++) {
MonoObject *boxed = variant_to_mono_object(p_array[i]);
mono_array_setref(ret, i, boxed);
}
@@ -985,95 +1169,143 @@ Array mono_array_to_Array(MonoArray *p_array) {
return ret;
}
-// TODO: Use memcpy where possible
+MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) {
+ const int32_t *src = p_array.ptr();
+ int length = p_array.size();
-MonoArray *PoolIntArray_to_mono_array(const PoolIntArray &p_array) {
- PoolIntArray::Read r = p_array.read();
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), length);
- MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), p_array.size());
+ int32_t *dst = (int32_t *)mono_array_addr(ret, int32_t, 0);
+ memcpy(dst, src, length);
- for (int i = 0; i < p_array.size(); i++) {
- mono_array_set(ret, int32_t, i, r[i]);
- }
+ return ret;
+}
+
+PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array) {
+ PackedInt32Array ret;
+ if (!p_array)
+ return ret;
+ int length = mono_array_length(p_array);
+ ret.resize(length);
+ int32_t *dst = ret.ptrw();
+
+ const int32_t *src = (const int32_t *)mono_array_addr(p_array, int32_t, 0);
+ memcpy(dst, src, length);
return ret;
}
-PoolIntArray mono_array_to_PoolIntArray(MonoArray *p_array) {
- PoolIntArray ret;
+MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) {
+ const int64_t *src = p_array.ptr();
+ int length = p_array.size();
+
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int64_t), length);
+
+ int64_t *dst = (int64_t *)mono_array_addr(ret, int64_t, 0);
+ memcpy(dst, src, length);
+
+ return ret;
+}
+
+PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array) {
+ PackedInt64Array ret;
if (!p_array)
return ret;
int length = mono_array_length(p_array);
ret.resize(length);
- PoolIntArray::Write w = ret.write();
+ int64_t *dst = ret.ptrw();
- for (int i = 0; i < length; i++) {
- w[i] = mono_array_get(p_array, int32_t, i);
- }
+ const int64_t *src = (const int64_t *)mono_array_addr(p_array, int64_t, 0);
+ memcpy(dst, src, length);
return ret;
}
-MonoArray *PoolByteArray_to_mono_array(const PoolByteArray &p_array) {
- PoolByteArray::Read r = p_array.read();
+MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) {
+ const uint8_t *src = p_array.ptr();
+ int length = p_array.size();
- MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), p_array.size());
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), length);
- for (int i = 0; i < p_array.size(); i++) {
- mono_array_set(ret, uint8_t, i, r[i]);
- }
+ uint8_t *dst = (uint8_t *)mono_array_addr(ret, uint8_t, 0);
+ memcpy(dst, src, length);
return ret;
}
-PoolByteArray mono_array_to_PoolByteArray(MonoArray *p_array) {
- PoolByteArray ret;
+PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array) {
+ PackedByteArray ret;
if (!p_array)
return ret;
int length = mono_array_length(p_array);
ret.resize(length);
- PoolByteArray::Write w = ret.write();
+ uint8_t *dst = ret.ptrw();
- for (int i = 0; i < length; i++) {
- w[i] = mono_array_get(p_array, uint8_t, i);
- }
+ const uint8_t *src = (const uint8_t *)mono_array_addr(p_array, uint8_t, 0);
+ memcpy(dst, src, length);
return ret;
}
-MonoArray *PoolRealArray_to_mono_array(const PoolRealArray &p_array) {
- PoolRealArray::Read r = p_array.read();
+MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) {
+ const float *src = p_array.ptr();
+ int length = p_array.size();
- MonoArray *ret = mono_array_new(mono_domain_get(), REAL_T_MONOCLASS, p_array.size());
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(float), length);
- for (int i = 0; i < p_array.size(); i++) {
- mono_array_set(ret, real_t, i, r[i]);
- }
+ float *dst = (float *)mono_array_addr(ret, float, 0);
+ memcpy(dst, src, length);
return ret;
}
-PoolRealArray mono_array_to_PoolRealArray(MonoArray *p_array) {
- PoolRealArray ret;
+PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array) {
+ PackedFloat32Array ret;
if (!p_array)
return ret;
int length = mono_array_length(p_array);
ret.resize(length);
- PoolRealArray::Write w = ret.write();
+ float *dst = ret.ptrw();
- for (int i = 0; i < length; i++) {
- w[i] = mono_array_get(p_array, real_t, i);
- }
+ const float *src = (const float *)mono_array_addr(p_array, float, 0);
+ memcpy(dst, src, length);
return ret;
}
-MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array) {
- PoolStringArray::Read r = p_array.read();
+MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) {
+ const double *src = p_array.ptr();
+ int length = p_array.size();
- MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_array.size());
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(double), length);
- for (int i = 0; i < p_array.size(); i++) {
+ double *dst = (double *)mono_array_addr(ret, double, 0);
+ memcpy(dst, src, length);
+
+ return ret;
+}
+
+PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array) {
+ PackedFloat64Array ret;
+ if (!p_array)
+ return ret;
+ int length = mono_array_length(p_array);
+ ret.resize(length);
+ double *dst = ret.ptrw();
+
+ const double *src = (const double *)mono_array_addr(p_array, double, 0);
+ memcpy(dst, src, length);
+
+ return ret;
+}
+
+MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) {
+ const String *r = p_array.ptr();
+ int length = p_array.size();
+
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), length);
+
+ for (int i = 0; i < length; i++) {
MonoString *boxed = mono_string_from_godot(r[i]);
mono_array_setref(ret, i, boxed);
}
@@ -1081,13 +1313,13 @@ MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array) {
return ret;
}
-PoolStringArray mono_array_to_PoolStringArray(MonoArray *p_array) {
- PoolStringArray ret;
+PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array) {
+ PackedStringArray ret;
if (!p_array)
return ret;
int length = mono_array_length(p_array);
ret.resize(length);
- PoolStringArray::Write w = ret.write();
+ String *w = ret.ptrw();
for (int i = 0; i < length; i++) {
MonoString *elem = mono_array_get(p_array, MonoString *, i);
@@ -1097,88 +1329,188 @@ PoolStringArray mono_array_to_PoolStringArray(MonoArray *p_array) {
return ret;
}
-MonoArray *PoolColorArray_to_mono_array(const PoolColorArray &p_array) {
- PoolColorArray::Read r = p_array.read();
+MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) {
+ const Color *src = p_array.ptr();
+ int length = p_array.size();
- MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), p_array.size());
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), length);
- for (int i = 0; i < p_array.size(); i++) {
- M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i);
- *raw = MARSHALLED_OUT(Color, r[i]);
+ if constexpr (InteropLayout::MATCHES_Color) {
+ Color *dst = (Color *)mono_array_addr(ret, Color, 0);
+ memcpy(dst, src, length);
+ } else {
+ for (int i = 0; i < length; i++) {
+ M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i);
+ *raw = MARSHALLED_OUT(Color, src[i]);
+ }
}
return ret;
}
-PoolColorArray mono_array_to_PoolColorArray(MonoArray *p_array) {
- PoolColorArray ret;
+PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array) {
+ PackedColorArray ret;
if (!p_array)
return ret;
int length = mono_array_length(p_array);
ret.resize(length);
- PoolColorArray::Write w = ret.write();
+ Color *dst = ret.ptrw();
- for (int i = 0; i < length; i++) {
- w[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i));
+ if constexpr (InteropLayout::MATCHES_Color) {
+ const Color *src = (const Color *)mono_array_addr(p_array, Color, 0);
+ memcpy(dst, src, length);
+ } else {
+ for (int i = 0; i < length; i++) {
+ dst[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i));
+ }
}
return ret;
}
-MonoArray *PoolVector2Array_to_mono_array(const PoolVector2Array &p_array) {
- PoolVector2Array::Read r = p_array.read();
+MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) {
+ const Vector2 *src = p_array.ptr();
+ int length = p_array.size();
- MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), p_array.size());
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), length);
- for (int i = 0; i < p_array.size(); i++) {
- M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i);
- *raw = MARSHALLED_OUT(Vector2, r[i]);
+ if constexpr (InteropLayout::MATCHES_Vector2) {
+ Vector2 *dst = (Vector2 *)mono_array_addr(ret, Vector2, 0);
+ memcpy(dst, src, length);
+ } else {
+ for (int i = 0; i < length; i++) {
+ M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i);
+ *raw = MARSHALLED_OUT(Vector2, src[i]);
+ }
}
return ret;
}
-PoolVector2Array mono_array_to_PoolVector2Array(MonoArray *p_array) {
- PoolVector2Array ret;
+PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array) {
+ PackedVector2Array ret;
if (!p_array)
return ret;
int length = mono_array_length(p_array);
ret.resize(length);
- PoolVector2Array::Write w = ret.write();
+ Vector2 *dst = ret.ptrw();
- for (int i = 0; i < length; i++) {
- w[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i));
+ if constexpr (InteropLayout::MATCHES_Vector2) {
+ const Vector2 *src = (const Vector2 *)mono_array_addr(p_array, Vector2, 0);
+ memcpy(dst, src, length);
+ } else {
+ for (int i = 0; i < length; i++) {
+ dst[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i));
+ }
}
return ret;
}
-MonoArray *PoolVector3Array_to_mono_array(const PoolVector3Array &p_array) {
- PoolVector3Array::Read r = p_array.read();
+MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) {
+ const Vector3 *src = p_array.ptr();
+ int length = p_array.size();
- MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), p_array.size());
+ MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), length);
- for (int i = 0; i < p_array.size(); i++) {
- M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i);
- *raw = MARSHALLED_OUT(Vector3, r[i]);
+ if constexpr (InteropLayout::MATCHES_Vector3) {
+ Vector3 *dst = (Vector3 *)mono_array_addr(ret, Vector3, 0);
+ memcpy(dst, src, length);
+ } else {
+ for (int i = 0; i < length; i++) {
+ M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i);
+ *raw = MARSHALLED_OUT(Vector3, src[i]);
+ }
}
return ret;
}
-PoolVector3Array mono_array_to_PoolVector3Array(MonoArray *p_array) {
- PoolVector3Array ret;
+PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array) {
+ PackedVector3Array ret;
if (!p_array)
return ret;
int length = mono_array_length(p_array);
ret.resize(length);
- PoolVector3Array::Write w = ret.write();
+ Vector3 *dst = ret.ptrw();
- for (int i = 0; i < length; i++) {
- w[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i));
+ if constexpr (InteropLayout::MATCHES_Vector3) {
+ const Vector3 *src = (const Vector3 *)mono_array_addr(p_array, Vector3, 0);
+ memcpy(dst, src, length);
+ } else {
+ for (int i = 0; i < length; i++) {
+ dst[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i));
+ }
}
return ret;
}
+Callable managed_to_callable(const M_Callable &p_managed_callable) {
+ if (p_managed_callable.delegate) {
+ // TODO: Use pooling for ManagedCallable instances.
+ CallableCustom *managed_callable = memnew(ManagedCallable(p_managed_callable.delegate));
+ return Callable(managed_callable);
+ } else {
+ Object *target = p_managed_callable.target ?
+ unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) :
+ nullptr;
+ StringName *method_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name));
+ StringName method = method_ptr ? *method_ptr : StringName();
+ return Callable(target, method);
+ }
+}
+
+M_Callable callable_to_managed(const Callable &p_callable) {
+ if (p_callable.is_custom()) {
+ CallableCustom *custom = p_callable.get_custom();
+ CallableCustom::CompareEqualFunc compare_equal_func = custom->get_compare_equal_func();
+
+ if (compare_equal_func == ManagedCallable::compare_equal_func_ptr) {
+ ManagedCallable *managed_callable = static_cast<ManagedCallable *>(custom);
+ return {
+ nullptr, nullptr,
+ managed_callable->get_delegate()
+ };
+ } else if (compare_equal_func == SignalAwaiterCallable::compare_equal_func_ptr) {
+ SignalAwaiterCallable *signal_awaiter_callable = static_cast<SignalAwaiterCallable *>(custom);
+ return {
+ GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(signal_awaiter_callable->get_object())),
+ GDMonoUtils::create_managed_from(signal_awaiter_callable->get_signal()),
+ nullptr
+ };
+ } else if (compare_equal_func == EventSignalCallable::compare_equal_func_ptr) {
+ EventSignalCallable *event_signal_callable = static_cast<EventSignalCallable *>(custom);
+ return {
+ GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(event_signal_callable->get_object())),
+ GDMonoUtils::create_managed_from(event_signal_callable->get_signal()),
+ nullptr
+ };
+ }
+
+ // Some other CallableCustom. We only support ManagedCallable.
+ return { nullptr, nullptr, nullptr };
+ } else {
+ MonoObject *target_managed = GDMonoUtils::unmanaged_get_managed(p_callable.get_object());
+ MonoObject *method_string_name_managed = GDMonoUtils::create_managed_from(p_callable.get_method());
+ return { target_managed, method_string_name_managed, nullptr };
+ }
+}
+
+Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) {
+ Object *owner = p_managed_signal.owner ?
+ unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) :
+ nullptr;
+ StringName *name_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name));
+ StringName name = name_ptr ? *name_ptr : StringName();
+ return Signal(owner, name);
+}
+
+M_SignalInfo signal_info_to_managed(const Signal &p_signal) {
+ Object *owner = p_signal.get_object();
+ MonoObject *owner_managed = GDMonoUtils::unmanaged_get_managed(owner);
+ MonoObject *name_string_name_managed = GDMonoUtils::create_managed_from(p_signal.get_name());
+ return { owner_managed, name_string_name_managed };
+}
+
} // namespace GDMonoMarshal
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index e662e7814e..f2d887e6d6 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -33,6 +33,7 @@
#include "core/variant.h"
+#include "../managed_callable.h"
#include "gd_mono.h"
#include "gd_mono_utils.h"
@@ -62,7 +63,7 @@ T *unbox_addr(MonoObject *p_obj) {
#define BOX_PTR(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(IntPtr), x)
#define BOX_ENUM(m_enum_class, x) mono_value_box(mono_domain_get(), m_enum_class, &x)
-Variant::Type managed_to_variant_type(const ManagedType &p_type);
+Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant = nullptr);
bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type);
bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type);
@@ -80,7 +81,7 @@ _FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) {
}
_FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) {
- if (p_mono_string == NULL)
+ if (p_mono_string == nullptr)
return String();
return mono_string_to_godot_not_null(p_mono_string);
@@ -122,51 +123,95 @@ Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_ty
/// If the MonoObject* cannot be converted to Variant, then 'ToString()' is called instead.
String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc);
+// System.Collections.Generic
+
+MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
+Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
+
+MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+
// Array
MonoArray *Array_to_mono_array(const Array &p_array);
+MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class);
Array mono_array_to_Array(MonoArray *p_array);
-// PoolIntArray
+// PackedInt32Array
+
+MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array);
+PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array);
+
+// PackedInt64Array
+
+MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array);
+PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array);
-MonoArray *PoolIntArray_to_mono_array(const PoolIntArray &p_array);
-PoolIntArray mono_array_to_PoolIntArray(MonoArray *p_array);
+// PackedByteArray
-// PoolByteArray
+MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array);
+PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array);
-MonoArray *PoolByteArray_to_mono_array(const PoolByteArray &p_array);
-PoolByteArray mono_array_to_PoolByteArray(MonoArray *p_array);
+// PackedFloat32Array
-// PoolRealArray
+MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array);
+PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array);
-MonoArray *PoolRealArray_to_mono_array(const PoolRealArray &p_array);
-PoolRealArray mono_array_to_PoolRealArray(MonoArray *p_array);
+// PackedFloat64Array
-// PoolStringArray
+MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array);
+PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array);
-MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array);
-PoolStringArray mono_array_to_PoolStringArray(MonoArray *p_array);
+// PackedStringArray
-// PoolColorArray
+MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array);
+PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array);
-MonoArray *PoolColorArray_to_mono_array(const PoolColorArray &p_array);
-PoolColorArray mono_array_to_PoolColorArray(MonoArray *p_array);
+// PackedColorArray
-// PoolVector2Array
+MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array);
+PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array);
-MonoArray *PoolVector2Array_to_mono_array(const PoolVector2Array &p_array);
-PoolVector2Array mono_array_to_PoolVector2Array(MonoArray *p_array);
+// PackedVector2Array
-// PoolVector3Array
+MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array);
+PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array);
-MonoArray *PoolVector3Array_to_mono_array(const PoolVector3Array &p_array);
-PoolVector3Array mono_array_to_PoolVector3Array(MonoArray *p_array);
+// PackedVector3Array
+
+MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array);
+PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array);
+
+#pragma pack(push, 1)
+
+struct M_Callable {
+ MonoObject *target;
+ MonoObject *method_string_name;
+ MonoDelegate *delegate;
+};
+
+struct M_SignalInfo {
+ MonoObject *owner;
+ MonoObject *name_string_name;
+};
+
+#pragma pack(pop)
+
+// Callable
+Callable managed_to_callable(const M_Callable &p_managed_callable);
+M_Callable callable_to_managed(const Callable &p_callable);
+
+// SignalInfo
+Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal);
+M_SignalInfo signal_info_to_managed(const Signal &p_signal);
// Structures
namespace InteropLayout {
enum {
+ MATCHES_int = (sizeof(int32_t) == sizeof(uint32_t)),
+
MATCHES_float = (sizeof(float) == sizeof(uint32_t)),
MATCHES_double = (sizeof(double) == sizeof(uint64_t)),
@@ -181,10 +226,18 @@ enum {
offsetof(Vector2, x) == (sizeof(real_t) * 0) &&
offsetof(Vector2, y) == (sizeof(real_t) * 1)),
+ MATCHES_Vector2i = (MATCHES_int && (sizeof(Vector2i) == (sizeof(int32_t) * 2)) &&
+ offsetof(Vector2i, x) == (sizeof(int32_t) * 0) &&
+ offsetof(Vector2i, y) == (sizeof(int32_t) * 1)),
+
MATCHES_Rect2 = (MATCHES_Vector2 && (sizeof(Rect2) == (sizeof(Vector2) * 2)) &&
offsetof(Rect2, position) == (sizeof(Vector2) * 0) &&
offsetof(Rect2, size) == (sizeof(Vector2) * 1)),
+ MATCHES_Rect2i = (MATCHES_Vector2i && (sizeof(Rect2i) == (sizeof(Vector2i) * 2)) &&
+ offsetof(Rect2i, position) == (sizeof(Vector2i) * 0) &&
+ offsetof(Rect2i, size) == (sizeof(Vector2i) * 1)),
+
MATCHES_Transform2D = (MATCHES_Vector2 && (sizeof(Transform2D) == (sizeof(Vector2) * 3))), // No field offset required, it stores an array
MATCHES_Vector3 = (MATCHES_real_t && (sizeof(Vector3) == (sizeof(real_t) * 3)) &&
@@ -192,6 +245,11 @@ enum {
offsetof(Vector3, y) == (sizeof(real_t) * 1) &&
offsetof(Vector3, z) == (sizeof(real_t) * 2)),
+ MATCHES_Vector3i = (MATCHES_int && (sizeof(Vector3i) == (sizeof(int32_t) * 3)) &&
+ offsetof(Vector3i, x) == (sizeof(int32_t) * 0) &&
+ offsetof(Vector3i, y) == (sizeof(int32_t) * 1) &&
+ offsetof(Vector3i, z) == (sizeof(int32_t) * 2)),
+
MATCHES_Basis = (MATCHES_Vector3 && (sizeof(Basis) == (sizeof(Vector3) * 3))), // No field offset required, it stores an array
MATCHES_Quat = (MATCHES_real_t && (sizeof(Quat) == (sizeof(real_t) * 4)) &&
@@ -222,8 +280,9 @@ enum {
// In the future we may force this if we want to ref return these structs
#ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY
/* clang-format off */
-GD_STATIC_ASSERT(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 &&
- MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color &&MATCHES_Plane);
+static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 &&
+ MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color &&
+ MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i);
/* clang-format on */
#endif
@@ -244,6 +303,19 @@ struct M_Vector2 {
}
};
+struct M_Vector2i {
+ int32_t x, y;
+
+ static _FORCE_INLINE_ Vector2i convert_to(const M_Vector2i &p_from) {
+ return Vector2i(p_from.x, p_from.y);
+ }
+
+ static _FORCE_INLINE_ M_Vector2i convert_from(const Vector2i &p_from) {
+ M_Vector2i ret = { p_from.x, p_from.y };
+ return ret;
+ }
+};
+
struct M_Rect2 {
M_Vector2 position;
M_Vector2 size;
@@ -259,6 +331,21 @@ struct M_Rect2 {
}
};
+struct M_Rect2i {
+ M_Vector2i position;
+ M_Vector2i size;
+
+ static _FORCE_INLINE_ Rect2i convert_to(const M_Rect2i &p_from) {
+ return Rect2i(M_Vector2i::convert_to(p_from.position),
+ M_Vector2i::convert_to(p_from.size));
+ }
+
+ static _FORCE_INLINE_ M_Rect2i convert_from(const Rect2i &p_from) {
+ M_Rect2i ret = { M_Vector2i::convert_from(p_from.position), M_Vector2i::convert_from(p_from.size) };
+ return ret;
+ }
+};
+
struct M_Transform2D {
M_Vector2 elements[3];
@@ -291,6 +378,19 @@ struct M_Vector3 {
}
};
+struct M_Vector3i {
+ int32_t x, y, z;
+
+ static _FORCE_INLINE_ Vector3i convert_to(const M_Vector3i &p_from) {
+ return Vector3i(p_from.x, p_from.y, p_from.z);
+ }
+
+ static _FORCE_INLINE_ M_Vector3i convert_from(const Vector3i &p_from) {
+ M_Vector3i ret = { p_from.x, p_from.y, p_from.z };
+ return ret;
+ }
+};
+
struct M_Basis {
M_Vector3 elements[3];
@@ -416,9 +516,12 @@ struct M_Plane {
}
DECL_TYPE_MARSHAL_TEMPLATES(Vector2)
+DECL_TYPE_MARSHAL_TEMPLATES(Vector2i)
DECL_TYPE_MARSHAL_TEMPLATES(Rect2)
+DECL_TYPE_MARSHAL_TEMPLATES(Rect2i)
DECL_TYPE_MARSHAL_TEMPLATES(Transform2D)
DECL_TYPE_MARSHAL_TEMPLATES(Vector3)
+DECL_TYPE_MARSHAL_TEMPLATES(Vector3i)
DECL_TYPE_MARSHAL_TEMPLATES(Basis)
DECL_TYPE_MARSHAL_TEMPLATES(Quat)
DECL_TYPE_MARSHAL_TEMPLATES(Transform)
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index 971c5ac737..432aa74a6f 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -30,13 +30,14 @@
#include "gd_mono_method.h"
+#include <mono/metadata/attrdefs.h>
+#include <mono/metadata/debug-helpers.h>
+
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"
-#include <mono/metadata/attrdefs.h>
-
void GDMonoMethod::_update_signature() {
// Apparently MonoMethodSignature needs not to be freed.
// mono_method_signature caches the result, we don't need to cache it ourselves.
@@ -58,9 +59,9 @@ void GDMonoMethod::_update_signature(MonoMethodSignature *p_method_sig) {
}
}
- void *iter = NULL;
+ void *iter = nullptr;
MonoType *param_raw_type;
- while ((param_raw_type = mono_signature_get_params(p_method_sig, &iter)) != NULL) {
+ while ((param_raw_type = mono_signature_get_params(p_method_sig, &iter)) != nullptr) {
ManagedType param_type;
param_type.type_encoding = mono_type_get_type(param_raw_type);
@@ -81,11 +82,11 @@ GDMonoClass *GDMonoMethod::get_enclosing_class() const {
}
bool GDMonoMethod::is_static() {
- return mono_method_get_flags(mono_method, NULL) & MONO_METHOD_ATTR_STATIC;
+ return mono_method_get_flags(mono_method, nullptr) & MONO_METHOD_ATTR_STATIC;
}
IMonoClassMember::Visibility GDMonoMethod::get_visibility() {
- switch (mono_method_get_flags(mono_method, NULL) & MONO_METHOD_ATTR_ACCESS_MASK) {
+ switch (mono_method_get_flags(mono_method, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK) {
case MONO_METHOD_ATTR_PRIVATE:
return IMonoClassMember::PRIVATE;
case MONO_METHOD_ATTR_FAM_AND_ASSEM:
@@ -101,55 +102,46 @@ IMonoClassMember::Visibility GDMonoMethod::get_visibility() {
}
}
-MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc) {
- if (get_return_type().type_encoding != MONO_TYPE_VOID || get_parameters_count() > 0) {
- MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), get_parameters_count());
+MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc) const {
+ MonoException *exc = nullptr;
+ MonoObject *ret;
+
+ if (params_count > 0) {
+ MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), params_count);
for (int i = 0; i < params_count; i++) {
MonoObject *boxed_param = GDMonoMarshal::variant_to_mono_object(p_params[i], param_types[i]);
mono_array_setref(params, i, boxed_param);
}
- MonoException *exc = NULL;
- MonoObject *ret = GDMonoUtils::runtime_invoke_array(mono_method, p_object, params, &exc);
-
- if (exc) {
- ret = NULL;
- if (r_exc) {
- *r_exc = exc;
- } else {
- GDMonoUtils::set_pending_exception(exc);
- }
- }
-
- return ret;
+ ret = GDMonoUtils::runtime_invoke_array(mono_method, p_object, params, &exc);
} else {
- MonoException *exc = NULL;
- GDMonoUtils::runtime_invoke(mono_method, p_object, NULL, &exc);
-
- if (exc) {
- if (r_exc) {
- *r_exc = exc;
- } else {
- GDMonoUtils::set_pending_exception(exc);
- }
- }
+ ret = GDMonoUtils::runtime_invoke(mono_method, p_object, nullptr, &exc);
+ }
- return NULL;
+ if (exc) {
+ ret = nullptr;
+ if (r_exc) {
+ *r_exc = exc;
+ } else {
+ GDMonoUtils::set_pending_exception(exc);
+ }
}
+
+ return ret;
}
-MonoObject *GDMonoMethod::invoke(MonoObject *p_object, MonoException **r_exc) {
- ERR_FAIL_COND_V(get_parameters_count() > 0, NULL);
- return invoke_raw(p_object, NULL, r_exc);
+MonoObject *GDMonoMethod::invoke(MonoObject *p_object, MonoException **r_exc) const {
+ ERR_FAIL_COND_V(get_parameters_count() > 0, nullptr);
+ return invoke_raw(p_object, nullptr, r_exc);
}
-MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc) {
- MonoException *exc = NULL;
+MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc) const {
+ MonoException *exc = nullptr;
MonoObject *ret = GDMonoUtils::runtime_invoke(mono_method, p_object, p_params, &exc);
if (exc) {
- ret = NULL;
+ ret = nullptr;
if (r_exc) {
*r_exc = exc;
} else {
@@ -173,19 +165,19 @@ bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) {
}
MonoObject *GDMonoMethod::get_attribute(GDMonoClass *p_attr_class) {
- ERR_FAIL_NULL_V(p_attr_class, NULL);
+ ERR_FAIL_NULL_V(p_attr_class, nullptr);
if (!attrs_fetched)
fetch_attributes();
if (!attributes)
- return NULL;
+ return nullptr;
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
void GDMonoMethod::fetch_attributes() {
- ERR_FAIL_COND(attributes != NULL);
+ ERR_FAIL_COND(attributes != nullptr);
attributes = mono_custom_attrs_from_method(mono_method);
attrs_fetched = true;
}
@@ -247,7 +239,7 @@ void GDMonoMethod::get_parameter_names(Vector<StringName> &names) const {
}
void GDMonoMethod::get_parameter_types(Vector<ManagedType> &types) const {
- for (int i = 0; i < param_types.size(); ++i) {
+ for (int i = 0; i < params_count; ++i) {
types.push_back(param_types[i]);
}
}
@@ -256,13 +248,22 @@ const MethodInfo &GDMonoMethod::get_method_info() {
if (!method_info_fetched) {
method_info.name = name;
- method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type), "");
+
+ bool nil_is_variant = false;
+ method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), "");
+ if (method_info.return_val.type == Variant::NIL && nil_is_variant)
+ method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
Vector<StringName> names;
get_parameter_names(names);
for (int i = 0; i < params_count; ++i) {
- method_info.arguments.push_back(PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i]), names[i]));
+ nil_is_variant = false;
+ PropertyInfo arg_info = PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i], &nil_is_variant), names[i]);
+ if (arg_info.type == Variant::NIL && nil_is_variant)
+ arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+
+ method_info.arguments.push_back(arg_info);
}
// TODO: default arguments
@@ -281,7 +282,7 @@ GDMonoMethod::GDMonoMethod(StringName p_name, MonoMethod *p_method) {
method_info_fetched = false;
attrs_fetched = false;
- attributes = NULL;
+ attributes = nullptr;
_update_signature();
}
diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h
index b47e42dec2..54b2eba3e8 100644
--- a/modules/mono/mono_gd/gd_mono_method.h
+++ b/modules/mono/mono_gd/gd_mono_method.h
@@ -57,28 +57,28 @@ class GDMonoMethod : public IMonoClassMember {
MonoMethod *mono_method;
public:
- virtual GDMonoClass *get_enclosing_class() const GD_FINAL;
+ virtual GDMonoClass *get_enclosing_class() const final;
- virtual MemberType get_member_type() const GD_FINAL { return MEMBER_TYPE_METHOD; }
+ virtual MemberType get_member_type() const final { return MEMBER_TYPE_METHOD; }
- virtual StringName get_name() const GD_FINAL { return name; }
+ virtual StringName get_name() const final { return name; }
- virtual bool is_static() GD_FINAL;
+ virtual bool is_static() final;
- virtual Visibility get_visibility() GD_FINAL;
+ virtual Visibility get_visibility() final;
- virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL;
- virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL;
+ virtual bool has_attribute(GDMonoClass *p_attr_class) final;
+ virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) final;
void fetch_attributes();
- _FORCE_INLINE_ MonoMethod *get_mono_ptr() { return mono_method; }
+ _FORCE_INLINE_ MonoMethod *get_mono_ptr() const { return mono_method; }
- _FORCE_INLINE_ int get_parameters_count() { return params_count; }
- _FORCE_INLINE_ ManagedType get_return_type() { return return_type; }
+ _FORCE_INLINE_ int get_parameters_count() const { return params_count; }
+ _FORCE_INLINE_ ManagedType get_return_type() const { return return_type; }
- MonoObject *invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc = NULL);
- MonoObject *invoke(MonoObject *p_object, MonoException **r_exc = NULL);
- MonoObject *invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc = NULL);
+ MonoObject *invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc = nullptr) const;
+ MonoObject *invoke(MonoObject *p_object, MonoException **r_exc = nullptr) const;
+ MonoObject *invoke_raw(MonoObject *p_object, void **p_params, MonoException **r_exc = nullptr) const;
String get_full_name(bool p_signature = false) const;
String get_full_name_no_class() const;
diff --git a/modules/mono/mono_gd/gd_mono_method_thunk.h b/modules/mono/mono_gd/gd_mono_method_thunk.h
index d8c9a5eb02..0e05e974e9 100644
--- a/modules/mono/mono_gd/gd_mono_method_thunk.h
+++ b/modules/mono/mono_gd/gd_mono_method_thunk.h
@@ -39,7 +39,7 @@
#include "gd_mono_method.h"
#include "gd_mono_utils.h"
-#if !defined(JAVASCRIPT_ENABLED)
+#if !defined(JAVASCRIPT_ENABLED) && !defined(IPHONE_ENABLED)
#define HAVE_METHOD_THUNKS
#endif
@@ -60,16 +60,16 @@ public:
}
_FORCE_INLINE_ bool is_null() {
- return mono_method_thunk == NULL;
+ return mono_method_thunk == nullptr;
}
_FORCE_INLINE_ void nullify() {
- mono_method_thunk = NULL;
+ mono_method_thunk = nullptr;
}
_FORCE_INLINE_ void set_from_method(GDMonoMethod *p_mono_method) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_mono_method == NULL);
+ CRASH_COND(p_mono_method == nullptr);
CRASH_COND(p_mono_method->get_return_type().type_encoding != MONO_TYPE_VOID);
if (p_mono_method->is_static()) {
@@ -82,7 +82,7 @@ public:
}
GDMonoMethodThunk() :
- mono_method_thunk(NULL) {
+ mono_method_thunk(nullptr) {
}
explicit GDMonoMethodThunk(GDMonoMethod *p_mono_method) {
@@ -106,16 +106,16 @@ public:
}
_FORCE_INLINE_ bool is_null() {
- return mono_method_thunk == NULL;
+ return mono_method_thunk == nullptr;
}
_FORCE_INLINE_ void nullify() {
- mono_method_thunk = NULL;
+ mono_method_thunk = nullptr;
}
_FORCE_INLINE_ void set_from_method(GDMonoMethod *p_mono_method) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_mono_method == NULL);
+ CRASH_COND(p_mono_method == nullptr);
CRASH_COND(p_mono_method->get_return_type().type_encoding == MONO_TYPE_VOID);
if (p_mono_method->is_static()) {
@@ -128,12 +128,12 @@ public:
}
GDMonoMethodThunkR() :
- mono_method_thunk(NULL) {
+ mono_method_thunk(nullptr) {
}
explicit GDMonoMethodThunkR(GDMonoMethod *p_mono_method) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_mono_method == NULL);
+ CRASH_COND(p_mono_method == nullptr);
#endif
mono_method_thunk = (M)mono_method_get_unmanaged_thunk(p_mono_method->get_mono_ptr());
}
@@ -146,7 +146,7 @@ struct VariadicInvokeMonoMethodImpl {
static void invoke(GDMonoMethod *p_mono_method, P1 p_arg1, ParamTypes... p_args, MonoException **r_exc) {
if (p_mono_method->is_static()) {
void *args[ThunkParamCount] = { p_arg1, p_args... };
- p_mono_method->invoke_raw(NULL, args, r_exc);
+ p_mono_method->invoke_raw(nullptr, args, r_exc);
} else {
void *args[ThunkParamCount] = { p_args... };
p_mono_method->invoke_raw((MonoObject *)p_arg1, args, r_exc);
@@ -167,7 +167,7 @@ struct VariadicInvokeMonoMethod<0> {
#ifdef DEBUG_ENABLED
CRASH_COND(!p_mono_method->is_static());
#endif
- p_mono_method->invoke_raw(NULL, NULL, r_exc);
+ p_mono_method->invoke_raw(nullptr, nullptr, r_exc);
}
};
@@ -176,9 +176,9 @@ struct VariadicInvokeMonoMethod<1, P1> {
static void invoke(GDMonoMethod *p_mono_method, P1 p_arg1, MonoException **r_exc) {
if (p_mono_method->is_static()) {
void *args[1] = { p_arg1 };
- p_mono_method->invoke_raw(NULL, args, r_exc);
+ p_mono_method->invoke_raw(nullptr, args, r_exc);
} else {
- p_mono_method->invoke_raw((MonoObject *)p_arg1, NULL, r_exc);
+ p_mono_method->invoke_raw((MonoObject *)p_arg1, nullptr, r_exc);
}
}
};
@@ -203,7 +203,7 @@ struct VariadicInvokeMonoMethodRImpl {
static R invoke(GDMonoMethod *p_mono_method, P1 p_arg1, ParamTypes... p_args, MonoException **r_exc) {
if (p_mono_method->is_static()) {
void *args[ThunkParamCount] = { p_arg1, p_args... };
- MonoObject *r = p_mono_method->invoke_raw(NULL, args, r_exc);
+ MonoObject *r = p_mono_method->invoke_raw(nullptr, args, r_exc);
return unbox_if_needed<R>(r, p_mono_method->get_return_type());
} else {
void *args[ThunkParamCount] = { p_args... };
@@ -226,7 +226,7 @@ struct VariadicInvokeMonoMethodR<0, R> {
#ifdef DEBUG_ENABLED
CRASH_COND(!p_mono_method->is_static());
#endif
- MonoObject *r = p_mono_method->invoke_raw(NULL, NULL, r_exc);
+ MonoObject *r = p_mono_method->invoke_raw(nullptr, nullptr, r_exc);
return unbox_if_needed<R>(r, p_mono_method->get_return_type());
}
};
@@ -236,10 +236,10 @@ struct VariadicInvokeMonoMethodR<1, R, P1> {
static R invoke(GDMonoMethod *p_mono_method, P1 p_arg1, MonoException **r_exc) {
if (p_mono_method->is_static()) {
void *args[1] = { p_arg1 };
- MonoObject *r = p_mono_method->invoke_raw(NULL, args, r_exc);
+ MonoObject *r = p_mono_method->invoke_raw(nullptr, args, r_exc);
return unbox_if_needed<R>(r, p_mono_method->get_return_type());
} else {
- MonoObject *r = p_mono_method->invoke_raw((MonoObject *)p_arg1, NULL, r_exc);
+ MonoObject *r = p_mono_method->invoke_raw((MonoObject *)p_arg1, nullptr, r_exc);
return unbox_if_needed<R>(r, p_mono_method->get_return_type());
}
}
@@ -256,16 +256,16 @@ public:
}
_FORCE_INLINE_ bool is_null() {
- return mono_method == NULL;
+ return mono_method == nullptr;
}
_FORCE_INLINE_ void nullify() {
- mono_method = NULL;
+ mono_method = nullptr;
}
_FORCE_INLINE_ void set_from_method(GDMonoMethod *p_mono_method) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_mono_method == NULL);
+ CRASH_COND(p_mono_method == nullptr);
CRASH_COND(p_mono_method->get_return_type().type_encoding != MONO_TYPE_VOID);
if (p_mono_method->is_static()) {
@@ -278,7 +278,7 @@ public:
}
GDMonoMethodThunk() :
- mono_method(NULL) {
+ mono_method(nullptr) {
}
explicit GDMonoMethodThunk(GDMonoMethod *p_mono_method) {
@@ -297,16 +297,16 @@ public:
}
_FORCE_INLINE_ bool is_null() {
- return mono_method == NULL;
+ return mono_method == nullptr;
}
_FORCE_INLINE_ void nullify() {
- mono_method = NULL;
+ mono_method = nullptr;
}
_FORCE_INLINE_ void set_from_method(GDMonoMethod *p_mono_method) {
#ifdef DEBUG_ENABLED
- CRASH_COND(p_mono_method == NULL);
+ CRASH_COND(p_mono_method == nullptr);
CRASH_COND(p_mono_method->get_return_type().type_encoding == MONO_TYPE_VOID);
if (p_mono_method->is_static()) {
@@ -319,7 +319,7 @@ public:
}
GDMonoMethodThunkR() :
- mono_method(NULL) {
+ mono_method(nullptr) {
}
explicit GDMonoMethodThunkR(GDMonoMethod *p_mono_method) {
diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp
index 3b5ce58d80..c3e7598f2d 100644
--- a/modules/mono/mono_gd/gd_mono_property.cpp
+++ b/modules/mono/mono_gd/gd_mono_property.cpp
@@ -57,7 +57,7 @@ GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_own
MonoMethodSignature *setter_sig = mono_method_signature(prop_method);
- void *iter = NULL;
+ void *iter = nullptr;
MonoType *param_raw_type = mono_signature_get_params(setter_sig, &iter);
type.type_encoding = mono_type_get_type(param_raw_type);
@@ -66,7 +66,7 @@ GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_own
}
attrs_fetched = false;
- attributes = NULL;
+ attributes = nullptr;
}
GDMonoProperty::~GDMonoProperty() {
@@ -77,17 +77,17 @@ GDMonoProperty::~GDMonoProperty() {
bool GDMonoProperty::is_static() {
MonoMethod *prop_method = mono_property_get_get_method(mono_property);
- if (prop_method == NULL)
+ if (prop_method == nullptr)
prop_method = mono_property_get_set_method(mono_property);
- return mono_method_get_flags(prop_method, NULL) & MONO_METHOD_ATTR_STATIC;
+ return mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_STATIC;
}
IMonoClassMember::Visibility GDMonoProperty::get_visibility() {
MonoMethod *prop_method = mono_property_get_get_method(mono_property);
- if (prop_method == NULL)
+ if (prop_method == nullptr)
prop_method = mono_property_get_set_method(mono_property);
- switch (mono_method_get_flags(prop_method, NULL) & MONO_METHOD_ATTR_ACCESS_MASK) {
+ switch (mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK) {
case MONO_METHOD_ATTR_PRIVATE:
return IMonoClassMember::PRIVATE;
case MONO_METHOD_ATTR_FAM_AND_ASSEM:
@@ -116,36 +116,36 @@ bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) {
}
MonoObject *GDMonoProperty::get_attribute(GDMonoClass *p_attr_class) {
- ERR_FAIL_NULL_V(p_attr_class, NULL);
+ ERR_FAIL_NULL_V(p_attr_class, nullptr);
if (!attrs_fetched)
fetch_attributes();
if (!attributes)
- return NULL;
+ return nullptr;
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
}
void GDMonoProperty::fetch_attributes() {
- ERR_FAIL_COND(attributes != NULL);
+ ERR_FAIL_COND(attributes != nullptr);
attributes = mono_custom_attrs_from_property(owner->get_mono_ptr(), mono_property);
attrs_fetched = true;
}
bool GDMonoProperty::has_getter() {
- return mono_property_get_get_method(mono_property) != NULL;
+ return mono_property_get_get_method(mono_property) != nullptr;
}
bool GDMonoProperty::has_setter() {
- return mono_property_get_set_method(mono_property) != NULL;
+ return mono_property_get_set_method(mono_property) != nullptr;
}
void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc) {
MonoMethod *prop_method = mono_property_get_set_method(mono_property);
MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), 1);
mono_array_setref(params, 0, p_value);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::runtime_invoke_array(prop_method, p_object, params, &exc);
if (exc) {
if (r_exc) {
@@ -157,7 +157,7 @@ void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoEx
}
void GDMonoProperty::set_value(MonoObject *p_object, void **p_params, MonoException **r_exc) {
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::property_set_value(mono_property, p_object, p_params, &exc);
if (exc) {
@@ -170,11 +170,11 @@ void GDMonoProperty::set_value(MonoObject *p_object, void **p_params, MonoExcept
}
MonoObject *GDMonoProperty::get_value(MonoObject *p_object, MonoException **r_exc) {
- MonoException *exc = NULL;
- MonoObject *ret = GDMonoUtils::property_get_value(mono_property, p_object, NULL, &exc);
+ MonoException *exc = nullptr;
+ MonoObject *ret = GDMonoUtils::property_get_value(mono_property, p_object, nullptr, &exc);
if (exc) {
- ret = NULL;
+ ret = nullptr;
if (r_exc) {
*r_exc = exc;
} else {
diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h
index 692037f76a..4653758a86 100644
--- a/modules/mono/mono_gd/gd_mono_property.h
+++ b/modules/mono/mono_gd/gd_mono_property.h
@@ -47,17 +47,17 @@ class GDMonoProperty : public IMonoClassMember {
MonoCustomAttrInfo *attributes;
public:
- virtual GDMonoClass *get_enclosing_class() const GD_FINAL { return owner; }
+ virtual GDMonoClass *get_enclosing_class() const final { return owner; }
- virtual MemberType get_member_type() const GD_FINAL { return MEMBER_TYPE_PROPERTY; }
+ virtual MemberType get_member_type() const final { return MEMBER_TYPE_PROPERTY; }
- virtual StringName get_name() const GD_FINAL { return name; }
+ virtual StringName get_name() const final { return name; }
- virtual bool is_static() GD_FINAL;
- virtual Visibility get_visibility() GD_FINAL;
+ virtual bool is_static() final;
+ virtual Visibility get_visibility() final;
- virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL;
- virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL;
+ virtual bool has_attribute(GDMonoClass *p_attr_class) final;
+ virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) final;
void fetch_attributes();
bool has_getter();
@@ -65,9 +65,9 @@ public:
_FORCE_INLINE_ ManagedType get_type() const { return type; }
- void set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc = NULL);
- void set_value(MonoObject *p_object, void **p_params, MonoException **r_exc = NULL);
- MonoObject *get_value(MonoObject *p_object, MonoException **r_exc = NULL);
+ void set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc = nullptr);
+ void set_value(MonoObject *p_object, void **p_params, MonoException **r_exc = nullptr);
+ MonoObject *get_value(MonoObject *p_object, MonoException **r_exc = nullptr);
bool get_bool_value(MonoObject *p_object);
int get_int_value(MonoObject *p_object);
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 05077a00c4..f9d492dabb 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -30,20 +30,23 @@
#include "gd_mono_utils.h"
+#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
+#include "core/debugger/engine_debugger.h"
+#include "core/debugger/script_debugger.h"
#include "core/os/dir_access.h"
+#include "core/os/mutex.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "core/reference.h"
#ifdef TOOLS_ENABLED
-#include "editor/script_editor_debugger.h"
+#include "editor/debugger/editor_debugger_node.h"
#endif
#include "../csharp_script.h"
#include "../utils/macros.h"
-#include "../utils/mutex_utils.h"
#include "gd_mono.h"
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
@@ -55,7 +58,7 @@ namespace GDMonoUtils {
MonoObject *unmanaged_get_managed(Object *unmanaged) {
if (!unmanaged)
- return NULL;
+ return nullptr;
if (unmanaged->get_script_instance()) {
CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance());
@@ -69,25 +72,24 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
void *data = unmanaged->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
- ERR_FAIL_NULL_V(data, NULL);
+ ERR_FAIL_NULL_V(data, nullptr);
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
if (!script_binding.inited) {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+ MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
if (!script_binding.inited) { // Other thread may have set it up
// Already had a binding that needs to be setup
CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, unmanaged);
- ERR_FAIL_COND_V(!script_binding.inited, NULL);
+ ERR_FAIL_COND_V(!script_binding.inited, nullptr);
}
}
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
- ERR_FAIL_COND_V(gchandle.is_null(), NULL);
+ MonoGCHandleData &gchandle = script_binding.gchandle;
- MonoObject *target = gchandle->get_target();
+ MonoObject *target = gchandle.get_target();
if (target)
return target;
@@ -98,13 +100,13 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
#ifdef DEBUG_ENABLED
CRASH_COND(script_binding.type_name == StringName());
- CRASH_COND(script_binding.wrapper_class == NULL);
+ CRASH_COND(script_binding.wrapper_class == nullptr);
#endif
MonoObject *mono_object = GDMonoUtils::create_managed_for_godot_object(script_binding.wrapper_class, script_binding.type_name, unmanaged);
- ERR_FAIL_NULL_V(mono_object, NULL);
+ ERR_FAIL_NULL_V(mono_object, nullptr);
- gchandle->set_handle(MonoGCHandle::new_strong_handle(mono_object), MonoGCHandle::STRONG_HANDLE);
+ gchandle = MonoGCHandleData::new_strong_handle(mono_object);
// Tie managed to unmanaged
Reference *ref = Object::cast_to<Reference>(unmanaged);
@@ -126,10 +128,15 @@ void set_main_thread(MonoThread *p_thread) {
}
MonoThread *attach_current_thread() {
- ERR_FAIL_COND_V(!GDMono::get_singleton()->is_runtime_initialized(), NULL);
+ ERR_FAIL_COND_V(!GDMono::get_singleton()->is_runtime_initialized(), nullptr);
MonoDomain *scripts_domain = GDMono::get_singleton()->get_scripts_domain();
+#ifndef GD_MONO_SINGLE_APPDOMAIN
MonoThread *mono_thread = mono_thread_attach(scripts_domain ? scripts_domain : mono_get_root_domain());
- ERR_FAIL_NULL_V(mono_thread, NULL);
+#else
+ // The scripts domain is the root domain
+ MonoThread *mono_thread = mono_thread_attach(scripts_domain);
+#endif
+ ERR_FAIL_NULL_V(mono_thread, nullptr);
return mono_thread;
}
@@ -151,13 +158,36 @@ MonoThread *get_current_thread() {
}
bool is_thread_attached() {
- return mono_domain_get() != NULL;
+ return mono_domain_get() != nullptr;
+}
+
+uint32_t new_strong_gchandle(MonoObject *p_object) {
+ return mono_gchandle_new(p_object, /* pinned: */ false);
+}
+
+uint32_t new_strong_gchandle_pinned(MonoObject *p_object) {
+ return mono_gchandle_new(p_object, /* pinned: */ true);
+}
+
+uint32_t new_weak_gchandle(MonoObject *p_object) {
+ return mono_gchandle_new_weakref(p_object, /* track_resurrection: */ false);
+}
+
+void free_gchandle(uint32_t p_gchandle) {
+ mono_gchandle_free(p_gchandle);
}
void runtime_object_init(MonoObject *p_this_obj, GDMonoClass *p_class, MonoException **r_exc) {
GDMonoMethod *ctor = p_class->get_method(".ctor", 0);
ERR_FAIL_NULL(ctor);
- ctor->invoke_raw(p_this_obj, NULL, r_exc);
+ ctor->invoke_raw(p_this_obj, nullptr, r_exc);
+}
+
+bool mono_delegate_equal(MonoDelegate *p_a, MonoDelegate *p_b) {
+ MonoException *exc = nullptr;
+ MonoBoolean res = CACHED_METHOD_THUNK(Delegate, Equals).invoke((MonoObject *)p_a, (MonoObject *)p_b, &exc);
+ UNHANDLED_EXCEPTION(exc);
+ return (bool)res;
}
GDMonoClass *get_object_class(MonoObject *p_object) {
@@ -197,18 +227,18 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) {
if (assembly == GDMono::get_singleton()->get_editor_api_assembly())
return klass;
#endif
- } while ((klass = klass->get_parent_class()) != NULL);
+ } while ((klass = klass->get_parent_class()) != nullptr);
- return NULL;
+ return nullptr;
}
MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object) {
bool parent_is_object_class = ClassDB::is_parent_class(p_object->get_class_name(), p_native);
- ERR_FAIL_COND_V_MSG(!parent_is_object_class, NULL,
+ ERR_FAIL_COND_V_MSG(!parent_is_object_class, nullptr,
"Type inherits from native type '" + p_native + "', so it can't be instanced in object of type: '" + p_object->get_class() + "'.");
MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
- ERR_FAIL_NULL_V(mono_object, NULL);
+ ERR_FAIL_NULL_V(mono_object, nullptr);
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, p_object);
@@ -218,9 +248,21 @@ MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringNa
return mono_object;
}
+MonoObject *create_managed_from(const StringName &p_from) {
+ MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(StringName));
+ ERR_FAIL_NULL_V(mono_object, nullptr);
+
+ // Construct
+ GDMonoUtils::runtime_object_init(mono_object, CACHED_CLASS(StringName));
+
+ CACHED_FIELD(StringName, ptr)->set_value_raw(mono_object, memnew(StringName(p_from)));
+
+ return mono_object;
+}
+
MonoObject *create_managed_from(const NodePath &p_from) {
MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(NodePath));
- ERR_FAIL_NULL_V(mono_object, NULL);
+ ERR_FAIL_NULL_V(mono_object, nullptr);
// Construct
GDMonoUtils::runtime_object_init(mono_object, CACHED_CLASS(NodePath));
@@ -232,7 +274,7 @@ MonoObject *create_managed_from(const NodePath &p_from) {
MonoObject *create_managed_from(const RID &p_from) {
MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(RID));
- ERR_FAIL_NULL_V(mono_object, NULL);
+ ERR_FAIL_NULL_V(mono_object, nullptr);
// Construct
GDMonoUtils::runtime_object_init(mono_object, CACHED_CLASS(RID));
@@ -244,15 +286,15 @@ MonoObject *create_managed_from(const RID &p_from) {
MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class) {
MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
- ERR_FAIL_NULL_V(mono_object, NULL);
+ ERR_FAIL_NULL_V(mono_object, nullptr);
// Search constructor that takes a pointer as parameter
MonoMethod *m;
- void *iter = NULL;
+ void *iter = nullptr;
while ((m = mono_class_get_methods(p_class->get_mono_ptr(), &iter))) {
if (strcmp(mono_method_get_name(m), ".ctor") == 0) {
MonoMethodSignature *sig = mono_method_signature(m);
- void *front = NULL;
+ void *front = nullptr;
if (mono_signature_get_param_count(sig) == 1 &&
mono_class_from_mono_type(mono_signature_get_params(sig, &front)) == CACHED_CLASS(IntPtr)->get_mono_ptr()) {
break;
@@ -260,12 +302,12 @@ MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class) {
}
}
- CRASH_COND(m == NULL);
+ CRASH_COND(m == nullptr);
Array *new_array = memnew(Array(p_from));
void *args[1] = { &new_array };
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::runtime_invoke(m, mono_object, args, &exc);
UNHANDLED_EXCEPTION(exc);
@@ -274,15 +316,15 @@ MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class) {
MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) {
MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
- ERR_FAIL_NULL_V(mono_object, NULL);
+ ERR_FAIL_NULL_V(mono_object, nullptr);
// Search constructor that takes a pointer as parameter
MonoMethod *m;
- void *iter = NULL;
+ void *iter = nullptr;
while ((m = mono_class_get_methods(p_class->get_mono_ptr(), &iter))) {
if (strcmp(mono_method_get_name(m), ".ctor") == 0) {
MonoMethodSignature *sig = mono_method_signature(m);
- void *front = NULL;
+ void *front = nullptr;
if (mono_signature_get_param_count(sig) == 1 &&
mono_class_from_mono_type(mono_signature_get_params(sig, &front)) == CACHED_CLASS(IntPtr)->get_mono_ptr()) {
break;
@@ -290,12 +332,12 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class)
}
}
- CRASH_COND(m == NULL);
+ CRASH_COND(m == nullptr);
Dictionary *new_dict = memnew(Dictionary(p_from));
void *args[1] = { &new_dict };
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
GDMonoUtils::runtime_invoke(m, mono_object, args, &exc);
UNHANDLED_EXCEPTION(exc);
@@ -305,7 +347,7 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class)
MonoDomain *create_domain(const String &p_friendly_name) {
print_verbose("Mono: Creating domain '" + p_friendly_name + "'...");
- MonoDomain *domain = mono_domain_create_appdomain((char *)p_friendly_name.utf8().get_data(), NULL);
+ MonoDomain *domain = mono_domain_create_appdomain((char *)p_friendly_name.utf8().get_data(), nullptr);
if (domain) {
// Workaround to avoid this exception:
@@ -317,6 +359,14 @@ MonoDomain *create_domain(const String &p_friendly_name) {
return domain;
}
+String get_type_desc(MonoType *p_type) {
+ return mono_type_full_name(p_type);
+}
+
+String get_type_desc(MonoReflectionType *p_reftype) {
+ return get_type_desc(mono_reflection_type_get_type(p_reftype));
+}
+
String get_exception_name_and_message(MonoException *p_exc) {
String res;
@@ -330,7 +380,7 @@ String get_exception_name_and_message(MonoException *p_exc) {
res += ": ";
MonoProperty *prop = mono_class_get_property_from_name(klass, "Message");
- MonoString *msg = (MonoString *)property_get_value(prop, (MonoObject *)p_exc, NULL, NULL);
+ MonoString *msg = (MonoString *)property_get_value(prop, (MonoObject *)p_exc, nullptr, nullptr);
res += GDMonoMarshal::mono_string_to_godot(msg);
return res;
@@ -341,7 +391,7 @@ void set_exception_message(MonoException *p_exc, String message) {
MonoProperty *prop = mono_class_get_property_from_name(klass, "Message");
MonoString *msg = GDMonoMarshal::mono_string_from_godot(message);
void *params[1] = { msg };
- property_set_value(prop, (MonoObject *)p_exc, params, NULL);
+ property_set_value(prop, (MonoObject *)p_exc, params, nullptr);
}
void debug_print_unhandled_exception(MonoException *p_exc) {
@@ -351,7 +401,7 @@ void debug_print_unhandled_exception(MonoException *p_exc) {
void debug_send_unhandled_exception_error(MonoException *p_exc) {
#ifdef DEBUG_ENABLED
- if (!ScriptDebugger::get_singleton()) {
+ if (!EngineDebugger::is_active()) {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
ERR_PRINT(GDMonoUtils::get_exception_name_and_message(p_exc));
@@ -360,7 +410,11 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
return;
}
- _TLS_RECURSION_GUARD_;
+ static thread_local bool _recursion_flag_ = false;
+ if (_recursion_flag_)
+ return;
+ _recursion_flag_ = true;
+ SCOPE_EXIT { _recursion_flag_ = false; };
ScriptLanguage::StackInfo separator;
separator.file = String();
@@ -370,14 +424,14 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
Vector<ScriptLanguage::StackInfo> si;
String exc_msg;
- while (p_exc != NULL) {
+ while (p_exc != nullptr) {
GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace);
MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr());
MonoBoolean need_file_info = true;
void *ctor_args[2] = { p_exc, &need_file_info };
- MonoException *unexpected_exc = NULL;
+ MonoException *unexpected_exc = nullptr;
CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc);
if (unexpected_exc) {
@@ -386,7 +440,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
}
Vector<ScriptLanguage::StackInfo> _si;
- if (stack_trace != NULL) {
+ if (stack_trace != nullptr) {
_si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace);
for (int i = _si.size() - 1; i >= 0; i--)
si.insert(0, _si[i]);
@@ -396,10 +450,10 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
GDMonoClass *exc_class = GDMono::get_singleton()->get_class(mono_get_exception_class());
GDMonoProperty *inner_exc_prop = exc_class->get_property("InnerException");
- CRASH_COND(inner_exc_prop == NULL);
+ CRASH_COND(inner_exc_prop == nullptr);
MonoObject *inner_exc = inner_exc_prop->get_value((MonoObject *)p_exc);
- if (inner_exc != NULL)
+ if (inner_exc != nullptr)
si.insert(0, separator);
p_exc = (MonoException *)inner_exc;
@@ -410,7 +464,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
int line = si.size() ? si[0].line : __LINE__;
String error_msg = "Unhandled exception";
- ScriptDebugger::get_singleton()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si);
+ EngineDebugger::get_script_debugger()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si);
#endif
}
@@ -437,8 +491,7 @@ void set_pending_exception(MonoException *p_exc) {
#endif
}
-_THREAD_LOCAL_(int)
-current_invoke_count = 0;
+thread_local int current_invoke_count = 0;
MonoObject *runtime_invoke(MonoMethod *p_method, void *p_obj, void **p_params, MonoException **r_exc) {
GD_MONO_BEGIN_RUNTIME_INVOKE;
@@ -526,7 +579,7 @@ namespace Marshal {
bool type_is_generic_array(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericArray).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
@@ -534,94 +587,75 @@ bool type_is_generic_array(MonoReflectionType *p_reftype) {
bool type_is_generic_dictionary(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
- MonoException *exc = NULL;
+ MonoException *exc = nullptr;
MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericDictionary).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
- MonoException *exc = NULL;
- CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
- UNHANDLED_EXCEPTION(exc);
-}
-
-void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
- MonoException *exc = NULL;
- CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc);
- UNHANDLED_EXCEPTION(exc);
-}
-
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) {
+bool type_is_system_generic_list(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
- MonoException *exc = NULL;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType).invoke(p_reftype, &exc);
+ MonoException *exc = nullptr;
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericList).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) {
+bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
- MonoException *exc = NULL;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType).invoke(p_reftype, &exc);
+ MonoException *exc = nullptr;
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericDictionary).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) {
+bool type_is_generic_ienumerable(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
- MonoException *exc = NULL;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info).invoke(p_reftype, r_elem_reftype, &exc);
+ MonoException *exc = nullptr;
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIEnumerable).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
+bool type_is_generic_icollection(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
- MonoException *exc = NULL;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info).invoke(p_reftype, r_key_reftype, r_value_reftype, &exc);
+ MonoException *exc = nullptr;
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericICollection).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-Array enumerable_to_array(MonoObject *p_enumerable) {
- NO_GLUE_RET(Array());
- Array result;
- MonoException *exc = NULL;
- CACHED_METHOD_THUNK(MarshalUtils, EnumerableToArray).invoke(p_enumerable, &result, &exc);
+bool type_is_generic_idictionary(MonoReflectionType *p_reftype) {
+ NO_GLUE_RET(false);
+ MonoException *exc = nullptr;
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIDictionary).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
+ return (bool)res;
}
-Dictionary idictionary_to_dictionary(MonoObject *p_idictionary) {
- NO_GLUE_RET(Dictionary());
- Dictionary result;
- MonoException *exc = NULL;
- CACHED_METHOD_THUNK(MarshalUtils, IDictionaryToDictionary).invoke(p_idictionary, &result, &exc);
+void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
+ MonoException *exc = nullptr;
+ CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
}
-Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary) {
- NO_GLUE_RET(Dictionary());
- Dictionary result;
- MonoException *exc = NULL;
- CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryToDictionary).invoke(p_generic_idictionary, &result, &exc);
+void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
+ MonoException *exc = nullptr;
+ CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
}
GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype) {
- NO_GLUE_RET(NULL);
- MonoException *exc = NULL;
+ NO_GLUE_RET(nullptr);
+ MonoException *exc = nullptr;
MonoReflectionType *reftype = CACHED_METHOD_THUNK(MarshalUtils, MakeGenericArrayType).invoke(p_elem_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype)));
}
GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) {
- NO_GLUE_RET(NULL);
- MonoException *exc = NULL;
+ NO_GLUE_RET(nullptr);
+ MonoException *exc = nullptr;
MonoReflectionType *reftype = CACHED_METHOD_THUNK(MarshalUtils, MakeGenericDictionaryType).invoke(p_key_reftype, p_value_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype)));
@@ -630,7 +664,7 @@ GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, Mon
} // namespace Marshal
ScopeThreadAttach::ScopeThreadAttach() :
- mono_thread(NULL) {
+ mono_thread(nullptr) {
if (likely(GDMono::get_singleton()->is_runtime_initialized()) && unlikely(!mono_domain_get())) {
mono_thread = GDMonoUtils::attach_current_thread();
}
@@ -642,6 +676,10 @@ ScopeThreadAttach::~ScopeThreadAttach() {
}
}
-// namespace Marshal
+StringName get_native_godot_class_name(GDMonoClass *p_class) {
+ MonoObject *native_name_obj = p_class->get_field(BINDINGS_NATIVE_NAME_FIELD)->get_value(nullptr);
+ StringName *ptr = GDMonoMarshal::unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(native_name_obj));
+ return ptr ? *ptr : StringName();
+}
} // namespace GDMonoUtils
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index db9f99bfdc..e3011ade5d 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -35,14 +35,13 @@
#include "../mono_gc_handle.h"
#include "../utils/macros.h"
-#include "../utils/thread_local.h"
#include "gd_mono_header.h"
#include "core/object.h"
#include "core/reference.h"
#define UNHANDLED_EXCEPTION(m_exc) \
- if (unlikely(m_exc != NULL)) { \
+ if (unlikely(m_exc != nullptr)) { \
GDMonoUtils::debug_unhandled_exception(m_exc); \
GD_UNREACHABLE(); \
}
@@ -53,22 +52,18 @@ namespace Marshal {
bool type_is_generic_array(MonoReflectionType *p_reftype);
bool type_is_generic_dictionary(MonoReflectionType *p_reftype);
+bool type_is_system_generic_list(MonoReflectionType *p_reftype);
+bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype);
+bool type_is_generic_ienumerable(MonoReflectionType *p_reftype);
+bool type_is_generic_icollection(MonoReflectionType *p_reftype);
+bool type_is_generic_idictionary(MonoReflectionType *p_reftype);
void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype);
void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype);
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype);
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype);
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
-
GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype);
GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
-Array enumerable_to_array(MonoObject *p_enumerable);
-Dictionary idictionary_to_dictionary(MonoObject *p_idictionary);
-Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary);
-
} // namespace Marshal
_FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) {
@@ -78,7 +73,7 @@ _FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash)
/**
* If the object has a csharp script, returns the target of the gchandle stored in the script instance
* Otherwise returns a newly constructed MonoObject* which is attached to the object
- * Returns NULL on error
+ * Returns nullptr on error
*/
MonoObject *unmanaged_get_managed(Object *unmanaged);
@@ -90,10 +85,17 @@ MonoThread *get_current_thread();
bool is_thread_attached();
_FORCE_INLINE_ bool is_main_thread() {
- return mono_domain_get() != NULL && mono_thread_get_main() == mono_thread_current();
+ return mono_domain_get() != nullptr && mono_thread_get_main() == mono_thread_current();
}
-void runtime_object_init(MonoObject *p_this_obj, GDMonoClass *p_class, MonoException **r_exc = NULL);
+uint32_t new_strong_gchandle(MonoObject *p_object);
+uint32_t new_strong_gchandle_pinned(MonoObject *p_object);
+uint32_t new_weak_gchandle(MonoObject *p_object);
+void free_gchandle(uint32_t p_gchandle);
+
+void runtime_object_init(MonoObject *p_this_obj, GDMonoClass *p_class, MonoException **r_exc = nullptr);
+
+bool mono_delegate_equal(MonoDelegate *p_a, MonoDelegate *p_b);
GDMonoClass *get_object_class(MonoObject *p_object);
GDMonoClass *type_get_proxy_class(const StringName &p_type);
@@ -101,6 +103,7 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class);
MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object);
+MonoObject *create_managed_from(const StringName &p_from);
MonoObject *create_managed_from(const NodePath &p_from);
MonoObject *create_managed_from(const RID &p_from);
MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class);
@@ -108,6 +111,9 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class);
MonoDomain *create_domain(const String &p_friendly_name);
+String get_type_desc(MonoType *p_type);
+String get_type_desc(MonoReflectionType *p_reftype);
+
String get_exception_name_and_message(MonoException *p_exc);
void set_exception_message(MonoException *p_exc, String message);
@@ -123,7 +129,7 @@ void print_unhandled_exception(MonoException *p_exc);
*/
void set_pending_exception(MonoException *p_exc);
-extern _THREAD_LOCAL_(int) current_invoke_count;
+extern thread_local int current_invoke_count;
_FORCE_INLINE_ int get_runtime_invoke_count() {
return current_invoke_count;
@@ -152,9 +158,11 @@ private:
MonoThread *mono_thread;
};
+StringName get_native_godot_class_name(GDMonoClass *p_class);
+
} // namespace GDMonoUtils
-#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoMarshal::mono_string_to_godot((MonoString *)m_class->get_field(BINDINGS_NATIVE_NAME_FIELD)->get_value(NULL)))
+#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoUtils::get_native_godot_class_name(m_class))
#define GD_MONO_BEGIN_RUNTIME_INVOKE \
int &_runtime_invoke_count_ref = GDMonoUtils::get_runtime_invoke_count_ref(); \
diff --git a/modules/mono/mono_gd/managed_type.h b/modules/mono/mono_gd/managed_type.h
index 11b832d0cc..84d1837853 100644
--- a/modules/mono/mono_gd/managed_type.h
+++ b/modules/mono/mono_gd/managed_type.h
@@ -46,7 +46,7 @@ struct ManagedType {
ManagedType() :
type_encoding(0),
- type_class(NULL) {
+ type_class(nullptr) {
}
ManagedType(int p_type_encoding, GDMonoClass *p_type_class) :
diff --git a/modules/mono/mono_gd/gd_mono_android.cpp b/modules/mono/mono_gd/support/android_support.cpp
index 761368878f..8bcdeec9dd 100644..100755
--- a/modules/mono/mono_gd/gd_mono_android.cpp
+++ b/modules/mono/mono_gd/support/android_support.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gd_mono_android.cpp */
+/* android_support.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "gd_mono_android.h"
+#include "android_support.h"
#if defined(ANDROID_ENABLED)
@@ -49,14 +49,16 @@
#include "platform/android/os_android.h"
#include "platform/android/thread_jandroid.h"
-#include "../utils/path_utils.h"
-#include "../utils/string_utils.h"
-#include "gd_mono_cache.h"
-#include "gd_mono_marshal.h"
+#include "../../utils/path_utils.h"
+#include "../../utils/string_utils.h"
+#include "../gd_mono_cache.h"
+#include "../gd_mono_marshal.h"
// Warning: JNI boilerplate ahead... continue at your own risk
-namespace GDMonoAndroid {
+namespace gdmono {
+namespace android {
+namespace support {
template <typename T>
struct ScopedLocalRef {
@@ -67,7 +69,7 @@ struct ScopedLocalRef {
_FORCE_INLINE_ operator T() const { return local_ref; }
_FORCE_INLINE_ operator jvalue() const { return (jvalue)local_ref; }
- _FORCE_INLINE_ operator bool() const { return local_ref != NULL; }
+ _FORCE_INLINE_ operator bool() const { return local_ref != nullptr; }
_FORCE_INLINE_ bool operator==(std::nullptr_t) const {
return local_ref == nullptr;
@@ -122,7 +124,7 @@ String determine_app_native_lib_dir() {
String result;
- const char *const nativeLibraryDirUtf8 = env->GetStringUTFChars(nativeLibraryDir, NULL);
+ const char *const nativeLibraryDirUtf8 = env->GetStringUTFChars(nativeLibraryDir, nullptr);
if (nativeLibraryDirUtf8) {
result.parse_utf8(nativeLibraryDirUtf8);
env->ReleaseStringUTFChars(nativeLibraryDir, nativeLibraryDirUtf8);
@@ -150,21 +152,21 @@ int gd_mono_convert_dl_flags(int flags) {
return lflags;
}
-#ifndef GD_MONO_ANDROID_SO_NAME
-#define GD_MONO_ANDROID_SO_NAME "libmonosgen-2.0.so"
+#ifndef GD_MONO_SO_NAME
+#define GD_MONO_SO_NAME "libmonosgen-2.0.so"
#endif
-const char *mono_so_name = GD_MONO_ANDROID_SO_NAME;
+const char *mono_so_name = GD_MONO_SO_NAME;
const char *godot_so_name = "libgodot_android.so";
-void *mono_dl_handle = NULL;
-void *godot_dl_handle = NULL;
+void *mono_dl_handle = nullptr;
+void *godot_dl_handle = nullptr;
void *try_dlopen(const String &p_so_path, int p_flags) {
if (!FileAccess::exists(p_so_path)) {
if (OS::get_singleton()->is_stdout_verbose())
OS::get_singleton()->print("Cannot find shared library: '%s'\n", p_so_path.utf8().get_data());
- return NULL;
+ return nullptr;
}
int lflags = gd_mono_convert_dl_flags(p_flags);
@@ -174,7 +176,7 @@ void *try_dlopen(const String &p_so_path, int p_flags) {
if (!handle) {
if (OS::get_singleton()->is_stdout_verbose())
OS::get_singleton()->print("Failed to open shared library: '%s'. Error: '%s'\n", p_so_path.utf8().get_data(), dlerror());
- return NULL;
+ return nullptr;
}
if (OS::get_singleton()->is_stdout_verbose())
@@ -184,7 +186,7 @@ void *try_dlopen(const String &p_so_path, int p_flags) {
}
void *gd_mono_android_dlopen(const char *p_name, int p_flags, char **r_err, void *p_user_data) {
- if (p_name == NULL) {
+ if (p_name == nullptr) {
// __Internal
if (!mono_dl_handle) {
@@ -209,7 +211,7 @@ void *gd_mono_android_dlopen(const char *p_name, int p_flags, char **r_err, void
return try_dlopen(so_path, p_flags);
}
- return NULL;
+ return nullptr;
}
void *gd_mono_android_dlsym(void *p_handle, const char *p_name, char **r_err, void *p_user_data) {
@@ -230,7 +232,7 @@ void *gd_mono_android_dlsym(void *p_handle, const char *p_name, char **r_err, vo
if (r_err)
*r_err = str_format_new("%s\n", dlerror());
- return NULL;
+ return nullptr;
}
void *gd_mono_android_dlclose(void *p_handle, void *p_user_data) {
@@ -238,9 +240,9 @@ void *gd_mono_android_dlclose(void *p_handle, void *p_user_data) {
// Not sure if this ever happens. Does Mono close the handle for the main module?
if (p_handle == mono_dl_handle)
- mono_dl_handle = NULL;
+ mono_dl_handle = nullptr;
- return NULL;
+ return nullptr;
}
int32_t build_version_sdk_int = 0;
@@ -265,7 +267,7 @@ int32_t get_build_version_sdk_int() {
return build_version_sdk_int;
}
-jobject certStore = NULL; // KeyStore
+jobject certStore = nullptr; // KeyStore
MonoBoolean _gd_mono_init_cert_store() {
// The JNI code is the equivalent of:
@@ -293,7 +295,7 @@ MonoBoolean _gd_mono_init_cert_store() {
if (jni_exception_check(env))
return 0;
- env->CallVoidMethod(certStoreLocal, load, NULL);
+ env->CallVoidMethod(certStoreLocal, load, nullptr);
if (jni_exception_check(env))
return 0;
@@ -317,7 +319,7 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
if (!mono_error_ok(&mono_error)) {
ERR_PRINT(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&mono_error) + "'.");
mono_error_cleanup(&mono_error);
- return NULL;
+ return nullptr;
}
JNIEnv *env = ThreadAndroid::get_env();
@@ -326,20 +328,20 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
mono_free(alias_utf8);
ScopedLocalRef<jclass> keyStoreClass(env, env->FindClass("java/security/KeyStore"));
- ERR_FAIL_NULL_V(keyStoreClass, NULL);
+ ERR_FAIL_NULL_V(keyStoreClass, nullptr);
ScopedLocalRef<jclass> certificateClass(env, env->FindClass("java/security/cert/Certificate"));
- ERR_FAIL_NULL_V(certificateClass, NULL);
+ ERR_FAIL_NULL_V(certificateClass, nullptr);
jmethodID getCertificate = env->GetMethodID(keyStoreClass, "getCertificate", "(Ljava/lang/String;)Ljava/security/cert/Certificate;");
- ERR_FAIL_NULL_V(getCertificate, NULL);
+ ERR_FAIL_NULL_V(getCertificate, nullptr);
jmethodID getEncoded = env->GetMethodID(certificateClass, "getEncoded", "()[B");
- ERR_FAIL_NULL_V(getEncoded, NULL);
+ ERR_FAIL_NULL_V(getEncoded, nullptr);
ScopedLocalRef<jobject> certificate(env, env->CallObjectMethod(certStore, getCertificate, js_alias.get()));
if (!certificate)
- return NULL;
+ return nullptr;
ScopedLocalRef<jbyteArray> encoded(env, (jbyteArray)env->CallObjectMethod(certificate, getEncoded));
jsize encodedLength = env->GetArrayLength(encoded);
@@ -352,11 +354,16 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
return encoded_ret;
}
+void register_internal_calls() {
+ mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_init_cert_store", (void *)_gd_mono_init_cert_store);
+ mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_android_cert_store_lookup", (void *)_gd_mono_android_cert_store_lookup);
+}
+
void initialize() {
// We need to set this environment variable to make the monodroid BCL use btls instead of legacy as the default provider
OS::get_singleton()->set_environment("XA_TLS_PROVIDER", "btls");
- mono_dl_fallback_register(gd_mono_android_dlopen, gd_mono_android_dlsym, gd_mono_android_dlclose, NULL);
+ mono_dl_fallback_register(gd_mono_android_dlopen, gd_mono_android_dlsym, gd_mono_android_dlclose, nullptr);
String app_native_lib_dir = get_app_native_lib_dir();
String so_path = path::join(app_native_lib_dir, godot_so_name);
@@ -364,31 +371,28 @@ void initialize() {
godot_dl_handle = try_dlopen(so_path, gd_mono_convert_dl_flags(MONO_DL_LAZY));
}
-void register_internal_calls() {
- mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_init_cert_store", (void *)_gd_mono_init_cert_store);
- mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_android_cert_store_lookup", (void *)_gd_mono_android_cert_store_lookup);
-}
-
void cleanup() {
// This is called after shutting down the Mono runtime
if (mono_dl_handle)
- gd_mono_android_dlclose(mono_dl_handle, NULL);
+ gd_mono_android_dlclose(mono_dl_handle, nullptr);
if (godot_dl_handle)
- gd_mono_android_dlclose(godot_dl_handle, NULL);
+ gd_mono_android_dlclose(godot_dl_handle, nullptr);
JNIEnv *env = ThreadAndroid::get_env();
if (certStore) {
env->DeleteGlobalRef(certStore);
- certStore = NULL;
+ certStore = nullptr;
}
}
-} // namespace GDMonoAndroid
+} // namespace support
+} // namespace android
+} // namespace gdmono
-using namespace GDMonoAndroid;
+using namespace gdmono::android::support;
// The following are P/Invoke functions required by the monodroid profile of the BCL.
// These are P/Invoke functions and not internal calls, hence why they use
@@ -417,7 +421,7 @@ GD_PINVOKE_EXPORT int32_t monodroid_get_system_property(const char *p_name, char
memcpy(*r_value, prop_value_str, len);
(*r_value)[len] = '\0';
} else {
- *r_value = NULL;
+ *r_value = nullptr;
}
}
@@ -604,7 +608,7 @@ GD_PINVOKE_EXPORT int32_t _monodroid_get_dns_servers(void **r_dns_servers_array)
if (!r_dns_servers_array)
return -1;
- *r_dns_servers_array = NULL;
+ *r_dns_servers_array = nullptr;
char *dns_servers[dns_servers_len];
int dns_servers_count = 0;
@@ -648,23 +652,23 @@ GD_PINVOKE_EXPORT const char *_monodroid_timezone_get_default_id() {
JNIEnv *env = ThreadAndroid::get_env();
ScopedLocalRef<jclass> timeZoneClass(env, env->FindClass("java/util/TimeZone"));
- ERR_FAIL_NULL_V(timeZoneClass, NULL);
+ ERR_FAIL_NULL_V(timeZoneClass, nullptr);
jmethodID getDefault = env->GetStaticMethodID(timeZoneClass, "getDefault", "()Ljava/util/TimeZone;");
- ERR_FAIL_NULL_V(getDefault, NULL);
+ ERR_FAIL_NULL_V(getDefault, nullptr);
jmethodID getID = env->GetMethodID(timeZoneClass, "getID", "()Ljava/lang/String;");
- ERR_FAIL_NULL_V(getID, NULL);
+ ERR_FAIL_NULL_V(getID, nullptr);
ScopedLocalRef<jobject> defaultTimeZone(env, env->CallStaticObjectMethod(timeZoneClass, getDefault));
if (!defaultTimeZone)
- return NULL;
+ return nullptr;
ScopedLocalRef<jstring> defaultTimeZoneID(env, (jstring)env->CallObjectMethod(defaultTimeZone, getID));
if (!defaultTimeZoneID)
- return NULL;
+ return nullptr;
const char *default_time_zone_id = env->GetStringUTFChars(defaultTimeZoneID, 0);
diff --git a/modules/mono/mono_gd/gd_mono_android.h b/modules/mono/mono_gd/support/android_support.h
index 0e04847924..dc2e6c95ed 100644..100755
--- a/modules/mono/mono_gd/gd_mono_android.h
+++ b/modules/mono/mono_gd/support/android_support.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gd_mono_android.h */
+/* android_support.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,25 +28,28 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GD_MONO_ANDROID_H
-#define GD_MONO_ANDROID_H
+#ifndef ANDROID_SUPPORT_H
+#define ANDROID_SUPPORT_H
#if defined(ANDROID_ENABLED)
#include "core/ustring.h"
-namespace GDMonoAndroid {
+namespace gdmono {
+namespace android {
+namespace support {
String get_app_native_lib_dir();
void initialize();
+void cleanup();
void register_internal_calls();
-void cleanup();
-
-} // namespace GDMonoAndroid
+} // namespace support
+} // namespace android
+} // namespace gdmono
#endif // ANDROID_ENABLED
-#endif // GD_MONO_ANDROID_H
+#endif // ANDROID_SUPPORT_H
diff --git a/modules/opus/stub/register_types.cpp b/modules/mono/mono_gd/support/ios_support.h
index a4329e142c..e28af120e3 100644..100755
--- a/modules/opus/stub/register_types.cpp
+++ b/modules/mono/mono_gd/support/ios_support.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* register_types.cpp */
+/* ios_support.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,10 +28,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "register_types.h"
+#ifndef IOS_SUPPORT_H
+#define IOS_SUPPORT_H
-// Dummy module as libvorbis is needed by other modules (theora ...)
+#if defined(IPHONE_ENABLED)
-void register_opus_types() {}
+#include "core/ustring.h"
-void unregister_opus_types() {}
+namespace gdmono {
+namespace ios {
+namespace support {
+
+void initialize();
+void cleanup();
+
+} // namespace support
+} // namespace ios
+} // namespace gdmono
+
+#endif // IPHONE_ENABLED
+
+#endif // IOS_SUPPORT_H
diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm
new file mode 100755
index 0000000000..e3d1a647fd
--- /dev/null
+++ b/modules/mono/mono_gd/support/ios_support.mm
@@ -0,0 +1,151 @@
+/*************************************************************************/
+/* ios_support.mm */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "ios_support.h"
+
+#if defined(IPHONE_ENABLED)
+
+#import <Foundation/Foundation.h>
+#include <os/log.h>
+
+#include "core/ustring.h"
+
+#include "../gd_mono_marshal.h"
+
+// Implemented mostly following: https://github.com/mono/mono/blob/master/sdks/ios/app/runtime.m
+
+// Definition generated by the Godot exporter
+extern "C" void gd_mono_setup_aot();
+
+namespace gdmono {
+namespace ios {
+namespace support {
+
+void ios_mono_log_callback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) {
+ os_log_info(OS_LOG_DEFAULT, "(%s %s) %s", log_domain, log_level, message);
+ if (fatal) {
+ os_log_info(OS_LOG_DEFAULT, "Exit code: %d.", 1);
+ exit(1);
+ }
+}
+
+void initialize() {
+ mono_dllmap_insert(NULL, "System.Native", NULL, "__Internal", NULL);
+ mono_dllmap_insert(NULL, "System.IO.Compression.Native", NULL, "__Internal", NULL);
+ mono_dllmap_insert(NULL, "System.Security.Cryptography.Native.Apple", NULL, "__Internal", NULL);
+
+#ifdef IOS_DEVICE
+ // This function is defined in an auto-generated source file
+ gd_mono_setup_aot();
+#endif
+
+ mono_set_signal_chaining(true);
+ mono_set_crash_chaining(true);
+}
+
+void cleanup() {
+}
+
+} // namespace support
+} // namespace ios
+} // namespace gdmono
+
+// The following are P/Invoke functions required by the monotouch profile of the BCL.
+// These are P/Invoke functions and not internal calls, hence why they use
+// 'mono_bool' and 'const char*' instead of 'MonoBoolean' and 'MonoString*'.
+
+#define GD_PINVOKE_EXPORT extern "C" __attribute__((visibility("default")))
+
+GD_PINVOKE_EXPORT const char *xamarin_get_locale_country_code() {
+ NSLocale *locale = [NSLocale currentLocale];
+ NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];
+ if (countryCode == NULL) {
+ return strdup("US");
+ }
+ return strdup([countryCode UTF8String]);
+}
+
+GD_PINVOKE_EXPORT void xamarin_log(const uint16_t *p_unicode_message) {
+ int length = 0;
+ const uint16_t *ptr = p_unicode_message;
+ while (*ptr++)
+ length += sizeof(uint16_t);
+ NSString *msg = [[NSString alloc] initWithBytes:p_unicode_message length:length encoding:NSUTF16LittleEndianStringEncoding];
+
+ os_log_info(OS_LOG_DEFAULT, "%{public}@", msg);
+}
+
+GD_PINVOKE_EXPORT const char *xamarin_GetFolderPath(int p_folder) {
+ NSSearchPathDirectory dd = (NSSearchPathDirectory)p_folder;
+ NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:dd inDomains:NSUserDomainMask] lastObject];
+ NSString *path = [url path];
+ return strdup([path UTF8String]);
+}
+
+GD_PINVOKE_EXPORT char *xamarin_timezone_get_local_name() {
+ NSTimeZone *tz = nil;
+ tz = [NSTimeZone localTimeZone];
+ NSString *name = [tz name];
+ return (name != nil) ? strdup([name UTF8String]) : strdup("Local");
+}
+
+GD_PINVOKE_EXPORT char **xamarin_timezone_get_names(uint32_t *p_count) {
+ NSArray *array = [NSTimeZone knownTimeZoneNames];
+ *p_count = array.count;
+ char **result = (char **)malloc(sizeof(char *) * (*p_count));
+ for (uint32_t i = 0; i < *p_count; i++) {
+ NSString *s = [array objectAtIndex:i];
+ result[i] = strdup(s.UTF8String);
+ }
+ return result;
+}
+
+GD_PINVOKE_EXPORT void *xamarin_timezone_get_data(const char *p_name, uint32_t *p_size) { // FIXME: uint32_t since Dec 2019, unsigned long before
+ NSTimeZone *tz = nil;
+ if (p_name) {
+ NSString *n = [[NSString alloc] initWithUTF8String:p_name];
+ tz = [[[NSTimeZone alloc] initWithName:n] autorelease];
+ [n release];
+ } else {
+ tz = [NSTimeZone localTimeZone];
+ }
+ NSData *data = [tz data];
+ *p_size = [data length];
+ void *result = malloc(*p_size);
+ memcpy(result, data.bytes, *p_size);
+ return result;
+}
+
+GD_PINVOKE_EXPORT void xamarin_start_wwan(const char *p_uri) {
+ // FIXME: What's this for? No idea how to implement.
+ os_log_error(OS_LOG_DEFAULT, "Not implemented: 'xamarin_start_wwan'");
+}
+
+#endif // IPHONE_ENABLED
diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp
index 4823ba3679..94431e7c30 100644
--- a/modules/mono/register_types.cpp
+++ b/modules/mono/register_types.cpp
@@ -34,11 +34,11 @@
#include "csharp_script.h"
-CSharpLanguage *script_language_cs = NULL;
+CSharpLanguage *script_language_cs = nullptr;
Ref<ResourceFormatLoaderCSharpScript> resource_loader_cs;
Ref<ResourceFormatSaverCSharpScript> resource_saver_cs;
-_GodotSharp *_godotsharp = NULL;
+_GodotSharp *_godotsharp = nullptr;
void register_mono_types() {
ClassDB::register_class<CSharpScript>();
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index d3226762ea..e77a2e98f2 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -36,108 +36,192 @@
#include "mono_gd/gd_mono_marshal.h"
#include "mono_gd/gd_mono_utils.h"
-namespace SignalAwaiterUtils {
-
-Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p_target, MonoObject *p_awaiter) {
-
+Error gd_mono_connect_signal_awaiter(Object *p_source, const StringName &p_signal, Object *p_target, MonoObject *p_awaiter) {
ERR_FAIL_NULL_V(p_source, ERR_INVALID_DATA);
ERR_FAIL_NULL_V(p_target, ERR_INVALID_DATA);
- Ref<SignalAwaiterHandle> sa_con = memnew(SignalAwaiterHandle(p_awaiter));
-#ifdef DEBUG_ENABLED
- sa_con->set_connection_target(p_target);
-#endif
+ // TODO: Use pooling for ManagedCallable instances.
+ SignalAwaiterCallable *awaiter_callable = memnew(SignalAwaiterCallable(p_target, p_awaiter, p_signal));
+ Callable callable = Callable(awaiter_callable);
+
+ return p_source->connect(p_signal, callable, Vector<Variant>(), Object::CONNECT_ONESHOT);
+}
+
+bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) {
+ const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a);
+ const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b);
- Vector<Variant> binds;
- binds.push_back(sa_con);
+ if (a->target_id != b->target_id)
+ return false;
+
+ if (a->signal != b->signal)
+ return false;
+
+ return true;
+}
+
+bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
+ if (compare_equal(p_a, p_b))
+ return false;
+ return p_a < p_b;
+}
+
+uint32_t SignalAwaiterCallable::hash() const {
+ uint32_t hash = signal.hash();
+ return hash_djb2_one_64(target_id, hash);
+}
- Error err = p_source->connect(p_signal, sa_con.ptr(),
- CSharpLanguage::get_singleton()->get_string_names()._signal_callback,
- binds, Object::CONNECT_ONESHOT);
+String SignalAwaiterCallable::get_as_text() const {
+ Object *base = ObjectDB::get_instance(target_id);
+ if (base) {
+ String class_name = base->get_class();
+ Ref<Script> script = base->get_script();
+ if (script.is_valid() && script->get_path().is_resource_file()) {
- if (err != OK) {
- // Set it as completed to prevent it from calling the failure callback when released.
- // The awaiter will be aware of the failure by checking the returned error.
- sa_con->set_completed(true);
+ class_name += "(" + script->get_path().get_file() + ")";
+ }
+ return class_name + "::SignalAwaiterMiddleman::" + String(signal);
+ } else {
+ return "null::SignalAwaiterMiddleman::" + String(signal);
}
+}
- return err;
+CallableCustom::CompareEqualFunc SignalAwaiterCallable::get_compare_equal_func() const {
+ return compare_equal_func_ptr;
}
-} // namespace SignalAwaiterUtils
-Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+CallableCustom::CompareLessFunc SignalAwaiterCallable::get_compare_less_func() const {
+ return compare_less_func_ptr;
+}
+
+ObjectID SignalAwaiterCallable::get_object() const {
+ return target_id;
+}
+
+void SignalAwaiterCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
+ r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; // Can't find anything better
+ r_return_value = Variant();
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V_MSG(conn_target_id && !ObjectDB::get_instance(conn_target_id), Variant(),
+ ERR_FAIL_COND_MSG(target_id.is_valid() && !ObjectDB::get_instance(target_id),
"Resumed after await, but class instance is gone.");
#endif
- if (p_argcount < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
- r_error.argument = 1;
- return Variant();
- }
+ MonoArray *signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_argcount);
- Ref<SignalAwaiterHandle> self = *p_args[p_argcount - 1];
-
- if (self.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = p_argcount - 1;
- r_error.expected = Variant::OBJECT;
- return Variant();
+ for (int i = 0; i < p_argcount; i++) {
+ MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_arguments[i]);
+ mono_array_setref(signal_args, i, boxed);
}
- set_completed(true);
-
- int signal_argc = p_argcount - 1;
- MonoArray *signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), signal_argc);
+ MonoObject *awaiter = awaiter_handle.get_target();
- for (int i = 0; i < signal_argc; i++) {
- MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]);
- mono_array_setref(signal_args, i, boxed);
+ if (!awaiter) {
+ r_call_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ return;
}
- MonoException *exc = NULL;
- GD_MONO_BEGIN_RUNTIME_INVOKE;
- CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback).invoke(get_target(), signal_args, &exc);
- GD_MONO_END_RUNTIME_INVOKE;
+ MonoException *exc = nullptr;
+ CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback).invoke(awaiter, signal_args, &exc);
if (exc) {
GDMonoUtils::set_pending_exception(exc);
- ERR_FAIL_V(Variant());
+ ERR_FAIL();
+ } else {
+ r_call_error.error = Callable::CallError::CALL_OK;
}
+}
- return Variant();
+SignalAwaiterCallable::SignalAwaiterCallable(Object *p_target, MonoObject *p_awaiter, const StringName &p_signal) :
+ target_id(p_target->get_instance_id()),
+ awaiter_handle(MonoGCHandleData::new_strong_handle(p_awaiter)),
+ signal(p_signal) {
}
-void SignalAwaiterHandle::_bind_methods() {
+SignalAwaiterCallable::~SignalAwaiterCallable() {
+ awaiter_handle.release();
+}
- ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &SignalAwaiterHandle::_signal_callback, MethodInfo("_signal_callback"));
+bool EventSignalCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) {
+ const EventSignalCallable *a = static_cast<const EventSignalCallable *>(p_a);
+ const EventSignalCallable *b = static_cast<const EventSignalCallable *>(p_b);
+
+ if (a->owner != b->owner)
+ return false;
+
+ if (a->event_signal != b->event_signal)
+ return false;
+
+ return true;
}
-SignalAwaiterHandle::SignalAwaiterHandle(MonoObject *p_managed) :
- MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) {
+bool EventSignalCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
+ if (compare_equal(p_a, p_b))
+ return false;
+ return p_a < p_b;
+}
-#ifdef DEBUG_ENABLED
- conn_target_id = 0;
-#endif
+uint32_t EventSignalCallable::hash() const {
+ uint32_t hash = event_signal->field->get_name().hash();
+ return hash_djb2_one_64(owner->get_instance_id(), hash);
}
-SignalAwaiterHandle::~SignalAwaiterHandle() {
+String EventSignalCallable::get_as_text() const {
+ String class_name = owner->get_class();
+ Ref<Script> script = owner->get_script();
+ if (script.is_valid() && script->get_path().is_resource_file()) {
+ class_name += "(" + script->get_path().get_file() + ")";
+ }
+ StringName signal = event_signal->field->get_name();
+ return class_name + "::EventSignalMiddleman::" + String(signal);
+}
+
+CallableCustom::CompareEqualFunc EventSignalCallable::get_compare_equal_func() const {
+ return compare_equal_func_ptr;
+}
- if (!completed) {
- MonoObject *awaiter = get_target();
+CallableCustom::CompareLessFunc EventSignalCallable::get_compare_less_func() const {
+ return compare_less_func_ptr;
+}
- if (awaiter) {
- MonoException *exc = NULL;
- GD_MONO_BEGIN_RUNTIME_INVOKE;
- CACHED_METHOD_THUNK(SignalAwaiter, FailureCallback).invoke(awaiter, &exc);
- GD_MONO_END_RUNTIME_INVOKE;
+ObjectID EventSignalCallable::get_object() const {
+ return owner->get_instance_id();
+}
- if (exc) {
- GDMonoUtils::set_pending_exception(exc);
- ERR_FAIL();
- }
- }
+StringName EventSignalCallable::get_signal() const {
+ return event_signal->field->get_name();
+}
+
+void EventSignalCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
+ r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; // Can't find anything better
+ r_return_value = Variant();
+
+ ERR_FAIL_COND(p_argcount < event_signal->invoke_method->get_parameters_count());
+
+ CSharpInstance *csharp_instance = CAST_CSHARP_INSTANCE(owner->get_script_instance());
+ ERR_FAIL_NULL(csharp_instance);
+
+ MonoObject *owner_managed = csharp_instance->get_mono_object();
+ ERR_FAIL_NULL(owner_managed);
+
+ MonoObject *delegate_field_value = event_signal->field->get_value(owner_managed);
+ if (!delegate_field_value) {
+ r_call_error.error = Callable::CallError::CALL_OK;
+ return;
}
+
+ MonoException *exc = nullptr;
+ event_signal->invoke_method->invoke(delegate_field_value, p_arguments, &exc);
+
+ if (exc) {
+ GDMonoUtils::set_pending_exception(exc);
+ ERR_FAIL();
+ } else {
+ r_call_error.error = Callable::CallError::CALL_OK;
+ }
+}
+
+EventSignalCallable::EventSignalCallable(Object *p_owner, const CSharpScript::EventSignal *p_event_signal) :
+ owner(p_owner),
+ event_signal(p_event_signal) {
}
diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h
index a9956ad5ba..c550315a23 100644
--- a/modules/mono/signal_awaiter_utils.h
+++ b/modules/mono/signal_awaiter_utils.h
@@ -32,40 +32,66 @@
#define SIGNAL_AWAITER_UTILS_H
#include "core/reference.h"
+
+#include "csharp_script.h"
#include "mono_gc_handle.h"
-namespace SignalAwaiterUtils {
+Error gd_mono_connect_signal_awaiter(Object *p_source, const StringName &p_signal, Object *p_target, MonoObject *p_awaiter);
+
+class SignalAwaiterCallable : public CallableCustom {
+ ObjectID target_id;
+ MonoGCHandleData awaiter_handle;
+ StringName signal;
+
+public:
+ static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b);
+ static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b);
-Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p_target, MonoObject *p_awaiter);
-}
+ static constexpr CompareEqualFunc compare_equal_func_ptr = &SignalAwaiterCallable::compare_equal;
+ static constexpr CompareEqualFunc compare_less_func_ptr = &SignalAwaiterCallable::compare_less;
-class SignalAwaiterHandle : public MonoGCHandle {
+ uint32_t hash() const override;
- GDCLASS(SignalAwaiterHandle, MonoGCHandle);
+ String get_as_text() const override;
- bool completed;
+ CompareEqualFunc get_compare_equal_func() const override;
+ CompareLessFunc get_compare_less_func() const override;
-#ifdef DEBUG_ENABLED
- ObjectID conn_target_id;
-#endif
+ ObjectID get_object() const override;
- Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ _FORCE_INLINE_ StringName get_signal() const { return signal; }
+
+ void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
+
+ SignalAwaiterCallable(Object *p_target, MonoObject *p_awaiter, const StringName &p_signal);
+ ~SignalAwaiterCallable();
+};
-protected:
- static void _bind_methods();
+class EventSignalCallable : public CallableCustom {
+ Object *owner;
+ const CSharpScript::EventSignal *event_signal;
public:
- _FORCE_INLINE_ bool is_completed() { return completed; }
- _FORCE_INLINE_ void set_completed(bool p_completed) { completed = p_completed; }
+ static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b);
+ static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b);
+
+ static constexpr CompareEqualFunc compare_equal_func_ptr = &EventSignalCallable::compare_equal;
+ static constexpr CompareEqualFunc compare_less_func_ptr = &EventSignalCallable::compare_less;
+
+ uint32_t hash() const override;
+
+ String get_as_text() const override;
+
+ CompareEqualFunc get_compare_equal_func() const override;
+ CompareLessFunc get_compare_less_func() const override;
+
+ ObjectID get_object() const override;
+
+ StringName get_signal() const;
-#ifdef DEBUG_ENABLED
- _FORCE_INLINE_ void set_connection_target(Object *p_target) {
- conn_target_id = p_target->get_instance_id();
- }
-#endif
+ void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
- SignalAwaiterHandle(MonoObject *p_managed);
- ~SignalAwaiterHandle();
+ EventSignalCallable(Object *p_owner, const CSharpScript::EventSignal *p_event_signal);
};
#endif // SIGNAL_AWAITER_UTILS_H
diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h
index 754000dc14..8650d6cc09 100644
--- a/modules/mono/utils/macros.h
+++ b/modules/mono/utils/macros.h
@@ -36,38 +36,6 @@
#define _GD_VARNAME_CONCAT_(m_a, m_b, m_c) _GD_VARNAME_CONCAT_A_(m_a, m_b, m_c)
#define GD_UNIQUE_NAME(m_name) _GD_VARNAME_CONCAT_(m_name, _, __COUNTER__)
-// static assert
-// TODO: Get rid of this macro once we upgrade to C++11
-
-#ifdef __cpp_static_assert
-#define GD_STATIC_ASSERT(m_cond) static_assert((m_cond), "Condition '" #m_cond "' failed")
-#else
-#define GD_STATIC_ASSERT(m_cond) typedef int GD_UNIQUE_NAME(godot_static_assert)[((m_cond) ? 1 : -1)]
-#endif
-
-// final
-// TODO: Get rid of this macro once we upgrade to C++11
-
-#if (__cplusplus >= 201103L)
-#define GD_FINAL final
-#else
-#define GD_FINAL
-#endif
-
-// noreturn
-// TODO: Get rid of this macro once we upgrade to C++11
-
-#if (__cplusplus >= 201103L)
-#define GD_NORETURN [[noreturn]]
-#elif defined(__GNUC__)
-#define GD_NORETURN __attribute__((noreturn))
-#elif defined(_MSC_VER)
-#define GD_NORETURN __declspec(noreturn)
-#else
-#define GD_NORETURN
-#pragma message "Macro GD_NORETURN will have no effect"
-#endif
-
// unreachable
#if defined(_MSC_VER)
@@ -81,4 +49,25 @@
} while (true);
#endif
+namespace gdmono {
+
+template <typename F>
+struct ScopeExit {
+ ScopeExit(F p_exit_func) :
+ exit_func(p_exit_func) {}
+ ~ScopeExit() { exit_func(); }
+ F exit_func;
+};
+
+class ScopeExitAux {
+public:
+ template <typename F>
+ ScopeExit<F> operator+(F p_exit_func) { return ScopeExit<F>(p_exit_func); }
+};
+
+} // namespace gdmono
+
+#define SCOPE_EXIT \
+ auto GD_UNIQUE_NAME(gd_scope_exit) = gdmono::ScopeExitAux() + [=]()
+
#endif // UTIL_MACROS_H
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index c1cd5f1db4..8f0ad8ba5e 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -73,13 +73,13 @@ LONG _RegKeyQueryString(HKEY hKey, const String &p_value_name, String &r_value)
buffer.resize(512);
DWORD dwBufferSize = buffer.size();
- LONG res = RegQueryValueExW(hKey, p_value_name.c_str(), 0, NULL, (LPBYTE)buffer.ptr(), &dwBufferSize);
+ LONG res = RegQueryValueExW(hKey, p_value_name.c_str(), 0, nullptr, (LPBYTE)buffer.ptr(), &dwBufferSize);
if (res == ERROR_MORE_DATA) {
// dwBufferSize now contains the actual size
Vector<WCHAR> buffer;
buffer.resize(dwBufferSize);
- res = RegQueryValueExW(hKey, p_value_name.c_str(), 0, NULL, (LPBYTE)buffer.ptr(), &dwBufferSize);
+ res = RegQueryValueExW(hKey, p_value_name.c_str(), 0, nullptr, (LPBYTE)buffer.ptr(), &dwBufferSize);
}
if (res == ERROR_SUCCESS) {
@@ -180,7 +180,7 @@ String find_msbuild_tools_path() {
String output;
int exit_code;
- OS::get_singleton()->execute(vswhere_path, vswhere_args, true, NULL, &output, &exit_code);
+ OS::get_singleton()->execute(vswhere_path, vswhere_args, true, nullptr, &output, &exit_code);
if (exit_code == 0) {
Vector<String> lines = output.split("\n");
diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp
index 432b306414..8fadf3c109 100644
--- a/modules/mono/utils/osx_utils.cpp
+++ b/modules/mono/utils/osx_utils.cpp
@@ -39,9 +39,9 @@
bool osx_is_app_bundle_installed(const String &p_bundle_id) {
- CFURLRef app_url = NULL;
- CFStringRef bundle_id = CFStringCreateWithCString(NULL, p_bundle_id.utf8(), kCFStringEncodingUTF8);
- OSStatus result = LSFindApplicationForInfo(kLSUnknownCreator, bundle_id, NULL, NULL, &app_url);
+ CFURLRef app_url = nullptr;
+ CFStringRef bundle_id = CFStringCreateWithCString(nullptr, p_bundle_id.utf8(), kCFStringEncodingUTF8);
+ OSStatus result = LSFindApplicationForInfo(kLSUnknownCreator, bundle_id, nullptr, nullptr, &app_url);
CFRelease(bundle_id);
if (app_url)
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index 545da6c79e..973375a471 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -80,7 +80,7 @@ String find_executable(const String &p_name) {
String cwd() {
#ifdef WINDOWS_ENABLED
- const DWORD expected_size = ::GetCurrentDirectoryW(0, NULL);
+ const DWORD expected_size = ::GetCurrentDirectoryW(0, nullptr);
String buffer;
buffer.resize((int)expected_size);
@@ -90,7 +90,7 @@ String cwd() {
return buffer.simplify_path();
#else
char buffer[PATH_MAX];
- if (::getcwd(buffer, sizeof(buffer)) == NULL)
+ if (::getcwd(buffer, sizeof(buffer)) == nullptr)
return ".";
String result;
@@ -114,12 +114,12 @@ String realpath(const String &p_path) {
// Open file without read/write access
HANDLE hFile = ::CreateFileW(p_path.c_str(), 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE)
return p_path;
- const DWORD expected_size = ::GetFinalPathNameByHandleW(hFile, NULL, 0, FILE_NAME_NORMALIZED);
+ const DWORD expected_size = ::GetFinalPathNameByHandleW(hFile, nullptr, 0, FILE_NAME_NORMALIZED);
if (expected_size == 0) {
::CloseHandle(hFile);
@@ -133,7 +133,7 @@ String realpath(const String &p_path) {
::CloseHandle(hFile);
return buffer.simplify_path();
#elif UNIX_ENABLED
- char *resolved_path = ::realpath(p_path.utf8().get_data(), NULL);
+ char *resolved_path = ::realpath(p_path.utf8().get_data(), nullptr);
if (!resolved_path)
return p_path;
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index 911ac5c4a3..907811355f 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -162,22 +162,22 @@ String escape_csharp_keyword(const String &p_name) {
#endif
Error read_all_file_utf8(const String &p_path, String &r_content) {
- PoolVector<uint8_t> sourcef;
+ Vector<uint8_t> sourcef;
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'.");
int len = f->get_len();
sourcef.resize(len + 1);
- PoolVector<uint8_t>::Write w = sourcef.write();
- int r = f->get_buffer(w.ptr(), len);
+ uint8_t *w = sourcef.ptrw();
+ int r = f->get_buffer(w, len);
f->close();
memdelete(f);
ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
w[len] = 0;
String source;
- if (source.parse_utf8((const char *)w.ptr())) {
+ if (source.parse_utf8((const char *)w)) {
ERR_FAIL_V(ERR_INVALID_DATA);
}
@@ -212,7 +212,7 @@ String str_format(const char *p_format, ...) {
#define gd_vscprintf(m_format, m_args_copy) _vscprintf(m_format, m_args_copy)
#else
#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf(m_buffer, m_count, m_format, m_args_copy)
-#define gd_vscprintf(m_format, m_args_copy) vsnprintf(NULL, 0, p_format, m_args_copy)
+#define gd_vscprintf(m_format, m_args_copy) vsnprintf(nullptr, 0, p_format, m_args_copy)
#endif
String str_format(const char *p_format, va_list p_list) {
diff --git a/modules/mono/utils/thread_local.h b/modules/mono/utils/thread_local.h
deleted file mode 100644
index b1cc2e37ea..0000000000
--- a/modules/mono/utils/thread_local.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*************************************************************************/
-/* thread_local.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 THREAD_LOCAL_H
-#define THREAD_LOCAL_H
-
-#ifdef HAVE_CXX11_THREAD_LOCAL
-#define _THREAD_LOCAL_(m_t) thread_local m_t
-#else
-
-#if !defined(__GNUC__) && !defined(_MSC_VER)
-#error Platform or compiler not supported
-#endif
-
-#if defined(__GNUC__)
-
-#ifdef HAVE_GCC___THREAD
-#define _THREAD_LOCAL_(m_t) __thread m_t
-#else
-#define USE_CUSTOM_THREAD_LOCAL
-#endif
-
-#elif defined(_MSC_VER)
-
-#ifdef HAVE_DECLSPEC_THREAD
-#define _THREAD_LOCAL_(m_t) __declspec(thread) m_t
-#else
-#define USE_CUSTOM_THREAD_LOCAL
-#endif
-
-#endif // __GNUC__ _MSC_VER
-
-#endif // HAVE_CXX11_THREAD_LOCAL
-
-#ifdef USE_CUSTOM_THREAD_LOCAL
-#define _THREAD_LOCAL_(m_t) ThreadLocal<m_t>
-#endif
-
-#include "core/typedefs.h"
-
-#ifdef WINDOWS_ENABLED
-#define _CALLBACK_FUNC_ __stdcall
-#else
-#define _CALLBACK_FUNC_
-#endif
-
-struct ThreadLocalStorage {
-
- void *get_value() const;
- void set_value(void *p_value) const;
-
- void alloc(void(_CALLBACK_FUNC_ *p_destr_callback)(void *));
- void free();
-
-private:
- struct Impl;
- Impl *pimpl;
-};
-
-template <typename T>
-class ThreadLocal {
-
- ThreadLocalStorage storage;
-
- T init_val;
-
- static void _CALLBACK_FUNC_ destr_callback(void *tls_data) {
- memdelete(static_cast<T *>(tls_data));
- }
-
- T *_tls_get_value() const {
- void *tls_data = storage.get_value();
-
- if (tls_data)
- return static_cast<T *>(tls_data);
-
- T *data = memnew(T(init_val));
-
- storage.set_value(data);
-
- return data;
- }
-
- void _initialize(const T &p_init_val) {
- init_val = p_init_val;
- storage.alloc(&destr_callback);
- }
-
-public:
- ThreadLocal() {
- _initialize(T());
- }
-
- ThreadLocal(const T &p_init_val) {
- _initialize(p_init_val);
- }
-
- ThreadLocal(const ThreadLocal &other) {
- _initialize(*other._tls_get_value());
- }
-
- ~ThreadLocal() {
- storage.free();
- }
-
- _FORCE_INLINE_ T *operator&() const {
- return _tls_get_value();
- }
-
- _FORCE_INLINE_ operator T &() const {
- return *_tls_get_value();
- }
-
- _FORCE_INLINE_ ThreadLocal &operator=(const T &val) {
- T *ptr = _tls_get_value();
- *ptr = val;
- return *this;
- }
-};
-
-struct FlagScopeGuard {
-
- FlagScopeGuard(bool &p_flag) :
- flag(p_flag) {
- flag = !flag;
- }
-
- ~FlagScopeGuard() {
- flag = !flag;
- }
-
-private:
- bool &flag;
-};
-
-#undef _CALLBACK_FUNC_
-
-#define _TLS_RECURSION_GUARD_V_(m_ret) \
- static _THREAD_LOCAL_(bool) _recursion_flag_ = false; \
- if (_recursion_flag_) \
- return m_ret; \
- FlagScopeGuard _recursion_guard_(_recursion_flag_);
-
-#define _TLS_RECURSION_GUARD_ \
- static _THREAD_LOCAL_(bool) _recursion_flag_ = false; \
- if (_recursion_flag_) \
- return; \
- FlagScopeGuard _recursion_guard_(_recursion_flag_);
-
-#endif // THREAD_LOCAL_H
diff --git a/modules/ogg/SCsub b/modules/ogg/SCsub
index 6a72a519fe..e768fb4ae8 100644
--- a/modules/ogg/SCsub
+++ b/modules/ogg/SCsub
@@ -1,12 +1,15 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
+
+# Only kept to build the thirdparty library used by the theora and webm
+# modules.
env_ogg = env_modules.Clone()
# Thirdparty source files
-if env['builtin_libogg']:
+if env["builtin_libogg"]:
thirdparty_dir = "#thirdparty/libogg/"
thirdparty_sources = [
"bitwise.c",
diff --git a/modules/ogg/config.py b/modules/ogg/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/ogg/config.py
+++ b/modules/ogg/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/ogg/register_types.h b/modules/ogg/register_types.h
index 09095c9b62..849d27bb06 100644
--- a/modules/ogg/register_types.h
+++ b/modules/ogg/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef OGG_REGISTER_TYPES_H
+#define OGG_REGISTER_TYPES_H
+
void register_ogg_types();
void unregister_ogg_types();
+
+#endif // OGG_REGISTER_TYPES_H
diff --git a/modules/opensimplex/SCsub b/modules/opensimplex/SCsub
index 311d33b047..52d8b145ef 100644
--- a/modules/opensimplex/SCsub
+++ b/modules/opensimplex/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_opensimplex = env_modules.Clone()
diff --git a/modules/opensimplex/config.py b/modules/opensimplex/config.py
index c1010ad433..90b85dbd70 100644
--- a/modules/opensimplex/config.py
+++ b/modules/opensimplex/config.py
@@ -1,14 +1,17 @@
def can_build(env, platform):
- return True
+ return True
+
def configure(env):
- pass
+ pass
+
def get_doc_classes():
return [
"NoiseTexture",
- "OpenSimplexNoise"
+ "OpenSimplexNoise",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml
index 0790cde557..c06f3096de 100644
--- a/modules/opensimplex/doc_classes/NoiseTexture.xml
+++ b/modules/opensimplex/doc_classes/NoiseTexture.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="NoiseTexture" inherits="Texture" version="4.0">
+<class name="NoiseTexture" inherits="Texture2D" version="4.0">
<brief_description>
[OpenSimplexNoise] filled texture.
</brief_description>
<description>
Uses an [OpenSimplexNoise] to fill the texture data. You can specify the texture size but keep in mind that larger textures will take longer to generate and seamless noise only works with square sized textures.
NoiseTexture can also generate normalmap textures.
- The class uses [Thread]s to generate the texture data internally, so [method Texture.get_data] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the data:
+ The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_data] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the data:
[codeblock]
var texture = preload("res://noise.tres")
yield(texture, "changed")
@@ -24,7 +24,6 @@
<member name="bump_strength" type="float" setter="set_bump_strength" getter="get_bump_strength" default="8.0">
Strength of the bump maps used in this texture. A higher value will make the bump maps appear larger while a lower value will make them appear softer.
</member>
- <member name="flags" type="int" setter="set_flags" getter="get_flags" override="true" default="7" />
<member name="height" type="int" setter="set_height" getter="get_height" default="512">
Height of the generated texture.
</member>
diff --git a/modules/opensimplex/icons/icon_noise_texture.svg b/modules/opensimplex/icons/NoiseTexture.svg
index 5908c2b2d4..5908c2b2d4 100644
--- a/modules/opensimplex/icons/icon_noise_texture.svg
+++ b/modules/opensimplex/icons/NoiseTexture.svg
diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp
index aa1c822813..2018f90e9f 100644
--- a/modules/opensimplex/noise_texture.cpp
+++ b/modules/opensimplex/noise_texture.cpp
@@ -34,7 +34,7 @@
NoiseTexture::NoiseTexture() {
update_queued = false;
- noise_thread = NULL;
+ noise_thread = nullptr;
regen_queued = false;
first_time = true;
@@ -42,17 +42,16 @@ NoiseTexture::NoiseTexture() {
seamless = false;
as_normalmap = false;
bump_strength = 8.0;
- flags = FLAGS_DEFAULT;
noise = Ref<OpenSimplexNoise>();
- texture = VS::get_singleton()->texture_create();
-
_queue_update();
}
NoiseTexture::~NoiseTexture() {
- VS::get_singleton()->free(texture);
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
if (noise_thread) {
Thread::wait_to_finish(noise_thread);
memdelete(noise_thread);
@@ -77,7 +76,6 @@ void NoiseTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture::get_bump_strength);
ClassDB::bind_method(D_METHOD("_update_texture"), &NoiseTexture::_update_texture);
- ClassDB::bind_method(D_METHOD("_queue_update"), &NoiseTexture::_queue_update);
ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture::_generate_texture);
ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture::_thread_done);
@@ -85,7 +83,7 @@ void NoiseTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
}
@@ -101,8 +99,12 @@ void NoiseTexture::_validate_property(PropertyInfo &property) const {
void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
data = p_image;
if (data.is_valid()) {
- VS::get_singleton()->texture_allocate(texture, size.x, size.y, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, flags);
- VS::get_singleton()->texture_set_data(texture, p_image);
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_create(p_image);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_create(p_image);
+ }
}
emit_changed();
}
@@ -112,7 +114,7 @@ void NoiseTexture::_thread_done(const Ref<Image> &p_image) {
_set_texture_data(p_image);
Thread::wait_to_finish(noise_thread);
memdelete(noise_thread);
- noise_thread = NULL;
+ noise_thread = nullptr;
if (regen_queued) {
noise_thread = Thread::create(_thread_function, this);
regen_queued = false;
@@ -135,14 +137,19 @@ void NoiseTexture::_queue_update() {
Ref<Image> NoiseTexture::_generate_texture() {
- if (noise.is_null()) return Ref<Image>();
+ // Prevent memdelete due to unref() on other thread.
+ Ref<OpenSimplexNoise> ref_noise = noise;
+
+ if (ref_noise.is_null()) {
+ return Ref<Image>();
+ }
Ref<Image> image;
if (seamless) {
- image = noise->get_seamless_image(size.x);
+ image = ref_noise->get_seamless_image(size.x);
} else {
- image = noise->get_image(size.x, size.y);
+ image = ref_noise->get_image(size.x, size.y);
}
if (as_normalmap) {
@@ -181,11 +188,11 @@ void NoiseTexture::set_noise(Ref<OpenSimplexNoise> p_noise) {
if (p_noise == noise)
return;
if (noise.is_valid()) {
- noise->disconnect(CoreStringNames::get_singleton()->changed, this, "_queue_update");
+ noise->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
}
noise = p_noise;
if (noise.is_valid()) {
- noise->connect(CoreStringNames::get_singleton()->changed, this, "_queue_update");
+ noise->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
}
_queue_update();
}
@@ -250,13 +257,12 @@ int NoiseTexture::get_height() const {
return size.y;
}
-void NoiseTexture::set_flags(uint32_t p_flags) {
- flags = p_flags;
- VS::get_singleton()->texture_set_flags(texture, flags);
-}
+RID NoiseTexture::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_2d_placeholder_create();
+ }
-uint32_t NoiseTexture::get_flags() const {
- return flags;
+ return texture;
}
Ref<Image> NoiseTexture::get_data() const {
diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h
index 285fd1eba9..b1d7d3fac9 100644
--- a/modules/opensimplex/noise_texture.h
+++ b/modules/opensimplex/noise_texture.h
@@ -39,8 +39,8 @@
#include "editor/editor_plugin.h"
#include "editor/property_editor.h"
-class NoiseTexture : public Texture {
- GDCLASS(NoiseTexture, Texture);
+class NoiseTexture : public Texture2D {
+ GDCLASS(NoiseTexture, Texture2D);
private:
Ref<Image> data;
@@ -51,7 +51,7 @@ private:
bool update_queued;
bool regen_queued;
- RID texture;
+ mutable RID texture;
uint32_t flags;
Ref<OpenSimplexNoise> noise;
@@ -91,10 +91,7 @@ public:
int get_width() const;
int get_height() const;
- virtual void set_flags(uint32_t p_flags);
- virtual uint32_t get_flags() const;
-
- virtual RID get_rid() const { return texture; }
+ virtual RID get_rid() const;
virtual bool has_alpha() const { return false; }
virtual Ref<Image> get_data() const;
diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp
index bd187e6b5b..238faa4130 100644
--- a/modules/opensimplex/open_simplex_noise.cpp
+++ b/modules/opensimplex/open_simplex_noise.cpp
@@ -98,10 +98,10 @@ void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) {
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(p_width * p_height * 4);
- PoolVector<uint8_t>::Write wd8 = data.write();
+ uint8_t *wd8 = data.ptrw();
for (int i = 0; i < p_height; i++) {
for (int j = 0; j < p_width; j++) {
@@ -121,10 +121,10 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) {
Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) {
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(p_size * p_size * 4);
- PoolVector<uint8_t>::Write wd8 = data.write();
+ uint8_t *wd8 = data.ptrw();
for (int i = 0; i < p_size; i++) {
for (int j = 0; j < p_size; j++) {
@@ -186,9 +186,9 @@ void OpenSimplexNoise::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
ADD_PROPERTY(PropertyInfo(Variant::INT, "octaves", PROPERTY_HINT_RANGE, vformat("1,%d,1", MAX_OCTAVES)), "set_octaves", "get_octaves");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "period", PROPERTY_HINT_RANGE, "0.1,256.0,0.1"), "set_period", "get_period");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "persistence", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistence", "get_persistence");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "period", PROPERTY_HINT_RANGE, "0.1,256.0,0.1"), "set_period", "get_period");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "persistence", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistence", "get_persistence");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity");
}
float OpenSimplexNoise::get_noise_1d(float x) {
diff --git a/modules/opensimplex/register_types.h b/modules/opensimplex/register_types.h
index 56e128f09e..51c6815eae 100644
--- a/modules/opensimplex/register_types.h
+++ b/modules/opensimplex/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef OPENSIMPLEX_REGISTER_TYPES_H
+#define OPENSIMPLEX_REGISTER_TYPES_H
+
void register_opensimplex_types();
void unregister_opensimplex_types();
+
+#endif // OPENSIMPLEX_REGISTER_TYPES_H
diff --git a/modules/opus/SCsub b/modules/opus/SCsub
index 1db5b0987e..e51590d808 100644
--- a/modules/opus/SCsub
+++ b/modules/opus/SCsub
@@ -1,18 +1,19 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
-stub = True
+# Only kept to build the thirdparty library used by the webm module.
+# AudioStreamOpus was dropped in 3.0 due to incompatibility with the new audio
+# engine. If you want to port it, fetch it from the Git history.
env_opus = env_modules.Clone()
# Thirdparty source files
-if env['builtin_opus']:
+if env["builtin_opus"]:
thirdparty_dir = "#thirdparty/opus/"
thirdparty_sources = [
-
# Sync with opus_sources.mk
"opus.c",
"opus_decoder.c",
@@ -21,17 +22,14 @@ if env['builtin_opus']:
"opus_multistream_encoder.c",
"opus_multistream_decoder.c",
"repacketizer.c",
-
"analysis.c",
"mlp.c",
"mlp_data.c",
-
# Sync with libopusfile Makefile.am
"info.c",
"internal.c",
"opusfile.c",
"stream.c",
-
# Sync with celt_sources.mk
"celt/bands.c",
"celt/celt.c",
@@ -51,12 +49,11 @@ if env['builtin_opus']:
"celt/quant_bands.c",
"celt/rate.c",
"celt/vq.c",
- #"celt/arm/arm_celt_map.c",
- #"celt/arm/armcpu.c",
- #"celt/arm/celt_ne10_fft.c",
- #"celt/arm/celt_ne10_mdct.c",
- #"celt/arm/celt_neon_intr.c",
-
+ # "celt/arm/arm_celt_map.c",
+ # "celt/arm/armcpu.c",
+ # "celt/arm/celt_ne10_fft.c",
+ # "celt/arm/celt_ne10_mdct.c",
+ # "celt/arm/celt_neon_intr.c",
# Sync with silk_sources.mk
"silk/CNG.c",
"silk/code_signs.c",
@@ -205,7 +202,7 @@ if env['builtin_opus']:
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources + opus_sources_silk]
# also requires libogg
- if env['builtin_libogg']:
+ if env["builtin_libogg"]:
env_opus.Prepend(CPPPATH=["#thirdparty/libogg"])
env_opus.Append(CPPDEFINES=["HAVE_CONFIG_H"])
@@ -221,23 +218,19 @@ if env['builtin_opus']:
env_opus.Prepend(CPPPATH=[thirdparty_dir + "/" + dir for dir in thirdparty_include_paths])
if env["platform"] == "android":
- if ("android_arch" in env and env["android_arch"] == "armv7"):
+ if "android_arch" in env and env["android_arch"] == "armv7":
env_opus.Append(CPPDEFINES=["OPUS_ARM_OPT"])
- elif ("android_arch" in env and env["android_arch"] == "arm64v8"):
+ elif "android_arch" in env and env["android_arch"] == "arm64v8":
env_opus.Append(CPPDEFINES=["OPUS_ARM64_OPT"])
elif env["platform"] == "iphone":
- if ("arch" in env and env["arch"] == "arm"):
+ if "arch" in env and env["arch"] == "arm":
env_opus.Append(CPPDEFINES=["OPUS_ARM_OPT"])
- elif ("arch" in env and env["arch"] == "arm64"):
+ elif "arch" in env and env["arch"] == "arm64":
env_opus.Append(CPPDEFINES=["OPUS_ARM64_OPT"])
env_thirdparty = env_opus.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
-if not stub:
- # Module files
- env_opus.add_source_files(env.modules_sources, "*.cpp")
-else:
- # Module files
- env_opus.add_source_files(env.modules_sources, "stub/register_types.cpp")
+# Module files
+env_opus.add_source_files(env.modules_sources, "register_types.cpp")
diff --git a/modules/opus/audio_stream_opus.cpp b/modules/opus/audio_stream_opus.cpp
deleted file mode 100644
index 67a07628d9..0000000000
--- a/modules/opus/audio_stream_opus.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/*************************************************************************/
-/* audio_stream_opus.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 "audio_stream_opus.h"
-
-/**
- @author George Marques <george@gmarqu.es>
-*/
-
-const float AudioStreamPlaybackOpus::osrate = 48000.0f;
-
-int AudioStreamPlaybackOpus::_op_read_func(void *_stream, unsigned char *_ptr, int _nbytes) {
- FileAccess *fa = (FileAccess *)_stream;
-
- if (fa->eof_reached())
- return 0;
-
- uint8_t *dst = (uint8_t *)_ptr;
-
- int read = fa->get_buffer(dst, _nbytes);
-
- return read;
-}
-
-int AudioStreamPlaybackOpus::_op_seek_func(void *_stream, opus_int64 _offset, int _whence) {
-
-#ifdef SEEK_SET
- FileAccess *fa = (FileAccess *)_stream;
-
- switch (_whence) {
- case SEEK_SET: {
- fa->seek(_offset);
- } break;
- case SEEK_CUR: {
- fa->seek(fa->get_position() + _offset);
- } break;
- case SEEK_END: {
- fa->seek_end(_offset);
- } break;
- default: {
- ERR_PRINT("Opus seek function failure: Unexpected value in _whence\n");
- }
- }
- int ret = fa->eof_reached() ? -1 : 0;
- return ret;
-#else
- return -1; // no seeking
-#endif
-}
-
-int AudioStreamPlaybackOpus::_op_close_func(void *_stream) {
- if (!_stream)
- return 0;
- FileAccess *fa = (FileAccess *)_stream;
- if (fa->is_open())
- fa->close();
- return 0;
-}
-
-opus_int64 AudioStreamPlaybackOpus::_op_tell_func(void *_stream) {
- FileAccess *_fa = (FileAccess *)_stream;
- return (opus_int64)_fa->get_position();
-}
-
-void AudioStreamPlaybackOpus::_clear_stream() {
- if (!stream_loaded)
- return;
-
- op_free(opus_file);
- _close_file();
-
- stream_loaded = false;
- stream_channels = 1;
- playing = false;
-}
-
-void AudioStreamPlaybackOpus::_close_file() {
- if (f) {
- memdelete(f);
- f = NULL;
- }
-}
-
-Error AudioStreamPlaybackOpus::_load_stream() {
-
- ERR_FAIL_COND_V(!stream_valid, ERR_UNCONFIGURED);
-
- _clear_stream();
- if (file == "")
- return ERR_INVALID_DATA;
-
- Error err;
- f = FileAccess::open(file, FileAccess::READ, &err);
-
- ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + file + "'.");
-
- int _err = 0;
-
- opus_file = op_open_callbacks(f, &_op_callbacks, NULL, 0, &_err);
-
- switch (_err) {
- case OP_EREAD: { // - Can't read the file.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CANT_READ);
- } break;
- case OP_EVERSION: // - Unrecognized version number.
- case OP_ENOTFORMAT: // - Stream is not Opus data.
- case OP_EIMPL: { // - Stream used non-implemented feature.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
- } break;
- case OP_EBADLINK: // - Failed to find old data after seeking.
- case OP_EBADTIMESTAMP: // - Timestamp failed the validity checks.
- case OP_EBADHEADER: { // - Invalid or missing Opus bitstream header.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- } break;
- case OP_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_BUG);
- } break;
- }
- repeats = 0;
- stream_loaded = true;
-
- return OK;
-}
-
-AudioStreamPlaybackOpus::AudioStreamPlaybackOpus() {
- loops = false;
- playing = false;
- f = NULL;
- stream_loaded = false;
- stream_valid = false;
- repeats = 0;
- paused = true;
- stream_channels = 0;
- current_section = 0;
- length = 0;
- loop_restart_time = 0;
- pre_skip = 0;
-
- _op_callbacks.read = _op_read_func;
- _op_callbacks.seek = _op_seek_func;
- _op_callbacks.tell = _op_tell_func;
- _op_callbacks.close = _op_close_func;
-}
-
-Error AudioStreamPlaybackOpus::set_file(const String &p_file) {
- file = p_file;
- stream_valid = false;
- Error err;
- f = FileAccess::open(file, FileAccess::READ, &err);
-
- ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + file + "'.");
-
- int _err;
-
- opus_file = op_open_callbacks(f, &_op_callbacks, NULL, 0, &_err);
-
- switch (_err) {
- case OP_EREAD: { // - Can't read the file.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CANT_READ);
- } break;
- case OP_EVERSION: // - Unrecognized version number.
- case OP_ENOTFORMAT: // - Stream is not Opus data.
- case OP_EIMPL: { // - Stream used non-implemented feature.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
- } break;
- case OP_EBADLINK: // - Failed to find old data after seeking.
- case OP_EBADTIMESTAMP: // - Timestamp failed the validity checks.
- case OP_EBADHEADER: { // - Invalid or missing Opus bitstream header.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- } break;
- case OP_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_BUG);
- } break;
- }
-
- const OpusHead *oinfo = op_head(opus_file, -1);
-
- stream_channels = oinfo->channel_count;
- pre_skip = oinfo->pre_skip;
- frames_mixed = pre_skip;
- ogg_int64_t len = op_pcm_total(opus_file, -1);
- if (len < 0) {
- length = 0;
- } else {
- length = (len / osrate);
- }
-
- op_free(opus_file);
- memdelete(f);
- f = NULL;
- stream_valid = true;
-
- return OK;
-}
-
-void AudioStreamPlaybackOpus::play(float p_from) {
- if (playing)
- stop();
-
- if (_load_stream() != OK)
- return;
-
- frames_mixed = pre_skip;
- playing = true;
- if (p_from > 0) {
- seek(p_from);
- }
-}
-
-void AudioStreamPlaybackOpus::stop() {
- _clear_stream();
- playing = false;
-}
-
-void AudioStreamPlaybackOpus::seek(float p_time) {
- if (!playing) return;
- ogg_int64_t pcm_offset = (ogg_int64_t)(p_time * osrate);
- bool ok = op_pcm_seek(opus_file, pcm_offset) == 0;
- if (!ok) {
- ERR_PRINT("Seek time over stream size.");
- return;
- }
- frames_mixed = osrate * p_time;
-}
-
-int AudioStreamPlaybackOpus::mix(int16_t *p_buffer, int p_frames) {
- if (!playing)
- return 0;
-
- int total = p_frames;
-
- while (true) {
-
- int todo = p_frames;
-
- if (todo < MIN_MIX) {
- break;
- }
-
- int ret = op_read(opus_file, (opus_int16 *)p_buffer, todo * stream_channels, &current_section);
- if (ret < 0) {
- playing = false;
- ERR_BREAK_MSG(ret < 0, "Error reading Opus file: " + file + ".");
- } else if (ret == 0) { // end of song, reload?
- op_free(opus_file);
-
- _close_file();
-
- f = FileAccess::open(file, FileAccess::READ);
-
- int errv = 0;
- opus_file = op_open_callbacks(f, &_op_callbacks, NULL, 0, &errv);
- if (errv != 0) {
- playing = false;
- break; // :(
- }
-
- if (!has_loop()) {
- playing = false;
- repeats = 1;
- break;
- }
-
- if (loop_restart_time) {
- bool ok = op_pcm_seek(opus_file, (loop_restart_time * osrate) + pre_skip) == 0;
- if (!ok) {
- playing = false;
- ERR_PRINT("Loop restart time rejected");
- }
-
- frames_mixed = (loop_restart_time * osrate) + pre_skip;
- } else {
- frames_mixed = pre_skip;
- }
- repeats++;
- continue;
- }
-
- stream_channels = op_head(opus_file, current_section)->channel_count;
-
- frames_mixed += ret;
-
- p_buffer += ret * stream_channels;
- p_frames -= ret;
- }
-
- return total - p_frames;
-}
-
-float AudioStreamPlaybackOpus::get_length() const {
- if (!stream_loaded) {
- if (const_cast<AudioStreamPlaybackOpus *>(this)->_load_stream() != OK)
- return 0;
- }
- return length;
-}
-
-float AudioStreamPlaybackOpus::get_playback_position() const {
-
- int32_t frames = int32_t(frames_mixed);
- if (frames < 0)
- frames = 0;
- return double(frames) / osrate;
-}
-
-int AudioStreamPlaybackOpus::get_minimum_buffer_size() const {
- return MIN_MIX;
-}
-
-AudioStreamPlaybackOpus::~AudioStreamPlaybackOpus() {
- _clear_stream();
-}
-
-RES ResourceFormatLoaderAudioStreamOpus::load(const String &p_path, const String &p_original_path, Error *r_error) {
- if (r_error)
- *r_error = OK;
-
- AudioStreamOpus *opus_stream = memnew(AudioStreamOpus);
- opus_stream->set_file(p_path);
- return Ref<AudioStreamOpus>(opus_stream);
-}
-
-void ResourceFormatLoaderAudioStreamOpus::get_recognized_extensions(List<String> *p_extensions) const {
-
- p_extensions->push_back("opus");
-}
-String ResourceFormatLoaderAudioStreamOpus::get_resource_type(const String &p_path) const {
-
- if (p_path.get_extension().to_lower() == "opus")
- return "AudioStreamOpus";
- return "";
-}
-
-bool ResourceFormatLoaderAudioStreamOpus::handles_type(const String &p_type) const {
- return (p_type == "AudioStream" || p_type == "AudioStreamOpus");
-}
diff --git a/modules/opus/audio_stream_opus.h b/modules/opus/audio_stream_opus.h
deleted file mode 100644
index 5c0a02a9d0..0000000000
--- a/modules/opus/audio_stream_opus.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*************************************************************************/
-/* audio_stream_opus.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 AUDIO_STREAM_OPUS_H
-#define AUDIO_STREAM_OPUS_H
-
-#include "core/io/resource_loader.h"
-#include "core/os/file_access.h"
-#include "scene/resources/audio_stream.h"
-
-#include <opus/opusfile.h>
-
-/**
- @author George Marques <george@gmarqu.es>
-*/
-
-class AudioStreamPlaybackOpus : public AudioStreamPlayback {
-
- GDCLASS(AudioStreamPlaybackOpus, AudioStreamPlayback);
-
- enum {
- MIN_MIX = 1024
- };
-
- FileAccess *f;
-
- OpusFileCallbacks _op_callbacks;
- float length;
- static int _op_read_func(void *_stream, unsigned char *_ptr, int _nbytes);
- static int _op_seek_func(void *_stream, opus_int64 _offset, int _whence);
- static int _op_close_func(void *_stream);
- static opus_int64 _op_tell_func(void *_stream);
- static const float osrate;
-
- String file;
- int64_t frames_mixed;
-
- bool stream_loaded;
- volatile bool playing;
- OggOpusFile *opus_file;
- int stream_channels;
- int current_section;
- int pre_skip;
-
- bool paused;
- bool loops;
- int repeats;
-
- Error _load_stream();
- void _clear_stream();
- void _close_file();
-
- bool stream_valid;
- float loop_restart_time;
-
-public:
- Error set_file(const String &p_file);
-
- virtual void play(float p_from = 0);
- virtual void stop();
- virtual bool is_playing() const { return playing; }
-
- virtual void set_loop_restart_time(float p_time) { loop_restart_time = p_time; }
-
- virtual void set_paused(bool p_paused) { paused = p_paused; }
- virtual bool is_paused() const { return paused; }
-
- virtual void set_loop(bool p_enable) { loops = p_enable; }
- virtual bool has_loop() const { return loops; }
-
- virtual float get_length() const;
-
- virtual String get_stream_name() const { return ""; }
-
- virtual int get_loop_count() const { return repeats; }
-
- virtual float get_playback_position() const;
- virtual void seek(float p_time);
-
- virtual int get_channels() const { return stream_channels; }
- virtual int get_mix_rate() const { return osrate; }
-
- virtual int get_minimum_buffer_size() const;
-
- virtual int mix(int16_t *p_buffer, int p_frames);
-
- AudioStreamPlaybackOpus();
- ~AudioStreamPlaybackOpus();
-};
-
-class AudioStreamOpus : public AudioStream {
-
- GDCLASS(AudioStreamOpus, AudioStream);
-
- String file;
-
-public:
- Ref<AudioStreamPlayback> instance_playback() {
- Ref<AudioStreamPlaybackOpus> pb = memnew(AudioStreamPlaybackOpus);
- pb->set_file(file);
- return pb;
- }
-
- void set_file(const String &p_file) { file = p_file; }
-};
-
-class ResourceFormatLoaderAudioStreamOpus : public ResourceFormatLoader {
-public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
- virtual bool handles_type(const String &p_type) const;
- virtual String get_resource_type(const String &p_path) const;
-};
-
-#endif // AUDIO_STREAM_OPUS_H
diff --git a/modules/opus/config.py b/modules/opus/config.py
index a1cde10ea0..d22f9454ed 100644
--- a/modules/opus/config.py
+++ b/modules/opus/config.py
@@ -1,13 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
-
-def get_doc_classes():
- return [
- "AudioStreamOpus",
- ]
-
-def get_doc_path():
- return "doc_classes"
diff --git a/modules/opus/register_types.cpp b/modules/opus/register_types.cpp
index dff309b49c..a4329e142c 100644
--- a/modules/opus/register_types.cpp
+++ b/modules/opus/register_types.cpp
@@ -30,23 +30,8 @@
#include "register_types.h"
-#include "audio_stream_opus.h"
+// Dummy module as libvorbis is needed by other modules (theora ...)
-static Ref<ResourceFormatLoaderAudioStreamOpus> opus_stream_loader;
+void register_opus_types() {}
-void register_opus_types() {
- // Sorry guys, do not enable this unless you can figure out a way
- // to get Opus to not do any memory allocation or system calls
- // in the audio thread.
- // Currently the implementation even reads files from the audio thread,
- // and this is not how audio programming works.
-
- //opus_stream_loader = memnew(ResourceFormatLoaderAudioStreamOpus);
- //ResourceLoader::add_resource_format_loader(opus_stream_loader);
- //ClassDB::register_class<AudioStreamOpus>();
-}
-
-void unregister_opus_types() {
-
- //memdelete(opus_stream_loader);
-}
+void unregister_opus_types() {}
diff --git a/modules/opus/register_types.h b/modules/opus/register_types.h
index 445be4e166..ad6e083c82 100644
--- a/modules/opus/register_types.h
+++ b/modules/opus/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef OPUS_REGISTER_TYPES_H
+#define OPUS_REGISTER_TYPES_H
+
void register_opus_types();
void unregister_opus_types();
+
+#endif // OPUS_REGISTER_TYPES_H
diff --git a/modules/pvr/SCsub b/modules/pvr/SCsub
index 18da38fbbd..e0baf851f1 100644
--- a/modules/pvr/SCsub
+++ b/modules/pvr/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_pvr = env_modules.Clone()
diff --git a/modules/pvr/config.py b/modules/pvr/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/pvr/config.py
+++ b/modules/pvr/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/pvr/register_types.h b/modules/pvr/register_types.h
index 06c54f50b1..8318996a46 100644
--- a/modules/pvr/register_types.h
+++ b/modules/pvr/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef PVR_REGISTER_TYPES_H
+#define PVR_REGISTER_TYPES_H
+
void register_pvr_types();
void unregister_pvr_types();
+
+#endif // PVR_REGISTER_TYPES_H
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 65c21d5af8..a8e8a9a2f1 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -51,7 +51,7 @@ enum PVRFLags {
};
-RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_CANT_OPEN;
@@ -96,12 +96,12 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
print_line("surfcount: "+itos(surfcount));
*/
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(surfsize);
ERR_FAIL_COND_V(data.size() == 0, RES());
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
f->get_buffer(&w[0], surfsize);
err = f->get_error();
ERR_FAIL_COND_V(err != OK, RES());
@@ -152,18 +152,11 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
ERR_FAIL_V_MSG(RES(), "Unsupported format in PVR texture: " + itos(flags & 0xFF) + ".");
}
- w.release();
-
- int tex_flags = Texture::FLAG_FILTER | Texture::FLAG_REPEAT;
-
- if (mipmaps)
- tex_flags |= Texture::FLAG_MIPMAPS;
-
Ref<Image> image = memnew(Image(width, height, mipmaps, format, data));
ERR_FAIL_COND_V(image->empty(), RES());
Ref<ImageTexture> texture = memnew(ImageTexture);
- texture->create_from_image(image, tex_flags);
+ texture->create_from_image(image);
if (r_error)
*r_error = OK;
@@ -177,12 +170,12 @@ void ResourceFormatPVR::get_recognized_extensions(List<String> *p_extensions) co
}
bool ResourceFormatPVR::handles_type(const String &p_type) const {
- return ClassDB::is_parent_class(p_type, "Texture");
+ return ClassDB::is_parent_class(p_type, "Texture2D");
}
String ResourceFormatPVR::get_resource_type(const String &p_path) const {
if (p_path.get_extension().to_lower() == "pvr")
- return "Texture";
+ return "Texture2D";
return "";
}
@@ -205,10 +198,10 @@ static void _compress_pvrtc4(Image *p_img) {
new_img.instance();
new_img->create(img->get_width(), img->get_height(), img->has_mipmaps(), use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4);
- PoolVector<uint8_t> data = new_img->get_data();
+ Vector<uint8_t> data = new_img->get_data();
{
- PoolVector<uint8_t>::Write wr = data.write();
- PoolVector<uint8_t>::Read r = img->get_data().read();
+ uint8_t *wr = data.ptrw();
+ const uint8_t *r = img->get_data().ptr();
for (int i = 0; i <= new_img->get_mipmap_count(); i++) {
@@ -541,7 +534,7 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int
// local neighbourhood of blocks
PVRTCBlock *p_blocks[2][2];
- PVRTCBlock *prev[2][2] = { { NULL, NULL }, { NULL, NULL } };
+ PVRTCBlock *prev[2][2] = { { nullptr, nullptr }, { nullptr, nullptr } };
struct
{
@@ -645,17 +638,14 @@ static void _pvrtc_decompress(Image *p_img) {
bool _2bit = (p_img->get_format() == Image::FORMAT_PVRTC2 || p_img->get_format() == Image::FORMAT_PVRTC2A);
- PoolVector<uint8_t> data = p_img->get_data();
- PoolVector<uint8_t>::Read r = data.read();
+ Vector<uint8_t> data = p_img->get_data();
+ const uint8_t *r = data.ptr();
- PoolVector<uint8_t> newdata;
+ Vector<uint8_t> newdata;
newdata.resize(p_img->get_width() * p_img->get_height() * 4);
- PoolVector<uint8_t>::Write w = newdata.write();
-
- decompress_pvrtc((PVRTCBlock *)r.ptr(), _2bit, p_img->get_width(), p_img->get_height(), 0, (unsigned char *)w.ptr());
+ uint8_t *w = newdata.ptrw();
- w.release();
- r.release();
+ decompress_pvrtc((PVRTCBlock *)r, _2bit, p_img->get_width(), p_img->get_height(), 0, (unsigned char *)w);
bool make_mipmaps = p_img->has_mipmaps();
p_img->create(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata);
diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h
index e384ed2b4c..07ef129689 100644
--- a/modules/pvr/texture_loader_pvr.h
+++ b/modules/pvr/texture_loader_pvr.h
@@ -36,7 +36,7 @@
class ResourceFormatPVR : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/recast/SCsub b/modules/recast/SCsub
deleted file mode 100644
index 94d9968164..0000000000
--- a/modules/recast/SCsub
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-Import('env_modules')
-
-env_recast = env_modules.Clone()
-
-# Thirdparty source files
-if env['builtin_recast']:
- thirdparty_dir = "#thirdparty/recastnavigation/Recast/"
- thirdparty_sources = [
- "Source/Recast.cpp",
- "Source/RecastAlloc.cpp",
- "Source/RecastArea.cpp",
- "Source/RecastAssert.cpp",
- "Source/RecastContour.cpp",
- "Source/RecastFilter.cpp",
- "Source/RecastLayers.cpp",
- "Source/RecastMesh.cpp",
- "Source/RecastMeshDetail.cpp",
- "Source/RecastRasterization.cpp",
- "Source/RecastRegion.cpp",
- ]
- thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
-
- env_recast.Prepend(CPPPATH=[thirdparty_dir + "/Include"])
-
- env_thirdparty = env_recast.Clone()
- env_thirdparty.disable_warnings()
- env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
-
-# Godot source files
-env_recast.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/regex/SCsub b/modules/regex/SCsub
index 6238cd3d9f..753650adcb 100644
--- a/modules/regex/SCsub
+++ b/modules/regex/SCsub
@@ -1,16 +1,16 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_regex = env_modules.Clone()
-if env['builtin_pcre2']:
- thirdparty_dir = '#thirdparty/pcre2/src/'
- thirdparty_flags = ['PCRE2_STATIC', 'HAVE_CONFIG_H']
+if env["builtin_pcre2"]:
+ thirdparty_dir = "#thirdparty/pcre2/src/"
+ thirdparty_flags = ["PCRE2_STATIC", "HAVE_CONFIG_H"]
- if env['builtin_pcre2_with_jit']:
- thirdparty_flags.append('SUPPORT_JIT')
+ if env["builtin_pcre2_with_jit"]:
+ thirdparty_flags.append("SUPPORT_JIT")
thirdparty_sources = [
"pcre2_auto_possess.c",
@@ -24,7 +24,7 @@ if env['builtin_pcre2']:
"pcre2_extuni.c",
"pcre2_find_bracket.c",
"pcre2_jit_compile.c",
- #"pcre2_jit_match.c", "pcre2_jit_misc.c", # these files are included in pcre2_jit_compile.c.
+ # "pcre2_jit_match.c", "pcre2_jit_misc.c", # these files are included in pcre2_jit_compile.c.
"pcre2_maketables.c",
"pcre2_match.c",
"pcre2_match_data.c",
diff --git a/modules/regex/config.py b/modules/regex/config.py
index 42cfe3b43c..df9f44cb95 100644
--- a/modules/regex/config.py
+++ b/modules/regex/config.py
@@ -1,14 +1,17 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"RegEx",
"RegExMatch",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml
index e9f46b9853..3130c53331 100644
--- a/modules/regex/doc_classes/RegEx.xml
+++ b/modules/regex/doc_classes/RegEx.xml
@@ -10,7 +10,7 @@
var regex = RegEx.new()
regex.compile("\\w-(\\d+)")
[/codeblock]
- The search pattern must be escaped first for gdscript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code].
+ The search pattern must be escaped first for GDScript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code].
Using [method search] you can find the pattern within the given text. If a pattern is found, [RegExMatch] is returned and you can retrieve details of the results using functions such as [method RegExMatch.get_string] and [method RegExMatch.get_start].
[codeblock]
var regex = RegEx.new()
@@ -35,6 +35,8 @@
# Would print 01 03 3f 42
# Note that d0c would not match
[/codeblock]
+ [b]Note:[/b] Godot's regex implementation is based on the [url=https://www.pcre.org/]PCRE2[/url] library. You can view the full pattern reference [url=https://www.pcre.org/current/doc/html/pcre2pattern.html]here[/url].
+ [b]Tip:[/b] You can use [url=https://regexr.com/]Regexr[/url] to test regular expressions online.
</description>
<tutorials>
</tutorials>
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp
index 53d1a1dd65..25cc580591 100644
--- a/modules/regex/regex.cpp
+++ b/modules/regex/regex.cpp
@@ -80,7 +80,7 @@ Dictionary RegExMatch::get_names() const {
Dictionary result;
- for (const Map<String, int>::Element *i = names.front(); i != NULL; i = i->next()) {
+ for (const Map<String, int>::Element *i = names.front(); i != nullptr; i = i->next()) {
result[i->key()] = i->value();
}
@@ -180,14 +180,14 @@ void RegEx::clear() {
if (code) {
pcre2_code_free_16((pcre2_code_16 *)code);
- code = NULL;
+ code = nullptr;
}
} else {
if (code) {
pcre2_code_free_32((pcre2_code_32 *)code);
- code = NULL;
+ code = nullptr;
}
}
}
@@ -242,7 +242,7 @@ Error RegEx::compile(const String &p_pattern) {
Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) const {
- ERR_FAIL_COND_V(!is_valid(), NULL);
+ ERR_FAIL_COND_V(!is_valid(), nullptr);
Ref<RegExMatch> result = memnew(RegExMatch);
@@ -263,7 +263,7 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
if (res < 0) {
pcre2_match_data_free_16(match);
- return NULL;
+ return nullptr;
}
uint32_t size = pcre2_get_ovector_count_16(match);
@@ -295,7 +295,7 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
pcre2_match_data_free_32(match);
pcre2_match_context_free_32(mctx);
- return NULL;
+ return nullptr;
}
uint32_t size = pcre2_get_ovector_count_32(match);
@@ -431,7 +431,7 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a
bool RegEx::is_valid() const {
- return (code != NULL);
+ return (code != nullptr);
}
String RegEx::get_pattern() const {
@@ -479,26 +479,26 @@ RegEx::RegEx() {
if (sizeof(CharType) == 2) {
- general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, NULL);
+ general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, nullptr);
} else {
- general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, NULL);
+ general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
}
- code = NULL;
+ code = nullptr;
}
RegEx::RegEx(const String &p_pattern) {
if (sizeof(CharType) == 2) {
- general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, NULL);
+ general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, nullptr);
} else {
- general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, NULL);
+ general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
}
- code = NULL;
+ code = nullptr;
compile(p_pattern);
}
diff --git a/modules/regex/register_types.h b/modules/regex/register_types.h
index 99a6bbeb2c..cf377cdf5f 100644
--- a/modules/regex/register_types.h
+++ b/modules/regex/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef REGEX_REGISTER_TYPES_H
+#define REGEX_REGISTER_TYPES_H
+
void register_regex_types();
void unregister_regex_types();
+
+#endif // REGEX_REGISTER_TYPES_H
diff --git a/modules/register_module_types.h b/modules/register_module_types.h
index b410457201..acd9fc7c97 100644
--- a/modules/register_module_types.h
+++ b/modules/register_module_types.h
@@ -31,6 +31,7 @@
#ifndef REGISTER_MODULE_TYPES_H
#define REGISTER_MODULE_TYPES_H
+void preregister_module_types();
void register_module_types();
void unregister_module_types();
diff --git a/modules/squish/SCsub b/modules/squish/SCsub
index 15320bcd0c..b31032403f 100644
--- a/modules/squish/SCsub
+++ b/modules/squish/SCsub
@@ -1,12 +1,12 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_squish = env_modules.Clone()
# Thirdparty source files
-if env['builtin_squish']:
+if env["builtin_squish"]:
thirdparty_dir = "#thirdparty/squish/"
thirdparty_sources = [
"alpha.cpp",
diff --git a/modules/squish/config.py b/modules/squish/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/squish/config.py
+++ b/modules/squish/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index 58b8115dfc..bb77f68590 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -37,20 +37,20 @@ void image_decompress_squish(Image *p_image) {
int h = p_image->get_height();
Image::Format target_format = Image::FORMAT_RGBA8;
- PoolVector<uint8_t> data;
+ 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();
data.resize(target_size);
- PoolVector<uint8_t>::Read rb = p_image->get_data().read();
- PoolVector<uint8_t>::Write wb = data.write();
+ 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) {
+ } 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;
@@ -71,9 +71,13 @@ void image_decompress_squish(Image *p_image) {
}
p_image->create(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) {
+ p_image->convert_ra_rgba8_to_rg();
+ }
}
-void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source) {
+void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels) {
if (p_image->get_format() >= Image::FORMAT_DXT1)
return; //do not compress, already compressed
@@ -92,75 +96,35 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres
Image::Format target_format = Image::FORMAT_RGBA8;
- Image::DetectChannels dc = p_image->get_detected_channels();
-
- if (p_source == Image::COMPRESS_SOURCE_LAYERED) {
- //keep what comes in
- switch (p_image->get_format()) {
- case Image::FORMAT_L8: {
- dc = Image::DETECTED_L;
- } break;
- case Image::FORMAT_LA8: {
- dc = Image::DETECTED_LA;
- } break;
- case Image::FORMAT_R8: {
- dc = Image::DETECTED_R;
- } break;
- case Image::FORMAT_RG8: {
- dc = Image::DETECTED_RG;
- } break;
- case Image::FORMAT_RGB8: {
- dc = Image::DETECTED_RGB;
- } break;
- case Image::FORMAT_RGBA8:
- case Image::FORMAT_RGBA4444:
- case Image::FORMAT_RGBA5551: {
- dc = Image::DETECTED_RGBA;
- } break;
- default: {
- }
- }
- }
-
p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
- if (p_source == Image::COMPRESS_SOURCE_SRGB && (dc == Image::DETECTED_R || dc == Image::DETECTED_RG)) {
- //R and RG do not support SRGB
- dc = Image::DETECTED_RGB;
- }
-
- if (p_source == Image::COMPRESS_SOURCE_NORMAL) {
- //R and RG do not support SRGB
- dc = Image::DETECTED_RG;
- }
-
- switch (dc) {
- case Image::DETECTED_L: {
+ switch (p_channels) {
+ case Image::USED_CHANNELS_L: {
target_format = Image::FORMAT_DXT1;
squish_comp |= squish::kDxt1;
} break;
- case Image::DETECTED_LA: {
+ case Image::USED_CHANNELS_LA: {
target_format = Image::FORMAT_DXT5;
squish_comp |= squish::kDxt5;
} break;
- case Image::DETECTED_R: {
+ case Image::USED_CHANNELS_R: {
target_format = Image::FORMAT_RGTC_R;
squish_comp |= squish::kBc4;
} break;
- case Image::DETECTED_RG: {
+ case Image::USED_CHANNELS_RG: {
target_format = Image::FORMAT_RGTC_RG;
squish_comp |= squish::kBc5;
} break;
- case Image::DETECTED_RGB: {
+ case Image::USED_CHANNELS_RGB: {
target_format = Image::FORMAT_DXT1;
squish_comp |= squish::kDxt1;
} break;
- case Image::DETECTED_RGBA: {
+ case Image::USED_CHANNELS_RGBA: {
//TODO, should convert both, then measure which one does a better job
target_format = Image::FORMAT_DXT5;
@@ -173,14 +137,14 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres
}
}
- PoolVector<uint8_t> data;
+ 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->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0;
data.resize(target_size);
int shift = Image::get_format_pixel_rshift(target_format);
- PoolVector<uint8_t>::Read rb = p_image->get_data().read();
- PoolVector<uint8_t>::Write wb = data.write();
+ const uint8_t *rb = p_image->get_data().ptr();
+ uint8_t *wb = data.ptrw();
int dst_ofs = 0;
@@ -196,9 +160,6 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres
h = MAX(h / 2, 1);
}
- rb.release();
- wb.release();
-
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
}
}
diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h
index b5a209ceb9..19e6d57474 100644
--- a/modules/squish/image_compress_squish.h
+++ b/modules/squish/image_compress_squish.h
@@ -33,7 +33,7 @@
#include "core/image.h"
-void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source);
+void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels);
void image_decompress_squish(Image *p_image);
#endif // IMAGE_COMPRESS_SQUISH_H
diff --git a/modules/squish/register_types.h b/modules/squish/register_types.h
index 0845e2b500..ab56c54d4a 100644
--- a/modules/squish/register_types.h
+++ b/modules/squish/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef SQUISH_REGISTER_TYPES_H
+#define SQUISH_REGISTER_TYPES_H
+
void register_squish_types();
void unregister_squish_types();
+
+#endif // SQUISH_REGISTER_TYPES_H
diff --git a/modules/stb_vorbis/SCsub b/modules/stb_vorbis/SCsub
index d14939a3b1..266c87c802 100644
--- a/modules/stb_vorbis/SCsub
+++ b/modules/stb_vorbis/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_stb_vorbis = env_modules.Clone()
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index f2d0f5c9a6..9609c234ec 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -57,7 +57,8 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra
if (todo) {
//end of file!
- if (vorbis_stream->loop && mixed > 0) {
+ bool is_not_empty = mixed > 0 || stb_vorbis_stream_length_in_samples(ogg_stream) > 0;
+ if (vorbis_stream->loop && is_not_empty) {
//loop
seek(vorbis_stream->loop_offset);
loops++;
@@ -121,7 +122,7 @@ void AudioStreamPlaybackOGGVorbis::seek(float p_time) {
AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() {
if (ogg_alloc.alloc_buffer) {
stb_vorbis_close(ogg_stream);
- AudioServer::get_singleton()->audio_data_free(ogg_alloc.alloc_buffer);
+ memfree(ogg_alloc.alloc_buffer);
}
}
@@ -129,11 +130,11 @@ Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() {
Ref<AudioStreamPlaybackOGGVorbis> ovs;
- ERR_FAIL_COND_V(data == NULL, ovs);
+ ERR_FAIL_COND_V(data == nullptr, ovs);
ovs.instance();
ovs->vorbis_stream = Ref<AudioStreamOGGVorbis>(this);
- ovs->ogg_alloc.alloc_buffer = (char *)AudioServer::get_singleton()->audio_data_alloc(decode_mem_size);
+ ovs->ogg_alloc.alloc_buffer = (char *)memalloc(decode_mem_size);
ovs->ogg_alloc.alloc_buffer_length_in_bytes = decode_mem_size;
ovs->frames_mixed = 0;
ovs->active = false;
@@ -142,8 +143,8 @@ Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() {
ovs->ogg_stream = stb_vorbis_open_memory((const unsigned char *)data, data_len, &error, &ovs->ogg_alloc);
if (!ovs->ogg_stream) {
- AudioServer::get_singleton()->audio_data_free(ovs->ogg_alloc.alloc_buffer);
- ovs->ogg_alloc.alloc_buffer = NULL;
+ memfree(ovs->ogg_alloc.alloc_buffer);
+ ovs->ogg_alloc.alloc_buffer = nullptr;
ERR_FAIL_COND_V(!ovs->ogg_stream, Ref<AudioStreamPlaybackOGGVorbis>());
}
@@ -157,43 +158,43 @@ String AudioStreamOGGVorbis::get_stream_name() const {
void AudioStreamOGGVorbis::clear_data() {
if (data) {
- AudioServer::get_singleton()->audio_data_free(data);
- data = NULL;
+ memfree(data);
+ data = nullptr;
data_len = 0;
}
}
-void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) {
+void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) {
int src_data_len = p_data.size();
#define MAX_TEST_MEM (1 << 20)
uint32_t alloc_try = 1024;
- PoolVector<char> alloc_mem;
- PoolVector<char>::Write w;
- stb_vorbis *ogg_stream = NULL;
+ Vector<char> alloc_mem;
+ char *w;
+ stb_vorbis *ogg_stream = nullptr;
stb_vorbis_alloc ogg_alloc;
while (alloc_try < MAX_TEST_MEM) {
alloc_mem.resize(alloc_try);
- w = alloc_mem.write();
+ w = alloc_mem.ptrw();
- ogg_alloc.alloc_buffer = w.ptr();
+ ogg_alloc.alloc_buffer = w;
ogg_alloc.alloc_buffer_length_in_bytes = alloc_try;
- PoolVector<uint8_t>::Read src_datar = p_data.read();
+ const uint8_t *src_datar = p_data.ptr();
int error;
- ogg_stream = stb_vorbis_open_memory((const unsigned char *)src_datar.ptr(), src_data_len, &error, &ogg_alloc);
+ ogg_stream = stb_vorbis_open_memory((const unsigned char *)src_datar, src_data_len, &error, &ogg_alloc);
if (!ogg_stream && error == VORBIS_outofmem) {
- w.release();
+
alloc_try *= 2;
} else {
ERR_FAIL_COND(alloc_try == MAX_TEST_MEM);
- ERR_FAIL_COND(ogg_stream == NULL);
+ ERR_FAIL_COND(ogg_stream == nullptr);
stb_vorbis_info info = stb_vorbis_get_info(ogg_stream);
@@ -209,7 +210,8 @@ void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) {
// free any existing data
clear_data();
- data = AudioServer::get_singleton()->audio_data_alloc(src_data_len, src_datar.ptr());
+ data = memalloc(src_data_len);
+ copymem(data, src_datar, src_data_len);
data_len = src_data_len;
break;
@@ -217,15 +219,15 @@ void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) {
}
}
-PoolVector<uint8_t> AudioStreamOGGVorbis::get_data() const {
+Vector<uint8_t> AudioStreamOGGVorbis::get_data() const {
- PoolVector<uint8_t> vdata;
+ Vector<uint8_t> vdata;
if (data_len && data) {
vdata.resize(data_len);
{
- PoolVector<uint8_t>::Write w = vdata.write();
- copymem(w.ptr(), data, data_len);
+ uint8_t *w = vdata.ptrw();
+ copymem(w, data, data_len);
}
}
@@ -265,14 +267,14 @@ void AudioStreamOGGVorbis::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamOGGVorbis::set_loop_offset);
ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOGGVorbis::get_loop_offset);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "loop_offset"), "set_loop_offset", "get_loop_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset");
}
AudioStreamOGGVorbis::AudioStreamOGGVorbis() {
- data = NULL;
+ data = nullptr;
data_len = 0;
length = 0;
sample_rate = 1;
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
index e909759acb..f296e8c19f 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
@@ -102,8 +102,8 @@ public:
virtual Ref<AudioStreamPlayback> instance_playback();
virtual String get_stream_name() const;
- void set_data(const PoolVector<uint8_t> &p_data);
- PoolVector<uint8_t> get_data() const;
+ void set_data(const Vector<uint8_t> &p_data);
+ Vector<uint8_t> get_data() const;
virtual float get_length() const; //if supported, otherwise return 0
diff --git a/modules/stb_vorbis/config.py b/modules/stb_vorbis/config.py
index 200b8dfd50..1eb0a8cf33 100644
--- a/modules/stb_vorbis/config.py
+++ b/modules/stb_vorbis/config.py
@@ -1,13 +1,16 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"AudioStreamOGGVorbis",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
index 38d3bd5468..8a1bb62e24 100644
--- a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
+++ b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml
@@ -11,7 +11,7 @@
<methods>
</methods>
<members>
- <member name="data" type="PoolByteArray" setter="set_data" getter="get_data" default="PoolByteArray( )">
+ <member name="data" type="PackedByteArray" setter="set_data" getter="get_data" default="PackedByteArray( )">
Contains the audio data in bytes.
</member>
<member name="loop" type="bool" setter="set_loop" getter="has_loop" default="false">
diff --git a/modules/stb_vorbis/register_types.h b/modules/stb_vorbis/register_types.h
index f6147abd01..f5a1dd31bc 100644
--- a/modules/stb_vorbis/register_types.h
+++ b/modules/stb_vorbis/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef STB_VORBIS_REGISTER_TYPES_H
+#define STB_VORBIS_REGISTER_TYPES_H
+
void register_stb_vorbis_types();
void unregister_stb_vorbis_types();
+
+#endif // STB_VORBIS_REGISTER_TYPES_H
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
index 06399f4005..13d96541e3 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
@@ -73,7 +73,7 @@ String ResourceImporterOGGVorbis::get_preset_name(int p_idx) const {
void ResourceImporterOGGVorbis::get_import_options(List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "loop_offset"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0));
}
Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
@@ -87,11 +87,11 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin
size_t len = f->get_len();
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(len);
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
- f->get_buffer(w.ptr(), len);
+ f->get_buffer(w, len);
memdelete(f);
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h
index 43541bcf3c..8d6f71a456 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.h
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h
@@ -50,7 +50,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
ResourceImporterOGGVorbis();
};
diff --git a/modules/svg/SCsub b/modules/svg/SCsub
index 7961d1f33e..0bfba34fe5 100644
--- a/modules/svg/SCsub
+++ b/modules/svg/SCsub
@@ -1,14 +1,14 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_svg = env_modules.Clone()
# Thirdparty source files
thirdparty_dir = "#thirdparty/nanosvg/"
thirdparty_sources = [
- "nanosvg.cc"
+ "nanosvg.cc",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
diff --git a/modules/svg/config.py b/modules/svg/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/svg/config.py
+++ b/modules/svg/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 7f91908a33..3c2784f8de 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -65,7 +65,7 @@ inline void change_nsvg_paint_color(NSVGpaint *p_paint, const uint32_t p_old, co
void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image) {
- for (NSVGshape *shape = p_svg_image->shapes; shape != NULL; shape = shape->next) {
+ for (NSVGshape *shape = p_svg_image->shapes; shape != nullptr; shape = shape->next) {
for (int i = 0; i < replace_colors.old_colors.size(); i++) {
change_nsvg_paint_color(&(shape->stroke), replace_colors.old_colors[i], replace_colors.new_colors[i]);
@@ -94,11 +94,11 @@ void ImageLoaderSVG::set_convert_colors(Dictionary *p_replace_color) {
}
}
-Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors) {
+Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const Vector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors) {
NSVGimage *svg_image;
- PoolVector<uint8_t>::Read src_r = p_data->read();
- svg_image = nsvgParse((char *)src_r.ptr(), "px", 96);
- if (svg_image == NULL) {
+ const uint8_t *src_r = p_data->ptr();
+ svg_image = nsvgParse((char *)src_r, "px", 96);
+ if (svg_image == nullptr) {
ERR_PRINT("SVG Corrupted");
return ERR_FILE_CORRUPT;
}
@@ -115,14 +115,13 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
const int h = (int)(svg_image->height * p_scale * upscale);
ERR_FAIL_COND_V_MSG(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale)));
- PoolVector<uint8_t> dst_image;
+ Vector<uint8_t> dst_image;
dst_image.resize(w * h * 4);
- PoolVector<uint8_t>::Write dw = dst_image.write();
+ uint8_t *dw = dst_image.ptrw();
- rasterizer.rasterize(svg_image, 0, 0, p_scale * upscale, (unsigned char *)dw.ptr(), w, h, w * 4);
+ rasterizer.rasterize(svg_image, 0, 0, p_scale * upscale, (unsigned char *)dw, w, h, w * 4);
- dw.release();
p_image->create(w, h, false, Image::FORMAT_RGBA8, dst_image);
if (upsample) {
p_image->shrink_x2();
@@ -136,10 +135,10 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, bool convert_colors) {
size_t str_len = strlen(p_svg_str);
- PoolVector<uint8_t> src_data;
+ Vector<uint8_t> src_data;
src_data.resize(str_len + 1);
- PoolVector<uint8_t>::Write src_w = src_data.write();
- memcpy(src_w.ptr(), p_svg_str, str_len + 1);
+ uint8_t *src_w = src_data.ptrw();
+ memcpy(src_w, p_svg_str, str_len + 1);
return _create_image(p_image, &src_data, p_scale, upsample, convert_colors);
}
@@ -147,11 +146,11 @@ Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p
Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
uint32_t size = f->get_len();
- PoolVector<uint8_t> src_image;
+ Vector<uint8_t> src_image;
src_image.resize(size + 1);
- PoolVector<uint8_t>::Write src_w = src_image.write();
- f->get_buffer(src_w.ptr(), size);
- src_w.ptr()[size] = '\0';
+ uint8_t *src_w = src_image.ptrw();
+ f->get_buffer(src_w, size);
+ src_w[size] = '\0';
return _create_image(p_image, &src_image, p_scale, 1.0);
}
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index 24cee82480..0fa4a0fdf4 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -60,10 +60,10 @@ class ImageLoaderSVG : public ImageFormatLoader {
} replace_colors;
static SVGRasterizer rasterizer;
static void _convert_colors(NSVGimage *p_svg_image);
- static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors = false);
+ static Error _create_image(Ref<Image> p_image, const Vector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors = false);
public:
- static void set_convert_colors(Dictionary *p_replace_color = NULL);
+ static void set_convert_colors(Dictionary *p_replace_color = nullptr);
static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, bool convert_colors = false);
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
diff --git a/modules/svg/register_types.cpp b/modules/svg/register_types.cpp
index b0782dae88..37875313aa 100644
--- a/modules/svg/register_types.cpp
+++ b/modules/svg/register_types.cpp
@@ -32,7 +32,7 @@
#include "image_loader_svg.h"
-static ImageLoaderSVG *image_loader_svg = NULL;
+static ImageLoaderSVG *image_loader_svg = nullptr;
void register_svg_types() {
diff --git a/modules/svg/register_types.h b/modules/svg/register_types.h
index aa50540552..a3d914e0cb 100644
--- a/modules/svg/register_types.h
+++ b/modules/svg/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef SVG_REGISTER_TYPES_H
+#define SVG_REGISTER_TYPES_H
+
void register_svg_types();
void unregister_svg_types();
+
+#endif // SVG_REGISTER_TYPES_H
diff --git a/modules/tga/SCsub b/modules/tga/SCsub
index 7e405f405c..067caa6ea0 100644
--- a/modules/tga/SCsub
+++ b/modules/tga/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_tga = env_modules.Clone()
diff --git a/modules/tga/config.py b/modules/tga/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/tga/config.py
+++ b/modules/tga/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index 480016eb97..fc9d727bb0 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -36,12 +36,12 @@
Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size) {
Error error;
- PoolVector<uint8_t> pixels;
+ Vector<uint8_t> pixels;
error = pixels.resize(p_pixel_size);
if (error != OK)
return error;
- PoolVector<uint8_t>::Write pixels_w = pixels.write();
+ uint8_t *pixels_w = pixels.ptrw();
size_t compressed_pos = 0;
size_t output_pos = 0;
@@ -55,12 +55,12 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t
if (c & 0x80) {
for (size_t i = 0; i < p_pixel_size; i++) {
- pixels_w.ptr()[i] = p_compressed_buffer[compressed_pos];
+ pixels_w[i] = p_compressed_buffer[compressed_pos];
compressed_pos += 1;
}
for (size_t i = 0; i < count; i++) {
for (size_t j = 0; j < p_pixel_size; j++) {
- p_uncompressed_buffer[output_pos + j] = pixels_w.ptr()[j];
+ p_uncompressed_buffer[output_pos + j] = pixels_w[j];
}
output_pos += p_pixel_size;
}
@@ -116,9 +116,9 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
x_end = -1;
}
- PoolVector<uint8_t> image_data;
+ Vector<uint8_t> image_data;
image_data.resize(width * height * sizeof(uint32_t));
- PoolVector<uint8_t>::Write image_data_w = image_data.write();
+ uint8_t *image_data_w = image_data.ptrw();
size_t i = 0;
uint32_t x = x_start;
@@ -199,8 +199,6 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
}
}
- image_data_w.release();
-
p_image->create(width, height, 0, Image::FORMAT_RGBA8, image_data);
return OK;
@@ -208,7 +206,7 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
- PoolVector<uint8_t> src_image;
+ Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(src_image_len < (int)sizeof(tga_header_s), ERR_FILE_CORRUPT);
@@ -259,49 +257,49 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
if (err == OK) {
f->seek(f->get_position() + tga_header.id_length);
- PoolVector<uint8_t> palette;
+ Vector<uint8_t> palette;
if (has_color_map) {
size_t color_map_size = tga_header.color_map_length * (tga_header.color_map_depth >> 3);
err = palette.resize(color_map_size);
if (err == OK) {
- PoolVector<uint8_t>::Write palette_w = palette.write();
+ uint8_t *palette_w = palette.ptrw();
f->get_buffer(&palette_w[0], color_map_size);
} else {
return OK;
}
}
- PoolVector<uint8_t>::Write src_image_w = src_image.write();
+ uint8_t *src_image_w = src_image.ptrw();
f->get_buffer(&src_image_w[0], src_image_len - f->get_position());
- PoolVector<uint8_t>::Read src_image_r = src_image.read();
+ const uint8_t *src_image_r = src_image.ptr();
const size_t pixel_size = tga_header.pixel_depth >> 3;
const size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size;
- PoolVector<uint8_t> uncompressed_buffer;
+ Vector<uint8_t> uncompressed_buffer;
uncompressed_buffer.resize(buffer_size);
- PoolVector<uint8_t>::Write uncompressed_buffer_w = uncompressed_buffer.write();
- PoolVector<uint8_t>::Read uncompressed_buffer_r;
+ uint8_t *uncompressed_buffer_w = uncompressed_buffer.ptrw();
+ const uint8_t *uncompressed_buffer_r;
- const uint8_t *buffer = NULL;
+ const uint8_t *buffer = nullptr;
if (is_encoded) {
- err = decode_tga_rle(src_image_r.ptr(), pixel_size, uncompressed_buffer_w.ptr(), buffer_size);
+ err = decode_tga_rle(src_image_r, pixel_size, uncompressed_buffer_w, buffer_size);
if (err == OK) {
- uncompressed_buffer_r = uncompressed_buffer.read();
- buffer = uncompressed_buffer_r.ptr();
+ uncompressed_buffer_r = uncompressed_buffer.ptr();
+ buffer = uncompressed_buffer_r;
}
} else {
- buffer = src_image_r.ptr();
+ buffer = src_image_r;
};
if (err == OK) {
- PoolVector<uint8_t>::Read palette_r = palette.read();
- err = convert_to_image(p_image, buffer, tga_header, palette_r.ptr(), is_monochrome);
+ const uint8_t *palette_r = palette.ptr();
+ err = convert_to_image(p_image, buffer, tga_header, palette_r, is_monochrome);
}
}
diff --git a/modules/tga/register_types.cpp b/modules/tga/register_types.cpp
index 359f4d785e..0d9268ebbf 100644
--- a/modules/tga/register_types.cpp
+++ b/modules/tga/register_types.cpp
@@ -32,7 +32,7 @@
#include "image_loader_tga.h"
-static ImageLoaderTGA *image_loader_tga = NULL;
+static ImageLoaderTGA *image_loader_tga = nullptr;
void register_tga_types() {
diff --git a/modules/tga/register_types.h b/modules/tga/register_types.h
index beef05a590..94a77d295e 100644
--- a/modules/tga/register_types.h
+++ b/modules/tga/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef TGA_REGISTER_TYPES_H
+#define TGA_REGISTER_TYPES_H
+
void register_tga_types();
void unregister_tga_types();
+
+#endif // TGA_REGISTER_TYPES_H
diff --git a/modules/theora/SCsub b/modules/theora/SCsub
index ff65d2f8ec..a01e65b4b0 100644
--- a/modules/theora/SCsub
+++ b/modules/theora/SCsub
@@ -1,71 +1,71 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_theora = env_modules.Clone()
# Thirdparty source files
-if env['builtin_libtheora']:
+if env["builtin_libtheora"]:
thirdparty_dir = "#thirdparty/libtheora/"
thirdparty_sources = [
- #"analyze.c",
- #"apiwrapper.c",
+ # "analyze.c",
+ # "apiwrapper.c",
"bitpack.c",
"cpu.c",
- #"decapiwrapper.c",
+ # "decapiwrapper.c",
"decinfo.c",
"decode.c",
"dequant.c",
- #"encapiwrapper.c",
- #"encfrag.c",
- #"encinfo.c",
- #"encode.c",
- #"encoder_disabled.c",
- #"enquant.c",
- #"fdct.c",
+ # "encapiwrapper.c",
+ # "encfrag.c",
+ # "encinfo.c",
+ # "encode.c",
+ # "encoder_disabled.c",
+ # "enquant.c",
+ # "fdct.c",
"fragment.c",
"huffdec.c",
- #"huffenc.c",
+ # "huffenc.c",
"idct.c",
"info.c",
"internal.c",
- #"mathops.c",
- #"mcenc.c",
+ # "mathops.c",
+ # "mcenc.c",
"quant.c",
- #"rate.c",
+ # "rate.c",
"state.c",
- #"tokenize.c",
+ # "tokenize.c",
]
thirdparty_sources_x86 = [
- #"x86/mmxencfrag.c",
- #"x86/mmxfdct.c",
+ # "x86/mmxencfrag.c",
+ # "x86/mmxfdct.c",
"x86/mmxfrag.c",
"x86/mmxidct.c",
"x86/mmxstate.c",
- #"x86/sse2fdct.c",
- #"x86/x86enc.c",
+ # "x86/sse2fdct.c",
+ # "x86/x86enc.c",
"x86/x86state.c",
]
thirdparty_sources_x86_vc = [
- #"x86_vc/mmxencfrag.c",
- #"x86_vc/mmxfdct.c",
+ # "x86_vc/mmxencfrag.c",
+ # "x86_vc/mmxfdct.c",
"x86_vc/mmxfrag.c",
"x86_vc/mmxidct.c",
"x86_vc/mmxstate.c",
- #"x86_vc/x86enc.c",
+ # "x86_vc/x86enc.c",
"x86_vc/x86state.c",
]
- if (env["x86_libtheora_opt_gcc"]):
+ if env["x86_libtheora_opt_gcc"]:
thirdparty_sources += thirdparty_sources_x86
- if (env["x86_libtheora_opt_vc"]):
+ if env["x86_libtheora_opt_vc"]:
thirdparty_sources += thirdparty_sources_x86_vc
- if (env["x86_libtheora_opt_gcc"] or env["x86_libtheora_opt_vc"]):
+ if env["x86_libtheora_opt_gcc"] or env["x86_libtheora_opt_vc"]:
env_theora.Append(CPPDEFINES=["OC_X86_ASM"])
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
@@ -73,9 +73,9 @@ if env['builtin_libtheora']:
env_theora.Prepend(CPPPATH=[thirdparty_dir])
# also requires libogg and libvorbis
- if env['builtin_libogg']:
+ if env["builtin_libogg"]:
env_theora.Prepend(CPPPATH=["#thirdparty/libogg"])
- if env['builtin_libvorbis']:
+ if env["builtin_libvorbis"]:
env_theora.Prepend(CPPPATH=["#thirdparty/libvorbis"])
env_thirdparty = env_theora.Clone()
diff --git a/modules/theora/config.py b/modules/theora/config.py
index c7713d7607..413acce2df 100644
--- a/modules/theora/config.py
+++ b/modules/theora/config.py
@@ -1,13 +1,16 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"VideoStreamTheora",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/theora/register_types.h b/modules/theora/register_types.h
index 66eb49aed1..4f0670b2c7 100644
--- a/modules/theora/register_types.h
+++ b/modules/theora/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef THEORA_REGISTER_TYPES_H
+#define THEORA_REGISTER_TYPES_H
+
void register_theora_types();
void unregister_theora_types();
+
+#endif // THEORA_REGISTER_TYPES_H
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 00c7e87568..b9f276fb12 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -87,8 +87,8 @@ void VideoStreamPlaybackTheora::video_write(void) {
int pitch = 4;
frame_data.resize(size.x * size.y * pitch);
{
- PoolVector<uint8_t>::Write w = frame_data.write();
- char *dst = (char *)w.ptr();
+ uint8_t *w = frame_data.ptrw();
+ char *dst = (char *)w;
//uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y/2);
@@ -110,7 +110,7 @@ void VideoStreamPlaybackTheora::video_write(void) {
Ref<Image> img = memnew(Image(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data)); //zero copy image creation
- texture->set_data(img); //zero copy send to visual server
+ texture->update(img, true); //zero copy send to visual server
frames_pending = 1;
}
@@ -144,7 +144,7 @@ void VideoStreamPlaybackTheora::clear() {
thread_sem->post(); //just in case
Thread::wait_to_finish(thread);
memdelete(thread);
- thread = NULL;
+ thread = nullptr;
ring_buffer.clear();
#endif
@@ -159,7 +159,7 @@ void VideoStreamPlaybackTheora::clear() {
if (file) {
memdelete(file);
}
- file = NULL;
+ file = nullptr;
playing = false;
};
@@ -167,7 +167,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
ERR_FAIL_COND(playing);
ogg_packet op;
- th_setup_info *ts = NULL;
+ th_setup_info *ts = nullptr;
file_name = p_file;
if (file) {
@@ -336,7 +336,9 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
size.x = w;
size.y = h;
- texture->create(w, h, Image::FORMAT_RGBA8, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE);
+ Ref<Image> img;
+ img.instance();
+ img->create(w, h, false, Image::FORMAT_RGBA8);
} else {
/* tear down the partial theora setup */
@@ -369,7 +371,7 @@ float VideoStreamPlaybackTheora::get_time() const {
return time - /* AudioServer::get_singleton()->get_output_latency() - */ delay_compensation;
};
-Ref<Texture> VideoStreamPlaybackTheora::get_texture() const {
+Ref<Texture2D> VideoStreamPlaybackTheora::get_texture() const {
return texture;
}
@@ -672,7 +674,7 @@ void VideoStreamPlaybackTheora::_streaming_thread(void *ud) {
VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
- file = NULL;
+ file = nullptr;
theora_p = 0;
vorbis_p = 0;
videobuf_ready = 0;
@@ -683,8 +685,8 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
buffering = false;
texture = Ref<ImageTexture>(memnew(ImageTexture));
- mix_callback = NULL;
- mix_udata = NULL;
+ mix_callback = nullptr;
+ mix_udata = nullptr;
audio_track = 0;
delay_compensation = 0;
audio_frames_wrote = 0;
@@ -694,7 +696,7 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
ring_buffer.resize(rb_power);
read_buffer.resize(RB_SIZE_KB * 1024);
thread_sem = Semaphore::create();
- thread = NULL;
+ thread = nullptr;
thread_exit = false;
thread_eof = false;
@@ -723,7 +725,7 @@ void VideoStreamTheora::_bind_methods() {
////////////
-RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h
index 0f201ffa9d..f98368ed8b 100644
--- a/modules/theora/video_stream_theora.h
+++ b/modules/theora/video_stream_theora.h
@@ -54,7 +54,7 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
//Image frames[MAX_FRAMES];
Image::Format format;
- PoolVector<uint8_t> frame_data;
+ Vector<uint8_t> frame_data;
int frames_pending;
FileAccess *file;
String file_name;
@@ -147,7 +147,7 @@ public:
void set_file(const String &p_file);
- virtual Ref<Texture> get_texture() const;
+ virtual Ref<Texture2D> get_texture() const;
virtual void update(float p_delta);
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata);
@@ -187,7 +187,7 @@ public:
class ResourceFormatLoaderTheora : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/tinyexr/SCsub b/modules/tinyexr/SCsub
index 97f9797b58..e7fd44fabd 100644
--- a/modules/tinyexr/SCsub
+++ b/modules/tinyexr/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_tinyexr = env_modules.Clone()
diff --git a/modules/tinyexr/config.py b/modules/tinyexr/config.py
index 098f1eafa9..53b8f2f2e3 100644
--- a/modules/tinyexr/config.py
+++ b/modules/tinyexr/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return env['tools']
+ return env["tools"]
+
def configure(env):
pass
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 79cb135abb..1c0f3cd03e 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -37,12 +37,12 @@
Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
- PoolVector<uint8_t> src_image;
+ Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
src_image.resize(src_image_len);
- PoolVector<uint8_t>::Write w = src_image.write();
+ uint8_t *w = src_image.ptrw();
f->get_buffer(&w[0], src_image_len);
@@ -56,17 +56,17 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
EXRVersion exr_version;
EXRImage exr_image;
EXRHeader exr_header;
- const char *err = NULL;
+ const char *err = nullptr;
InitEXRHeader(&exr_header);
- int ret = ParseEXRVersionFromMemory(&exr_version, w.ptr(), src_image_len);
+ int ret = ParseEXRVersionFromMemory(&exr_version, w, src_image_len);
if (ret != TINYEXR_SUCCESS) {
return ERR_FILE_CORRUPT;
}
- ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, w.ptr(), src_image_len, &err);
+ ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, w, src_image_len, &err);
if (ret != TINYEXR_SUCCESS) {
if (err) {
ERR_PRINT(String(err));
@@ -82,7 +82,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
}
InitEXRImage(&exr_image);
- ret = LoadEXRImageFromMemory(&exr_image, &exr_header, w.ptr(), src_image_len, &err);
+ ret = LoadEXRImageFromMemory(&exr_image, &exr_header, w, src_image_len, &err);
if (ret != TINYEXR_SUCCESS) {
if (err) {
ERR_PRINT(String(err));
@@ -136,7 +136,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
// EXR image data loaded, now parse it into Godot-friendly image data
- PoolVector<uint8_t> imgdata;
+ Vector<uint8_t> imgdata;
Image::Format format;
int output_channels = 0;
@@ -180,8 +180,8 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
}
{
- PoolVector<uint8_t>::Write wd = imgdata.write();
- uint16_t *iw = (uint16_t *)wd.ptr();
+ uint8_t *wd = imgdata.ptrw();
+ uint16_t *iw = (uint16_t *)wd;
// Assume `out_rgba` have enough memory allocated.
for (int tile_index = 0; tile_index < num_tiles; tile_index++) {
@@ -194,7 +194,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
const float *r_channel_start = reinterpret_cast<const float *>(tile.images[idxR]);
const float *g_channel_start = reinterpret_cast<const float *>(tile.images[idxG]);
const float *b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]);
- const float *a_channel_start = NULL;
+ const float *a_channel_start = nullptr;
if (idxA != -1) {
a_channel_start = reinterpret_cast<const float *>(tile.images[idxA]);
@@ -206,7 +206,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
const float *r_channel = r_channel_start + y * tile_width;
const float *g_channel = g_channel_start + y * tile_width;
const float *b_channel = b_channel_start + y * tile_width;
- const float *a_channel = NULL;
+ const float *a_channel = nullptr;
if (a_channel_start) {
a_channel = a_channel_start + y * tile_width;
@@ -235,8 +235,6 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
p_image->create(exr_image.width, exr_image.height, false, format, imgdata);
- w.release();
-
FreeEXRHeader(&exr_header);
FreeEXRImage(&exr_image);
diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp
index 17f920746f..05080289bd 100644
--- a/modules/tinyexr/image_saver_tinyexr.cpp
+++ b/modules/tinyexr/image_saver_tinyexr.cpp
@@ -58,7 +58,8 @@ static bool is_supported_format(Image::Format p_format) {
enum SrcPixelType {
SRC_FLOAT,
SRC_HALF,
- SRC_BYTE
+ SRC_BYTE,
+ SRC_UNSUPPORTED
};
static SrcPixelType get_source_pixel_type(Image::Format p_format) {
@@ -79,7 +80,7 @@ static SrcPixelType get_source_pixel_type(Image::Format p_format) {
case Image::FORMAT_RGBA8:
return SRC_BYTE;
default:
- CRASH_NOW();
+ return SRC_UNSUPPORTED;
}
}
@@ -101,7 +102,7 @@ static int get_target_pixel_type(Image::Format p_format) {
case Image::FORMAT_RGBA8:
return TINYEXR_PIXELTYPE_HALF;
default:
- CRASH_NOW();
+ return -1;
}
}
@@ -112,7 +113,7 @@ static int get_pixel_type_size(int p_pixel_type) {
case TINYEXR_PIXELTYPE_FLOAT:
return 4;
}
- CRASH_NOW();
+ return -1;
}
static int get_channel_count(Image::Format p_format) {
@@ -134,7 +135,7 @@ static int get_channel_count(Image::Format p_format) {
case Image::FORMAT_RGBA8:
return 4;
default:
- CRASH_NOW();
+ return -1;
}
}
@@ -158,7 +159,7 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
// Godot does not support more than 4 channels,
// so we can preallocate header infos on the stack and use only the subset we need
- PoolByteArray channels[max_channels];
+ PackedByteArray channels[max_channels];
unsigned char *channels_ptrs[max_channels];
EXRChannelInfo channel_infos[max_channels];
int pixel_types[max_channels];
@@ -173,35 +174,39 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
};
int channel_count = get_channel_count(format);
+ ERR_FAIL_COND_V(channel_count < 0, ERR_UNAVAILABLE);
ERR_FAIL_COND_V(p_grayscale && channel_count != 1, ERR_INVALID_PARAMETER);
int target_pixel_type = get_target_pixel_type(format);
+ ERR_FAIL_COND_V(target_pixel_type < 0, ERR_UNAVAILABLE);
int target_pixel_type_size = get_pixel_type_size(target_pixel_type);
+ ERR_FAIL_COND_V(target_pixel_type_size < 0, ERR_UNAVAILABLE);
SrcPixelType src_pixel_type = get_source_pixel_type(format);
+ ERR_FAIL_COND_V(src_pixel_type == SRC_UNSUPPORTED, ERR_UNAVAILABLE);
const int pixel_count = p_img->get_width() * p_img->get_height();
const int *channel_mapping = channel_mappings[channel_count - 1];
{
- PoolByteArray src_data = p_img->get_data();
- PoolByteArray::Read src_r = src_data.read();
+ PackedByteArray src_data = p_img->get_data();
+ const uint8_t *src_r = src_data.ptr();
for (int channel_index = 0; channel_index < channel_count; ++channel_index) {
// De-interleave channels
- PoolByteArray &dst = channels[channel_index];
+ PackedByteArray &dst = channels[channel_index];
dst.resize(pixel_count * target_pixel_type_size);
- PoolByteArray::Write dst_w = dst.write();
+ uint8_t *dst_w = dst.ptrw();
if (src_pixel_type == SRC_FLOAT && target_pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
// Note: we don't save mipmaps
CRASH_COND(src_data.size() < pixel_count * channel_count * target_pixel_type_size);
- const float *src_rp = (float *)src_r.ptr();
- float *dst_wp = (float *)dst_w.ptr();
+ const float *src_rp = (float *)src_r;
+ float *dst_wp = (float *)dst_w;
for (int i = 0; i < pixel_count; ++i) {
dst_wp[i] = src_rp[channel_index + i * channel_count];
@@ -211,8 +216,8 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
CRASH_COND(src_data.size() < pixel_count * channel_count * target_pixel_type_size);
- const uint16_t *src_rp = (uint16_t *)src_r.ptr();
- uint16_t *dst_wp = (uint16_t *)dst_w.ptr();
+ const uint16_t *src_rp = (uint16_t *)src_r;
+ uint16_t *dst_wp = (uint16_t *)dst_w;
for (int i = 0; i < pixel_count; ++i) {
dst_wp[i] = src_rp[channel_index + i * channel_count];
@@ -222,8 +227,8 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
CRASH_COND(src_data.size() < pixel_count * channel_count);
- const uint8_t *src_rp = (uint8_t *)src_r.ptr();
- uint16_t *dst_wp = (uint16_t *)dst_w.ptr();
+ const uint8_t *src_rp = (uint8_t *)src_r;
+ uint16_t *dst_wp = (uint16_t *)dst_w;
for (int i = 0; i < pixel_count; ++i) {
dst_wp[i] = Math::make_half_float(src_rp[channel_index + i * channel_count] / 255.f);
@@ -235,7 +240,7 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
int remapped_index = channel_mapping[channel_index];
- channels_ptrs[remapped_index] = dst_w.ptr();
+ channels_ptrs[remapped_index] = dst_w;
// No conversion
pixel_types[remapped_index] = target_pixel_type;
diff --git a/modules/tinyexr/register_types.cpp b/modules/tinyexr/register_types.cpp
index d8529fd893..af05a411e1 100644
--- a/modules/tinyexr/register_types.cpp
+++ b/modules/tinyexr/register_types.cpp
@@ -33,7 +33,7 @@
#include "image_loader_tinyexr.h"
#include "image_saver_tinyexr.h"
-static ImageLoaderTinyEXR *image_loader_tinyexr = NULL;
+static ImageLoaderTinyEXR *image_loader_tinyexr = nullptr;
void register_tinyexr_types() {
@@ -47,5 +47,5 @@ void unregister_tinyexr_types() {
memdelete(image_loader_tinyexr);
- Image::save_exr_func = NULL;
+ Image::save_exr_func = nullptr;
}
diff --git a/modules/tinyexr/register_types.h b/modules/tinyexr/register_types.h
index 2028cd4a33..9739488312 100644
--- a/modules/tinyexr/register_types.h
+++ b/modules/tinyexr/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef TINYEXR_REGISTER_TYPES_H
+#define TINYEXR_REGISTER_TYPES_H
+
void register_tinyexr_types();
void unregister_tinyexr_types();
+
+#endif // TINYEXR_REGISTER_TYPES_H
diff --git a/modules/upnp/SCsub b/modules/upnp/SCsub
index 3f56a69594..2e129e15ca 100644
--- a/modules/upnp/SCsub
+++ b/modules/upnp/SCsub
@@ -1,13 +1,13 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_upnp = env_modules.Clone()
# Thirdparty source files
-if env['builtin_miniupnpc']:
+if env["builtin_miniupnpc"]:
thirdparty_dir = "#thirdparty/miniupnpc/"
thirdparty_sources = [
"miniupnpc.c",
diff --git a/modules/upnp/config.py b/modules/upnp/config.py
index 8724ff1a51..3e15b940a1 100644
--- a/modules/upnp/config.py
+++ b/modules/upnp/config.py
@@ -1,14 +1,17 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"UPNP",
- "UPNPDevice"
+ "UPNPDevice",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/upnp/doc_classes/UPNP.xml b/modules/upnp/doc_classes/UPNP.xml
index 8549c173db..785c8dad50 100644
--- a/modules/upnp/doc_classes/UPNP.xml
+++ b/modules/upnp/doc_classes/UPNP.xml
@@ -45,7 +45,7 @@
<description>
Adds a mapping to forward the external [code]port[/code] (between 1 and 65535) on the default gateway (see [method get_gateway]) to the [code]internal_port[/code] on the local machine for the given protocol [code]proto[/code] (either [code]TCP[/code] or [code]UDP[/code], with UDP being the default). If a port mapping for the given port and protocol combination already exists on that gateway device, this method tries to overwrite it. If that is not desired, you can retrieve the gateway manually with [method get_gateway] and call [method add_port_mapping] on it, if any.
If [code]internal_port[/code] is [code]0[/code] (the default), the same port number is used for both the external and the internal port (the [code]port[/code] value).
- The description ([code]desc[/code]) is shown in some router UIs and can be used to point out which application added the mapping, and the lifetime of the mapping can be limited by [code]duration[/code]. However, some routers are incompatible with one or both of these, so use with caution and add fallback logic in case of errors to retry without them if in doubt.
+ The description ([code]desc[/code]) is shown in some router UIs and can be used to point out which application added the mapping. The mapping's lease duration can be limited by specifying a [code]duration[/code] (in seconds). However, some routers are incompatible with one or both of these, so use with caution and add fallback logic in case of errors to retry without them if in doubt.
See [enum UPNPResult] for possible return values.
</description>
</method>
diff --git a/modules/upnp/register_types.h b/modules/upnp/register_types.h
index 4d752e4a94..0c71db9ffa 100644
--- a/modules/upnp/register_types.h
+++ b/modules/upnp/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef UPNP_REGISTER_TYPES_H
+#define UPNP_REGISTER_TYPES_H
+
void register_upnp_types();
void unregister_upnp_types();
+
+#endif // UPNP_REGISTER_TYPES_H
diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp
index 5ef7575b0c..988bf3017d 100644
--- a/modules/upnp/upnp.cpp
+++ b/modules/upnp/upnp.cpp
@@ -44,9 +44,8 @@ bool UPNP::is_common_device(const String &dev) const {
}
int UPNP::discover(int timeout, int ttl, const String &device_filter) {
- ERR_FAIL_COND_V(timeout < 0, UPNP_RESULT_INVALID_PARAM);
- ERR_FAIL_COND_V(ttl < 0, UPNP_RESULT_INVALID_PARAM);
- ERR_FAIL_COND_V(ttl > 255, UPNP_RESULT_INVALID_PARAM);
+ ERR_FAIL_COND_V_MSG(timeout < 0, UPNP_RESULT_INVALID_PARAM, "The response's wait time can't be negative.");
+ ERR_FAIL_COND_V_MSG(ttl < 0 || ttl > 255, UPNP_RESULT_INVALID_PARAM, "The time-to-live must be set between 0 and 255 (inclusive).");
devices.clear();
@@ -54,9 +53,9 @@ int UPNP::discover(int timeout, int ttl, const String &device_filter) {
struct UPNPDev *devlist;
if (is_common_device(device_filter)) {
- devlist = upnpDiscover(timeout, discover_multicast_if.utf8().get_data(), NULL, discover_local_port, discover_ipv6, ttl, &error);
+ devlist = upnpDiscover(timeout, discover_multicast_if.utf8().get_data(), nullptr, discover_local_port, discover_ipv6, ttl, &error);
} else {
- devlist = upnpDiscoverAll(timeout, discover_multicast_if.utf8().get_data(), NULL, discover_local_port, discover_ipv6, ttl, &error);
+ devlist = upnpDiscoverAll(timeout, discover_multicast_if.utf8().get_data(), nullptr, discover_local_port, discover_ipv6, ttl, &error);
}
if (error != UPNPDISCOVER_SUCCESS) {
@@ -133,7 +132,7 @@ void UPNP::parse_igd(Ref<UPNPDevice> dev, UPNPDev *devlist) {
parserootdesc(xml, size, &data);
free(xml);
- xml = 0;
+ xml = nullptr;
GetUPNPUrls(urls, &data, dev->get_description_url().utf8().get_data(), 0);
@@ -235,20 +234,20 @@ int UPNP::get_device_count() const {
}
Ref<UPNPDevice> UPNP::get_device(int index) const {
- ERR_FAIL_INDEX_V(index, devices.size(), NULL);
+ ERR_FAIL_INDEX_V(index, devices.size(), nullptr);
return devices.get(index);
}
void UPNP::add_device(Ref<UPNPDevice> device) {
- ERR_FAIL_COND(device == NULL);
+ ERR_FAIL_COND(device == nullptr);
devices.push_back(device);
}
void UPNP::set_device(int index, Ref<UPNPDevice> device) {
ERR_FAIL_INDEX(index, devices.size());
- ERR_FAIL_COND(device == NULL);
+ ERR_FAIL_COND(device == nullptr);
devices.set(index, device);
}
@@ -264,17 +263,17 @@ void UPNP::clear_devices() {
}
Ref<UPNPDevice> UPNP::get_gateway() const {
- ERR_FAIL_COND_V(devices.size() < 1, NULL);
+ ERR_FAIL_COND_V_MSG(devices.size() < 1, nullptr, "Couldn't find any UPNPDevices.");
for (int i = 0; i < devices.size(); i++) {
Ref<UPNPDevice> dev = get_device(i);
- if (dev != NULL && dev->is_valid_gateway()) {
+ if (dev != nullptr && dev->is_valid_gateway()) {
return dev;
}
}
- return NULL;
+ return nullptr;
}
void UPNP::set_discover_multicast_if(const String &m_if) {
@@ -304,7 +303,7 @@ bool UPNP::is_discover_ipv6() const {
String UPNP::query_external_address() const {
Ref<UPNPDevice> dev = get_gateway();
- if (dev == NULL) {
+ if (dev == nullptr) {
return "";
}
@@ -314,7 +313,7 @@ String UPNP::query_external_address() const {
int UPNP::add_port_mapping(int port, int port_internal, String desc, String proto, int duration) const {
Ref<UPNPDevice> dev = get_gateway();
- if (dev == NULL) {
+ if (dev == nullptr) {
return UPNP_RESULT_NO_GATEWAY;
}
@@ -326,7 +325,7 @@ int UPNP::add_port_mapping(int port, int port_internal, String desc, String prot
int UPNP::delete_port_mapping(int port, String proto) const {
Ref<UPNPDevice> dev = get_gateway();
- if (dev == NULL) {
+ if (dev == nullptr) {
return UPNP_RESULT_NO_GATEWAY;
}
diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h
index d052e155de..46f44e04e5 100644
--- a/modules/upnp/upnp.h
+++ b/modules/upnp/upnp.h
@@ -46,7 +46,7 @@ private:
int discover_local_port;
bool discover_ipv6;
- Vector<Ref<UPNPDevice> > devices;
+ Vector<Ref<UPNPDevice>> devices;
bool is_common_device(const String &dev) const;
void add_device_to_list(UPNPDev *dev, UPNPDev *devlist);
diff --git a/modules/upnp/upnp_device.cpp b/modules/upnp/upnp_device.cpp
index 6edfbc2d7d..40eb6106a0 100644
--- a/modules/upnp/upnp_device.cpp
+++ b/modules/upnp/upnp_device.cpp
@@ -35,7 +35,7 @@
#include <miniupnpc/upnpcommands.h>
String UPNPDevice::query_external_address() const {
- ERR_FAIL_COND_V(!is_valid_gateway(), "");
+ ERR_FAIL_COND_V_MSG(!is_valid_gateway(), "", "The Internet Gateway Device must be valid.");
char addr[16];
int i = UPNP_GetExternalIPAddress(
@@ -43,17 +43,17 @@ String UPNPDevice::query_external_address() const {
igd_service_type.utf8().get_data(),
(char *)&addr);
- ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, "");
+ ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, "", "Couldn't get external IP address.");
return String(addr);
}
int UPNPDevice::add_port_mapping(int port, int port_internal, String desc, String proto, int duration) const {
- ERR_FAIL_COND_V(!is_valid_gateway(), UPNP::UPNP_RESULT_INVALID_GATEWAY);
- ERR_FAIL_COND_V(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT);
- ERR_FAIL_COND_V(port_internal < 0 || port_internal > 65535, UPNP::UPNP_RESULT_INVALID_PORT); // Needs to allow 0 because 0 signifies "use external port as internal port"
- ERR_FAIL_COND_V(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL);
- ERR_FAIL_COND_V(duration < 0, UPNP::UPNP_RESULT_INVALID_DURATION);
+ ERR_FAIL_COND_V_MSG(!is_valid_gateway(), UPNP::UPNP_RESULT_INVALID_GATEWAY, "The Internet Gateway Device must be valid.");
+ ERR_FAIL_COND_V_MSG(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 1 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(port_internal < 0 || port_internal > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 0 and 65535 (inclusive)."); // Needs to allow 0 because 0 signifies "use external port as internal port"
+ ERR_FAIL_COND_V_MSG(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL, "The protocol must be either TCP or UDP.");
+ ERR_FAIL_COND_V_MSG(duration < 0, UPNP::UPNP_RESULT_INVALID_DURATION, "The port mapping's lease duration can't be negative.");
if (port_internal < 1) {
port_internal = port;
@@ -65,29 +65,29 @@ int UPNPDevice::add_port_mapping(int port, int port_internal, String desc, Strin
itos(port).utf8().get_data(),
itos(port_internal).utf8().get_data(),
igd_our_addr.utf8().get_data(),
- desc.empty() ? 0 : desc.utf8().get_data(),
+ desc.empty() ? nullptr : desc.utf8().get_data(),
proto.utf8().get_data(),
- NULL, // Remote host, always NULL as IGDs don't support it
- duration > 0 ? itos(duration).utf8().get_data() : 0);
+ nullptr, // Remote host, always nullptr as IGDs don't support it
+ duration > 0 ? itos(duration).utf8().get_data() : nullptr);
- ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i));
+ ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i), "Couldn't add port mapping.");
return UPNP::UPNP_RESULT_SUCCESS;
}
int UPNPDevice::delete_port_mapping(int port, String proto) const {
- ERR_FAIL_COND_V(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT);
- ERR_FAIL_COND_V(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL);
+ ERR_FAIL_COND_V_MSG(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 1 and 65535 (inclusive).");
+ ERR_FAIL_COND_V_MSG(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL, "The protocol must be either TCP or UDP.");
int i = UPNP_DeletePortMapping(
igd_control_url.utf8().get_data(),
igd_service_type.utf8().get_data(),
itos(port).utf8().get_data(),
proto.utf8().get_data(),
- NULL // Remote host, always NULL as IGDs don't support it
+ nullptr // Remote host, always nullptr as IGDs don't support it
);
- ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i));
+ ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i), "Couldn't delete port mapping.");
return UPNP::UPNP_RESULT_SUCCESS;
}
diff --git a/modules/vhacd/SCsub b/modules/vhacd/SCsub
index 685976dc33..ecd432b275 100644
--- a/modules/vhacd/SCsub
+++ b/modules/vhacd/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_vhacd = env_modules.Clone()
@@ -19,7 +19,7 @@ thirdparty_sources = [
"src/btAlignedAllocator.cpp",
"src/vhacdRaycastMesh.cpp",
"src/VHACD.cpp",
- "src/btConvexHullComputer.cpp"
+ "src/btConvexHullComputer.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
diff --git a/modules/vhacd/config.py b/modules/vhacd/config.py
index 9ced70d2fb..d22f9454ed 100644
--- a/modules/vhacd/config.py
+++ b/modules/vhacd/config.py
@@ -1,6 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
-
diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp
index 26c6146bab..c006a9deec 100644
--- a/modules/vhacd/register_types.cpp
+++ b/modules/vhacd/register_types.cpp
@@ -32,7 +32,7 @@
#include "scene/resources/mesh.h"
#include "thirdparty/vhacd/public/VHACD.h"
-static Vector<Vector<Face3> > convex_decompose(const Vector<Face3> &p_faces) {
+static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces) {
Vector<float> vertices;
vertices.resize(p_faces.size() * 9);
@@ -54,7 +54,7 @@ static Vector<Vector<Face3> > convex_decompose(const Vector<Face3> &p_faces) {
int hull_count = decomposer->GetNConvexHulls();
- Vector<Vector<Face3> > ret;
+ Vector<Vector<Face3>> ret;
for (int i = 0; i < hull_count; i++) {
Vector<Face3> triangles;
@@ -84,5 +84,5 @@ void register_vhacd_types() {
}
void unregister_vhacd_types() {
- Mesh::convex_composition_function = NULL;
+ Mesh::convex_composition_function = nullptr;
}
diff --git a/modules/vhacd/register_types.h b/modules/vhacd/register_types.h
index de56620813..d02a990901 100644
--- a/modules/vhacd/register_types.h
+++ b/modules/vhacd/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef VHACD_REGISTER_TYPES_H
+#define VHACD_REGISTER_TYPES_H
+
void register_vhacd_types();
void unregister_vhacd_types();
+
+#endif // VHACD_REGISTER_TYPES_H
diff --git a/modules/visual_script/SCsub b/modules/visual_script/SCsub
index 3c3d2caa57..16faea08d7 100644
--- a/modules/visual_script/SCsub
+++ b/modules/visual_script/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_vs = env_modules.Clone()
diff --git a/modules/visual_script/config.py b/modules/visual_script/config.py
index 087a13a200..bd459ca344 100644
--- a/modules/visual_script/config.py
+++ b/modules/visual_script/config.py
@@ -1,9 +1,11 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"@VisualScript",
@@ -56,5 +58,6 @@ def get_doc_classes():
"VisualScriptYield",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml
index 9cd79aa781..db1ef2adc6 100644
--- a/modules/visual_script/doc_classes/VisualScript.xml
+++ b/modules/visual_script/doc_classes/VisualScript.xml
@@ -15,7 +15,7 @@
<method name="add_custom_signal">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Add a custom signal with the specified name to the VisualScript.
@@ -24,7 +24,7 @@
<method name="add_function">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Add a function with the specified name to the VisualScript.
@@ -33,7 +33,7 @@
<method name="add_node">
<return type="void">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="id" type="int">
</argument>
@@ -48,7 +48,7 @@
<method name="add_variable">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="default_value" type="Variant" default="null">
</argument>
@@ -61,7 +61,7 @@
<method name="custom_signal_add_argument">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="type" type="int" enum="Variant.Type">
</argument>
@@ -76,7 +76,7 @@
<method name="custom_signal_get_argument_count" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Get the count of a custom signal's arguments.
@@ -85,7 +85,7 @@
<method name="custom_signal_get_argument_name" qualifiers="const">
<return type="String">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="argidx" type="int">
</argument>
@@ -96,7 +96,7 @@
<method name="custom_signal_get_argument_type" qualifiers="const">
<return type="int" enum="Variant.Type">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="argidx" type="int">
</argument>
@@ -107,7 +107,7 @@
<method name="custom_signal_remove_argument">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="argidx" type="int">
</argument>
@@ -118,7 +118,7 @@
<method name="custom_signal_set_argument_name">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="argidx" type="int">
</argument>
@@ -131,7 +131,7 @@
<method name="custom_signal_set_argument_type">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="argidx" type="int">
</argument>
@@ -144,7 +144,7 @@
<method name="custom_signal_swap_argument">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="argidx" type="int">
</argument>
@@ -157,7 +157,7 @@
<method name="data_connect">
<return type="void">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="from_node" type="int">
</argument>
@@ -174,7 +174,7 @@
<method name="data_disconnect">
<return type="void">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="from_node" type="int">
</argument>
@@ -191,7 +191,7 @@
<method name="get_function_node_id" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns the id of a function's entry point node.
@@ -200,7 +200,7 @@
<method name="get_function_scroll" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns the position of the center of the screen for a given function.
@@ -209,7 +209,7 @@
<method name="get_node" qualifiers="const">
<return type="VisualScriptNode">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="id" type="int">
</argument>
@@ -220,7 +220,7 @@
<method name="get_node_position" qualifiers="const">
<return type="Vector2">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="id" type="int">
</argument>
@@ -231,7 +231,7 @@
<method name="get_variable_default_value" qualifiers="const">
<return type="Variant">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns the default (initial) value of a variable.
@@ -240,7 +240,7 @@
<method name="get_variable_export" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns whether a variable is exported.
@@ -249,7 +249,7 @@
<method name="get_variable_info" qualifiers="const">
<return type="Dictionary">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns the information for a given variable as a dictionary. The information includes its name, type, hint and usage.
@@ -258,7 +258,7 @@
<method name="has_custom_signal" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns whether a signal exists with the specified name.
@@ -267,7 +267,7 @@
<method name="has_data_connection" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="from_node" type="int">
</argument>
@@ -284,7 +284,7 @@
<method name="has_function" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns whether a function exists with the specified name.
@@ -293,7 +293,7 @@
<method name="has_node" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="id" type="int">
</argument>
@@ -304,7 +304,7 @@
<method name="has_sequence_connection" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="from_node" type="int">
</argument>
@@ -319,7 +319,7 @@
<method name="has_variable" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Returns whether a variable exists with the specified name.
@@ -328,7 +328,7 @@
<method name="remove_custom_signal">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Remove a custom signal with the given name.
@@ -337,7 +337,7 @@
<method name="remove_function">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Remove a specific function and its nodes from the script.
@@ -346,7 +346,7 @@
<method name="remove_node">
<return type="void">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="id" type="int">
</argument>
@@ -357,7 +357,7 @@
<method name="remove_variable">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<description>
Remove a variable with the given name.
@@ -366,9 +366,9 @@
<method name="rename_custom_signal">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
- <argument index="1" name="new_name" type="String">
+ <argument index="1" name="new_name" type="StringName">
</argument>
<description>
Change the name of a custom signal.
@@ -377,9 +377,9 @@
<method name="rename_function">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
- <argument index="1" name="new_name" type="String">
+ <argument index="1" name="new_name" type="StringName">
</argument>
<description>
Change the name of a function.
@@ -388,9 +388,9 @@
<method name="rename_variable">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
- <argument index="1" name="new_name" type="String">
+ <argument index="1" name="new_name" type="StringName">
</argument>
<description>
Change the name of a variable.
@@ -399,7 +399,7 @@
<method name="sequence_connect">
<return type="void">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="from_node" type="int">
</argument>
@@ -415,7 +415,7 @@
<method name="sequence_disconnect">
<return type="void">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="from_node" type="int">
</argument>
@@ -430,7 +430,7 @@
<method name="set_function_scroll">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="ofs" type="Vector2">
</argument>
@@ -441,7 +441,7 @@
<method name="set_instance_base_type">
<return type="void">
</return>
- <argument index="0" name="type" type="String">
+ <argument index="0" name="type" type="StringName">
</argument>
<description>
Set the base type of the script.
@@ -450,7 +450,7 @@
<method name="set_node_position">
<return type="void">
</return>
- <argument index="0" name="func" type="String">
+ <argument index="0" name="func" type="StringName">
</argument>
<argument index="1" name="id" type="int">
</argument>
@@ -463,7 +463,7 @@
<method name="set_variable_default_value">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="value" type="Variant">
</argument>
@@ -474,7 +474,7 @@
<method name="set_variable_export">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="enable" type="bool">
</argument>
@@ -485,7 +485,7 @@
<method name="set_variable_info">
<return type="void">
</return>
- <argument index="0" name="name" type="String">
+ <argument index="0" name="name" type="StringName">
</argument>
<argument index="1" name="value" type="Dictionary">
</argument>
diff --git a/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml b/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
index c8e391c4a1..4d07f878a2 100644
--- a/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
+++ b/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
@@ -14,7 +14,7 @@
<member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type" default="0">
The type to get the constant from.
</member>
- <member name="constant" type="String" setter="set_basic_type_constant" getter="get_basic_type_constant">
+ <member name="constant" type="StringName" setter="set_basic_type_constant" getter="get_basic_type_constant">
The name of the constant to return.
</member>
</members>
diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
index 95085d9652..ef4183e6f6 100644
--- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
+++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
@@ -89,7 +89,7 @@
<constant name="MATH_EASE" value="23" enum="BuiltinFunc">
Easing function, based on exponent. 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in.
</constant>
- <constant name="MATH_DECIMALS" value="24" enum="BuiltinFunc">
+ <constant name="MATH_STEP_DECIMALS" value="24" enum="BuiltinFunc">
Return the number of digit places after the decimal that the first non-zero digit occurs.
</constant>
<constant name="MATH_STEPIFY" value="25" enum="BuiltinFunc">
@@ -197,10 +197,10 @@
Deserialize a [Variant] from a string serialized using [constant VAR_TO_STR].
</constant>
<constant name="VAR_TO_BYTES" value="61" enum="BuiltinFunc">
- Serialize a [Variant] to a [PoolByteArray].
+ Serialize a [Variant] to a [PackedByteArray].
</constant>
<constant name="BYTES_TO_VAR" value="62" enum="BuiltinFunc">
- Deserialize a [Variant] from a [PoolByteArray] serialized using [constant VAR_TO_BYTES].
+ Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES].
</constant>
<constant name="COLORN" value="63" enum="BuiltinFunc">
Return the [Color] with the given name and alpha ranging from 0 to 1.
diff --git a/modules/visual_script/doc_classes/VisualScriptClassConstant.xml b/modules/visual_script/doc_classes/VisualScriptClassConstant.xml
index cf35808823..de5d731cc0 100644
--- a/modules/visual_script/doc_classes/VisualScriptClassConstant.xml
+++ b/modules/visual_script/doc_classes/VisualScriptClassConstant.xml
@@ -15,10 +15,10 @@
<methods>
</methods>
<members>
- <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" default="&quot;Object&quot;">
+ <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="@&quot;Object&quot;">
The constant's parent class.
</member>
- <member name="constant" type="String" setter="set_class_constant" getter="get_class_constant" default="&quot;&quot;">
+ <member name="constant" type="StringName" setter="set_class_constant" getter="get_class_constant" default="@&quot;&quot;">
The constant to return. See the given class for its available constants.
</member>
</members>
diff --git a/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml b/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml
index 60a19ac7a7..5c9c8d3eca 100644
--- a/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml
+++ b/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml
@@ -15,7 +15,7 @@
<methods>
</methods>
<members>
- <member name="signal" type="String" setter="set_signal" getter="get_signal" default="&quot;&quot;">
+ <member name="signal" type="StringName" setter="set_signal" getter="get_signal" default="@&quot;&quot;">
The signal to emit.
</member>
</members>
diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml
index 16c3af7ab2..2d0fac1fa0 100644
--- a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml
+++ b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml
@@ -11,19 +11,19 @@
<members>
<member name="base_script" type="String" setter="set_base_script" getter="get_base_script">
</member>
- <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" default="&quot;Object&quot;">
+ <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="@&quot;Object&quot;">
</member>
<member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type">
</member>
<member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptFunctionCall.CallMode" default="0">
</member>
- <member name="function" type="String" setter="set_function" getter="get_function" default="&quot;&quot;">
+ <member name="function" type="StringName" setter="set_function" getter="get_function" default="@&quot;&quot;">
</member>
<member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path">
</member>
<member name="rpc_call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" enum="VisualScriptFunctionCall.RPCCallMode" default="0">
</member>
- <member name="singleton" type="String" setter="set_singleton" getter="get_singleton">
+ <member name="singleton" type="StringName" setter="set_singleton" getter="get_singleton">
</member>
<member name="use_default_args" type="int" setter="set_use_default_args" getter="get_use_default_args">
</member>
diff --git a/modules/visual_script/doc_classes/VisualScriptInputAction.xml b/modules/visual_script/doc_classes/VisualScriptInputAction.xml
index 0b6325bf0a..6c296fdb4b 100644
--- a/modules/visual_script/doc_classes/VisualScriptInputAction.xml
+++ b/modules/visual_script/doc_classes/VisualScriptInputAction.xml
@@ -9,7 +9,7 @@
<methods>
</methods>
<members>
- <member name="action" type="String" setter="set_action_name" getter="get_action_name" default="&quot;&quot;">
+ <member name="action" type="StringName" setter="set_action_name" getter="get_action_name" default="@&quot;&quot;">
</member>
<member name="mode" type="int" setter="set_action_mode" getter="get_action_mode" enum="VisualScriptInputAction.Mode" default="0">
</member>
diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVar.xml b/modules/visual_script/doc_classes/VisualScriptLocalVar.xml
index 6c31ae1a30..c3741eea89 100644
--- a/modules/visual_script/doc_classes/VisualScriptLocalVar.xml
+++ b/modules/visual_script/doc_classes/VisualScriptLocalVar.xml
@@ -18,7 +18,7 @@
<member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type" default="0">
The local variable's type.
</member>
- <member name="var_name" type="String" setter="set_var_name" getter="get_var_name" default="&quot;new_local&quot;">
+ <member name="var_name" type="StringName" setter="set_var_name" getter="get_var_name" default="@&quot;new_local&quot;">
The local variable's name.
</member>
</members>
diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml b/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml
index 0a9a509958..619bbb90ca 100644
--- a/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml
+++ b/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml
@@ -20,7 +20,7 @@
<member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type" default="0">
The local variable's type.
</member>
- <member name="var_name" type="String" setter="set_var_name" getter="get_var_name" default="&quot;new_local&quot;">
+ <member name="var_name" type="StringName" setter="set_var_name" getter="get_var_name" default="@&quot;new_local&quot;">
The local variable's name.
</member>
</members>
diff --git a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml
index cf436116b8..f13d449064 100644
--- a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml
+++ b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml
@@ -11,15 +11,15 @@
<members>
<member name="base_script" type="String" setter="set_base_script" getter="get_base_script">
</member>
- <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" default="&quot;Object&quot;">
+ <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="@&quot;Object&quot;">
</member>
<member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type">
</member>
- <member name="index" type="String" setter="set_index" getter="get_index">
+ <member name="index" type="StringName" setter="set_index" getter="get_index">
</member>
<member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path">
</member>
- <member name="property" type="String" setter="set_property" getter="get_property" default="&quot;&quot;">
+ <member name="property" type="StringName" setter="set_property" getter="get_property" default="@&quot;&quot;">
</member>
<member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertyGet.CallMode" default="0">
</member>
diff --git a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml
index 357b4b9f5c..629576e261 100644
--- a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml
+++ b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml
@@ -13,15 +13,15 @@
</member>
<member name="base_script" type="String" setter="set_base_script" getter="get_base_script">
</member>
- <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" default="&quot;Object&quot;">
+ <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="@&quot;Object&quot;">
</member>
<member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type">
</member>
- <member name="index" type="String" setter="set_index" getter="get_index">
+ <member name="index" type="StringName" setter="set_index" getter="get_index">
</member>
<member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path">
</member>
- <member name="property" type="String" setter="set_property" getter="get_property" default="&quot;&quot;">
+ <member name="property" type="StringName" setter="set_property" getter="get_property" default="@&quot;&quot;">
</member>
<member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertySet.CallMode" default="0">
</member>
diff --git a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml
index 43fe9d16ea..80a8d31041 100644
--- a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml
+++ b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml
@@ -11,7 +11,7 @@
<members>
<member name="base_script" type="String" setter="set_base_script" getter="get_base_script" default="&quot;&quot;">
</member>
- <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" default="&quot;Object&quot;">
+ <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="@&quot;Object&quot;">
</member>
</members>
<constants>
diff --git a/modules/visual_script/doc_classes/VisualScriptVariableGet.xml b/modules/visual_script/doc_classes/VisualScriptVariableGet.xml
index 0746ab293e..d182e14e4d 100644
--- a/modules/visual_script/doc_classes/VisualScriptVariableGet.xml
+++ b/modules/visual_script/doc_classes/VisualScriptVariableGet.xml
@@ -15,7 +15,7 @@
<methods>
</methods>
<members>
- <member name="var_name" type="String" setter="set_variable" getter="get_variable" default="&quot;&quot;">
+ <member name="var_name" type="StringName" setter="set_variable" getter="get_variable" default="@&quot;&quot;">
The variable's name.
</member>
</members>
diff --git a/modules/visual_script/doc_classes/VisualScriptVariableSet.xml b/modules/visual_script/doc_classes/VisualScriptVariableSet.xml
index e7d83e60ab..3bd392dd85 100644
--- a/modules/visual_script/doc_classes/VisualScriptVariableSet.xml
+++ b/modules/visual_script/doc_classes/VisualScriptVariableSet.xml
@@ -16,7 +16,7 @@
<methods>
</methods>
<members>
- <member name="var_name" type="String" setter="set_variable" getter="get_variable" default="&quot;&quot;">
+ <member name="var_name" type="StringName" setter="set_variable" getter="get_variable" default="@&quot;&quot;">
The variable's name.
</member>
</members>
diff --git a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml
index 8f6941ce1e..483cdfeaf8 100644
--- a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml
+++ b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml
@@ -9,13 +9,13 @@
<methods>
</methods>
<members>
- <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" default="&quot;Object&quot;">
+ <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="@&quot;Object&quot;">
</member>
<member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptYieldSignal.CallMode" default="0">
</member>
<member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path">
</member>
- <member name="signal" type="String" setter="set_signal" getter="get_signal" default="&quot;&quot;">
+ <member name="signal" type="StringName" setter="set_signal" getter="get_signal" default="@&quot;&quot;">
</member>
</members>
<constants>
diff --git a/modules/visual_script/icons/icon_visual_script.svg b/modules/visual_script/icons/VisualScript.svg
index f6475d590e..f6475d590e 100644
--- a/modules/visual_script/icons/icon_visual_script.svg
+++ b/modules/visual_script/icons/VisualScript.svg
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index 63bd88ad81..5ea84a32c4 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -41,9 +41,9 @@
#include "visual_script_nodes.h"
#include "visual_script_yield_nodes.h"
-VisualScriptLanguage *visual_script_language = NULL;
+VisualScriptLanguage *visual_script_language = nullptr;
#ifdef TOOLS_ENABLED
-static _VisualScriptEditor *vs_editor_singleton = NULL;
+static _VisualScriptEditor *vs_editor_singleton = nullptr;
#endif
void register_visual_script_types() {
diff --git a/modules/visual_script/register_types.h b/modules/visual_script/register_types.h
index 546c2fbff3..c18c2930b1 100644
--- a/modules/visual_script/register_types.h
+++ b/modules/visual_script/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef VISUAL_SCRIPT_REGISTER_TYPES_H
+#define VISUAL_SCRIPT_REGISTER_TYPES_H
+
void register_visual_script_types();
void unregister_visual_script_types();
+
+#endif // VISUAL_SCRIPT_REGISTER_TYPES_H
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index c591e3b5c2..fe1d82f977 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -36,6 +36,8 @@
#include "scene/main/node.h"
#include "visual_script_nodes.h"
+#include <stdint.h>
+
//used by editor, this is not really saved
void VisualScriptNode::set_breakpoint(bool p_breakpoint) {
breakpoint = p_breakpoint;
@@ -86,13 +88,13 @@ void VisualScriptNode::validate_input_default_values() {
continue;
} else {
//not the same, reconvert
- Variant::CallError ce;
+ Callable::CallError ce;
Variant existing = default_input_values[i];
const Variant *existingp = &existing;
default_input_values[i] = Variant::construct(expected, &existingp, 1, ce, false);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
//could not convert? force..
- default_input_values[i] = Variant::construct(expected, NULL, 0, ce, false);
+ default_input_values[i] = Variant::construct(expected, nullptr, 0, ce, false);
}
}
}
@@ -156,8 +158,8 @@ VisualScriptNode::VisualScriptNode() {
VisualScriptNodeInstance::VisualScriptNodeInstance() {
- sequence_outputs = NULL;
- input_ports = NULL;
+ sequence_outputs = nullptr;
+ input_ports = nullptr;
}
VisualScriptNodeInstance::~VisualScriptNodeInstance() {
@@ -196,7 +198,7 @@ void VisualScript::remove_function(const StringName &p_name) {
for (Map<int, Function::NodeData>::Element *E = functions[p_name].nodes.front(); E; E = E->next()) {
- E->get().node->disconnect("ports_changed", this, "_node_ports_changed");
+ E->get().node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed));
E->get().node->scripts_used.erase(this);
}
@@ -338,7 +340,7 @@ void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<Visual
nd.pos = p_pos;
Ref<VisualScriptNode> vsn = p_node;
- vsn->connect("ports_changed", this, "_node_ports_changed", varray(p_id));
+ vsn->connect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed), varray(p_id));
vsn->scripts_used.insert(this);
vsn->validate_input_default_values(); // Validate when fully loaded
@@ -387,7 +389,7 @@ void VisualScript::remove_node(const StringName &p_func, int p_id) {
func.function_id = -1; //revert to invalid
}
- func.nodes[p_id].node->disconnect("ports_changed", this, "_node_ports_changed");
+ func.nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed));
func.nodes[p_id].node->scripts_used.erase(this);
func.nodes.erase(p_id);
@@ -725,6 +727,26 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p
variables[p_new_name] = variables[p_name];
variables.erase(p_name);
+
+ List<StringName> funcs;
+ get_function_list(&funcs);
+ for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions
+ List<int> ids;
+ get_node_list(F->get(), &ids);
+ for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ Ref<VisualScriptVariableGet> nodeget = get_node(F->get(), E->get());
+ if (nodeget.is_valid()) {
+ if (nodeget->get_variable() == p_name)
+ nodeget->set_variable(p_new_name);
+ } else {
+ Ref<VisualScriptVariableSet> nodeset = get_node(F->get(), E->get());
+ if (nodeset.is_valid()) {
+ if (nodeset->get_variable() == p_name)
+ nodeset->set_variable(p_new_name);
+ }
+ }
+ }
+ }
}
void VisualScript::add_custom_signal(const StringName &p_name) {
@@ -825,7 +847,7 @@ void VisualScript::rename_custom_signal(const StringName &p_name, const StringNa
void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) const {
- for (const Map<StringName, Vector<Argument> >::Element *E = custom_signals.front(); E; E = E->next()) {
+ for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) {
r_custom_signals->push_back(E->key());
}
@@ -926,13 +948,11 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
VisualScriptInstance *instance = memnew(VisualScriptInstance);
instance->create(Ref<VisualScript>(this), p_this);
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->lock();
-
- instances[p_this] = instance;
+ {
+ MutexLock lock(VisualScriptLanguage::singleton->lock);
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->unlock();
+ instances[p_this] = instance;
+ }
return instance;
}
@@ -981,7 +1001,7 @@ bool VisualScript::has_script_signal(const StringName &p_signal) const {
void VisualScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
- for (const Map<StringName, Vector<Argument> >::Element *E = custom_signals.front(); E; E = E->next()) {
+ for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) {
MethodInfo mi;
mi.name = E->key();
@@ -1102,6 +1122,60 @@ bool VisualScript::are_subnodes_edited() const {
}
#endif
+Vector<ScriptNetData> VisualScript::get_rpc_methods() const {
+ return rpc_functions;
+}
+
+uint16_t VisualScript::get_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < rpc_functions.size(); i++) {
+ if (rpc_functions[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName VisualScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName());
+ return rpc_functions[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rpc_mode(const StringName &p_method) const {
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> VisualScript::get_rset_properties() const {
+ return rpc_variables;
+}
+
+uint16_t VisualScript::get_rset_property_id(const StringName &p_variable) const {
+ for (int i = 0; i < rpc_variables.size(); i++) {
+ if (rpc_variables[i].name == p_variable) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName VisualScript::get_rset_property(const uint16_t p_rset_property_id) const {
+ ERR_FAIL_COND_V(p_rset_property_id >= rpc_variables.size(), StringName());
+ return rpc_variables[p_rset_property_id].name;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const {
+ ERR_FAIL_COND_V(p_rset_variable_id >= rpc_variables.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_variables[p_rset_variable_id].mode;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rset_mode(const StringName &p_variable) const {
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
+}
+
void VisualScript::_set_data(const Dictionary &p_data) {
Dictionary d = p_data;
@@ -1206,6 +1280,30 @@ void VisualScript::_set_data(const Dictionary &p_data) {
is_tool_script = d["is_tool_script"];
else
is_tool_script = false;
+
+ // Takes all the rpc methods
+ rpc_functions.clear();
+ rpc_variables.clear();
+ for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
+ if (E->get().function_id >= 0 && E->get().nodes.find(E->get().function_id)) {
+ Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
+ if (vsf.is_valid()) {
+ if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = vsf->get_rpc_mode();
+ if (rpc_functions.find(nd) == -1) {
+ rpc_functions.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ // Visual script doesn't have rset :(
+
+ // Sort so we are 100% that they are always the same.
+ rpc_functions.sort_custom<SortNetData>();
}
Dictionary VisualScript::_get_data() const {
@@ -1224,7 +1322,7 @@ Dictionary VisualScript::_get_data() const {
d["variables"] = vars;
Array sigs;
- for (const Map<StringName, Vector<Argument> >::Element *E = custom_signals.front(); E; E = E->next()) {
+ for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) {
Dictionary cs;
cs["name"] = E->key();
@@ -1295,8 +1393,6 @@ Dictionary VisualScript::_get_data() const {
void VisualScript::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_node_ports_changed"), &VisualScript::_node_ports_changed);
-
ClassDB::bind_method(D_METHOD("add_function", "name"), &VisualScript::add_function);
ClassDB::bind_method(D_METHOD("has_function", "name"), &VisualScript::has_function);
ClassDB::bind_method(D_METHOD("remove_function", "name"), &VisualScript::remove_function);
@@ -1364,6 +1460,10 @@ VisualScript::VisualScript() {
is_tool_script = false;
}
+bool VisualScript::inherits_script(const Ref<Script> &p_script) const {
+ return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough
+}
+
StringName VisualScript::get_default_func() const {
return StringName("f_312843592");
}
@@ -1480,7 +1580,7 @@ bool VisualScriptInstance::has_method(const StringName &p_method) const {
//#define VSDEBUG(m_text) print_line(m_text)
#define VSDEBUG(m_text)
-void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Variant::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node) {
+void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Callable::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node) {
ERR_FAIL_COND(node->pass_idx == -1);
@@ -1497,7 +1597,7 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int
for (int i = 0; i < dc; i++) {
_dependency_step(deps[i], p_pass, pass_stack, input_args, output_args, variant_stack, r_error, error_str, r_error_node);
- if (r_error.error != Variant::CallError::CALL_OK)
+ if (r_error.error != Callable::CallError::CALL_OK)
return;
}
}
@@ -1518,16 +1618,16 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int
output_args[i] = &variant_stack[node->output_ports[i]];
}
- Variant *working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)NULL;
+ Variant *working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr;
node->step(input_args, output_args, VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE, working_mem, r_error, error_str);
//ignore return
- if (r_error.error != Variant::CallError::CALL_OK) {
+ if (r_error.error != Callable::CallError::CALL_OK) {
*r_error_node = node;
}
}
-Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Variant::CallError &r_error) {
+Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Callable::CallError &r_error) {
Map<StringName, Function>::Element *F = functions.find(p_method);
ERR_FAIL_COND_V(!F, Variant());
@@ -1539,8 +1639,8 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
const Variant **input_args = (const Variant **)(sequence_bits + f->node_count);
Variant **output_args = (Variant **)(input_args + max_input_args);
int flow_max = f->flow_stack_size;
- int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)NULL;
- int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)NULL;
+ int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)nullptr;
+ int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)nullptr;
String error_str;
@@ -1548,12 +1648,12 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
bool error = false;
int current_node_id = f->node;
Variant return_value;
- Variant *working_mem = NULL;
+ Variant *working_mem = nullptr;
int flow_stack_pos = p_flow_stack_pos;
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
VisualScriptLanguage::singleton->enter_function(this, &p_method, variant_stack, &working_mem, &current_node_id);
}
#endif
@@ -1567,7 +1667,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
VSDEBUG("AT STACK POS: " + itos(flow_stack_pos));
//setup working mem
- working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)NULL;
+ working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr;
VSDEBUG("WORKING MEM: " + itos(node->working_mem_idx));
@@ -1589,7 +1689,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
for (int i = 0; i < dc; i++) {
_dependency_step(deps[i], p_pass, pass_stack, input_args, output_args, variant_stack, r_error, error_str, &node);
- if (r_error.error != Variant::CallError::CALL_OK) {
+ if (r_error.error != Callable::CallError::CALL_OK) {
error = true;
current_node_id = node->id;
break;
@@ -1649,7 +1749,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
int ret = node->step(input_args, output_args, start_mode, working_mem, r_error, error_str);
- if (r_error.error != Variant::CallError::CALL_OK) {
+ if (r_error.error != Callable::CallError::CALL_OK) {
//use error from step
error = true;
break;
@@ -1658,7 +1758,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
if (ret & VisualScriptNodeInstance::STEP_YIELD_BIT) {
//yielded!
if (node->get_working_memory_size() == 0) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("A node yielded without working memory, please read the docs on how to yield properly!");
error = true;
break;
@@ -1667,7 +1767,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
Ref<VisualScriptFunctionState> state = *working_mem;
if (!state.is_valid()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Node yielded, but did not return a function state in the first working memory.");
error = true;
break;
@@ -1686,11 +1786,11 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
state->pass = p_pass;
copymem(state->stack.ptrw(), p_stack, p_stack_size);
//step 2, run away, return directly
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
#ifdef DEBUG_ENABLED
//will re-enter later, so exiting
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
VisualScriptLanguage::singleton->exit_function();
}
#endif
@@ -1700,26 +1800,26 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
// line
bool do_break = false;
- if (ScriptDebugger::get_singleton()->get_lines_left() > 0) {
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0) {
- if (ScriptDebugger::get_singleton()->get_depth() <= 0)
- ScriptDebugger::get_singleton()->set_lines_left(ScriptDebugger::get_singleton()->get_lines_left() - 1);
- if (ScriptDebugger::get_singleton()->get_lines_left() <= 0)
+ if (EngineDebugger::get_script_debugger()->get_depth() <= 0)
+ EngineDebugger::get_script_debugger()->set_lines_left(EngineDebugger::get_script_debugger()->get_lines_left() - 1);
+ if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0)
do_break = true;
}
- if (ScriptDebugger::get_singleton()->is_breakpoint(current_node_id, source))
+ if (EngineDebugger::get_script_debugger()->is_breakpoint(current_node_id, source))
do_break = true;
if (do_break) {
VisualScriptLanguage::singleton->debug_break("Breakpoint", true);
}
- ScriptDebugger::get_singleton()->line_poll();
+ EngineDebugger::get_singleton()->line_poll();
}
#endif
int output = ret & VisualScriptNodeInstance::STEP_MASK;
@@ -1729,7 +1829,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
if (ret & VisualScriptNodeInstance::STEP_EXIT_FUNCTION_BIT) {
if (node->get_working_memory_size() == 0) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Return value must be assigned to first element of node working memory! Fix your node please.");
error = true;
} else {
@@ -1741,12 +1841,12 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
break; //exit function requested, bye
}
- VisualScriptNodeInstance *next = NULL; //next node
+ VisualScriptNodeInstance *next = nullptr; //next node
if ((ret == output || ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) && node->sequence_output_count) {
//if no exit bit was set, and has sequence outputs, guess next node
if (output >= node->sequence_output_count) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Node returned an invalid sequence output: ") + itos(output);
error = true;
break;
@@ -1808,7 +1908,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
if (!found) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Found sequence bit but not the node in the stack, report bug!");
error = true;
break;
@@ -1820,7 +1920,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
} else {
// check for stack overflow
if (flow_stack_pos + 1 >= flow_max) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Stack overflow with stack depth: ") + itos(output);
error = true;
break;
@@ -1872,22 +1972,22 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
String err_func = p_method;
int err_line = current_node_id; //not a line but it works as one
- if (node && (r_error.error != Variant::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) {
+ if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) {
if (error_str != String()) {
error_str += " ";
}
- if (r_error.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+ if (r_error.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
int errorarg = r_error.argument;
- error_str += "Cannot convert argument " + itos(errorarg + 1) + " to " + Variant::get_type_name(r_error.expected) + ".";
- } else if (r_error.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
+ error_str += "Cannot convert argument " + itos(errorarg + 1) + " to " + Variant::get_type_name(Variant::Type(r_error.expected)) + ".";
+ } else if (r_error.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
error_str += "Expected " + itos(r_error.argument) + " arguments.";
- } else if (r_error.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
+ } else if (r_error.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
error_str += "Expected " + itos(r_error.argument) + " arguments.";
- } else if (r_error.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ } else if (r_error.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
error_str += "Invalid Call.";
- } else if (r_error.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
+ } else if (r_error.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
error_str += "Base Instance is null";
}
}
@@ -1907,7 +2007,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
VisualScriptLanguage::singleton->exit_function();
}
#endif
@@ -1920,13 +2020,13 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
return return_value;
}
-Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_OK; //ok by default
+ r_error.error = Callable::CallError::CALL_OK; //ok by default
Map<StringName, Function>::Element *F = functions.find(p_method);
if (!F) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
@@ -1957,8 +2057,8 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
const Variant **input_args = (const Variant **)(sequence_bits + f->node_count);
Variant **output_args = (Variant **)(input_args + max_input_args);
int flow_max = f->flow_stack_size;
- int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)NULL;
- int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)NULL;
+ int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)nullptr;
+ int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)nullptr;
for (int i = 0; i < f->node_count; i++) {
sequence_bits[i] = false; //all starts as false
@@ -1968,7 +2068,7 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
Map<int, VisualScriptNodeInstance *>::Element *E = instances.find(f->node);
if (!E) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_V_MSG(Variant(), "No VisualScriptFunction node in function.");
}
@@ -1982,14 +2082,14 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
VSDEBUG("ARGUMENTS: " + itos(f->argument_count) = " RECEIVED: " + itos(p_argcount));
if (p_argcount < f->argument_count) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = node->get_input_port_count();
return Variant();
}
if (p_argcount > f->argument_count) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = node->get_input_port_count();
return Variant();
@@ -2014,15 +2114,15 @@ void VisualScriptInstance::notification(int p_notification) {
Variant what = p_notification;
const Variant *whatp = &what;
- Variant::CallError ce;
+ Callable::CallError ce;
call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); //do as call
}
String VisualScriptInstance::to_string(bool *r_valid) {
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
- Variant::CallError ce;
- Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce);
- if (ce.error == Variant::CallError::CALL_OK) {
+ Callable::CallError ce;
+ Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
+ if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
if (r_valid)
*r_valid = false;
@@ -2043,31 +2143,44 @@ Ref<Script> VisualScriptInstance::get_script() const {
return script;
}
-MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const {
+Vector<ScriptNetData> VisualScriptInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- if (p_method == script->get_default_func())
- return MultiplayerAPI::RPC_MODE_DISABLED;
+uint16_t VisualScriptInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
+}
- const Map<StringName, VisualScript::Function>::Element *E = script->functions.find(p_method);
- if (!E) {
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
+StringName VisualScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_method(p_rpc_method_id);
+}
- if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) {
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_mode_by_id(p_rpc_method_id);
+}
- Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
- if (vsf.is_valid()) {
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
+}
- return vsf->get_rpc_mode();
- }
- }
+Vector<ScriptNetData> VisualScriptInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+uint16_t VisualScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
}
-MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const {
+StringName VisualScriptInstance::get_rset_property(const uint16_t p_rset_property_id) const {
+ return script->get_rset_property(p_rset_property_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const {
+ return script->get_rset_mode_by_id(p_rset_variable_id);
+}
+
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return script->get_rset_mode(p_variable);
}
void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) {
@@ -2148,12 +2261,12 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
instance->id = F->key();
instance->input_port_count = node->get_input_value_port_count();
- instance->input_ports = NULL;
+ instance->input_ports = nullptr;
instance->output_port_count = node->get_output_value_port_count();
- instance->output_ports = NULL;
+ instance->output_ports = nullptr;
instance->sequence_output_count = node->get_output_sequence_port_count();
instance->sequence_index = function.node_count++;
- instance->sequence_outputs = NULL;
+ instance->sequence_outputs = nullptr;
instance->pass_idx = -1;
if (instance->input_port_count) {
@@ -2174,7 +2287,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
if (instance->sequence_output_count) {
instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count);
for (int i = 0; i < instance->sequence_output_count; i++) {
- instance->sequence_outputs[i] = NULL; //if it remains null, flow ends here
+ instance->sequence_outputs[i] = nullptr; //if it remains null, flow ends here
}
}
@@ -2298,13 +2411,11 @@ VisualScriptInstance::VisualScriptInstance() {
VisualScriptInstance::~VisualScriptInstance() {
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->lock();
-
- script->instances.erase(owner);
+ {
+ MutexLock lock(VisualScriptLanguage::singleton->lock);
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->unlock();
+ script->instances.erase(owner);
+ }
for (Map<int, VisualScriptNodeInstance *>::Element *E = instances.front(); E; E = E->next()) {
memdelete(E->get());
@@ -2315,23 +2426,23 @@ VisualScriptInstance::~VisualScriptInstance() {
/////////////////////
-Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
- ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+ ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
#endif
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
Array args;
if (p_argcount == 0) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
return Variant();
} else if (p_argcount == 1) {
@@ -2346,13 +2457,13 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
Ref<VisualScriptFunctionState> self = *p_args[p_argcount - 1]; //hi, I'm myself, needed this to remain alive.
if (self.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_argcount - 1;
r_error.expected = Variant::OBJECT;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index;
@@ -2370,7 +2481,7 @@ void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p
binds.push_back(p_binds[i]);
}
binds.push_back(Ref<VisualScriptFunctionState>(this)); //add myself on the back to avoid dying from unreferencing
- p_obj->connect(p_signal, this, "_signal_callback", binds, CONNECT_ONESHOT);
+ p_obj->connect_compat(p_signal, this, "_signal_callback", binds, CONNECT_ONESHOT);
}
bool VisualScriptFunctionState::is_valid() const {
@@ -2383,13 +2494,13 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
- ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+ ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
#endif
- Variant::CallError r_error;
- r_error.error = Variant::CallError::CALL_OK;
+ Callable::CallError r_error;
+ r_error.error = Callable::CallError::CALL_OK;
Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index;
@@ -2491,7 +2602,7 @@ int VisualScriptLanguage::find_function(const String &p_function, const String &
return -1;
}
-String VisualScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+String VisualScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
return String();
}
@@ -2506,12 +2617,12 @@ void VisualScriptLanguage::add_global_constant(const StringName &p_variable, con
bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, const String &p_error) {
//break because of parse error
- if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
+ if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_node = p_node;
_debug_parse_err_file = p_file;
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, false, true);
+ EngineDebugger::get_script_debugger()->debug(this, false, true);
return true;
} else {
return false;
@@ -2520,12 +2631,12 @@ bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, c
bool VisualScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) {
- if (ScriptDebugger::get_singleton() && Thread::get_caller_id() == Thread::get_main_id()) {
+ if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_node = -1;
_debug_parse_err_file = "";
_debug_error = p_error;
- ScriptDebugger::get_singleton()->debug(this, p_allow_continue, true);
+ EngineDebugger::get_script_debugger()->debug(this, p_allow_continue, true);
return true;
} else {
return false;
@@ -2692,7 +2803,7 @@ void VisualScriptLanguage::get_recognized_extensions(List<String> *p_extensions)
}
void VisualScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
}
-void VisualScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
+void VisualScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const {
}
void VisualScriptLanguage::profiling_start() {
@@ -2710,7 +2821,7 @@ int VisualScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, in
return 0;
}
-VisualScriptLanguage *VisualScriptLanguage::singleton = NULL;
+VisualScriptLanguage *VisualScriptLanguage::singleton = nullptr;
void VisualScriptLanguage::add_register_func(const String &p_name, VisualScriptNodeRegisterFunc p_func) {
@@ -2743,9 +2854,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
_step = "_step";
_subcall = "_subcall";
singleton = this;
-#ifndef NO_THREADS
- lock = Mutex::create();
-#endif
_debug_parse_err_node = -1;
_debug_parse_err_file = "";
@@ -2753,24 +2861,21 @@ VisualScriptLanguage::VisualScriptLanguage() {
int dmcs = GLOBAL_DEF("debug/settings/visual_script/max_call_stack", 1024);
ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/visual_script/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/visual_script/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024
- if (ScriptDebugger::get_singleton()) {
+ if (EngineDebugger::is_active()) {
//debugging enabled!
_debug_max_call_stack = dmcs;
_call_stack = memnew_arr(CallLevel, _debug_max_call_stack + 1);
} else {
_debug_max_call_stack = 0;
- _call_stack = NULL;
+ _call_stack = nullptr;
}
}
VisualScriptLanguage::~VisualScriptLanguage() {
- if (lock)
- memdelete(lock);
-
if (_call_stack) {
memdelete_arr(_call_stack);
}
- singleton = NULL;
+ singleton = nullptr;
}
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 9305226dc6..c154e56703 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -31,6 +31,8 @@
#ifndef VISUAL_SCRIPT_H
#define VISUAL_SCRIPT_H
+#include "core/debugger/engine_debugger.h"
+#include "core/debugger/script_debugger.h"
#include "core/os/thread.h"
#include "core/script_language.h"
@@ -155,7 +157,7 @@ public:
virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) = 0; //do a step, return which sequence port to go out
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) = 0; //do a step, return which sequence port to go out
Ref<VisualScriptNode> get_base_node() { return Ref<VisualScriptNode>(base); }
@@ -244,7 +246,9 @@ private:
Map<StringName, Function> functions;
Map<StringName, Variable> variables;
- Map<StringName, Vector<Argument> > custom_signals;
+ Map<StringName, Vector<Argument>> custom_signals;
+ Vector<ScriptNetData> rpc_functions;
+ Vector<ScriptNetData> rpc_variables;
Map<Object *, VisualScriptInstance *> instances;
@@ -268,6 +272,8 @@ protected:
static void _bind_methods();
public:
+ bool inherits_script(const Ref<Script> &p_script) const;
+
// TODO: Remove it in future when breaking changes are acceptable
StringName get_default_func() const;
void add_function(const StringName &p_name);
@@ -362,6 +368,18 @@ public:
virtual int get_member_line(const StringName &p_member) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_property) const;
+ virtual StringName get_rset_property(const uint16_t p_rset_property_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
#ifdef TOOLS_ENABLED
virtual bool are_subnodes_edited() const;
#endif
@@ -394,8 +412,8 @@ class VisualScriptInstance : public ScriptInstance {
StringName source;
- void _dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Variant::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node);
- Variant _call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Variant::CallError &r_error);
+ void _dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Callable::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node);
+ Variant _call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Callable::CallError &r_error);
//Map<StringName,Function> functions;
friend class VisualScriptFunctionState; //for yield
@@ -404,11 +422,11 @@ public:
virtual bool set(const StringName &p_name, const Variant &p_value);
virtual bool get(const StringName &p_name, Variant &r_ret) const;
virtual void get_property_list(List<PropertyInfo> *p_properties) const;
- virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const;
virtual void get_method_list(List<MethodInfo> *p_list) const;
virtual bool has_method(const StringName &p_method) const;
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual void notification(int p_notification);
String to_string(bool *r_valid);
@@ -441,7 +459,16 @@ public:
virtual ScriptLanguage *get_language();
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_property) const;
+ virtual StringName get_rset_property(const uint16_t p_rset_property_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
VisualScriptInstance();
@@ -464,7 +491,7 @@ class VisualScriptFunctionState : public Reference {
int flow_stack_pos;
int pass;
- Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
protected:
static void _bind_methods();
@@ -507,7 +534,7 @@ public:
static VisualScriptLanguage *singleton;
- Mutex *lock;
+ Mutex lock;
bool debug_break(const String &p_error, bool p_allow_continue = true);
bool debug_break_parse(const String &p_file, int p_node, const String &p_error);
@@ -517,13 +544,13 @@ public:
if (Thread::get_main_id() != Thread::get_caller_id())
return; //no support for other threads than main for now
- if (ScriptDebugger::get_singleton()->get_lines_left() > 0 && ScriptDebugger::get_singleton()->get_depth() >= 0)
- ScriptDebugger::get_singleton()->set_depth(ScriptDebugger::get_singleton()->get_depth() + 1);
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() + 1);
if (_debug_call_stack_pos >= _debug_max_call_stack) {
//stack overflow
_debug_error = "Stack Overflow (Stack Size: " + itos(_debug_max_call_stack) + ")";
- ScriptDebugger::get_singleton()->debug(this);
+ EngineDebugger::get_script_debugger()->debug(this);
return;
}
@@ -540,13 +567,13 @@ public:
if (Thread::get_main_id() != Thread::get_caller_id())
return; //no support for other threads than main for now
- if (ScriptDebugger::get_singleton()->get_lines_left() > 0 && ScriptDebugger::get_singleton()->get_depth() >= 0)
- ScriptDebugger::get_singleton()->set_depth(ScriptDebugger::get_singleton()->get_depth() - 1);
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() - 1);
if (_debug_call_stack_pos == 0) {
_debug_error = "Stack Underflow (Engine Bug)";
- ScriptDebugger::get_singleton()->debug(this);
+ EngineDebugger::get_script_debugger()->debug(this);
return;
}
@@ -571,12 +598,12 @@ public:
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
virtual bool is_using_templates();
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
- virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL, List<ScriptLanguage::Warning> *r_warnings = NULL, Set<int> *r_safe_lines = NULL) const;
+ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
virtual bool supports_builtin_mode() const;
virtual int find_function(const String &p_function, const String &p_code) const;
- virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const;
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
@@ -598,7 +625,7 @@ public:
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_public_functions(List<MethodInfo> *p_functions) const;
- virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
+ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const;
virtual void profiling_start();
virtual void profiling_stop();
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index 2894f6367b..bb291b1cb6 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -63,7 +63,7 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"is_nan",
"is_inf",
"ease",
- "decimals",
+ "step_decimals",
"stepify",
"lerp",
"inverse_lerp",
@@ -171,7 +171,7 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case MATH_EXP:
case MATH_ISNAN:
case MATH_ISINF:
- case MATH_DECIMALS:
+ case MATH_STEP_DECIMALS:
case MATH_SEED:
case MATH_RANDSEED:
case MATH_DEG2RAD:
@@ -277,22 +277,22 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case MATH_EXP:
case MATH_ISNAN:
case MATH_ISINF: {
- return PropertyInfo(Variant::REAL, "s");
+ return PropertyInfo(Variant::FLOAT, "s");
} break;
case MATH_ATAN2: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "y");
+ return PropertyInfo(Variant::FLOAT, "y");
else
- return PropertyInfo(Variant::REAL, "x");
+ return PropertyInfo(Variant::FLOAT, "x");
} break;
case MATH_FMOD:
case MATH_FPOSMOD:
case LOGIC_MAX:
case LOGIC_MIN: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "a");
+ return PropertyInfo(Variant::FLOAT, "a");
else
- return PropertyInfo(Variant::REAL, "b");
+ return PropertyInfo(Variant::FLOAT, "b");
} break;
case MATH_POSMOD: {
if (p_idx == 0)
@@ -302,63 +302,63 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
} break;
case MATH_POW: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "base");
+ return PropertyInfo(Variant::FLOAT, "base");
else
- return PropertyInfo(Variant::REAL, "exp");
+ return PropertyInfo(Variant::FLOAT, "exp");
} break;
case MATH_EASE: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "s");
+ return PropertyInfo(Variant::FLOAT, "s");
else
- return PropertyInfo(Variant::REAL, "curve");
+ return PropertyInfo(Variant::FLOAT, "curve");
} break;
- case MATH_DECIMALS: {
- return PropertyInfo(Variant::REAL, "step");
+ case MATH_STEP_DECIMALS: {
+ return PropertyInfo(Variant::FLOAT, "step");
} break;
case MATH_STEPIFY: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "s");
+ return PropertyInfo(Variant::FLOAT, "s");
else
- return PropertyInfo(Variant::REAL, "steps");
+ return PropertyInfo(Variant::FLOAT, "steps");
} break;
case MATH_LERP:
case MATH_LERP_ANGLE:
case MATH_INVERSE_LERP:
case MATH_SMOOTHSTEP: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "from");
+ return PropertyInfo(Variant::FLOAT, "from");
else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "to");
+ return PropertyInfo(Variant::FLOAT, "to");
else
- return PropertyInfo(Variant::REAL, "weight");
+ return PropertyInfo(Variant::FLOAT, "weight");
} break;
case MATH_RANGE_LERP: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "value");
+ return PropertyInfo(Variant::FLOAT, "value");
else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "istart");
+ return PropertyInfo(Variant::FLOAT, "istart");
else if (p_idx == 2)
- return PropertyInfo(Variant::REAL, "istop");
+ return PropertyInfo(Variant::FLOAT, "istop");
else if (p_idx == 3)
- return PropertyInfo(Variant::REAL, "ostart");
+ return PropertyInfo(Variant::FLOAT, "ostart");
else
- return PropertyInfo(Variant::REAL, "ostop");
+ return PropertyInfo(Variant::FLOAT, "ostop");
} break;
case MATH_MOVE_TOWARD: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "from");
+ return PropertyInfo(Variant::FLOAT, "from");
else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "to");
+ return PropertyInfo(Variant::FLOAT, "to");
else
- return PropertyInfo(Variant::REAL, "delta");
+ return PropertyInfo(Variant::FLOAT, "delta");
} break;
case MATH_DECTIME: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "value");
+ return PropertyInfo(Variant::FLOAT, "value");
else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "amount");
+ return PropertyInfo(Variant::FLOAT, "amount");
else
- return PropertyInfo(Variant::REAL, "step");
+ return PropertyInfo(Variant::FLOAT, "step");
} break;
case MATH_RANDOMIZE:
case MATH_RAND:
@@ -367,37 +367,37 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
} break;
case MATH_RANDOM: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "from");
+ return PropertyInfo(Variant::FLOAT, "from");
else
- return PropertyInfo(Variant::REAL, "to");
+ return PropertyInfo(Variant::FLOAT, "to");
} break;
case MATH_SEED:
case MATH_RANDSEED: {
return PropertyInfo(Variant::INT, "seed");
} break;
case MATH_DEG2RAD: {
- return PropertyInfo(Variant::REAL, "deg");
+ return PropertyInfo(Variant::FLOAT, "deg");
} break;
case MATH_RAD2DEG: {
- return PropertyInfo(Variant::REAL, "rad");
+ return PropertyInfo(Variant::FLOAT, "rad");
} break;
case MATH_LINEAR2DB: {
- return PropertyInfo(Variant::REAL, "nrg");
+ return PropertyInfo(Variant::FLOAT, "nrg");
} break;
case MATH_DB2LINEAR: {
- return PropertyInfo(Variant::REAL, "db");
+ return PropertyInfo(Variant::FLOAT, "db");
} break;
case MATH_POLAR2CARTESIAN: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "r");
+ return PropertyInfo(Variant::FLOAT, "r");
else
- return PropertyInfo(Variant::REAL, "th");
+ return PropertyInfo(Variant::FLOAT, "th");
} break;
case MATH_CARTESIAN2POLAR: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "x");
+ return PropertyInfo(Variant::FLOAT, "x");
else
- return PropertyInfo(Variant::REAL, "y");
+ return PropertyInfo(Variant::FLOAT, "y");
} break;
case MATH_WRAP: {
if (p_idx == 0)
@@ -410,11 +410,11 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case MATH_WRAPF:
case LOGIC_CLAMP: {
if (p_idx == 0)
- return PropertyInfo(Variant::REAL, "value");
+ return PropertyInfo(Variant::FLOAT, "value");
else if (p_idx == 1)
- return PropertyInfo(Variant::REAL, "min");
+ return PropertyInfo(Variant::FLOAT, "min");
else
- return PropertyInfo(Variant::REAL, "max");
+ return PropertyInfo(Variant::FLOAT, "max");
} break;
case LOGIC_NEAREST_PO2: {
return PropertyInfo(Variant::INT, "value");
@@ -467,7 +467,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
case BYTES_TO_VAR: {
if (p_idx == 0)
- return PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes");
+ return PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytes");
else
return PropertyInfo(Variant::BOOL, "allow_objects");
} break;
@@ -475,7 +475,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
if (p_idx == 0)
return PropertyInfo(Variant::STRING, "name");
else
- return PropertyInfo(Variant::REAL, "alpha");
+ return PropertyInfo(Variant::FLOAT, "alpha");
} break;
case FUNC_MAX: {
}
@@ -504,12 +504,14 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_FPOSMOD:
case MATH_FLOOR:
case MATH_CEIL: {
- t = Variant::REAL;
+ t = Variant::FLOAT;
} break;
- case MATH_POSMOD:
- case MATH_ROUND: {
+ case MATH_POSMOD: {
t = Variant::INT;
} break;
+ case MATH_ROUND: {
+ t = Variant::FLOAT;
+ } break;
case MATH_ABS: {
t = Variant::NIL;
} break;
@@ -519,16 +521,16 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_POW:
case MATH_LOG:
case MATH_EXP: {
- t = Variant::REAL;
+ t = Variant::FLOAT;
} break;
case MATH_ISNAN:
case MATH_ISINF: {
t = Variant::BOOL;
} break;
case MATH_EASE: {
- t = Variant::REAL;
+ t = Variant::FLOAT;
} break;
- case MATH_DECIMALS: {
+ case MATH_STEP_DECIMALS: {
t = Variant::INT;
} break;
case MATH_STEPIFY:
@@ -539,7 +541,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_SMOOTHSTEP:
case MATH_MOVE_TOWARD:
case MATH_DECTIME: {
- t = Variant::REAL;
+ t = Variant::FLOAT;
} break;
case MATH_RANDOMIZE: {
@@ -551,7 +553,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
} break;
case MATH_RANDF:
case MATH_RANDOM: {
- t = Variant::REAL;
+ t = Variant::FLOAT;
} break;
case MATH_SEED: {
@@ -568,7 +570,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case MATH_LINEAR2DB:
case MATH_WRAPF:
case MATH_DB2LINEAR: {
- t = Variant::REAL;
+ t = Variant::FLOAT;
} break;
case MATH_POLAR2CARTESIAN:
case MATH_CARTESIAN2POLAR: {
@@ -632,7 +634,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
} break;
case VAR_TO_BYTES: {
if (p_idx == 0)
- t = Variant::POOL_BYTE_ARRAY;
+ t = Variant::PACKED_BYTE_ARRAY;
else
t = Variant::BOOL;
@@ -675,15 +677,15 @@ VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::get_func() {
return func;
}
-#define VALIDATE_ARG_NUM(m_arg) \
- if (!p_inputs[m_arg]->is_num()) { \
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; \
- r_error.argument = m_arg; \
- r_error.expected = Variant::REAL; \
- return; \
+#define VALIDATE_ARG_NUM(m_arg) \
+ if (!p_inputs[m_arg]->is_num()) { \
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \
+ r_error.argument = m_arg; \
+ r_error.expected = Variant::FLOAT; \
+ return; \
}
-void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str) {
+void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) {
switch (p_func) {
case VisualScriptBuiltinFunc::MATH_SIN: {
@@ -781,15 +783,15 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
int64_t i = *p_inputs[0];
*r_return = ABS(i);
- } else if (p_inputs[0]->get_type() == Variant::REAL) {
+ } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
real_t r = *p_inputs[0];
*r_return = Math::abs(r);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
}
} break;
case VisualScriptBuiltinFunc::MATH_SIGN: {
@@ -798,15 +800,15 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
int64_t i = *p_inputs[0];
*r_return = i < 0 ? -1 : (i > 0 ? +1 : 0);
- } else if (p_inputs[0]->get_type() == Variant::REAL) {
+ } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
real_t r = *p_inputs[0];
*r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
}
} break;
case VisualScriptBuiltinFunc::MATH_POW: {
@@ -841,7 +843,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(1);
*r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
- case VisualScriptBuiltinFunc::MATH_DECIMALS: {
+ case VisualScriptBuiltinFunc::MATH_STEP_DECIMALS: {
VALIDATE_ARG_NUM(0);
*r_return = Math::step_decimals((double)*p_inputs[0]);
@@ -1047,7 +1049,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1081,7 +1083,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1089,7 +1091,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
}
if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -1111,7 +1113,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
if (type < 0 || type >= Variant::VARIANT_MAX) {
r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::INT;
return;
@@ -1141,7 +1143,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
case VisualScriptBuiltinFunc::TEXT_ORD: {
if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -1151,7 +1153,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
String str = p_inputs[0]->operator String();
if (str.length() != 1) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
*r_return = "Expected a string of length 1 (a character).";
@@ -1197,7 +1199,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
case VisualScriptBuiltinFunc::STR_TO_VAR: {
if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -1212,7 +1214,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
Error err = VariantParser::parse(&ss, *r_return, errs, line);
if (err != OK) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
*r_return = "Parse error at line " + itos(line) + ": " + errs;
@@ -1223,17 +1225,17 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
case VisualScriptBuiltinFunc::VAR_TO_BYTES: {
if (p_inputs[1]->get_type() != Variant::BOOL) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::BOOL;
return;
}
- PoolByteArray barr;
+ PackedByteArray barr;
int len;
bool full_objects = *p_inputs[1];
- Error err = encode_variant(*p_inputs[0], NULL, len, full_objects);
+ Error err = encode_variant(*p_inputs[0], nullptr, len, full_objects);
if (err) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::NIL;
r_error_str = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
@@ -1242,37 +1244,37 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
barr.resize(len);
{
- PoolByteArray::Write w = barr.write();
- encode_variant(*p_inputs[0], w.ptr(), len, full_objects);
+ uint8_t *w = barr.ptrw();
+ encode_variant(*p_inputs[0], w, len, full_objects);
}
*r_return = barr;
} break;
case VisualScriptBuiltinFunc::BYTES_TO_VAR: {
- if (p_inputs[0]->get_type() != Variant::POOL_BYTE_ARRAY) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
return;
}
if (p_inputs[1]->get_type() != Variant::BOOL) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::BOOL;
return;
}
- PoolByteArray varr = *p_inputs[0];
+ PackedByteArray varr = *p_inputs[0];
bool allow_objects = *p_inputs[1];
Variant ret;
{
- PoolByteArray::Read r = varr.read();
- Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects);
+ const uint8_t *r = varr.ptr();
+ Error err = decode_variant(ret, r, varr.size(), nullptr, allow_objects);
if (err != OK) {
r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
return;
}
}
@@ -1306,7 +1308,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
VisualScriptBuiltinFunc::exec_func(func, p_inputs, p_outputs[0], r_error, r_error_str);
return 0;
@@ -1361,7 +1363,7 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_ISNAN);
BIND_ENUM_CONSTANT(MATH_ISINF);
BIND_ENUM_CONSTANT(MATH_EASE);
- BIND_ENUM_CONSTANT(MATH_DECIMALS);
+ BIND_ENUM_CONSTANT(MATH_STEP_DECIMALS);
BIND_ENUM_CONSTANT(MATH_STEPIFY);
BIND_ENUM_CONSTANT(MATH_LERP);
BIND_ENUM_CONSTANT(MATH_INVERSE_LERP);
@@ -1455,7 +1457,7 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/isinf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ISINF>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/ease", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_EASE>);
- VisualScriptLanguage::singleton->add_register_func("functions/built_in/decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECIMALS>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/step_decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEP_DECIMALS>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/stepify", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEPIFY>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp_angle", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP_ANGLE>);
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index f5021cb545..d950f858d4 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -63,7 +63,7 @@ public:
MATH_ISNAN,
MATH_ISINF,
MATH_EASE,
- MATH_DECIMALS,
+ MATH_STEP_DECIMALS,
MATH_STEPIFY,
MATH_LERP,
MATH_INVERSE_LERP,
@@ -112,7 +112,7 @@ public:
static int get_func_argument_count(BuiltinFunc p_func);
static String get_func_name(BuiltinFunc p_func);
- static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str);
+ static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str);
static BuiltinFunc find_function(const String &p_string);
private:
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index ec20698ae8..59b1bcdd96 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -30,15 +30,15 @@
#include "visual_script_editor.h"
+#include "core/input/input_filter.h"
#include "core/object.h"
-#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "core/script_language.h"
#include "core/variant.h"
#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
-#include "scene/main/viewport.h"
+#include "scene/main/window.h"
#include "visual_script_expression.h"
#include "visual_script_flow_control.h"
#include "visual_script_func_nodes.h"
@@ -182,7 +182,7 @@ public:
_change_notify();
}
- VisualScriptEditorSignalEdit() { undo_redo = NULL; }
+ VisualScriptEditorSignalEdit() { undo_redo = nullptr; }
};
class VisualScriptEditorVariableEdit : public Object {
@@ -335,7 +335,7 @@ public:
_change_notify();
}
- VisualScriptEditorVariableEdit() { undo_redo = NULL; }
+ VisualScriptEditorVariableEdit() { undo_redo = nullptr; }
};
static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
@@ -346,12 +346,15 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
case Variant::BOOL: color = Color(0.55, 0.65, 0.94); break;
case Variant::INT: color = Color(0.49, 0.78, 0.94); break;
- case Variant::REAL: color = Color(0.38, 0.85, 0.96); break;
+ case Variant::FLOAT: color = Color(0.38, 0.85, 0.96); break;
case Variant::STRING: color = Color(0.42, 0.65, 0.93); break;
case Variant::VECTOR2: color = Color(0.74, 0.57, 0.95); break;
+ case Variant::VECTOR2I: color = Color(0.74, 0.57, 0.95); break;
case Variant::RECT2: color = Color(0.95, 0.57, 0.65); break;
+ case Variant::RECT2I: color = Color(0.95, 0.57, 0.65); break;
case Variant::VECTOR3: color = Color(0.84, 0.49, 0.93); break;
+ case Variant::VECTOR3I: color = Color(0.84, 0.49, 0.93); break;
case Variant::TRANSFORM2D: color = Color(0.77, 0.93, 0.41); break;
case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break;
case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break;
@@ -366,13 +369,15 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
case Variant::DICTIONARY: color = Color(0.47, 0.93, 0.69); break;
case Variant::ARRAY: color = Color(0.88, 0.88, 0.88); break;
- case Variant::POOL_BYTE_ARRAY: color = Color(0.67, 0.96, 0.78); break;
- case Variant::POOL_INT_ARRAY: color = Color(0.69, 0.86, 0.96); break;
- case Variant::POOL_REAL_ARRAY: color = Color(0.59, 0.91, 0.97); break;
- case Variant::POOL_STRING_ARRAY: color = Color(0.62, 0.77, 0.95); break;
- case Variant::POOL_VECTOR2_ARRAY: color = Color(0.82, 0.7, 0.96); break;
- case Variant::POOL_VECTOR3_ARRAY: color = Color(0.87, 0.61, 0.95); break;
- case Variant::POOL_COLOR_ARRAY: color = Color(0.91, 1.0, 0.59); break;
+ case Variant::PACKED_BYTE_ARRAY: color = Color(0.67, 0.96, 0.78); break;
+ case Variant::PACKED_INT32_ARRAY: color = Color(0.69, 0.86, 0.96); break;
+ case Variant::PACKED_FLOAT32_ARRAY: color = Color(0.59, 0.91, 0.97); break;
+ case Variant::PACKED_INT64_ARRAY: color = Color(0.69, 0.86, 0.96); break;
+ case Variant::PACKED_FLOAT64_ARRAY: color = Color(0.59, 0.91, 0.97); break;
+ case Variant::PACKED_STRING_ARRAY: color = Color(0.62, 0.77, 0.95); break;
+ case Variant::PACKED_VECTOR2_ARRAY: color = Color(0.82, 0.7, 0.96); break;
+ case Variant::PACKED_VECTOR3_ARRAY: color = Color(0.87, 0.61, 0.95); break;
+ case Variant::PACKED_COLOR_ARRAY: color = Color(0.91, 1.0, 0.59); break;
default:
color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.7, 0.7);
@@ -383,12 +388,15 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
case Variant::BOOL: color = Color(0.43, 0.56, 0.92); break;
case Variant::INT: color = Color(0.31, 0.7, 0.91); break;
- case Variant::REAL: color = Color(0.15, 0.8, 0.94); break;
+ case Variant::FLOAT: color = Color(0.15, 0.8, 0.94); break;
case Variant::STRING: color = Color(0.27, 0.56, 0.91); break;
case Variant::VECTOR2: color = Color(0.68, 0.46, 0.93); break;
+ case Variant::VECTOR2I: color = Color(0.68, 0.46, 0.93); break;
case Variant::RECT2: color = Color(0.93, 0.46, 0.56); break;
+ case Variant::RECT2I: color = Color(0.93, 0.46, 0.56); break;
case Variant::VECTOR3: color = Color(0.86, 0.42, 0.93); break;
+ case Variant::VECTOR3I: color = Color(0.86, 0.42, 0.93); break;
case Variant::TRANSFORM2D: color = Color(0.59, 0.81, 0.1); break;
case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break;
case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break;
@@ -403,13 +411,15 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
case Variant::DICTIONARY: color = Color(0.34, 0.91, 0.62); break;
case Variant::ARRAY: color = Color(0.45, 0.45, 0.45); break;
- case Variant::POOL_BYTE_ARRAY: color = Color(0.38, 0.92, 0.6); break;
- case Variant::POOL_INT_ARRAY: color = Color(0.38, 0.73, 0.92); break;
- case Variant::POOL_REAL_ARRAY: color = Color(0.25, 0.83, 0.95); break;
- case Variant::POOL_STRING_ARRAY: color = Color(0.38, 0.62, 0.92); break;
- case Variant::POOL_VECTOR2_ARRAY: color = Color(0.62, 0.36, 0.92); break;
- case Variant::POOL_VECTOR3_ARRAY: color = Color(0.79, 0.35, 0.92); break;
- case Variant::POOL_COLOR_ARRAY: color = Color(0.57, 0.73, 0.0); break;
+ case Variant::PACKED_BYTE_ARRAY: color = Color(0.38, 0.92, 0.6); break;
+ case Variant::PACKED_INT32_ARRAY: color = Color(0.38, 0.73, 0.92); break;
+ case Variant::PACKED_FLOAT32_ARRAY: color = Color(0.25, 0.83, 0.95); break;
+ case Variant::PACKED_INT64_ARRAY: color = Color(0.38, 0.73, 0.92); break;
+ case Variant::PACKED_FLOAT64_ARRAY: color = Color(0.25, 0.83, 0.95); break;
+ case Variant::PACKED_STRING_ARRAY: color = Color(0.38, 0.62, 0.92); break;
+ case Variant::PACKED_VECTOR2_ARRAY: color = Color(0.62, 0.36, 0.92); break;
+ case Variant::PACKED_VECTOR3_ARRAY: color = Color(0.79, 0.35, 0.92); break;
+ case Variant::PACKED_COLOR_ARRAY: color = Color(0.57, 0.73, 0.0); break;
default:
color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.3, 0.3);
@@ -499,37 +509,42 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
graph->show();
select_func_text->hide();
- Ref<Texture> type_icons[Variant::VARIANT_MAX] = {
- Control::get_icon("Variant", "EditorIcons"),
- Control::get_icon("bool", "EditorIcons"),
- Control::get_icon("int", "EditorIcons"),
- Control::get_icon("float", "EditorIcons"),
- Control::get_icon("String", "EditorIcons"),
- Control::get_icon("Vector2", "EditorIcons"),
- Control::get_icon("Rect2", "EditorIcons"),
- Control::get_icon("Vector3", "EditorIcons"),
- Control::get_icon("Transform2D", "EditorIcons"),
- Control::get_icon("Plane", "EditorIcons"),
- Control::get_icon("Quat", "EditorIcons"),
- Control::get_icon("AABB", "EditorIcons"),
- Control::get_icon("Basis", "EditorIcons"),
- Control::get_icon("Transform", "EditorIcons"),
- Control::get_icon("Color", "EditorIcons"),
- Control::get_icon("NodePath", "EditorIcons"),
- Control::get_icon("RID", "EditorIcons"),
- Control::get_icon("MiniObject", "EditorIcons"),
- Control::get_icon("Dictionary", "EditorIcons"),
- Control::get_icon("Array", "EditorIcons"),
- Control::get_icon("PoolByteArray", "EditorIcons"),
- Control::get_icon("PoolIntArray", "EditorIcons"),
- Control::get_icon("PoolRealArray", "EditorIcons"),
- Control::get_icon("PoolStringArray", "EditorIcons"),
- Control::get_icon("PoolVector2Array", "EditorIcons"),
- Control::get_icon("PoolVector3Array", "EditorIcons"),
- Control::get_icon("PoolColorArray", "EditorIcons")
+ Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = {
+ Control::get_theme_icon("Variant", "EditorIcons"),
+ Control::get_theme_icon("bool", "EditorIcons"),
+ Control::get_theme_icon("int", "EditorIcons"),
+ Control::get_theme_icon("float", "EditorIcons"),
+ Control::get_theme_icon("String", "EditorIcons"),
+ Control::get_theme_icon("Vector2", "EditorIcons"),
+ Control::get_theme_icon("Vector2i", "EditorIcons"),
+ Control::get_theme_icon("Rect2", "EditorIcons"),
+ Control::get_theme_icon("Rect2i", "EditorIcons"),
+ Control::get_theme_icon("Vector3", "EditorIcons"),
+ Control::get_theme_icon("Vector3i", "EditorIcons"),
+ Control::get_theme_icon("Transform2D", "EditorIcons"),
+ Control::get_theme_icon("Plane", "EditorIcons"),
+ Control::get_theme_icon("Quat", "EditorIcons"),
+ Control::get_theme_icon("AABB", "EditorIcons"),
+ Control::get_theme_icon("Basis", "EditorIcons"),
+ Control::get_theme_icon("Transform", "EditorIcons"),
+ Control::get_theme_icon("Color", "EditorIcons"),
+ Control::get_theme_icon("NodePath", "EditorIcons"),
+ Control::get_theme_icon("RID", "EditorIcons"),
+ Control::get_theme_icon("MiniObject", "EditorIcons"),
+ Control::get_theme_icon("Callable", "EditorIcons"),
+ Control::get_theme_icon("Signal", "EditorIcons"),
+ Control::get_theme_icon("Dictionary", "EditorIcons"),
+ Control::get_theme_icon("Array", "EditorIcons"),
+ Control::get_theme_icon("PackedByteArray", "EditorIcons"),
+ Control::get_theme_icon("PackedInt32Array", "EditorIcons"),
+ Control::get_theme_icon("PackedFloat32Array", "EditorIcons"),
+ Control::get_theme_icon("PackedStringArray", "EditorIcons"),
+ Control::get_theme_icon("PackedVector2Array", "EditorIcons"),
+ Control::get_theme_icon("PackedVector3Array", "EditorIcons"),
+ Control::get_theme_icon("PackedColorArray", "EditorIcons")
};
- Ref<Texture> seq_port = Control::get_icon("VisualShaderPort", "EditorIcons");
+ Ref<Texture2D> seq_port = Control::get_theme_icon("VisualShaderPort", "EditorIcons");
for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions
@@ -556,8 +571,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->set_meta("__vnode", node);
gnode->set_name(itos(E->get()));
- gnode->connect("dragged", this, "_node_moved", varray(E->get()));
- gnode->connect("close_request", this, "_remove_node", varray(E->get()), CONNECT_DEFERRED);
+ gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved), varray(E->get()));
+ gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node), varray(E->get()), CONNECT_DEFERRED);
if (E->get() != script->get_function_node_id(F->get())) {
//function can't be erased
@@ -575,7 +590,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Button *btn = memnew(Button);
btn->set_text(TTR("Add Input Port"));
hbnc->add_child(btn);
- btn->connect("pressed", this, "_add_input_port", varray(E->get()), CONNECT_DEFERRED);
+ btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E->get()), CONNECT_DEFERRED);
}
if (nd_list->is_output_port_editable()) {
if (nd_list->is_input_port_editable())
@@ -584,7 +599,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Button *btn = memnew(Button);
btn->set_text(TTR("Add Output Port"));
hbnc->add_child(btn);
- btn->connect("pressed", this, "_add_output_port", varray(E->get()), CONNECT_DEFERRED);
+ btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port), varray(E->get()), CONNECT_DEFERRED);
}
gnode->add_child(hbnc);
} else if (Object::cast_to<VisualScriptExpression>(node.ptr())) {
@@ -592,9 +607,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
LineEdit *line_edit = memnew(LineEdit);
line_edit->set_text(node->get_text());
line_edit->set_expand_to_text_length(true);
- line_edit->add_font_override("font", get_font("source", "EditorFonts"));
+ line_edit->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
gnode->add_child(line_edit);
- line_edit->connect("text_changed", this, "_expression_text_changed", varray(E->get()));
+ line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed), varray(E->get()));
} else {
String text = node->get_text();
if (!text.empty()) {
@@ -610,7 +625,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->set_comment(true);
gnode->set_resizable(true);
gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE);
- gnode->connect("resize_request", this, "_comment_node_resized", varray(E->get()));
+ gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized), varray(E->get()));
}
if (node_styles.has(node->get_category())) {
@@ -619,20 +634,28 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox("comment", "GraphNode");
Color c = sbf->get_border_color();
+ Color ic = c;
c.a = 1;
if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) {
- Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0) : Color(0.0, 0.0, 0.0);
+ Color mono_color;
+ if (((c.r + c.g + c.b) / 3) < 0.7) {
+ mono_color = Color(1.0, 1.0, 1.0);
+ ic = Color(0.0, 0.0, 0.0, 0.7);
+ } else {
+ mono_color = Color(0.0, 0.0, 0.0);
+ ic = Color(1.0, 1.0, 1.0, 0.7);
+ }
mono_color.a = 0.85;
c = mono_color;
}
- gnode->add_color_override("title_color", c);
+ gnode->add_theme_color_override("title_color", c);
c.a = 0.7;
- gnode->add_color_override("close_color", c);
- gnode->add_color_override("resizer_color", c);
- gnode->add_style_override("frame", sbf);
+ gnode->add_theme_color_override("close_color", c);
+ gnode->add_theme_color_override("resizer_color", ic);
+ gnode->add_theme_style_override("frame", sbf);
}
- const Color mono_color = get_color("mono_color", "Editor");
+ const Color mono_color = get_theme_color("mono_color", "Editor");
int slot_idx = 0;
@@ -702,7 +725,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
vbc->add_child(hbc2);
if (left_ok) {
- Ref<Texture> t;
+ Ref<Texture2D> t;
if (left_type >= 0 && left_type < Variant::VARIANT_MAX) {
t = type_icons[left_type];
}
@@ -720,8 +743,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
name_box->set_text(left_name);
name_box->set_expand_to_text_length(true);
- name_box->connect("resized", this, "_update_node_size", varray(E->get()));
- name_box->connect("focus_exited", this, "_port_name_focus_out", varray(name_box, E->get(), i, true));
+ name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get()));
+ name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, true));
} else {
hbc->add_child(memnew(Label(left_name)));
}
@@ -734,13 +757,13 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
opbtn->select(left_type);
opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
hbc->add_child(opbtn);
- opbtn->connect("item_selected", this, "_change_port_type", varray(E->get(), i, true), CONNECT_DEFERRED);
+ opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, true), CONNECT_DEFERRED);
}
Button *rmbtn = memnew(Button);
- rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Remove", "EditorIcons"));
+ rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
hbc->add_child(rmbtn);
- rmbtn->connect("pressed", this, "_remove_input_port", varray(E->get(), i), CONNECT_DEFERRED);
+ rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port), varray(E->get(), i), CONNECT_DEFERRED);
} else {
hbc->add_child(memnew(Label(left_name)));
}
@@ -753,14 +776,14 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
if (value.get_type() != left_type) {
//different type? for now convert
//not the same, reconvert
- Variant::CallError ce;
+ Callable::CallError ce;
const Variant *existingp = &value;
value = Variant::construct(left_type, &existingp, 1, ce, false);
}
if (left_type == Variant::COLOR) {
button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
- button->connect("draw", this, "_draw_color_over_button", varray(button, value));
+ button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button), varray(button, value));
} else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) {
Ref<Resource> res = value;
@@ -776,7 +799,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
button->set_text(value);
}
- button->connect("pressed", this, "_default_value_edited", varray(button, E->get(), i));
+ button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E->get(), i));
hbc2->add_child(button);
}
} else {
@@ -800,9 +823,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
if (is_vslist) {
Button *rmbtn = memnew(Button);
- rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Remove", "EditorIcons"));
+ rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
hbc->add_child(rmbtn);
- rmbtn->connect("pressed", this, "_remove_output_port", varray(E->get(), i), CONNECT_DEFERRED);
+ rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port), varray(E->get(), i), CONNECT_DEFERRED);
if (nd_list->is_output_port_type_editable()) {
OptionButton *opbtn = memnew(OptionButton);
@@ -812,7 +835,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
opbtn->select(right_type);
opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
hbc->add_child(opbtn);
- opbtn->connect("item_selected", this, "_change_port_type", varray(E->get(), i, false), CONNECT_DEFERRED);
+ opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type), varray(E->get(), i, false), CONNECT_DEFERRED);
}
if (nd_list->is_output_port_name_editable()) {
@@ -821,8 +844,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
name_box->set_text(right_name);
name_box->set_expand_to_text_length(true);
- name_box->connect("resized", this, "_update_node_size", varray(E->get()));
- name_box->connect("focus_exited", this, "_port_name_focus_out", varray(name_box, E->get(), i, false));
+ name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size), varray(E->get()));
+ name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out), varray(name_box, E->get(), i, false));
} else {
hbc->add_child(memnew(Label(right_name)));
}
@@ -830,7 +853,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
hbc->add_child(memnew(Label(right_name)));
}
- Ref<Texture> t;
+ Ref<Texture2D> t;
if (right_type >= 0 && right_type < Variant::VARIANT_MAX) {
t = type_icons[right_type];
}
@@ -844,9 +867,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->add_child(vbc);
- bool dark_theme = get_constant("dark_theme", "Editor");
+ bool dark_theme = get_theme_constant("dark_theme", "Editor");
if (i < mixed_seq_ports) {
- gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture>(), seq_port);
+ gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture2D>(), seq_port);
} else {
gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), right_ok, right_type, _color_from_type(right_type, dark_theme));
}
@@ -928,9 +951,9 @@ void VisualScriptEditor::_update_members() {
TreeItem *functions = members->create_item(root);
functions->set_selectable(0, false);
functions->set_text(0, TTR("Functions:"));
- functions->add_button(0, Control::get_icon("Override", "EditorIcons"), 1, false, TTR("Override an existing built-in function."));
- functions->add_button(0, Control::get_icon("Add", "EditorIcons"), 0, false, TTR("Create a new function."));
- functions->set_custom_color(0, Control::get_color("mono_color", "Editor"));
+ functions->add_button(0, Control::get_theme_icon("Override", "EditorIcons"), 1, false, TTR("Override an existing built-in function."));
+ functions->add_button(0, Control::get_theme_icon("Add", "EditorIcons"), 0, false, TTR("Create a new function."));
+ functions->set_custom_color(0, Control::get_theme_color("mono_color", "Editor"));
List<StringName> func_names;
script->get_function_list(&func_names);
@@ -944,7 +967,7 @@ void VisualScriptEditor::_update_members() {
ti->set_text(0, E->get());
ti->set_selectable(0, true);
ti->set_metadata(0, E->get());
- ti->add_button(0, Control::get_icon("Edit", "EditorIcons"), 0);
+ ti->add_button(0, Control::get_theme_icon("Edit", "EditorIcons"), 0);
if (selected == E->get())
ti->select(0);
}
@@ -952,37 +975,42 @@ void VisualScriptEditor::_update_members() {
TreeItem *variables = members->create_item(root);
variables->set_selectable(0, false);
variables->set_text(0, TTR("Variables:"));
- variables->add_button(0, Control::get_icon("Add", "EditorIcons"), -1, false, TTR("Create a new variable."));
- variables->set_custom_color(0, Control::get_color("mono_color", "Editor"));
-
- Ref<Texture> type_icons[Variant::VARIANT_MAX] = {
- Control::get_icon("Variant", "EditorIcons"),
- Control::get_icon("bool", "EditorIcons"),
- Control::get_icon("int", "EditorIcons"),
- Control::get_icon("float", "EditorIcons"),
- Control::get_icon("String", "EditorIcons"),
- Control::get_icon("Vector2", "EditorIcons"),
- Control::get_icon("Rect2", "EditorIcons"),
- Control::get_icon("Vector3", "EditorIcons"),
- Control::get_icon("Transform2D", "EditorIcons"),
- Control::get_icon("Plane", "EditorIcons"),
- Control::get_icon("Quat", "EditorIcons"),
- Control::get_icon("AABB", "EditorIcons"),
- Control::get_icon("Basis", "EditorIcons"),
- Control::get_icon("Transform", "EditorIcons"),
- Control::get_icon("Color", "EditorIcons"),
- Control::get_icon("NodePath", "EditorIcons"),
- Control::get_icon("RID", "EditorIcons"),
- Control::get_icon("MiniObject", "EditorIcons"),
- Control::get_icon("Dictionary", "EditorIcons"),
- Control::get_icon("Array", "EditorIcons"),
- Control::get_icon("PoolByteArray", "EditorIcons"),
- Control::get_icon("PoolIntArray", "EditorIcons"),
- Control::get_icon("PoolRealArray", "EditorIcons"),
- Control::get_icon("PoolStringArray", "EditorIcons"),
- Control::get_icon("PoolVector2Array", "EditorIcons"),
- Control::get_icon("PoolVector3Array", "EditorIcons"),
- Control::get_icon("PoolColorArray", "EditorIcons")
+ variables->add_button(0, Control::get_theme_icon("Add", "EditorIcons"), -1, false, TTR("Create a new variable."));
+ variables->set_custom_color(0, Control::get_theme_color("mono_color", "Editor"));
+
+ Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = {
+ Control::get_theme_icon("Variant", "EditorIcons"),
+ Control::get_theme_icon("bool", "EditorIcons"),
+ Control::get_theme_icon("int", "EditorIcons"),
+ Control::get_theme_icon("float", "EditorIcons"),
+ Control::get_theme_icon("String", "EditorIcons"),
+ Control::get_theme_icon("Vector2", "EditorIcons"),
+ Control::get_theme_icon("Vector2i", "EditorIcons"),
+ Control::get_theme_icon("Rect2", "EditorIcons"),
+ Control::get_theme_icon("Rect2i", "EditorIcons"),
+ Control::get_theme_icon("Vector3", "EditorIcons"),
+ Control::get_theme_icon("Vector3i", "EditorIcons"),
+ Control::get_theme_icon("Transform2D", "EditorIcons"),
+ Control::get_theme_icon("Plane", "EditorIcons"),
+ Control::get_theme_icon("Quat", "EditorIcons"),
+ Control::get_theme_icon("AABB", "EditorIcons"),
+ Control::get_theme_icon("Basis", "EditorIcons"),
+ Control::get_theme_icon("Transform", "EditorIcons"),
+ Control::get_theme_icon("Color", "EditorIcons"),
+ Control::get_theme_icon("NodePath", "EditorIcons"),
+ Control::get_theme_icon("RID", "EditorIcons"),
+ Control::get_theme_icon("MiniObject", "EditorIcons"),
+ Control::get_theme_icon("Callable", "EditorIcons"),
+ Control::get_theme_icon("Signal", "EditorIcons"),
+ Control::get_theme_icon("Dictionary", "EditorIcons"),
+ Control::get_theme_icon("Array", "EditorIcons"),
+ Control::get_theme_icon("PackedByteArray", "EditorIcons"),
+ Control::get_theme_icon("PackedInt32Array", "EditorIcons"),
+ Control::get_theme_icon("PackedFloat32Array", "EditorIcons"),
+ Control::get_theme_icon("PackedStringArray", "EditorIcons"),
+ Control::get_theme_icon("PackedVector2Array", "EditorIcons"),
+ Control::get_theme_icon("PackedVector3Array", "EditorIcons"),
+ Control::get_theme_icon("PackedColorArray", "EditorIcons")
};
List<StringName> var_names;
@@ -1005,8 +1033,8 @@ void VisualScriptEditor::_update_members() {
TreeItem *_signals = members->create_item(root);
_signals->set_selectable(0, false);
_signals->set_text(0, TTR("Signals:"));
- _signals->add_button(0, Control::get_icon("Add", "EditorIcons"), -1, false, TTR("Create a new signal."));
- _signals->set_custom_color(0, Control::get_color("mono_color", "Editor"));
+ _signals->add_button(0, Control::get_theme_icon("Add", "EditorIcons"), -1, false, TTR("Create a new signal."));
+ _signals->set_custom_color(0, Control::get_theme_color("mono_color", "Editor"));
List<StringName> signal_names;
script->get_custom_signal_list(&signal_names);
@@ -1022,12 +1050,12 @@ void VisualScriptEditor::_update_members() {
String base_type = script->get_instance_base_type();
String icon_type = base_type;
- if (!Control::has_icon(base_type, "EditorIcons")) {
+ if (!Control::has_theme_icon(base_type, "EditorIcons")) {
icon_type = "Object";
}
base_type_select->set_text(base_type);
- base_type_select->set_icon(Control::get_icon(icon_type, "EditorIcons"));
+ base_type_select->set_icon(Control::get_theme_icon(icon_type, "EditorIcons"));
updating_members = false;
}
@@ -1045,9 +1073,9 @@ void VisualScriptEditor::_member_selected() {
if (ti->get_parent() == members->get_root()->get_children()) {
#ifdef OSX_ENABLED
- bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_META);
+ bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_META);
#else
- bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
if (held_ctrl) {
ERR_FAIL_COND(!script->has_function(selected));
@@ -1143,6 +1171,8 @@ void VisualScriptEditor::_member_edited() {
undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name);
undo_redo->add_do_method(this, "_update_members");
undo_redo->add_undo_method(this, "_update_members");
+ undo_redo->add_do_method(this, "_update_graph");
+ undo_redo->add_undo_method(this, "_update_graph");
undo_redo->add_do_method(this, "emit_signal", "edited_script_changed");
undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed");
undo_redo->commit_action();
@@ -1225,7 +1255,7 @@ void VisualScriptEditor::_add_func_input() {
LineEdit *name_box = memnew(LineEdit);
name_box->set_h_size_flags(SIZE_EXPAND_FILL);
name_box->set_text("input");
- name_box->connect("focus_entered", this, "_deselect_input_names");
+ name_box->connect("focus_entered", callable_mp(this, &VisualScriptEditor::_deselect_input_names));
hbox->add_child(name_box);
Label *type_label = memnew(Label);
@@ -1240,7 +1270,7 @@ void VisualScriptEditor::_add_func_input() {
hbox->add_child(type_box);
Button *delete_button = memnew(Button);
- delete_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Remove", "EditorIcons"));
+ delete_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
delete_button->set_tooltip(vformat(TTR("Delete input port")));
hbox->add_child(delete_button);
@@ -1250,9 +1280,9 @@ void VisualScriptEditor::_add_func_input() {
}
func_input_vbox->add_child(hbox);
- hbox->set_meta("id", hbox->get_position_in_parent());
+ hbox->set_meta("id", hbox->get_index());
- delete_button->connect("pressed", this, "_remove_func_input", varray(hbox));
+ delete_button->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_func_input), varray(hbox));
name_box->select_all();
name_box->grab_focus();
@@ -1348,7 +1378,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
}
} else if (ti->get_parent() == root->get_children()) {
selected = ti->get_text(0);
- function_name_edit->set_position(Input::get_singleton()->get_mouse_position() - Vector2(60, -10));
+ function_name_edit->set_position(InputFilter::get_singleton()->get_mouse_position() - Vector2(60, -10));
function_name_edit->popup();
function_name_box->set_text(selected);
function_name_box->select_all();
@@ -1446,7 +1476,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
List<VisualScript::DataConnection> data_connections;
script->get_data_connection_list(func, &data_connections);
- HashMap<int, Set<int> > conn_map;
+ HashMap<int, Set<int>> conn_map;
for (const List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id && E->get().from_port == p_port) {
// push into the connections map
@@ -1710,7 +1740,7 @@ void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> key = p_event;
if (key.is_valid() && !key->is_pressed()) {
- mouse_up_position = Input::get_singleton()->get_mouse_position();
+ mouse_up_position = InputFilter::get_singleton()->get_mouse_position();
}
}
@@ -1720,7 +1750,7 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
if (key.is_valid() && key->is_pressed() && key->get_button_mask() == BUTTON_RIGHT) {
saved_position = graph->get_local_mouse_position();
- Point2 gpos = Input::get_singleton()->get_mouse_position();
+ Point2 gpos = InputFilter::get_singleton()->get_mouse_position();
_generic_search(script->get_instance_base_type(), gpos);
}
}
@@ -1820,7 +1850,7 @@ void VisualScriptEditor::_fn_name_box_input(const Ref<InputEvent> &p_event) {
return;
Ref<InputEventKey> key = p_event;
- if (key.is_valid() && key->is_pressed() && key->get_scancode() == KEY_ENTER) {
+ if (key.is_valid() && key->is_pressed() && key->get_keycode() == KEY_ENTER) {
function_name_edit->hide();
_rename_function(selected, function_name_box->get_text());
function_name_box->clear();
@@ -1920,7 +1950,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
- return NULL;
+ return nullptr;
Ref<Script> scr = p_current_node->get_script();
@@ -1933,7 +1963,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
return n;
}
- return NULL;
+ return nullptr;
}
void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
@@ -1974,9 +2004,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
if (String(d["type"]) == "visual_script_variable_drag") {
#ifdef OSX_ENABLED
- bool use_set = Input::get_singleton()->is_key_pressed(KEY_META);
+ bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_META);
#else
- bool use_set = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
Vector2 ofs = graph->get_scroll_ofs() + p_point;
if (graph->is_using_snap()) {
@@ -2169,9 +2199,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
#ifdef OSX_ENABLED
- bool use_node = Input::get_singleton()->is_key_pressed(KEY_META);
+ bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_META);
#else
- bool use_node = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
Array nodes = d["nodes"];
@@ -2233,7 +2263,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
- if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (!sn && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name()));
return;
}
@@ -2253,12 +2283,12 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
ofs /= EDSCALE;
#ifdef OSX_ENABLED
- bool use_get = Input::get_singleton()->is_key_pressed(KEY_META);
+ bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_META);
#else
- bool use_get = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
- if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (!node || InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
if (use_get)
undo_redo->create_action(TTR("Add Getter Property"));
@@ -2365,11 +2395,11 @@ void VisualScriptEditor::_draw_color_over_button(Object *obj, Color p_color) {
if (!button)
return;
- Ref<StyleBox> normal = get_stylebox("normal", "Button");
+ Ref<StyleBox> normal = get_theme_stylebox("normal", "Button");
button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color);
}
-void VisualScriptEditor::_button_resource_previewed(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, Variant p_ud) {
+void VisualScriptEditor::_button_resource_previewed(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud) {
Array ud = p_ud;
ERR_FAIL_COND(ud.size() != 2);
@@ -2408,7 +2438,7 @@ void VisualScriptEditor::set_edited_resource(const RES &p_res) {
variable_editor->script = script;
variable_editor->undo_redo = undo_redo;
- script->connect("node_ports_changed", this, "_node_ports_changed");
+ script->connect("node_ports_changed", callable_mp(this, &VisualScriptEditor::_node_ports_changed));
default_func = script->get_default_func();
@@ -2447,9 +2477,9 @@ String VisualScriptEditor::get_name() {
return name;
}
-Ref<Texture> VisualScriptEditor::get_icon() {
+Ref<Texture2D> VisualScriptEditor::get_theme_icon() {
- return Control::get_icon("VisualScript", "EditorIcons");
+ return Control::get_theme_icon("VisualScript", "EditorIcons");
}
bool VisualScriptEditor::is_unsaved() {
@@ -2585,7 +2615,7 @@ void VisualScriptEditor::get_breakpoints(List<int> *p_breakpoints) {
}
}
-void VisualScriptEditor::add_callback(const String &p_function, PoolStringArray p_args) {
+void VisualScriptEditor::add_callback(const String &p_function, PackedStringArray p_args) {
if (script->has_function(p_function)) {
_update_members();
@@ -2910,8 +2940,8 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
if (to_type != Variant::NIL && from_type != Variant::NIL && to_type != from_type) {
// add a constructor node between the ports
bool exceptions = false; // true if there are any exceptions
- exceptions = exceptions || (to_type == Variant::INT && from_type == Variant::REAL);
- exceptions = exceptions || (to_type == Variant::REAL && from_type == Variant::INT);
+ exceptions = exceptions || (to_type == Variant::INT && from_type == Variant::FLOAT);
+ exceptions = exceptions || (to_type == Variant::FLOAT && from_type == Variant::INT);
if (Variant::can_convert(from_type, to_type) && !exceptions) {
MethodInfo mi;
mi.name = Variant::get_type_name(to_type);
@@ -3066,8 +3096,8 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl
void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id) {
Set<int> nodes_to_move;
- HashMap<int, Map<int, int> > seqconns_to_move; // from => List(outp, to)
- HashMap<int, Map<int, Pair<int, int> > > dataconns_to_move; // to => List(inp_p => from, outp)
+ HashMap<int, Map<int, int>> seqconns_to_move; // from => List(outp, to)
+ HashMap<int, Map<int, Pair<int, int>>> dataconns_to_move; // to => List(inp_p => from, outp)
nodes_to_move.insert(p_id);
Set<int> sequence_connections;
@@ -3075,7 +3105,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
List<VisualScript::SequenceConnection> sequence_conns;
script->get_sequence_connection_list(p_func_from, &sequence_conns);
- HashMap<int, Map<int, int> > seqcons; // from => List(out_p => to)
+ HashMap<int, Map<int, int>> seqcons; // from => List(out_p => to)
for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
int from = E->get().from_node;
@@ -3090,7 +3120,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
int conn = p_id;
List<int> stack;
- HashMap<int, Set<int> > seen; // from, outp
+ HashMap<int, Set<int>> seen; // from, outp
while (seqcons.has(conn)) {
for (auto E = seqcons[conn].front(); E; E = E->next()) {
if (seen.has(conn) && seen[conn].has(E->key())) {
@@ -3127,7 +3157,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
List<VisualScript::DataConnection> data_connections;
script->get_data_connection_list(p_func_from, &data_connections);
- HashMap<int, Map<int, Pair<int, int> > > connections;
+ HashMap<int, Map<int, Pair<int, int>>> connections;
for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
int from = E->get().from_node;
@@ -3136,14 +3166,14 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
int in_p = E->get().to_port;
if (!connections.has(to))
- connections.set(to, Map<int, Pair<int, int> >());
+ connections.set(to, Map<int, Pair<int, int>>());
connections[to].insert(in_p, Pair<int, int>(from, out_p));
}
// go through the HashMap and do all sorts of crazy ass stuff now...
Set<int> nodes_to_be_added;
for (Set<int>::Element *F = nodes_to_move.front(); F; F = F->next()) {
- HashMap<int, Set<int> > seen;
+ HashMap<int, Set<int>> seen;
List<int> stack;
int id = F->get();
while (connections.has(id)) {
@@ -3178,7 +3208,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
seen[id].insert(E->key());
stack.push_back(id);
if (!dataconns_to_move.has(id))
- dataconns_to_move.set(id, Map<int, Pair<int, int> >());
+ dataconns_to_move.set(id, Map<int, Pair<int, int>>());
dataconns_to_move[id].insert(E->key(), Pair<int, int>(E->get().first, E->get().second));
id = E->get().first;
nodes_to_be_added.insert(id);
@@ -3249,7 +3279,7 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
dataconns_to_move.get_key_list(&keys);
for (List<int>::Element *E = keys.front(); E; E = E->next()) {
int to_node = E->get(); // to_node
- for (Map<int, Pair<int, int> >::Element *F = dataconns_to_move[E->get()].front(); F; F = F->next()) {
+ for (Map<int, Pair<int, int>>::Element *F = dataconns_to_move[E->get()].front(); F; F = F->next()) {
int inp_p = F->key();
Pair<int, int> fro = F->get();
@@ -3435,7 +3465,7 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua
undo_redo->create_action(TTR("Connect Node Data"));
VisualScriptReturn *vnode_return = Object::cast_to<VisualScriptReturn>(vnode.ptr());
- if (vnode_return != NULL && vnode_old->get_output_value_port_count() > 0) {
+ if (vnode_return != nullptr && vnode_old->get_output_value_port_count() > 0) {
vnode_return->set_enable_return_value(true);
}
if (vnode_old->get_output_value_port_count() <= 0) {
@@ -3701,11 +3731,11 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id) {
VisualScriptOperator *vnode_operator = Object::cast_to<VisualScriptOperator>(vnode_new.ptr());
- if (vnode_operator != NULL && !vnode_operator->has_input_sequence_port()) {
+ if (vnode_operator != nullptr && !vnode_operator->has_input_sequence_port()) {
return;
}
VisualScriptConstructor *vnode_constructor = Object::cast_to<VisualScriptConstructor>(vnode_new.ptr());
- if (vnode_constructor != NULL) {
+ if (vnode_constructor != nullptr) {
return;
}
if (vnode_old->get_output_sequence_port_count() <= 0) {
@@ -3851,7 +3881,7 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
Variant existing = vsn->get_default_input_value(p_input_port);
if (pinfo.type != Variant::NIL && existing.get_type() != pinfo.type) {
- Variant::CallError ce;
+ Callable::CallError ce;
const Variant *existingp = &existing;
existing = Variant::construct(pinfo.type, &existingp, 1, ce, false);
}
@@ -3877,7 +3907,7 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
}
}
- if (default_value_edit->edit(NULL, pinfo.name, pinfo.type, existing, pinfo.hint, pinfo.hint_string)) {
+ if (default_value_edit->edit(nullptr, pinfo.name, pinfo.type, existing, pinfo.hint, pinfo.hint_string)) {
if (pinfo.hint == PROPERTY_HINT_MULTILINE_TEXT)
default_value_edit->popup_centered_ratio();
else
@@ -3904,24 +3934,26 @@ void VisualScriptEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- variable_editor->connect("changed", this, "_update_members");
- signal_editor->connect("changed", this, "_update_members");
- FALLTHROUGH;
+ variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members));
+ variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED);
+ signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members));
+ signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED);
+ [[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
if (p_what != NOTIFICATION_READY && !is_visible_in_tree()) {
return;
}
- edit_variable_edit->add_style_override("bg", get_stylebox("bg", "Tree"));
- edit_signal_edit->add_style_override("bg", get_stylebox("bg", "Tree"));
- func_input_scroll->add_style_override("bg", get_stylebox("bg", "Tree"));
+ edit_variable_edit->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
+ edit_signal_edit->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
+ func_input_scroll->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
Ref<Theme> tm = EditorNode::get_singleton()->get_theme_base()->get_theme();
bool dark_theme = tm->get_constant("dark_theme", "Editor");
- List<Pair<String, Color> > colors;
+ List<Pair<String, Color>> colors;
if (dark_theme) {
colors.push_back(Pair<String, Color>("flow_control", Color(0.96, 0.96, 0.96)));
colors.push_back(Pair<String, Color>("functions", Color(0.96, 0.52, 0.51)));
@@ -3938,7 +3970,7 @@ void VisualScriptEditor::_notification(int p_what) {
colors.push_back(Pair<String, Color>("constants", Color(0.94, 0.18, 0.49)));
}
- for (List<Pair<String, Color> >::Element *E = colors.front(); E; E = E->next()) {
+ for (List<Pair<String, Color>>::Element *E = colors.front(); E; E = E->next()) {
Ref<StyleBoxFlat> sb = tm->get_stylebox("frame", "GraphNode");
if (!sb.is_null()) {
Ref<StyleBoxFlat> frame_style = sb->duplicate();
@@ -4137,7 +4169,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
}
- for (Map<int, Ref<VisualScriptNode> >::Element *E = clipboard->nodes.front(); E; E = E->next()) {
+ for (Map<int, Ref<VisualScriptNode>>::Element *E = clipboard->nodes.front(); E; E = E->next()) {
Ref<VisualScriptNode> node = E->get()->duplicate();
@@ -4184,7 +4216,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
case EDIT_CREATE_FUNCTION: {
StringName function = "";
- Map<int, Ref<VisualScriptNode> > nodes;
+ Map<int, Ref<VisualScriptNode>> nodes;
Set<int> selections;
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
@@ -4240,7 +4272,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
// the user wants to connect the nodes
int top_nd = -1;
Vector2 top;
- for (Map<int, Ref<VisualScriptNode> >::Element *E = nodes.front(); E; E = E->next()) {
+ for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) {
Ref<VisualScriptNode> nd = script->get_node(function, E->key());
if (nd.is_valid() && nd->has_input_sequence_port()) {
if (top_nd < 0) {
@@ -4304,7 +4336,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
List<Variant::Type> inputs; // input types
- List<Pair<int, int> > input_connections;
+ List<Pair<int, int>> input_connections;
{
List<VisualScript::DataConnection> dats;
script->get_data_connection_list(function, &dats);
@@ -4347,7 +4379,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
// Move the nodes
- for (Map<int, Ref<VisualScriptNode> >::Element *E = nodes.front(); E; E = E->next()) {
+ for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) {
undo_redo->add_do_method(script.ptr(), "remove_node", function, E->key());
undo_redo->add_do_method(script.ptr(), "add_node", new_fn, E->key(), E->get(), script->get_node_position(function, E->key()));
@@ -4402,7 +4434,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
// * might make the system more intelligent by checking port from info.
int i = 0;
- List<Pair<int, int> >::Element *F = input_connections.front();
+ List<Pair<int, int>>::Element *F = input_connections.front();
for (List<Variant::Type>::Element *E = inputs.front(); E && F; E = E->next(), F = F->next()) {
func_node->add_argument(E->get(), "arg_" + String::num_int64(i), i);
undo_redo->add_do_method(script.ptr(), "data_connect", new_fn, fn_id, i, F->get().first, F->get().second);
@@ -4467,9 +4499,9 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) {
TreeItem *root = members->get_root();
- Ref<Texture> del_icon = Control::get_icon("Remove", "EditorIcons");
+ Ref<Texture2D> del_icon = Control::get_theme_icon("Remove", "EditorIcons");
- Ref<Texture> edit_icon = Control::get_icon("Edit", "EditorIcons");
+ Ref<Texture2D> edit_icon = Control::get_theme_icon("Edit", "EditorIcons");
if (ti->get_parent() == root->get_children()) {
@@ -4566,7 +4598,7 @@ void VisualScriptEditor::_member_option(int p_option) {
} else if (p_option == MEMBER_EDIT) {
variable_editor->edit(name);
edit_variable_dialog->set_title(TTR("Editing Variable:") + " " + name);
- edit_variable_dialog->popup_centered_minsize(Size2(400, 200) * EDSCALE);
+ edit_variable_dialog->popup_centered(Size2(400, 200) * EDSCALE);
}
} break;
case MEMBER_SIGNAL: {
@@ -4587,7 +4619,7 @@ void VisualScriptEditor::_member_option(int p_option) {
} else if (p_option == MEMBER_EDIT) {
signal_editor->edit(name);
edit_signal_dialog->set_title(TTR("Editing Signal:") + " " + name);
- edit_signal_dialog->popup_centered_minsize(Size2(400, 300) * EDSCALE);
+ edit_signal_dialog->popup_centered(Size2(400, 300) * EDSCALE);
}
} break;
}
@@ -4601,76 +4633,23 @@ void VisualScriptEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter
void VisualScriptEditor::_bind_methods() {
- ClassDB::bind_method("_member_button", &VisualScriptEditor::_member_button);
- ClassDB::bind_method("_member_edited", &VisualScriptEditor::_member_edited);
- ClassDB::bind_method("_member_selected", &VisualScriptEditor::_member_selected);
- ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members);
- ClassDB::bind_method("_members_gui_input", &VisualScriptEditor::_members_gui_input);
- ClassDB::bind_method("_member_rmb_selected", &VisualScriptEditor::_member_rmb_selected);
- ClassDB::bind_method("_member_option", &VisualScriptEditor::_member_option);
- ClassDB::bind_method("_fn_name_box_input", &VisualScriptEditor::_fn_name_box_input);
-
- ClassDB::bind_method("_change_base_type", &VisualScriptEditor::_change_base_type);
- ClassDB::bind_method("_change_base_type_callback", &VisualScriptEditor::_change_base_type_callback);
- ClassDB::bind_method("_toggle_tool_script", &VisualScriptEditor::_toggle_tool_script);
- ClassDB::bind_method("_node_selected", &VisualScriptEditor::_node_selected);
- ClassDB::bind_method("_node_moved", &VisualScriptEditor::_node_moved);
ClassDB::bind_method("_move_node", &VisualScriptEditor::_move_node);
- ClassDB::bind_method("_begin_node_move", &VisualScriptEditor::_begin_node_move);
- ClassDB::bind_method("_end_node_move", &VisualScriptEditor::_end_node_move);
- ClassDB::bind_method("_remove_node", &VisualScriptEditor::_remove_node);
ClassDB::bind_method("_update_graph", &VisualScriptEditor::_update_graph, DEFVAL(-1));
- ClassDB::bind_method("_node_ports_changed", &VisualScriptEditor::_node_ports_changed);
-
- ClassDB::bind_method("_create_function_dialog", &VisualScriptEditor::_create_function_dialog);
- ClassDB::bind_method("_create_function", &VisualScriptEditor::_create_function);
- ClassDB::bind_method("_add_node_dialog", &VisualScriptEditor::_add_node_dialog);
- ClassDB::bind_method("_add_func_input", &VisualScriptEditor::_add_func_input);
- ClassDB::bind_method("_remove_func_input", &VisualScriptEditor::_remove_func_input);
- ClassDB::bind_method("_deselect_input_names", &VisualScriptEditor::_deselect_input_names);
-
- ClassDB::bind_method("_default_value_edited", &VisualScriptEditor::_default_value_edited);
- ClassDB::bind_method("_default_value_changed", &VisualScriptEditor::_default_value_changed);
- ClassDB::bind_method("_menu_option", &VisualScriptEditor::_menu_option);
- ClassDB::bind_method("_graph_ofs_changed", &VisualScriptEditor::_graph_ofs_changed);
+
ClassDB::bind_method("_center_on_node", &VisualScriptEditor::_center_on_node);
- ClassDB::bind_method("_comment_node_resized", &VisualScriptEditor::_comment_node_resized);
ClassDB::bind_method("_button_resource_previewed", &VisualScriptEditor::_button_resource_previewed);
ClassDB::bind_method("_port_action_menu", &VisualScriptEditor::_port_action_menu);
- ClassDB::bind_method("_selected_connect_node", &VisualScriptEditor::_selected_connect_node);
- ClassDB::bind_method("_selected_new_virtual_method", &VisualScriptEditor::_selected_new_virtual_method);
- ClassDB::bind_method("_cancel_connect_node", &VisualScriptEditor::_cancel_connect_node);
ClassDB::bind_method("_create_new_node_from_name", &VisualScriptEditor::_create_new_node_from_name);
- ClassDB::bind_method("_expression_text_changed", &VisualScriptEditor::_expression_text_changed);
- ClassDB::bind_method("_add_input_port", &VisualScriptEditor::_add_input_port);
- ClassDB::bind_method("_add_output_port", &VisualScriptEditor::_add_output_port);
- ClassDB::bind_method("_remove_input_port", &VisualScriptEditor::_remove_input_port);
- ClassDB::bind_method("_remove_output_port", &VisualScriptEditor::_remove_output_port);
- ClassDB::bind_method("_change_port_type", &VisualScriptEditor::_change_port_type);
- ClassDB::bind_method("_update_node_size", &VisualScriptEditor::_update_node_size);
- ClassDB::bind_method("_port_name_focus_out", &VisualScriptEditor::_port_name_focus_out);
ClassDB::bind_method("get_drag_data_fw", &VisualScriptEditor::get_drag_data_fw);
ClassDB::bind_method("can_drop_data_fw", &VisualScriptEditor::can_drop_data_fw);
ClassDB::bind_method("drop_data_fw", &VisualScriptEditor::drop_data_fw);
ClassDB::bind_method("_input", &VisualScriptEditor::_input);
- ClassDB::bind_method("_graph_gui_input", &VisualScriptEditor::_graph_gui_input);
-
- ClassDB::bind_method("_on_nodes_delete", &VisualScriptEditor::_on_nodes_delete);
- ClassDB::bind_method("_on_nodes_duplicate", &VisualScriptEditor::_on_nodes_duplicate);
-
- ClassDB::bind_method("_hide_timer", &VisualScriptEditor::_hide_timer);
-
- ClassDB::bind_method("_graph_connected", &VisualScriptEditor::_graph_connected);
- ClassDB::bind_method("_graph_disconnected", &VisualScriptEditor::_graph_disconnected);
- ClassDB::bind_method("_graph_connect_to_empty", &VisualScriptEditor::_graph_connect_to_empty);
ClassDB::bind_method("_update_graph_connections", &VisualScriptEditor::_update_graph_connections);
-
- ClassDB::bind_method("_selected_method", &VisualScriptEditor::_selected_method);
- ClassDB::bind_method("_draw_color_over_button", &VisualScriptEditor::_draw_color_over_button);
+ ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members);
ClassDB::bind_method("_generic_search", &VisualScriptEditor::_generic_search);
}
@@ -4697,7 +4676,7 @@ VisualScriptEditor::VisualScriptEditor() {
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/create_function"), EDIT_CREATE_FUNCTION);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/refresh_nodes"), REFRESH_GRAPH);
- edit_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+ edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_menu_option));
members_section = memnew(VBoxContainer);
// Add but wait until done setting up this.
@@ -4707,7 +4686,7 @@ VisualScriptEditor::VisualScriptEditor() {
CheckButton *tool_script_check = memnew(CheckButton);
tool_script_check->set_text(TTR("Make Tool:"));
members_section->add_child(tool_script_check);
- tool_script_check->connect("pressed", this, "_toggle_tool_script");
+ tool_script_check->connect("pressed", callable_mp(this, &VisualScriptEditor::_toggle_tool_script));
/// Members ///
@@ -4715,11 +4694,11 @@ VisualScriptEditor::VisualScriptEditor() {
members_section->add_margin_child(TTR("Members:"), members, true);
members->set_custom_minimum_size(Size2(0, 50 * EDSCALE));
members->set_hide_root(true);
- members->connect("button_pressed", this, "_member_button");
- members->connect("item_edited", this, "_member_edited");
- members->connect("cell_selected", this, "_member_selected", varray(), CONNECT_DEFERRED);
- members->connect("gui_input", this, "_members_gui_input");
- members->connect("item_rmb_selected", this, "_member_rmb_selected");
+ members->connect("button_pressed", callable_mp(this, &VisualScriptEditor::_member_button));
+ members->connect("item_edited", callable_mp(this, &VisualScriptEditor::_member_edited));
+ members->connect("cell_selected", callable_mp(this, &VisualScriptEditor::_member_selected), varray(), CONNECT_DEFERRED);
+ members->connect("gui_input", callable_mp(this, &VisualScriptEditor::_members_gui_input));
+ members->connect("item_rmb_selected", callable_mp(this, &VisualScriptEditor::_member_rmb_selected));
members->set_allow_rmb_select(true);
members->set_allow_reselect(true);
members->set_hide_folding(true);
@@ -4727,13 +4706,12 @@ VisualScriptEditor::VisualScriptEditor() {
member_popup = memnew(PopupMenu);
add_child(member_popup);
- member_popup->connect("id_pressed", this, "_member_option");
+ member_popup->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_member_option));
- function_name_edit = memnew(PopupDialog);
+ function_name_edit = memnew(AcceptDialog);
function_name_box = memnew(LineEdit);
function_name_edit->add_child(function_name_box);
- function_name_edit->set_h_size_flags(SIZE_EXPAND);
- function_name_box->connect("gui_input", this, "_fn_name_box_input");
+ function_name_box->connect("gui_input", callable_mp(this, &VisualScriptEditor::_fn_name_box_input));
function_name_box->set_expand_to_text_length(true);
add_child(function_name_edit);
@@ -4743,15 +4721,15 @@ VisualScriptEditor::VisualScriptEditor() {
add_child(graph);
graph->set_v_size_flags(Control::SIZE_EXPAND_FILL);
graph->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- graph->connect("node_selected", this, "_node_selected");
- graph->connect("_begin_node_move", this, "_begin_node_move");
- graph->connect("_end_node_move", this, "_end_node_move");
- graph->connect("delete_nodes_request", this, "_on_nodes_delete");
- graph->connect("duplicate_nodes_request", this, "_on_nodes_duplicate");
- graph->connect("gui_input", this, "_graph_gui_input");
+ graph->connect("node_selected", callable_mp(this, &VisualScriptEditor::_node_selected));
+ graph->connect("_begin_node_move", callable_mp(this, &VisualScriptEditor::_begin_node_move));
+ graph->connect("_end_node_move", callable_mp(this, &VisualScriptEditor::_end_node_move));
+ graph->connect("delete_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_delete));
+ graph->connect("duplicate_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_duplicate));
+ graph->connect("gui_input", callable_mp(this, &VisualScriptEditor::_graph_gui_input));
graph->set_drag_forwarding(this);
graph->hide();
- graph->connect("scroll_offset_changed", this, "_graph_ofs_changed");
+ graph->connect("scroll_offset_changed", callable_mp(this, &VisualScriptEditor::_graph_ofs_changed));
/// Add Buttons to Top Bar/Zoom bar.
HBoxContainer *graph_hbc = graph->get_zoom_hbox();
@@ -4761,18 +4739,18 @@ VisualScriptEditor::VisualScriptEditor() {
graph_hbc->add_child(base_lbl);
base_type_select = memnew(Button);
- base_type_select->connect("pressed", this, "_change_base_type");
+ base_type_select->connect("pressed", callable_mp(this, &VisualScriptEditor::_change_base_type));
graph_hbc->add_child(base_type_select);
Button *add_nds = memnew(Button);
add_nds->set_text(TTR("Add Nodes..."));
graph_hbc->add_child(add_nds);
- add_nds->connect("pressed", this, "_add_node_dialog");
+ add_nds->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_node_dialog));
Button *fn_btn = memnew(Button);
fn_btn->set_text(TTR("Add Function..."));
graph_hbc->add_child(fn_btn);
- fn_btn->connect("pressed", this, "_create_function_dialog");
+ fn_btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_create_function_dialog));
// Add Function Dialog.
VBoxContainer *function_vb = memnew(VBoxContainer);
@@ -4790,7 +4768,7 @@ VisualScriptEditor::VisualScriptEditor() {
func_name_box->set_h_size_flags(SIZE_EXPAND_FILL);
func_name_box->set_placeholder(TTR("function_name"));
func_name_box->set_text("");
- func_name_box->connect("focus_entered", this, "_deselect_input_names");
+ func_name_box->connect("focus_entered", callable_mp(this, &VisualScriptEditor::_deselect_input_names));
func_name_hbox->add_child(func_name_box);
// Add minor setting for function if needed, here!
@@ -4800,7 +4778,7 @@ VisualScriptEditor::VisualScriptEditor() {
Button *add_input_button = memnew(Button);
add_input_button->set_h_size_flags(SIZE_EXPAND_FILL);
add_input_button->set_text(TTR("Add Input"));
- add_input_button->connect("pressed", this, "_add_func_input");
+ add_input_button->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_func_input));
function_vb->add_child(add_input_button);
func_input_scroll = memnew(ScrollContainer);
@@ -4812,11 +4790,10 @@ VisualScriptEditor::VisualScriptEditor() {
func_input_scroll->add_child(func_input_vbox);
function_create_dialog = memnew(ConfirmationDialog);
- function_create_dialog->set_v_size_flags(SIZE_EXPAND_FILL);
function_create_dialog->set_title(TTR("Create Function"));
function_create_dialog->add_child(function_vb);
function_create_dialog->get_ok()->set_text(TTR("Create"));
- function_create_dialog->get_ok()->connect("pressed", this, "_create_function");
+ function_create_dialog->get_ok()->connect("pressed", callable_mp(this, &VisualScriptEditor::_create_function));
add_child(function_create_dialog);
select_func_text = memnew(Label);
@@ -4836,7 +4813,7 @@ VisualScriptEditor::VisualScriptEditor() {
hint_text_timer = memnew(Timer);
hint_text_timer->set_wait_time(4);
- hint_text_timer->connect("timeout", this, "_hide_timer");
+ hint_text_timer->connect("timeout", callable_mp(this, &VisualScriptEditor::_hide_timer));
add_child(hint_text_timer);
// Allowed casts (connections).
@@ -4854,9 +4831,9 @@ VisualScriptEditor::VisualScriptEditor() {
graph->add_valid_left_disconnect_type(TYPE_SEQUENCE);
- graph->connect("connection_request", this, "_graph_connected");
- graph->connect("disconnection_request", this, "_graph_disconnected");
- graph->connect("connection_to_empty", this, "_graph_connect_to_empty");
+ graph->connect("connection_request", callable_mp(this, &VisualScriptEditor::_graph_connected));
+ graph->connect("disconnection_request", callable_mp(this, &VisualScriptEditor::_graph_disconnected));
+ graph->connect("connection_to_empty", callable_mp(this, &VisualScriptEditor::_graph_connect_to_empty));
edit_signal_dialog = memnew(AcceptDialog);
edit_signal_dialog->get_ok()->set_text(TTR("Close"));
@@ -4880,7 +4857,7 @@ VisualScriptEditor::VisualScriptEditor() {
select_base_type = memnew(CreateDialog);
select_base_type->set_base_type("Object"); // Anything goes.
- select_base_type->connect("create", this, "_change_base_type_callback");
+ select_base_type->connect("create", callable_mp(this, &VisualScriptEditor::_change_base_type_callback));
add_child(select_base_type);
undo_redo = EditorNode::get_singleton()->get_undo_redo();
@@ -4892,22 +4869,21 @@ VisualScriptEditor::VisualScriptEditor() {
default_value_edit = memnew(CustomPropertyEditor);
add_child(default_value_edit);
- default_value_edit->connect("variant_changed", this, "_default_value_changed");
+ default_value_edit->connect("variant_changed", callable_mp(this, &VisualScriptEditor::_default_value_changed));
method_select = memnew(VisualScriptPropertySelector);
add_child(method_select);
- method_select->connect("selected", this, "_selected_method");
+ method_select->connect("selected", callable_mp(this, &VisualScriptEditor::_selected_method));
error_line = -1;
new_connect_node_select = memnew(VisualScriptPropertySelector);
add_child(new_connect_node_select);
- new_connect_node_select->set_resizable(true);
- new_connect_node_select->connect("selected", this, "_selected_connect_node");
- new_connect_node_select->get_cancel()->connect("pressed", this, "_cancel_connect_node");
+ new_connect_node_select->connect("selected", callable_mp(this, &VisualScriptEditor::_selected_connect_node));
+ new_connect_node_select->get_cancel()->connect("pressed", callable_mp(this, &VisualScriptEditor::_cancel_connect_node));
new_virtual_method_select = memnew(VisualScriptPropertySelector);
add_child(new_virtual_method_select);
- new_virtual_method_select->connect("selected", this, "_selected_new_virtual_method");
+ new_virtual_method_select->connect("selected", callable_mp(this, &VisualScriptEditor::_selected_new_virtual_method));
}
VisualScriptEditor::~VisualScriptEditor() {
@@ -4923,10 +4899,10 @@ static ScriptEditorBase *create_editor(const RES &p_resource) {
return memnew(VisualScriptEditor);
}
- return NULL;
+ return nullptr;
}
-VisualScriptEditor::Clipboard *VisualScriptEditor::clipboard = NULL;
+VisualScriptEditor::Clipboard *VisualScriptEditor::clipboard = nullptr;
void VisualScriptEditor::free_clipboard() {
if (clipboard)
@@ -4962,8 +4938,8 @@ Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_na
return node;
}
-_VisualScriptEditor *_VisualScriptEditor::singleton = NULL;
-Map<String, RefPtr> _VisualScriptEditor::custom_nodes;
+_VisualScriptEditor *_VisualScriptEditor::singleton = nullptr;
+Map<String, REF> _VisualScriptEditor::custom_nodes;
_VisualScriptEditor::_VisualScriptEditor() {
singleton = this;
@@ -4975,7 +4951,7 @@ _VisualScriptEditor::~_VisualScriptEditor() {
void _VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
String node_name = "custom/" + p_category + "/" + p_name;
- custom_nodes.insert(node_name, p_script.get_ref_ptr());
+ custom_nodes.insert(node_name, p_script);
VisualScriptLanguage::singleton->add_register_func(node_name, &_VisualScriptEditor::create_node_custom);
emit_signal("custom_nodes_updated");
}
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 7f3bf79d50..d9494e4d04 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -114,7 +114,7 @@ class VisualScriptEditor : public ScriptEditorBase {
UndoRedo *undo_redo;
Tree *members;
- PopupDialog *function_name_edit;
+ AcceptDialog *function_name_edit;
LineEdit *function_name_box;
Label *hint_text;
@@ -133,10 +133,10 @@ class VisualScriptEditor : public ScriptEditorBase {
String name;
Variant::Type ret;
bool ret_variant;
- Vector<Pair<Variant::Type, String> > args;
+ Vector<Pair<Variant::Type, String>> args;
};
- HashMap<StringName, Ref<StyleBox> > node_styles;
+ HashMap<StringName, Ref<StyleBox>> node_styles;
StringName edited_func;
StringName default_func;
@@ -153,7 +153,7 @@ class VisualScriptEditor : public ScriptEditorBase {
struct Clipboard {
- Map<int, Ref<VisualScriptNode> > nodes;
+ Map<int, Ref<VisualScriptNode>> nodes;
Map<int, Vector2> nodes_positions;
Set<VisualScript::SequenceConnection> sequence_connections;
@@ -277,7 +277,7 @@ class VisualScriptEditor : public ScriptEditorBase {
void _selected_method(const String &p_method, const String &p_type, const bool p_connecting);
void _draw_color_over_button(Object *obj, Color p_color);
- void _button_resource_previewed(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, Variant p_ud);
+ void _button_resource_previewed(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud);
VisualScriptNode::TypeGuess _guess_output_type(int p_port_action_node, int p_port_action_output, Set<int> &p_visited_nodes);
@@ -298,7 +298,7 @@ public:
virtual Vector<String> get_functions();
virtual void reload_text();
virtual String get_name();
- virtual Ref<Texture> get_icon();
+ virtual Ref<Texture2D> get_theme_icon();
virtual bool is_unsaved();
virtual Variant get_edit_state();
virtual void set_edit_state(const Variant &p_state);
@@ -313,7 +313,7 @@ public:
virtual void tag_saved_version();
virtual void reload(bool p_soft);
virtual void get_breakpoints(List<int> *p_breakpoints);
- virtual void add_callback(const String &p_function, PoolStringArray p_args);
+ virtual void add_callback(const String &p_function, PackedStringArray p_args);
virtual void update_settings();
virtual bool show_members_overview();
virtual void set_debugger_active(bool p_active);
@@ -341,7 +341,7 @@ protected:
static void _bind_methods();
static _VisualScriptEditor *singleton;
- static Map<String, RefPtr> custom_nodes;
+ static Map<String, REF> custom_nodes;
static Ref<VisualScriptNode> create_node_custom(const String &p_name);
public:
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index 4feef53c2e..71ed483d65 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -392,8 +392,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
case 'f': res = 12; break;
case 'r': res = 13; break;
case 'u': {
- //hexnumbarh - oct is deprecated
-
+ // hex number
for (int j = 0; j < 4; j++) {
CharType c = GET_CHAR();
@@ -418,7 +417,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
v = c - 'A';
v += 10;
} else {
- ERR_PRINT("BUG");
+ ERR_PRINT("Bug parsing hex constant.");
v = 0;
}
@@ -427,13 +426,8 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
}
} break;
- //case '\"': res='\"'; break;
- //case '\\': res='\\'; break;
- //case '/': res='/'; break;
default: {
res = next;
- //r_err_str="Invalid escape sequence";
- //return ERR_PARSE_ERROR;
} break;
}
@@ -658,12 +652,12 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
while (true) {
//keep appending stuff to expression
- ENode *expr = NULL;
+ ENode *expr = nullptr;
Token tk;
_get_token(tk);
if (error_set)
- return NULL;
+ return nullptr;
switch (tk.type) {
case TK_CURLY_BRACKET_OPEN: {
@@ -681,18 +675,18 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
//parse an expression
ENode *expr2 = _parse_expression();
if (!expr2)
- return NULL;
+ return nullptr;
dn->dict.push_back(expr2);
_get_token(tk);
if (tk.type != TK_COLON) {
_set_error("Expected ':'");
- return NULL;
+ return nullptr;
}
expr2 = _parse_expression();
if (!expr2)
- return NULL;
+ return nullptr;
dn->dict.push_back(expr2);
@@ -725,7 +719,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
//parse an expression
ENode *expr2 = _parse_expression();
if (!expr2)
- return NULL;
+ return nullptr;
an->array.push_back(expr2);
cofs = str_ofs;
@@ -745,11 +739,11 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
//a suexpression
ENode *e = _parse_expression();
if (error_set)
- return NULL;
+ return nullptr;
_get_token(tk);
if (tk.type != TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')'");
- return NULL;
+ return nullptr;
}
expr = e;
@@ -772,7 +766,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
expr = input;
} else {
_set_error("Invalid input identifier '" + what + "'. For script variables, use self (locals are for inputs)." + what);
- return NULL;
+ return nullptr;
}
} break;
case TK_SELF: {
@@ -792,7 +786,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
_get_token(tk);
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '('");
- return NULL;
+ return nullptr;
}
ConstructorNode *constructor = alloc_node<ConstructorNode>();
@@ -809,7 +803,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
//parse an expression
ENode *expr2 = _parse_expression();
if (!expr2)
- return NULL;
+ return nullptr;
constructor->arguments.push_back(expr2);
@@ -833,7 +827,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
_get_token(tk);
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '('");
- return NULL;
+ return nullptr;
}
BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>();
@@ -850,7 +844,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
//parse an expression
ENode *expr2 = _parse_expression();
if (!expr2)
- return NULL;
+ return nullptr;
bifunc->arguments.push_back(expr2);
@@ -892,7 +886,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
default: {
_set_error("Expected expression.");
- return NULL;
+ return nullptr;
} break;
}
@@ -902,7 +896,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
int cofs2 = str_ofs;
_get_token(tk);
if (error_set)
- return NULL;
+ return nullptr;
bool done = false;
@@ -915,14 +909,14 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
ENode *what = _parse_expression();
if (!what)
- return NULL;
+ return nullptr;
index->index = what;
_get_token(tk);
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']' at end of index.");
- return NULL;
+ return nullptr;
}
expr = index;
@@ -932,7 +926,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
_get_token(tk);
if (tk.type != TK_IDENTIFIER) {
_set_error("Expected identifier after '.'");
- return NULL;
+ return nullptr;
}
StringName identifier = tk.value;
@@ -956,7 +950,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
//parse an expression
ENode *expr2 = _parse_expression();
if (!expr2)
- return NULL;
+ return nullptr;
func_call->arguments.push_back(expr2);
@@ -1006,7 +1000,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
int cofs = str_ofs;
_get_token(tk);
if (error_set)
- return NULL;
+ return nullptr;
Variant::Operator op = Variant::OP_MAX;
@@ -1113,7 +1107,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
default: {
_set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op));
- return NULL;
+ return nullptr;
}
}
@@ -1130,7 +1124,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
if (next_op == -1) {
_set_error("Yet another parser bug....");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
// OK! create operator..
@@ -1143,17 +1137,17 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
if (expr_pos == expression.size()) {
//can happen..
_set_error("Unexpected end of expression...");
- return NULL;
+ return nullptr;
}
}
- //consecutively do unary opeators
+ //consecutively do unary operators
for (int i = expr_pos - 1; i >= next_op; i--) {
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
op->nodes[0] = expression[i + 1].node;
- op->nodes[1] = NULL;
+ op->nodes[1] = nullptr;
expression.write[i].is_op = false;
expression.write[i].node = op;
expression.remove(i + 1);
@@ -1163,7 +1157,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
OperatorNode *op = alloc_node<OperatorNode>();
@@ -1172,7 +1166,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
if (expression[next_op - 1].is_op) {
_set_error("Parser bug...");
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
if (expression[next_op + 1].is_op) {
@@ -1182,7 +1176,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
// due to how precedence works, unaries will always disappear first
_set_error("Unexpected two consecutive operators.");
- return NULL;
+ return nullptr;
}
op->nodes[0] = expression[next_op - 1].node; //expression goes as left
@@ -1205,8 +1199,8 @@ bool VisualScriptExpression::_compile_expression() {
if (nodes) {
memdelete(nodes);
- nodes = NULL;
- root = NULL;
+ nodes = nullptr;
+ root = nullptr;
}
error_str = String();
@@ -1216,11 +1210,11 @@ bool VisualScriptExpression::_compile_expression() {
root = _parse_expression();
if (error_set) {
- root = NULL;
+ root = nullptr;
if (nodes) {
memdelete(nodes);
}
- nodes = NULL;
+ nodes = nullptr;
return true;
}
@@ -1235,7 +1229,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
//execute by parsing the tree directly
- virtual bool _execute(const Variant **p_inputs, VisualScriptExpression::ENode *p_node, Variant &r_ret, String &r_error_str, Variant::CallError &ce) {
+ virtual bool _execute(const Variant **p_inputs, VisualScriptExpression::ENode *p_node, Variant &r_ret, String &r_error_str, Callable::CallError &ce) {
switch (p_node->type) {
case VisualScriptExpression::ENode::TYPE_INPUT: {
@@ -1377,7 +1371,7 @@ public:
r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = "Invalid arguments to construct '" + Variant::get_type_name(constructor->data_type) + "'.";
return true;
}
@@ -1404,7 +1398,7 @@ public:
VisualScriptBuiltinFunc::exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = "Builtin Call Failed. " + r_error_str;
return true;
}
@@ -1436,7 +1430,7 @@ public:
r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = "On call to '" + String(call->method) + "':";
return true;
}
@@ -1446,24 +1440,24 @@ public:
return false;
}
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (!expression->root || expression->error_set) {
r_error_str = expression->error_str;
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
bool error = _execute(p_inputs, expression->root, *p_outputs[0], r_error_str, r_error);
- if (error && r_error.error == Variant::CallError::CALL_OK) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ if (error && r_error.error == Callable::CallError::CALL_OK) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
#ifdef DEBUG_ENABLED
if (!error && expression->output_type != Variant::NIL && !Variant::can_convert_strict(p_outputs[0]->get_type(), expression->output_type)) {
r_error_str += "Can't convert expression result from " + Variant::get_type_name(p_outputs[0]->get_type()) + " to " + Variant::get_type_name(expression->output_type) + ".";
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
#endif
@@ -1484,8 +1478,8 @@ VisualScriptExpression::VisualScriptExpression() {
output_type = Variant::NIL;
expression_dirty = true;
error_set = true;
- root = NULL;
- nodes = NULL;
+ root = nullptr;
+ nodes = nullptr;
sequenced = false;
}
diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h
index d131713ef0..61b50ff99d 100644
--- a/modules/visual_script/visual_script_expression.h
+++ b/modules/visual_script/visual_script_expression.h
@@ -138,7 +138,7 @@ class VisualScriptExpression : public VisualScriptNode {
Type type;
- ENode() { next = NULL; }
+ ENode() { next = nullptr; }
virtual ~ENode() {
if (next) {
memdelete(next);
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index 213dc897af..475893e86d 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -135,7 +135,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (with_value) {
*p_working_mem = *p_inputs[0];
@@ -237,7 +237,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (p_start_mode == START_MODE_CONTINUE_SEQUENCE)
return 2;
@@ -323,7 +323,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
bool keep_going = p_inputs[0]->operator bool();
@@ -410,7 +410,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (p_start_mode == START_MODE_BEGIN_SEQUENCE) {
p_working_mem[0] = *p_inputs[0];
@@ -418,7 +418,7 @@ public:
bool can_iter = p_inputs[0]->iter_init(p_working_mem[1], valid);
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Input type not iterable: ") + Variant::get_type_name(p_inputs[0]->get_type());
return 0;
}
@@ -429,7 +429,7 @@ public:
*p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Iterator became invalid");
return 0;
}
@@ -440,7 +440,7 @@ public:
bool can_iter = p_working_mem[0].iter_next(p_working_mem[1], valid);
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Iterator became invalid: ") + Variant::get_type_name(p_inputs[0]->get_type());
return 0;
}
@@ -451,7 +451,7 @@ public:
*p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Iterator became invalid");
return 0;
}
@@ -549,7 +549,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (p_start_mode == START_MODE_BEGIN_SEQUENCE) {
@@ -645,7 +645,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (p_start_mode == START_MODE_CONTINUE_SEQUENCE) {
return case_count; //exit
@@ -836,14 +836,14 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
Object *obj = *p_inputs[0];
*p_outputs[0] = Variant();
if (!obj) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Instance is null";
return 0;
}
@@ -861,7 +861,7 @@ public:
}
Ref<Script> cast_script = Ref<Resource>(ResourceCache::get(script));
if (!cast_script.is_valid()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Script path is not a script: " + script;
return 1;
}
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 63c36ae431..3b6ae369ae 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -58,7 +58,7 @@ bool VisualScriptFunctionCall::has_input_sequence_port() const {
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
- return NULL;
+ return nullptr;
Ref<Script> scr = p_current_node->get_script();
@@ -71,7 +71,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
return n;
}
- return NULL;
+ return nullptr;
}
#endif
@@ -80,33 +80,33 @@ Node *VisualScriptFunctionCall::_get_base_node() const {
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
if (!script.is_valid())
- return NULL;
+ return nullptr;
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
if (!scene_tree)
- return NULL;
+ return nullptr;
Node *edited_scene = scene_tree->get_edited_scene_root();
if (!edited_scene)
- return NULL;
+ return nullptr;
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
if (!script_node)
- return NULL;
+ return nullptr;
if (!script_node->has_node(base_path))
- return NULL;
+ return nullptr;
Node *path_to = script_node->get_node(base_path);
return path_to;
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -788,7 +788,7 @@ public:
return true;
}
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
switch (call_mode) {
@@ -808,14 +808,14 @@ public:
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Base object is not a Node!";
return 0;
}
Node *another = node->get_node(node_path);
if (!another) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Path does not lead Node!";
return 0;
}
@@ -846,7 +846,7 @@ public:
} else if (returns == 1) {
v.call(function, p_inputs + 1, input_args, r_error);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid returns count for call_mode == CALL_MODE_INSTANCE";
return 0;
}
@@ -866,7 +866,7 @@ public:
Object *object = Engine::get_singleton()->get_singleton_object(singleton);
if (!object) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid singleton name: '" + String(singleton) + "'";
return 0;
}
@@ -884,7 +884,7 @@ public:
if (!validate) {
//ignore call errors if validation is disabled
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
r_error_str = String();
}
@@ -955,34 +955,34 @@ Node *VisualScriptPropertySet::_get_base_node() const {
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
if (!script.is_valid())
- return NULL;
+ return nullptr;
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
if (!scene_tree)
- return NULL;
+ return nullptr;
Node *edited_scene = scene_tree->get_edited_scene_root();
if (!edited_scene)
- return NULL;
+ return nullptr;
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
if (!script_node)
- return NULL;
+ return nullptr;
if (!script_node->has_node(base_path))
- return NULL;
+ return nullptr;
Node *path_to = script_node->get_node(base_path);
return path_to;
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -1020,8 +1020,8 @@ void VisualScriptPropertySet::_adjust_input_index(PropertyInfo &pinfo) const {
if (index != StringName()) {
Variant v;
- Variant::CallError ce;
- v = Variant::construct(pinfo.type, NULL, 0, ce);
+ Callable::CallError ce;
+ v = Variant::construct(pinfo.type, nullptr, 0, ce);
Variant i = v.get(index);
pinfo.type = i.get_type();
}
@@ -1167,8 +1167,8 @@ void VisualScriptPropertySet::_update_cache() {
//not super efficient..
Variant v;
- Variant::CallError ce;
- v = Variant::construct(basic_type, NULL, 0, ce);
+ Callable::CallError ce;
+ v = Variant::construct(basic_type, nullptr, 0, ce);
List<PropertyInfo> pinfo;
v.get_property_list(&pinfo);
@@ -1185,7 +1185,7 @@ void VisualScriptPropertySet::_update_cache() {
StringName type;
Ref<Script> script;
- Node *node = NULL;
+ Node *node = nullptr;
if (call_mode == CALL_MODE_NODE_PATH) {
@@ -1409,8 +1409,8 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
if (property.name == "index") {
- Variant::CallError ce;
- Variant v = Variant::construct(type_cache.type, NULL, 0, ce);
+ Callable::CallError ce;
+ Variant v = Variant::construct(type_cache.type, nullptr, 0, ce);
List<PropertyInfo> plist;
v.get_property_list(&plist);
String options = "";
@@ -1578,7 +1578,7 @@ public:
}
}
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
switch (call_mode) {
@@ -1597,7 +1597,7 @@ public:
}
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid set value '" + String(*p_inputs[0]) + "' on property '" + String(property) + "' of type " + object->get_class();
}
} break;
@@ -1605,14 +1605,14 @@ public:
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Base object is not a Node!";
return 0;
}
Node *another = node->get_node(node_path);
if (!another) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Path does not lead Node!";
return 0;
}
@@ -1629,7 +1629,7 @@ public:
}
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid set value '" + String(*p_inputs[0]) + "' on property '" + String(property) + "' of type " + another->get_class();
}
@@ -1651,7 +1651,7 @@ public:
}
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid set value '" + String(*p_inputs[1]) + "' (" + Variant::get_type_name(p_inputs[1]->get_type()) + ") on property '" + String(property) + "' of type " + Variant::get_type_name(v.get_type());
}
@@ -1735,34 +1735,34 @@ Node *VisualScriptPropertyGet::_get_base_node() const {
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
if (!script.is_valid())
- return NULL;
+ return nullptr;
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
if (!scene_tree)
- return NULL;
+ return nullptr;
Node *edited_scene = scene_tree->get_edited_scene_root();
if (!edited_scene)
- return NULL;
+ return nullptr;
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
if (!script_node)
- return NULL;
+ return nullptr;
if (!script_node->has_node(base_path))
- return NULL;
+ return nullptr;
Node *path_to = script_node->get_node(base_path);
return path_to;
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -1875,8 +1875,8 @@ void VisualScriptPropertyGet::_update_cache() {
//not super efficient..
Variant v;
- Variant::CallError ce;
- v = Variant::construct(basic_type, NULL, 0, ce);
+ Callable::CallError ce;
+ v = Variant::construct(basic_type, nullptr, 0, ce);
List<PropertyInfo> pinfo;
v.get_property_list(&pinfo);
@@ -1894,7 +1894,7 @@ void VisualScriptPropertyGet::_update_cache() {
StringName type;
Ref<Script> script;
- Node *node = NULL;
+ Node *node = nullptr;
if (call_mode == CALL_MODE_NODE_PATH) {
@@ -2124,8 +2124,8 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
if (property.name == "index") {
- Variant::CallError ce;
- Variant v = Variant::construct(type_cache, NULL, 0, ce);
+ Callable::CallError ce;
+ Variant v = Variant::construct(type_cache, nullptr, 0, ce);
List<PropertyInfo> plist;
v.get_property_list(&plist);
String options = "";
@@ -2211,7 +2211,7 @@ public:
VisualScriptPropertyGet *node;
VisualScriptInstance *instance;
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
switch (call_mode) {
@@ -2228,7 +2228,7 @@ public:
}
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Invalid index property name.");
return 0;
}
@@ -2237,14 +2237,14 @@ public:
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Base object is not a Node!");
return 0;
}
Node *another = node->get_node(node_path);
if (!another) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Path does not lead Node!");
return 0;
}
@@ -2258,7 +2258,7 @@ public:
}
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = vformat(RTR("Invalid index property name '%s' in node %s."), String(property), another->get_name());
return 0;
}
@@ -2275,7 +2275,7 @@ public:
}
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("Invalid index property name.");
}
};
@@ -2434,7 +2434,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
Object *obj = instance->get_owner_ptr();
@@ -2500,8 +2500,8 @@ void register_visual_script_func_nodes() {
Variant::Type t = Variant::Type(i);
String type_name = Variant::get_type_name(t);
- Variant::CallError ce;
- Variant vt = Variant::construct(t, NULL, 0, ce);
+ Callable::CallError ce;
+ Variant vt = Variant::construct(t, nullptr, 0, ce);
List<MethodInfo> ml;
vt.get_method_list(&ml);
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 36cafeec73..c860e08943 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -32,7 +32,7 @@
#include "core/engine.h"
#include "core/global_constants.h"
-#include "core/os/input.h"
+#include "core/input/input_filter.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "scene/main/node.h"
@@ -285,7 +285,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
int ac = node->get_argument_count();
@@ -294,7 +294,7 @@ public:
Variant::Type expected = node->get_argument_type(i);
if (expected != Variant::NIL) {
if (!Variant::can_convert_strict(p_inputs[i]->get_type(), expected)) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.expected = expected;
r_error.argument = i;
return 0;
@@ -762,7 +762,7 @@ public:
int input_count = 0;
virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (input_count > 0) {
Array arr;
@@ -1031,7 +1031,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
bool valid;
if (unary) {
@@ -1043,7 +1043,7 @@ public:
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
if (p_outputs[0]->get_type() == Variant::STRING) {
r_error_str = *p_outputs[0];
} else {
@@ -1165,7 +1165,7 @@ class VisualScriptNodeInstanceSelect : public VisualScriptNodeInstance {
public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
bool cond = *p_inputs[0];
if (cond)
@@ -1285,10 +1285,10 @@ public:
VisualScriptInstance *instance;
StringName variable;
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (!instance->get_variable(variable, p_outputs[0])) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("VariableGet not found in script: ") + "'" + String(variable) + "'";
return 0;
}
@@ -1407,11 +1407,11 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (!instance->set_variable(variable, *p_inputs[0])) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("VariableSet not found in script: ") + "'" + String(variable) + "'";
}
@@ -1482,8 +1482,8 @@ void VisualScriptConstant::set_constant_type(Variant::Type p_type) {
return;
type = p_type;
- Variant::CallError ce;
- value = Variant::construct(type, NULL, 0, ce);
+ Callable::CallError ce;
+ value = Variant::construct(type, nullptr, 0, ce);
ports_changed_notify();
_change_notify();
}
@@ -1537,7 +1537,7 @@ public:
Variant constant;
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = constant;
return 0;
@@ -1642,7 +1642,7 @@ public:
Ref<Resource> preload;
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = preload;
return 0;
@@ -1710,13 +1710,13 @@ class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance {
public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
bool valid;
*p_outputs[0] = p_inputs[0]->get(*p_inputs[1], &valid);
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid get: " + p_inputs[0]->get_construct_string();
}
return 0;
@@ -1785,14 +1785,14 @@ class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance {
public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
bool valid;
*p_outputs[0] = *p_inputs[0];
p_outputs[0]->set(*p_inputs[1], *p_inputs[2], &valid);
if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid set: " + p_inputs[1]->get_construct_string();
}
return 0;
@@ -1866,7 +1866,7 @@ public:
int index;
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = GlobalConstants::get_global_constant_value(index);
return 0;
@@ -1935,8 +1935,11 @@ PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) con
}
PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) const {
-
- return PropertyInfo(Variant::INT, String(base_type) + "." + String(name));
+ if (name == "") {
+ return PropertyInfo(Variant::INT, String(base_type));
+ } else {
+ return PropertyInfo(Variant::INT, String(base_type) + "." + String(name));
+ }
}
String VisualScriptClassConstant::get_caption() const {
@@ -1958,6 +1961,22 @@ StringName VisualScriptClassConstant::get_class_constant() {
void VisualScriptClassConstant::set_base_type(const StringName &p_which) {
base_type = p_which;
+ List<String> constants;
+ ClassDB::get_integer_constant_list(base_type, &constants, true);
+ if (constants.size() > 0) {
+ bool found_name = false;
+ for (List<String>::Element *E = constants.front(); E; E = E->next()) {
+ if (E->get() == name) {
+ found_name = true;
+ break;
+ }
+ }
+ if (!found_name) {
+ name = constants[0];
+ }
+ } else {
+ name = "";
+ }
_change_notify();
ports_changed_notify();
}
@@ -1972,11 +1991,11 @@ public:
bool valid;
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (!valid) {
r_error_str = "Invalid constant name, pick a valid class constant.";
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
*p_outputs[0] = value;
@@ -2121,11 +2140,11 @@ public:
bool valid;
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (!valid) {
r_error_str = "Invalid constant name, pick a valid basic type constant.";
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
*p_outputs[0] = value;
@@ -2240,7 +2259,7 @@ PropertyInfo VisualScriptMathConstant::get_input_value_port_info(int p_idx) cons
PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) const {
- return PropertyInfo(Variant::REAL, const_name[constant]);
+ return PropertyInfo(Variant::FLOAT, const_name[constant]);
}
String VisualScriptMathConstant::get_caption() const {
@@ -2264,7 +2283,7 @@ public:
float value;
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = value;
return 0;
@@ -2370,7 +2389,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = singleton;
return 0;
@@ -2493,18 +2512,18 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Base object is not a Node!";
return 0;
}
Node *another = node->get_node(path);
if (!another) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Path does not lead Node!";
return 0;
}
@@ -2529,7 +2548,7 @@ VisualScriptNodeInstance *VisualScriptSceneNode::instance(VisualScriptInstance *
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
- return NULL;
+ return nullptr;
Ref<Script> scr = p_current_node->get_script();
@@ -2542,7 +2561,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
return n;
}
- return NULL;
+ return nullptr;
}
#endif
@@ -2677,18 +2696,18 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Base object is not a Node!";
return 0;
}
SceneTree *tree = node->get_tree();
if (!tree) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Attempt to get SceneTree while node is not in the active tree.";
return 0;
}
@@ -2784,7 +2803,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = path;
return 0;
@@ -2866,7 +2885,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = instance->get_owner_ptr();
return 0;
@@ -3003,13 +3022,13 @@ public:
int work_mem_size;
virtual int get_working_memory_size() const { return work_mem_size; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (node->get_script_instance()) {
#ifdef DEBUG_ENABLED
if (!node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_step)) {
r_error_str = RTR("Custom node has no _step() method, can't process graph.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
#endif
@@ -3036,13 +3055,13 @@ public:
Variant ret = node->get_script_instance()->call(VisualScriptLanguage::singleton->_step, in_values, out_values, p_start_mode, work_mem);
if (ret.get_type() == Variant::STRING) {
r_error_str = ret;
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
} else if (ret.is_num()) {
ret_out = ret;
} else {
r_error_str = RTR("Invalid return value from _step(), must be integer (seq out), or string (error).");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
@@ -3111,8 +3130,6 @@ void VisualScriptCustomNode::_bind_methods() {
stepmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_VMETHOD(stepmi);
- ClassDB::bind_method(D_METHOD("_script_changed"), &VisualScriptCustomNode::_script_changed);
-
BIND_ENUM_CONSTANT(START_MODE_BEGIN_SEQUENCE);
BIND_ENUM_CONSTANT(START_MODE_CONTINUE_SEQUENCE);
BIND_ENUM_CONSTANT(START_MODE_RESUME_YIELD);
@@ -3125,7 +3142,7 @@ void VisualScriptCustomNode::_bind_methods() {
}
VisualScriptCustomNode::VisualScriptCustomNode() {
- connect("script_changed", this, "_script_changed");
+ connect("script_changed", callable_mp(this, &VisualScriptCustomNode::_script_changed));
}
//////////////////////////////////////////
@@ -3218,11 +3235,11 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (!valid) {
r_error_str = "Node requires a script with a _subcall(<args>) method to work.";
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
*p_outputs[0] = subcall->call(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error);
@@ -3349,7 +3366,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
return 0;
}
@@ -3464,11 +3481,11 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
- Variant::CallError ce;
+ Callable::CallError ce;
*p_outputs[0] = Variant::construct(type, p_inputs, argcount, ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = "Invalid arguments for constructor";
}
@@ -3502,7 +3519,7 @@ VisualScriptConstructor::VisualScriptConstructor() {
type = Variant::NIL;
}
-static Map<String, Pair<Variant::Type, MethodInfo> > constructor_map;
+static Map<String, Pair<Variant::Type, MethodInfo>> constructor_map;
static Ref<VisualScriptNode> create_constructor_node(const String &p_name) {
@@ -3593,7 +3610,7 @@ public:
StringName name;
virtual int get_working_memory_size() const { return 1; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_outputs[0] = *p_working_mem;
return 0;
@@ -3714,7 +3731,7 @@ public:
StringName name;
virtual int get_working_memory_size() const { return 1; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
*p_working_mem = *p_inputs[0];
*p_outputs[0] = *p_working_mem;
@@ -3849,20 +3866,20 @@ public:
StringName action;
VisualScriptInputAction::Mode mode;
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
switch (mode) {
case VisualScriptInputAction::MODE_PRESSED: {
- *p_outputs[0] = Input::get_singleton()->is_action_pressed(action);
+ *p_outputs[0] = InputFilter::get_singleton()->is_action_pressed(action);
} break;
case VisualScriptInputAction::MODE_RELEASED: {
- *p_outputs[0] = !Input::get_singleton()->is_action_pressed(action);
+ *p_outputs[0] = !InputFilter::get_singleton()->is_action_pressed(action);
} break;
case VisualScriptInputAction::MODE_JUST_PRESSED: {
- *p_outputs[0] = Input::get_singleton()->is_action_just_pressed(action);
+ *p_outputs[0] = InputFilter::get_singleton()->is_action_just_pressed(action);
} break;
case VisualScriptInputAction::MODE_JUST_RELEASED: {
- *p_outputs[0] = Input::get_singleton()->is_action_just_released(action);
+ *p_outputs[0] = InputFilter::get_singleton()->is_action_just_released(action);
} break;
}
@@ -3988,8 +4005,8 @@ void VisualScriptDeconstruct::_update_elements() {
elements.clear();
Variant v;
- Variant::CallError ce;
- v = Variant::construct(type, NULL, 0, ce);
+ Callable::CallError ce;
+ v = Variant::construct(type, nullptr, 0, ce);
List<PropertyInfo> pinfo;
v.get_property_list(&pinfo);
@@ -4046,7 +4063,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
Variant in = *p_inputs[0];
@@ -4055,7 +4072,7 @@ public:
*p_outputs[i] = in.get(outputs[i], &valid);
if (!valid) {
r_error_str = "Can't obtain element '" + String(outputs[i]) + "' from " + Variant::get_type_name(in.get_type());
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
}
@@ -4167,9 +4184,12 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("operators/logic/select", create_node_generic<VisualScriptSelect>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2), create_node_deconst_typed<Variant::Type::VECTOR2>);
+ VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2I), create_node_deconst_typed<Variant::Type::VECTOR2I>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>);
+ VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3I), create_node_deconst_typed<Variant::Type::VECTOR3I>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>);
+ VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM2D), create_node_deconst_typed<Variant::Type::TRANSFORM2D>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PLANE), create_node_deconst_typed<Variant::Type::PLANE>);
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUAT), create_node_deconst_typed<Variant::Type::QUAT>);
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index 99d7ffd05f..f57853078d 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -39,7 +39,7 @@
#include "modules/visual_script/visual_script_func_nodes.h"
#include "modules/visual_script/visual_script_nodes.h"
#include "scene/main/node.h"
-#include "scene/main/viewport.h"
+#include "scene/main/window.h"
void VisualScriptPropertySelector::_text_changed(const String &p_newtext) {
_update_search();
@@ -51,7 +51,7 @@ void VisualScriptPropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) {
if (k.is_valid()) {
- switch (k->get_scancode()) {
+ switch (k->get_keycode()) {
case KEY_UP:
case KEY_DOWN:
case KEY_PAGEUP:
@@ -97,35 +97,37 @@ void VisualScriptPropertySelector::_update_search() {
for (List<StringName>::Element *E = base_list.front(); E; E = E->next()) {
List<MethodInfo> methods;
List<PropertyInfo> props;
- TreeItem *category = NULL;
- Ref<Texture> type_icons[Variant::VARIANT_MAX] = {
- Control::get_icon("Variant", "EditorIcons"),
- Control::get_icon("bool", "EditorIcons"),
- Control::get_icon("int", "EditorIcons"),
- Control::get_icon("float", "EditorIcons"),
- Control::get_icon("String", "EditorIcons"),
- Control::get_icon("Vector2", "EditorIcons"),
- Control::get_icon("Rect2", "EditorIcons"),
- Control::get_icon("Vector3", "EditorIcons"),
- Control::get_icon("Transform2D", "EditorIcons"),
- Control::get_icon("Plane", "EditorIcons"),
- Control::get_icon("Quat", "EditorIcons"),
- Control::get_icon("AABB", "EditorIcons"),
- Control::get_icon("Basis", "EditorIcons"),
- Control::get_icon("Transform", "EditorIcons"),
- Control::get_icon("Color", "EditorIcons"),
- Control::get_icon("Path", "EditorIcons"),
- Control::get_icon("RID", "EditorIcons"),
- Control::get_icon("Object", "EditorIcons"),
- Control::get_icon("Dictionary", "EditorIcons"),
- Control::get_icon("Array", "EditorIcons"),
- Control::get_icon("PoolByteArray", "EditorIcons"),
- Control::get_icon("PoolIntArray", "EditorIcons"),
- Control::get_icon("PoolRealArray", "EditorIcons"),
- Control::get_icon("PoolStringArray", "EditorIcons"),
- Control::get_icon("PoolVector2Array", "EditorIcons"),
- Control::get_icon("PoolVector3Array", "EditorIcons"),
- Control::get_icon("PoolColorArray", "EditorIcons")
+ TreeItem *category = nullptr;
+ Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = {
+ vbc->get_theme_icon("Variant", "EditorIcons"),
+ vbc->get_theme_icon("bool", "EditorIcons"),
+ vbc->get_theme_icon("int", "EditorIcons"),
+ vbc->get_theme_icon("float", "EditorIcons"),
+ vbc->get_theme_icon("String", "EditorIcons"),
+ vbc->get_theme_icon("Vector2", "EditorIcons"),
+ vbc->get_theme_icon("Rect2", "EditorIcons"),
+ vbc->get_theme_icon("Vector3", "EditorIcons"),
+ vbc->get_theme_icon("Transform2D", "EditorIcons"),
+ vbc->get_theme_icon("Plane", "EditorIcons"),
+ vbc->get_theme_icon("Quat", "EditorIcons"),
+ vbc->get_theme_icon("AABB", "EditorIcons"),
+ vbc->get_theme_icon("Basis", "EditorIcons"),
+ vbc->get_theme_icon("Transform", "EditorIcons"),
+ vbc->get_theme_icon("Color", "EditorIcons"),
+ vbc->get_theme_icon("Path", "EditorIcons"),
+ vbc->get_theme_icon("RID", "EditorIcons"),
+ vbc->get_theme_icon("Object", "EditorIcons"),
+ vbc->get_theme_icon("Dictionary", "EditorIcons"),
+ vbc->get_theme_icon("Array", "EditorIcons"),
+ vbc->get_theme_icon("PackedByteArray", "EditorIcons"),
+ vbc->get_theme_icon("PackedInt32Array", "EditorIcons"),
+ vbc->get_theme_icon("PackedFloat32Array", "EditorIcons"),
+ vbc->get_theme_icon("PackedInt64Array", "EditorIcons"),
+ vbc->get_theme_icon("PackedFloat64Array", "EditorIcons"),
+ vbc->get_theme_icon("PackedStringArray", "EditorIcons"),
+ vbc->get_theme_icon("PackedVector2Array", "EditorIcons"),
+ vbc->get_theme_icon("PackedVector3Array", "EditorIcons"),
+ vbc->get_theme_icon("PackedColorArray", "EditorIcons")
};
{
String b = String(E->get());
@@ -133,7 +135,7 @@ void VisualScriptPropertySelector::_update_search() {
if (category) {
category->set_text(0, b.replace_first("*", ""));
category->set_selectable(0, false);
- Ref<Texture> icon;
+ Ref<Texture2D> icon;
String rep = b.replace("*", "");
icon = EditorNode::get_singleton()->get_class_icon(rep);
category->set_icon(0, icon);
@@ -193,8 +195,8 @@ void VisualScriptPropertySelector::_update_search() {
{
if (type != Variant::NIL) {
Variant v;
- Variant::CallError ce;
- v = Variant::construct(type, NULL, 0, ce);
+ Callable::CallError ce;
+ v = Variant::construct(type, nullptr, 0, ce);
v.get_method_list(&methods);
} else {
@@ -250,7 +252,7 @@ void VisualScriptPropertySelector::_update_search() {
TreeItem *item = search_options->create_item(category ? category : root);
item->set_text(0, desc);
- item->set_icon(0, get_icon("MemberMethod", "EditorIcons"));
+ item->set_icon(0, vbc->get_theme_icon("MemberMethod", "EditorIcons"));
item->set_metadata(0, name);
item->set_selectable(0, true);
@@ -262,7 +264,7 @@ void VisualScriptPropertySelector::_update_search() {
item->set_metadata(2, connecting);
}
- if (category && category->get_children() == NULL) {
+ if (category && category->get_children() == nullptr) {
memdelete(category); //old category was unused
}
}
@@ -279,7 +281,7 @@ void VisualScriptPropertySelector::_update_search() {
if (type == Variant::BOOL) {
get_visual_node_names("operators/logic/", Set<String>(), found, root, search_box);
}
- if (type == Variant::BOOL || type == Variant::INT || type == Variant::REAL || type == Variant::VECTOR2 || type == Variant::VECTOR3) {
+ if (type == Variant::BOOL || type == Variant::INT || type == Variant::FLOAT || type == Variant::VECTOR2 || type == Variant::VECTOR3) {
get_visual_node_names("operators/math/", Set<String>(), found, root, search_box);
}
}
@@ -302,19 +304,19 @@ void VisualScriptPropertySelector::_update_search() {
}
TreeItem *selected_item = search_options->search_item_text(search_box->get_text());
- if (!found && selected_item != NULL) {
+ if (!found && selected_item != nullptr) {
selected_item->select(0);
found = true;
}
- get_ok()->set_disabled(root->get_children() == NULL);
+ get_ok()->set_disabled(root->get_children() == nullptr);
}
void VisualScriptPropertySelector::create_visualscript_item(const String &name, TreeItem *const root, const String &search_input, const String &text) {
if (search_input == String() || text.findn(search_input) != -1) {
TreeItem *item = search_options->create_item(root);
item->set_text(0, text);
- item->set_icon(0, get_icon("VisualScript", "EditorIcons"));
+ item->set_icon(0, vbc->get_theme_icon("VisualScript", "EditorIcons"));
item->set_metadata(0, name);
item->set_metadata(1, "action");
item->set_selectable(0, true);
@@ -355,7 +357,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt
continue;
}
- bool in_modifier = false | p_modifiers.empty();
+ bool in_modifier = p_modifiers.empty();
for (Set<String>::Element *F = p_modifiers.front(); F && in_modifier; F = F->next()) {
if (E->get().findn(F->get()) != -1)
in_modifier = true;
@@ -397,7 +399,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt
}
item->set_text(0, type_name + String("").join(desc));
- item->set_icon(0, get_icon("VisualScript", "EditorIcons"));
+ item->set_icon(0, vbc->get_theme_icon("VisualScript", "EditorIcons"));
item->set_selectable(0, true);
item->set_metadata(0, E->get());
item->set_selectable(0, true);
@@ -414,7 +416,7 @@ void VisualScriptPropertySelector::_confirmed() {
if (!ti)
return;
emit_signal("selected", ti->get_metadata(0), ti->get_metadata(1), ti->get_metadata(2));
- hide();
+ set_visible(false);
}
void VisualScriptPropertySelector::_item_selected() {
@@ -479,7 +481,7 @@ void VisualScriptPropertySelector::_item_selected() {
List<String> *names = memnew(List<String>);
VisualScriptLanguage::singleton->get_registered_node_names(names);
- if (names->find(name) != NULL) {
+ if (names->find(name) != nullptr) {
Ref<VisualScriptOperator> operator_node = VisualScriptLanguage::singleton->create_node_from_name(name);
if (operator_node.is_valid()) {
Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(operator_node->get_class_name());
@@ -516,11 +518,15 @@ void VisualScriptPropertySelector::_item_selected() {
help_bit->set_text(text);
}
+void VisualScriptPropertySelector::_hide_requested() {
+ _cancel_pressed(); // From AcceptDialog.
+}
+
void VisualScriptPropertySelector::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- connect("confirmed", this, "_confirmed");
+ connect("confirmed", callable_mp(this, &VisualScriptPropertySelector::_confirmed));
}
}
@@ -529,9 +535,8 @@ void VisualScriptPropertySelector::select_method_from_base_type(const String &p_
base_type = p_base;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = false;
- instance = NULL;
+ instance = nullptr;
virtuals_only = p_virtuals_only;
show_window(.5f);
@@ -554,10 +559,9 @@ void VisualScriptPropertySelector::select_from_base_type(const String &p_base, c
base_type = p_base;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = true;
visual_script_generic = false;
- instance = NULL;
+ instance = nullptr;
virtuals_only = p_virtuals_only;
show_window(.5f);
@@ -581,7 +585,7 @@ void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_scrip
script = p_script->get_instance_id();
properties = true;
visual_script_generic = false;
- instance = NULL;
+ instance = nullptr;
virtuals_only = false;
show_window(.5f);
@@ -601,10 +605,9 @@ void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type,
base_type = "";
selected = p_current;
type = p_type;
- script = 0;
properties = true;
visual_script_generic = false;
- instance = NULL;
+ instance = nullptr;
virtuals_only = false;
show_window(.5f);
@@ -623,10 +626,9 @@ void VisualScriptPropertySelector::select_from_action(const String &p_type, cons
base_type = p_type;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = false;
visual_script_generic = false;
- instance = NULL;
+ instance = nullptr;
virtuals_only = false;
show_window(.5f);
@@ -645,7 +647,6 @@ void VisualScriptPropertySelector::select_from_instance(Object *p_instance, cons
base_type = p_basetype;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = true;
visual_script_generic = false;
instance = p_instance;
@@ -667,10 +668,9 @@ void VisualScriptPropertySelector::select_from_visual_script(const String &p_bas
base_type = p_base;
selected = "";
type = Variant::NIL;
- script = 0;
properties = true;
visual_script_generic = true;
- instance = NULL;
+ instance = nullptr;
virtuals_only = false;
show_window(.5f);
if (clear_text)
@@ -684,48 +684,39 @@ void VisualScriptPropertySelector::select_from_visual_script(const String &p_bas
}
void VisualScriptPropertySelector::show_window(float p_screen_ratio) {
- Rect2 rect;
- Point2 window_size = get_viewport_rect().size;
- rect.size = (window_size * p_screen_ratio).floor();
- rect.size.x = rect.size.x / 2.2f;
- rect.position = ((window_size - rect.size) / 2.0f).floor();
- popup(rect);
+
+ popup_centered_ratio(p_screen_ratio);
}
void VisualScriptPropertySelector::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_text_changed"), &VisualScriptPropertySelector::_text_changed);
- ClassDB::bind_method(D_METHOD("_confirmed"), &VisualScriptPropertySelector::_confirmed);
- ClassDB::bind_method(D_METHOD("_sbox_input"), &VisualScriptPropertySelector::_sbox_input);
- ClassDB::bind_method(D_METHOD("_item_selected"), &VisualScriptPropertySelector::_item_selected);
-
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "category"), PropertyInfo(Variant::BOOL, "connecting")));
}
VisualScriptPropertySelector::VisualScriptPropertySelector() {
- VBoxContainer *vbc = memnew(VBoxContainer);
+ vbc = memnew(VBoxContainer);
add_child(vbc);
//set_child_rect(vbc);
search_box = memnew(LineEdit);
vbc->add_margin_child(TTR("Search:"), search_box);
- search_box->connect("text_changed", this, "_text_changed");
- search_box->connect("gui_input", this, "_sbox_input");
+ search_box->connect("text_changed", callable_mp(this, &VisualScriptPropertySelector::_text_changed));
+ search_box->connect("gui_input", callable_mp(this, &VisualScriptPropertySelector::_sbox_input));
search_options = memnew(Tree);
vbc->add_margin_child(TTR("Matches:"), search_options, true);
get_ok()->set_text(TTR("Open"));
get_ok()->set_disabled(true);
register_text_enter(search_box);
set_hide_on_ok(false);
- search_options->connect("item_activated", this, "_confirmed");
- search_options->connect("cell_selected", this, "_item_selected");
+ search_options->connect("item_activated", callable_mp(this, &VisualScriptPropertySelector::_confirmed));
+ search_options->connect("cell_selected", callable_mp(this, &VisualScriptPropertySelector::_item_selected));
search_options->set_hide_root(true);
search_options->set_hide_folding(true);
virtuals_only = false;
seq_connect = false;
help_bit = memnew(EditorHelpBit);
vbc->add_margin_child(TTR("Description:"), help_bit);
- help_bit->connect("request_hide", this, "_closed");
+ help_bit->connect("request_hide", callable_mp(this, &VisualScriptPropertySelector::_hide_requested));
search_options->set_columns(3);
search_options->set_column_expand(1, false);
search_options->set_column_expand(2, false);
diff --git a/modules/visual_script/visual_script_property_selector.h b/modules/visual_script/visual_script_property_selector.h
index a1eb0b842c..cc49b2863d 100644
--- a/modules/visual_script/visual_script_property_selector.h
+++ b/modules/visual_script/visual_script_property_selector.h
@@ -41,16 +41,16 @@ class VisualScriptPropertySelector : public ConfirmationDialog {
LineEdit *search_box;
Tree *search_options;
+ void _text_changed(const String &p_newtext);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
void _update_search();
void create_visualscript_item(const String &name, TreeItem *const root, const String &search_input, const String &text);
-
void get_visual_node_names(const String &root_filter, const Set<String> &p_modifiers, bool &found, TreeItem *const root, LineEdit *const search_box);
- void _sbox_input(const Ref<InputEvent> &p_ie);
-
void _confirmed();
- void _text_changed(const String &p_newtext);
+ void _item_selected();
+ void _hide_requested();
EditorHelpBit *help_bit;
@@ -64,8 +64,7 @@ class VisualScriptPropertySelector : public ConfirmationDialog {
Object *instance;
bool virtuals_only;
bool seq_connect;
-
- void _item_selected();
+ VBoxContainer *vbc;
Vector<Variant::Type> type_filter;
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index 877d5836d2..b300aec385 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -99,7 +99,7 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (p_start_mode == START_MODE_RESUME_YIELD) {
return 0; //resuming yield
@@ -109,7 +109,7 @@ public:
SceneTree *tree = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop());
if (!tree) {
r_error_str = "Main Loop is not SceneTree";
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
@@ -188,7 +188,7 @@ void VisualScriptYield::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_wait_time"), &VisualScriptYield::get_wait_time);
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Frame,Physics Frame,Time", PROPERTY_USAGE_NOEDITOR), "set_yield_mode", "get_yield_mode");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "wait_time"), "set_wait_time", "get_wait_time");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wait_time"), "set_wait_time", "get_wait_time");
BIND_ENUM_CONSTANT(YIELD_FRAME);
BIND_ENUM_CONSTANT(YIELD_PHYSICS_FRAME);
@@ -228,7 +228,7 @@ bool VisualScriptYieldSignal::has_input_sequence_port() const {
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
- return NULL;
+ return nullptr;
Ref<Script> scr = p_current_node->get_script();
@@ -241,7 +241,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
return n;
}
- return NULL;
+ return nullptr;
}
#endif
@@ -250,33 +250,33 @@ Node *VisualScriptYieldSignal::_get_base_node() const {
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
if (!script.is_valid())
- return NULL;
+ return nullptr;
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
if (!scene_tree)
- return NULL;
+ return nullptr;
Node *edited_scene = scene_tree->get_edited_scene_root();
if (!edited_scene)
- return NULL;
+ return nullptr;
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
if (!script_node)
- return NULL;
+ return nullptr;
if (!script_node->has_node(base_path))
- return NULL;
+ return nullptr;
Node *path_to = script_node->get_node(base_path);
return path_to;
#else
- return NULL;
+ return nullptr;
#endif
}
@@ -509,14 +509,14 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
if (p_start_mode == START_MODE_RESUME_YIELD) {
return 0; //resuming yield
} else {
//yield
- Object *object = NULL;
+ Object *object = nullptr;
switch (call_mode) {
@@ -529,14 +529,14 @@ public:
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Base object is not a Node!";
return 0;
}
Node *another = node->get_node(node_path);
if (!another) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Path does not lead Node!";
return 0;
}
@@ -548,7 +548,7 @@ public:
object = *p_inputs[0];
if (!object) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Supplied instance input is null.";
return 0;
}
diff --git a/modules/vorbis/SCsub b/modules/vorbis/SCsub
index 3824fdd789..05d46757d3 100644
--- a/modules/vorbis/SCsub
+++ b/modules/vorbis/SCsub
@@ -1,18 +1,21 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
+
+# Only kept to build the thirdparty library used by the theora and webm
+# modules. We now use stb_vorbis for AudioStreamOGGVorbis.
env_vorbis = env_modules.Clone()
stub = True
# Thirdparty source files
-if env['builtin_libvorbis']:
+if env["builtin_libvorbis"]:
thirdparty_dir = "#thirdparty/libvorbis/"
thirdparty_sources = [
- #"analysis.c",
- #"barkmel.c",
+ # "analysis.c",
+ # "barkmel.c",
"bitrate.c",
"block.c",
"codebook.c",
@@ -26,14 +29,14 @@ if env['builtin_libvorbis']:
"mapping0.c",
"mdct.c",
"psy.c",
- #"psytune.c",
+ # "psytune.c",
"registry.c",
"res0.c",
"sharedbook.c",
"smallft.c",
"synthesis.c",
- #"tone.c",
- #"vorbisenc.c",
+ # "tone.c",
+ # "vorbisenc.c",
"vorbisfile.c",
"window.c",
]
@@ -43,16 +46,12 @@ if env['builtin_libvorbis']:
env_vorbis.Prepend(CPPPATH=[thirdparty_dir])
# also requires libogg
- if env['builtin_libogg']:
+ if env["builtin_libogg"]:
env_vorbis.Prepend(CPPPATH=["#thirdparty/libogg"])
env_thirdparty = env_vorbis.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
-if not stub:
- # Module files
- env_vorbis.add_source_files(env.modules_sources, "*.cpp")
-else:
- # Module files
- env_vorbis.add_source_files(env.modules_sources, "stub/register_types.cpp")
+# Module files
+env_vorbis.add_source_files(env.modules_sources, "register_types.cpp")
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
deleted file mode 100644
index 87067faf8e..0000000000
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-/*************************************************************************/
-/* audio_stream_ogg_vorbis.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 "audio_stream_ogg_vorbis.h"
-
-size_t AudioStreamPlaybackOGGVorbis::_ov_read_func(void *p_dst, size_t p_data, size_t p_count, void *_f) {
-
- //printf("read to %p, %i bytes, %i nmemb, %p\n",p_dst,p_data,p_count,_f);
- FileAccess *fa = (FileAccess *)_f;
- size_t read_total = p_data * p_count;
-
- if (fa->eof_reached())
- return 0;
-
- uint8_t *dst = (uint8_t *)p_dst;
-
- int read = fa->get_buffer(dst, read_total);
-
- return read;
-}
-
-int AudioStreamPlaybackOGGVorbis::_ov_seek_func(void *_f, ogg_int64_t offs, int whence) {
-
- //printf("seek to %p, offs %i, whence %i\n",_f,(int)offs,whence);
-
-#ifdef SEEK_SET
- //printf("seek set defined\n");
- FileAccess *fa = (FileAccess *)_f;
-
- if (whence == SEEK_SET) {
-
- fa->seek(offs);
- } else if (whence == SEEK_CUR) {
-
- fa->seek(fa->get_position() + offs);
- } else if (whence == SEEK_END) {
-
- fa->seek_end(offs);
- } else {
-
- ERR_PRINT("Vorbis seek function failure: Unexpected value in _whence\n");
- }
- int ret = fa->eof_reached() ? -1 : 0;
- //printf("returning %i\n",ret);
- return ret;
-
-#else
- return -1; // no seeking
-#endif
-}
-int AudioStreamPlaybackOGGVorbis::_ov_close_func(void *_f) {
-
- //printf("close %p\n",_f);
- if (!_f)
- return 0;
- FileAccess *fa = (FileAccess *)_f;
- if (fa->is_open())
- fa->close();
- return 0;
-}
-long AudioStreamPlaybackOGGVorbis::_ov_tell_func(void *_f) {
-
- //printf("close %p\n",_f);
-
- FileAccess *fa = (FileAccess *)_f;
- return fa->get_position();
-}
-
-int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) {
-
- if (!playing)
- return 0;
-
- int total = p_frames;
- while (true) {
-
- int todo = p_frames;
-
- if (todo < MIN_MIX) {
- break;
- }
-
-#ifdef BIG_ENDIAN_ENABLED
- long ret = ov_read(&vf, (char *)p_buffer, todo * stream_channels * sizeof(int16_t), 1, 2, 1, &current_section);
-#else
- long ret = ov_read(&vf, (char *)p_buffer, todo * stream_channels * sizeof(int16_t), 0, 2, 1, &current_section);
-#endif
-
- if (ret < 0) {
-
- playing = false;
- ERR_BREAK_MSG(ret < 0, "Error reading OGG Vorbis file: " + file + ".");
- } else if (ret == 0) { // end of song, reload?
-
- ov_clear(&vf);
-
- _close_file();
-
- if (!has_loop()) {
-
- playing = false;
- repeats = 1;
- break;
- }
-
- f = FileAccess::open(file, FileAccess::READ);
-
- int errv = ov_open_callbacks(f, &vf, NULL, 0, _ov_callbacks);
- if (errv != 0) {
- playing = false;
- break; // :(
- }
-
- if (loop_restart_time) {
- bool ok = ov_time_seek(&vf, loop_restart_time) == 0;
- if (!ok) {
- playing = false;
- ERR_PRINT("Loop restart time rejected");
- }
-
- frames_mixed = stream_srate * loop_restart_time;
- } else {
-
- frames_mixed = 0;
- }
- repeats++;
- continue;
- }
-
- ret /= stream_channels;
- ret /= sizeof(int16_t);
-
- frames_mixed += ret;
-
- p_buffer += ret * stream_channels;
- p_frames -= ret;
- }
-
- return total - p_frames;
-}
-
-void AudioStreamPlaybackOGGVorbis::play(float p_from) {
-
- if (playing)
- stop();
-
- if (_load_stream() != OK)
- return;
-
- frames_mixed = 0;
- playing = true;
- if (p_from > 0) {
- seek(p_from);
- }
-}
-
-void AudioStreamPlaybackOGGVorbis::_close_file() {
-
- if (f) {
-
- memdelete(f);
- f = NULL;
- }
-}
-
-bool AudioStreamPlaybackOGGVorbis::is_playing() const {
- return playing;
-}
-void AudioStreamPlaybackOGGVorbis::stop() {
-
- _clear_stream();
- playing = false;
- //_clear();
-}
-
-float AudioStreamPlaybackOGGVorbis::get_playback_position() const {
-
- int32_t frames = int32_t(frames_mixed);
- if (frames < 0)
- frames = 0;
- return double(frames) / stream_srate;
-}
-
-void AudioStreamPlaybackOGGVorbis::seek(float p_time) {
-
- if (!playing)
- return;
- bool ok = ov_time_seek(&vf, p_time) == 0;
- ERR_FAIL_COND(!ok);
- frames_mixed = stream_srate * p_time;
-}
-
-String AudioStreamPlaybackOGGVorbis::get_stream_name() const {
-
- return "";
-}
-
-void AudioStreamPlaybackOGGVorbis::set_loop(bool p_enable) {
-
- loops = p_enable;
-}
-
-bool AudioStreamPlaybackOGGVorbis::has_loop() const {
-
- return loops;
-}
-
-int AudioStreamPlaybackOGGVorbis::get_loop_count() const {
- return repeats;
-}
-
-Error AudioStreamPlaybackOGGVorbis::set_file(const String &p_file) {
-
- file = p_file;
- stream_valid = false;
- Error err;
- f = FileAccess::open(file, FileAccess::READ, &err);
- ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + p_file + "'.");
-
- int errv = ov_open_callbacks(f, &vf, NULL, 0, _ov_callbacks);
- switch (errv) {
-
- case OV_EREAD: { // - A read from media returned an error.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CANT_READ);
- } break;
- case OV_EVERSION: // - Vorbis version mismatch.
- case OV_ENOTVORBIS: { // - Bitstream is not Vorbis data.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
- } break;
- case OV_EBADHEADER: { // - Invalid Vorbis bitstream header.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- } break;
- case OV_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_BUG);
- } break;
- }
- const vorbis_info *vinfo = ov_info(&vf, -1);
- stream_channels = vinfo->channels;
- stream_srate = vinfo->rate;
- length = ov_time_total(&vf, -1);
- ov_clear(&vf);
- memdelete(f);
- f = NULL;
- stream_valid = true;
-
- return OK;
-}
-
-Error AudioStreamPlaybackOGGVorbis::_load_stream() {
-
- ERR_FAIL_COND_V(!stream_valid, ERR_UNCONFIGURED);
-
- _clear_stream();
- if (file == "")
- return ERR_INVALID_DATA;
-
- Error err;
- f = FileAccess::open(file, FileAccess::READ, &err);
- ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + file + "'.");
-
- int errv = ov_open_callbacks(f, &vf, NULL, 0, _ov_callbacks);
- switch (errv) {
-
- case OV_EREAD: { // - A read from media returned an error.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CANT_READ);
- } break;
- case OV_EVERSION: // - Vorbis version mismatch.
- case OV_ENOTVORBIS: { // - Bitstream is not Vorbis data.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
- } break;
- case OV_EBADHEADER: { // - Invalid Vorbis bitstream header.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- } break;
- case OV_EFAULT: { // - Internal logic fault; indicates a bug or heap/stack corruption.
- memdelete(f);
- f = NULL;
- ERR_FAIL_V(ERR_BUG);
- } break;
- }
- repeats = 0;
- stream_loaded = true;
-
- return OK;
-}
-
-float AudioStreamPlaybackOGGVorbis::get_length() const {
-
- if (!stream_loaded) {
- if (const_cast<AudioStreamPlaybackOGGVorbis *>(this)->_load_stream() != OK)
- return 0;
- }
- return length;
-}
-
-void AudioStreamPlaybackOGGVorbis::_clear_stream() {
-
- if (!stream_loaded)
- return;
-
- ov_clear(&vf);
- _close_file();
-
- stream_loaded = false;
- //stream_channels=1;
- playing = false;
-}
-
-void AudioStreamPlaybackOGGVorbis::set_paused(bool p_paused) {
-
- paused = p_paused;
-}
-
-bool AudioStreamPlaybackOGGVorbis::is_paused() const {
-
- return paused;
-}
-
-AudioStreamPlaybackOGGVorbis::AudioStreamPlaybackOGGVorbis() {
-
- loops = false;
- playing = false;
- _ov_callbacks.read_func = _ov_read_func;
- _ov_callbacks.seek_func = _ov_seek_func;
- _ov_callbacks.close_func = _ov_close_func;
- _ov_callbacks.tell_func = _ov_tell_func;
- f = NULL;
- stream_loaded = false;
- stream_valid = false;
- repeats = 0;
- paused = true;
- stream_channels = 0;
- stream_srate = 0;
- current_section = 0;
- length = 0;
- loop_restart_time = 0;
-}
-
-AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() {
-
- _clear_stream();
-}
-
-RES ResourceFormatLoaderAudioStreamOGGVorbis::load(const String &p_path, const String &p_original_path, Error *r_error) {
- if (r_error)
- *r_error = OK;
-
- AudioStreamOGGVorbis *ogg_stream = memnew(AudioStreamOGGVorbis);
- ogg_stream->set_file(p_path);
- return Ref<AudioStreamOGGVorbis>(ogg_stream);
-}
-
-void ResourceFormatLoaderAudioStreamOGGVorbis::get_recognized_extensions(List<String> *p_extensions) const {
-
- p_extensions->push_back("ogg");
-}
-String ResourceFormatLoaderAudioStreamOGGVorbis::get_resource_type(const String &p_path) const {
-
- if (p_path.get_extension().to_lower() == "ogg")
- return "AudioStreamOGGVorbis";
- return "";
-}
-
-bool ResourceFormatLoaderAudioStreamOGGVorbis::handles_type(const String &p_type) const {
- return (p_type == "AudioStream" || p_type == "AudioStreamOGG" || p_type == "AudioStreamOGGVorbis");
-}
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h
deleted file mode 100644
index 739765a12f..0000000000
--- a/modules/vorbis/audio_stream_ogg_vorbis.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*************************************************************************/
-/* audio_stream_ogg_vorbis.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 AUDIO_STREAM_OGG_VORBIS_H
-#define AUDIO_STREAM_OGG_VORBIS_H
-
-#include "core/io/resource_loader.h"
-#include "core/os/file_access.h"
-#include "core/os/thread_safe.h"
-#include "scene/resources/audio_stream.h"
-
-#include <vorbis/vorbisfile.h>
-
-class AudioStreamPlaybackOGGVorbis : public AudioStreamPlayback {
-
- GDCLASS(AudioStreamPlaybackOGGVorbis, AudioStreamPlayback);
-
- enum {
- MIN_MIX = 1024
- };
-
- FileAccess *f;
-
- ov_callbacks _ov_callbacks;
- float length;
- static size_t _ov_read_func(void *p_dst, size_t p_data, size_t p_count, void *_f);
- static int _ov_seek_func(void *_f, ogg_int64_t offs, int whence);
- static int _ov_close_func(void *_f);
- static long _ov_tell_func(void *_f);
-
- String file;
- int64_t frames_mixed;
-
- bool stream_loaded;
- volatile bool playing;
- OggVorbis_File vf;
- int stream_channels;
- int stream_srate;
- int current_section;
-
- bool paused;
- bool loops;
- int repeats;
-
- Error _load_stream();
- void _clear_stream();
- void _close_file();
-
- bool stream_valid;
- float loop_restart_time;
-
-public:
- Error set_file(const String &p_file);
-
- virtual void play(float p_from = 0);
- virtual void stop();
- virtual bool is_playing() const;
-
- virtual void set_loop_restart_time(float p_time) { loop_restart_time = p_time; }
-
- virtual void set_paused(bool p_paused);
- virtual bool is_paused() const;
-
- virtual void set_loop(bool p_enable);
- virtual bool has_loop() const;
-
- virtual float get_length() const;
-
- virtual String get_stream_name() const;
-
- virtual int get_loop_count() const;
-
- virtual float get_playback_position() const;
- virtual void seek(float p_time);
-
- virtual int get_channels() const { return stream_channels; }
- virtual int get_mix_rate() const { return stream_srate; }
-
- virtual int get_minimum_buffer_size() const { return 0; }
- virtual int mix(int16_t *p_buffer, int p_frames);
-
- AudioStreamPlaybackOGGVorbis();
- ~AudioStreamPlaybackOGGVorbis();
-};
-
-class AudioStreamOGGVorbis : public AudioStream {
-
- GDCLASS(AudioStreamOGGVorbis, AudioStream);
-
- String file;
-
-public:
- Ref<AudioStreamPlayback> instance_playback() {
- Ref<AudioStreamPlaybackOGGVorbis> pb = memnew(AudioStreamPlaybackOGGVorbis);
- pb->set_file(file);
- return pb;
- }
-
- void set_file(const String &p_file) { file = p_file; }
-};
-
-class ResourceFormatLoaderAudioStreamOGGVorbis : public ResourceFormatLoader {
-public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
- virtual bool handles_type(const String &p_type) const;
- virtual String get_resource_type(const String &p_path) const;
-};
-
-#endif // AUDIO_STREAM_OGG_H
diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/vorbis/config.py
+++ b/modules/vorbis/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/vorbis/register_types.cpp b/modules/vorbis/register_types.cpp
index de055551ad..8874b3887b 100644
--- a/modules/vorbis/register_types.cpp
+++ b/modules/vorbis/register_types.cpp
@@ -30,19 +30,8 @@
#include "register_types.h"
-#include "audio_stream_ogg_vorbis.h"
+// Dummy module as libvorbis is needed by other modules (theora ...)
-static Ref<ResourceFormatLoaderAudioStreamOGGVorbis> vorbis_stream_loader;
+void register_vorbis_types() {}
-void register_vorbis_types() {
-
- vorbis_stream_loader.instance();
- ResourceLoader::add_resource_format_loader(vorbis_stream_loader);
- ClassDB::register_class<AudioStreamOGGVorbis>();
-}
-
-void unregister_vorbis_types() {
-
- ResourceLoader::remove_resource_format_loader(vorbis_stream_loader);
- vorbis_stream_loader.unref();
-}
+void unregister_vorbis_types() {}
diff --git a/modules/vorbis/register_types.h b/modules/vorbis/register_types.h
index 83d4904a87..7fa0dfdeef 100644
--- a/modules/vorbis/register_types.h
+++ b/modules/vorbis/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef VORBIS_REGISTER_TYPES_H
+#define VORBIS_REGISTER_TYPES_H
+
void register_vorbis_types();
void unregister_vorbis_types();
+
+#endif // VORBIS_REGISTER_TYPES_H
diff --git a/modules/webm/SCsub b/modules/webm/SCsub
index 32e6727656..247b4ead37 100644
--- a/modules/webm/SCsub
+++ b/modules/webm/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_webm = env_modules.Clone()
@@ -18,14 +18,14 @@ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_webm.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "libwebm/"])
# also requires libogg, libvorbis and libopus
-if env['builtin_libogg']:
+if env["builtin_libogg"]:
env_webm.Prepend(CPPPATH=["#thirdparty/libogg"])
-if env['builtin_libvorbis']:
+if env["builtin_libvorbis"]:
env_webm.Prepend(CPPPATH=["#thirdparty/libvorbis"])
-if env['builtin_opus']:
+if env["builtin_opus"]:
env_webm.Prepend(CPPPATH=["#thirdparty/opus"])
-if env['builtin_libvpx']:
+if env["builtin_libvpx"]:
env_webm.Prepend(CPPPATH=["#thirdparty/libvpx"])
SConscript("libvpx/SCsub")
diff --git a/modules/webm/config.py b/modules/webm/config.py
index ba4dcce2f5..93b49d177a 100644
--- a/modules/webm/config.py
+++ b/modules/webm/config.py
@@ -1,13 +1,16 @@
def can_build(env, platform):
- return platform not in ['iphone']
+ return platform not in ["iphone"]
+
def configure(env):
pass
+
def get_doc_classes():
return [
"VideoStreamWebm",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub
index 14fa6c1268..dd6866ad0e 100644
--- a/modules/webm/libvpx/SCsub
+++ b/modules/webm/libvpx/SCsub
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
# Thirdparty sources
@@ -9,9 +9,7 @@ libvpx_dir = "#thirdparty/libvpx/"
libvpx_sources = [
"vp8/vp8_dx_iface.c",
-
"vp8/common/generic/systemdependent.c",
-
"vp8/common/alloccommon.c",
"vp8/common/blockd.c",
"vp8/common/copy_c.c",
@@ -37,16 +35,12 @@ libvpx_sources = [
"vp8/common/swapyv12buffer.c",
"vp8/common/treecoder.c",
"vp8/common/vp8_loopfilter.c",
-
"vp8/decoder/dboolhuff.c",
"vp8/decoder/decodeframe.c",
"vp8/decoder/decodemv.c",
"vp8/decoder/detokenize.c",
"vp8/decoder/onyxd_if.c",
-
-
"vp9/vp9_dx_iface.c",
-
"vp9/common/vp9_alloccommon.c",
"vp9/common/vp9_blockd.c",
"vp9/common/vp9_common_data.c",
@@ -69,21 +63,16 @@ libvpx_sources = [
"vp9/common/vp9_seg_common.c",
"vp9/common/vp9_thread_common.c",
"vp9/common/vp9_tile_common.c",
-
"vp9/decoder/vp9_decodeframe.c",
"vp9/decoder/vp9_decodemv.c",
"vp9/decoder/vp9_decoder.c",
"vp9/decoder/vp9_detokenize.c",
"vp9/decoder/vp9_dsubexp.c",
"vp9/decoder/vp9_dthread.c",
-
-
"vpx/src/vpx_codec.c",
"vpx/src/vpx_decoder.c",
"vpx/src/vpx_image.c",
"vpx/src/vpx_psnr.c",
-
-
"vpx_dsp/bitreader.c",
"vpx_dsp/bitreader_buffer.c",
"vpx_dsp/intrapred.c",
@@ -92,18 +81,11 @@ libvpx_sources = [
"vpx_dsp/prob.c",
"vpx_dsp/vpx_convolve.c",
"vpx_dsp/vpx_dsp_rtcd.c",
-
-
"vpx_mem/vpx_mem.c",
-
-
"vpx_scale/vpx_scale_rtcd.c",
-
"vpx_scale/generic/yv12config.c",
"vpx_scale/generic/yv12extend.c",
-
-
- "vpx_util/vpx_thread.c"
+ "vpx_util/vpx_thread.c",
]
libvpx_sources_mt = [
@@ -114,29 +96,23 @@ libvpx_sources_intrin_x86 = [
"vp8/common/x86/filter_x86.c",
"vp8/common/x86/loopfilter_x86.c",
"vp8/common/x86/vp8_asm_stubs.c",
-
-
- "vpx_dsp/x86/vpx_asm_stubs.c"
+ "vpx_dsp/x86/vpx_asm_stubs.c",
]
libvpx_sources_intrin_x86_mmx = [
"vp8/common/x86/idct_blk_mmx.c",
]
libvpx_sources_intrin_x86_sse2 = [
"vp8/common/x86/idct_blk_sse2.c",
-
-
"vp9/common/x86/vp9_idct_intrin_sse2.c",
-
-
"vpx_dsp/x86/inv_txfm_sse2.c",
"vpx_dsp/x86/loopfilter_sse2.c",
]
libvpx_sources_intrin_x86_ssse3 = [
- "vpx_dsp/x86/vpx_subpixel_8t_intrin_ssse3.c"
+ "vpx_dsp/x86/vpx_subpixel_8t_intrin_ssse3.c",
]
libvpx_sources_intrin_x86_avx2 = [
"vpx_dsp/x86/loopfilter_avx2.c",
- "vpx_dsp/x86/vpx_subpixel_8t_intrin_avx2.c"
+ "vpx_dsp/x86/vpx_subpixel_8t_intrin_avx2.c",
]
libvpx_sources_x86asm = [
"vp8/common/x86/copy_sse2.asm",
@@ -153,8 +129,6 @@ libvpx_sources_x86asm = [
"vp8/common/x86/subpixel_sse2.asm",
"vp8/common/x86/subpixel_ssse3.asm",
"vp8/common/x86/vp8_loopfilter_mmx.asm",
-
-
"vpx_dsp/x86/intrapred_sse2.asm",
"vpx_dsp/x86/intrapred_ssse3.asm",
"vpx_dsp/x86/inv_wht_sse2.asm",
@@ -163,21 +137,15 @@ libvpx_sources_x86asm = [
"vpx_dsp/x86/vpx_subpixel_8t_ssse3.asm",
"vpx_dsp/x86/vpx_subpixel_bilinear_sse2.asm",
"vpx_dsp/x86/vpx_subpixel_bilinear_ssse3.asm",
-
-
- "vpx_ports/emms.asm"
+ "vpx_ports/emms.asm",
]
libvpx_sources_x86_64asm = [
"vp8/common/x86/loopfilter_block_sse2_x86_64.asm",
-
-
- "vpx_dsp/x86/inv_txfm_ssse3_x86_64.asm"
+ "vpx_dsp/x86/inv_txfm_ssse3_x86_64.asm",
]
libvpx_sources_arm = [
"vpx_ports/arm_cpudetect.c",
-
-
"vp8/common/arm/loopfilter_arm.c",
]
libvpx_sources_arm_neon = [
@@ -196,12 +164,8 @@ libvpx_sources_arm_neon = [
"vp8/common/arm/neon/shortidct4x4llm_neon.c",
"vp8/common/arm/neon/sixtappredict_neon.c",
"vp8/common/arm/neon/vp8_loopfilter_neon.c",
-
-
"vp9/common/arm/neon/vp9_iht4x4_add_neon.c",
"vp9/common/arm/neon/vp9_iht8x8_add_neon.c",
-
-
"vpx_dsp/arm/idct16x16_1_add_neon.c",
"vpx_dsp/arm/idct16x16_add_neon.c",
"vpx_dsp/arm/idct16x16_neon.c",
@@ -220,22 +184,22 @@ libvpx_sources_arm_neon = [
"vpx_dsp/arm/vpx_convolve8_neon.c",
"vpx_dsp/arm/vpx_convolve_avg_neon.c",
"vpx_dsp/arm/vpx_convolve_copy_neon.c",
- "vpx_dsp/arm/vpx_convolve_neon.c"
+ "vpx_dsp/arm/vpx_convolve_neon.c",
]
libvpx_sources_arm_neon_gas = [
"vpx_dsp/arm/gas/intrapred_neon_asm.s",
"vpx_dsp/arm/gas/loopfilter_mb_neon.s",
- "vpx_dsp/arm/gas/save_reg_neon.s"
+ "vpx_dsp/arm/gas/save_reg_neon.s",
]
libvpx_sources_arm_neon_armasm_ms = [
"vpx_dsp/arm/armasm_ms/intrapred_neon_asm.asm",
"vpx_dsp/arm/armasm_ms/loopfilter_mb_neon.asm",
- "vpx_dsp/arm/armasm_ms/save_reg_neon.asm"
+ "vpx_dsp/arm/armasm_ms/save_reg_neon.asm",
]
libvpx_sources_arm_neon_gas_apple = [
"vpx_dsp/arm/gas_apple/intrapred_neon_asm.s",
"vpx_dsp/arm/gas_apple/loopfilter_mb_neon.s",
- "vpx_dsp/arm/gas_apple/save_reg_neon.s"
+ "vpx_dsp/arm/gas_apple/save_reg_neon.s",
]
libvpx_sources = [libvpx_dir + file for file in libvpx_sources]
@@ -258,25 +222,43 @@ env_libvpx = env_modules.Clone()
env_libvpx.disable_warnings()
env_libvpx.Prepend(CPPPATH=[libvpx_dir])
-webm_multithread = env["platform"] != 'javascript'
+webm_multithread = env["platform"] != "javascript"
cpu_bits = env["bits"]
webm_cpu_x86 = False
webm_cpu_arm = False
-if env["platform"] == 'uwp':
- if 'arm' in env["PROGSUFFIX"]:
+if env["platform"] == "uwp":
+ if "arm" in env["PROGSUFFIX"]:
webm_cpu_arm = True
else:
webm_cpu_x86 = True
else:
import platform
- is_x11_or_server_arm = ((env["platform"] == 'x11' or env["platform"] == 'server') and (platform.machine().startswith('arm') or platform.machine().startswith('aarch')))
- is_ios_x86 = (env["platform"] == 'iphone' and ("arch" in env and env["arch"].startswith('x86')))
- is_android_x86 = (env["platform"] == 'android' and env["android_arch"].startswith('x86'))
+
+ is_x11_or_server_arm = (env["platform"] == "linuxbsd" or env["platform"] == "server") and (
+ platform.machine().startswith("arm") or platform.machine().startswith("aarch")
+ )
+ is_ios_x86 = env["platform"] == "iphone" and ("arch" in env and env["arch"].startswith("x86"))
+ is_android_x86 = env["platform"] == "android" and env["android_arch"].startswith("x86")
if is_android_x86:
- cpu_bits = '32' if env["android_arch"] == 'x86' else '64'
- webm_cpu_x86 = not is_x11_or_server_arm and (cpu_bits == '32' or cpu_bits == '64') and (env["platform"] == 'windows' or env["platform"] == 'x11' or env["platform"] == 'osx' or env["platform"] == 'haiku' or is_android_x86 or is_ios_x86)
- webm_cpu_arm = is_x11_or_server_arm or (not is_ios_x86 and env["platform"] == 'iphone') or (not is_android_x86 and env["platform"] == 'android')
+ cpu_bits = "32" if env["android_arch"] == "x86" else "64"
+ webm_cpu_x86 = (
+ not is_x11_or_server_arm
+ and (cpu_bits == "32" or cpu_bits == "64")
+ and (
+ env["platform"] == "windows"
+ or env["platform"] == "linuxbsd"
+ or env["platform"] == "osx"
+ or env["platform"] == "haiku"
+ or is_android_x86
+ or is_ios_x86
+ )
+ )
+ webm_cpu_arm = (
+ is_x11_or_server_arm
+ or (not is_ios_x86 and env["platform"] == "iphone")
+ or (not is_android_x86 and env["platform"] == "android")
+ )
if webm_cpu_x86:
import subprocess
@@ -306,38 +288,43 @@ if webm_cpu_x86:
webm_simd_optimizations = False
if webm_cpu_x86:
- if env["platform"] == 'windows' or env["platform"] == 'uwp':
- env_libvpx["ASFORMAT"] = 'win'
- elif env["platform"] == 'osx' or env["platform"] == "iphone":
- env_libvpx["ASFORMAT"] = 'macho'
+ if env["platform"] == "windows" or env["platform"] == "uwp":
+ env_libvpx["ASFORMAT"] = "win"
+ elif env["platform"] == "osx" or env["platform"] == "iphone":
+ env_libvpx["ASFORMAT"] = "macho"
else:
- env_libvpx["ASFORMAT"] = 'elf'
+ env_libvpx["ASFORMAT"] = "elf"
env_libvpx["ASFORMAT"] += cpu_bits
- env_libvpx["AS"] = 'yasm'
- env_libvpx["ASFLAGS"] = '-I' + libvpx_dir[1:] + ' -f $ASFORMAT -D $ASCPU'
- env_libvpx["ASCOM"] = '$AS $ASFLAGS -o $TARGET $SOURCES'
+ env_libvpx["AS"] = "yasm"
+ env_libvpx["ASFLAGS"] = "-I" + libvpx_dir[1:] + " -f $ASFORMAT -D $ASCPU"
+ env_libvpx["ASCOM"] = "$AS $ASFLAGS -o $TARGET $SOURCES"
- if cpu_bits == '32':
- env_libvpx["ASCPU"] = 'X86_32'
- elif cpu_bits == '64':
- env_libvpx["ASCPU"] = 'X86_64'
+ if cpu_bits == "32":
+ env_libvpx["ASCPU"] = "X86_32"
+ elif cpu_bits == "64":
+ env_libvpx["ASCPU"] = "X86_64"
- env_libvpx.Append(CPPDEFINES=['WEBM_X86ASM'])
+ env_libvpx.Append(CPPDEFINES=["WEBM_X86ASM"])
webm_simd_optimizations = True
if webm_cpu_arm:
- if env["platform"] == 'iphone':
- env_libvpx["ASFLAGS"] = '-arch armv7'
- elif env["platform"] == 'android' and env["android_arch"] == 'armv7' or env["platform"] == 'x11' or env["platform"] == 'server':
- env_libvpx["ASFLAGS"] = '-mfpu=neon'
- elif env["platform"] == 'uwp':
- env_libvpx["AS"] = 'armasm'
- env_libvpx["ASFLAGS"] = ''
- env_libvpx["ASCOM"] = '$AS $ASFLAGS -o $TARGET $SOURCES'
-
- env_libvpx.Append(CPPDEFINES=['WEBM_ARMASM'])
+ if env["platform"] == "iphone":
+ env_libvpx["ASFLAGS"] = "-arch armv7"
+ elif (
+ env["platform"] == "android"
+ and env["android_arch"] == "armv7"
+ or env["platform"] == "linuxbsd"
+ or env["platform"] == "server"
+ ):
+ env_libvpx["ASFLAGS"] = "-mfpu=neon"
+ elif env["platform"] == "uwp":
+ env_libvpx["AS"] = "armasm"
+ env_libvpx["ASFLAGS"] = ""
+ env_libvpx["ASCOM"] = "$AS $ASFLAGS -o $TARGET $SOURCES"
+
+ env_libvpx.Append(CPPDEFINES=["WEBM_ARMASM"])
webm_simd_optimizations = True
@@ -350,45 +337,49 @@ if webm_multithread:
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_mt)
if webm_cpu_x86:
- is_clang_or_gcc = ('gcc' in os.path.basename(env["CC"])) or ('clang' in os.path.basename(env["CC"])) or ("osxcross" in env)
+ is_clang_or_gcc = (
+ ("gcc" in os.path.basename(env["CC"])) or ("clang" in os.path.basename(env["CC"])) or ("osxcross" in env)
+ )
env_libvpx_mmx = env_libvpx.Clone()
- if cpu_bits == '32' and is_clang_or_gcc:
- env_libvpx_mmx.Append(CCFLAGS=['-mmmx'])
+ if cpu_bits == "32" and is_clang_or_gcc:
+ env_libvpx_mmx.Append(CCFLAGS=["-mmmx"])
env_libvpx_mmx.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_mmx)
env_libvpx_sse2 = env_libvpx.Clone()
- if cpu_bits == '32' and is_clang_or_gcc:
- env_libvpx_sse2.Append(CCFLAGS=['-msse2'])
+ if cpu_bits == "32" and is_clang_or_gcc:
+ env_libvpx_sse2.Append(CCFLAGS=["-msse2"])
env_libvpx_sse2.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_sse2)
env_libvpx_ssse3 = env_libvpx.Clone()
if is_clang_or_gcc:
- env_libvpx_ssse3.Append(CCFLAGS=['-mssse3'])
+ env_libvpx_ssse3.Append(CCFLAGS=["-mssse3"])
env_libvpx_ssse3.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_ssse3)
env_libvpx_avx2 = env_libvpx.Clone()
if is_clang_or_gcc:
- env_libvpx_avx2.Append(CCFLAGS=['-mavx2'])
+ env_libvpx_avx2.Append(CCFLAGS=["-mavx2"])
env_libvpx_avx2.add_source_files(env.modules_sources, libvpx_sources_intrin_x86_avx2)
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_intrin_x86)
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_x86asm)
- if cpu_bits == '64':
+ if cpu_bits == "64":
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_x86_64asm)
elif webm_cpu_arm:
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm)
- if env["platform"] == 'android':
+ if env["platform"] == "android":
env_libvpx.Prepend(CPPPATH=[libvpx_dir + "third_party/android"])
env_libvpx.add_source_files(env.modules_sources, [libvpx_dir + "third_party/android/cpu-features.c"])
env_libvpx_neon = env_libvpx.Clone()
env_libvpx_neon.add_source_files(env.modules_sources, libvpx_sources_arm_neon)
- if env["platform"] == 'uwp':
+ if env["platform"] == "uwp":
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm_neon_armasm_ms)
- elif env["platform"] == 'iphone':
+ elif env["platform"] == "iphone":
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm_neon_gas_apple)
- elif (is_x11_or_server_arm and cpu_bits == '32') or (env["platform"] == 'android' and not env["android_arch"] == 'arm64v8'):
+ elif (is_x11_or_server_arm and cpu_bits == "32") or (
+ env["platform"] == "android" and not env["android_arch"] == "arm64v8"
+ ):
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm_neon_gas)
diff --git a/modules/webm/register_types.h b/modules/webm/register_types.h
index 962a0dab4e..6a02e3a87a 100644
--- a/modules/webm/register_types.h
+++ b/modules/webm/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef WEBM_REGISTER_TYPES_H
+#define WEBM_REGISTER_TYPES_H
+
void register_webm_types();
void unregister_webm_types();
+
+#endif // WEBM_REGISTER_TYPES_H
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 2763d30bb5..a2d0f78f5f 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -96,17 +96,17 @@ private:
VideoStreamPlaybackWebm::VideoStreamPlaybackWebm() :
audio_track(0),
- webm(NULL),
- video(NULL),
- audio(NULL),
- video_frames(NULL),
- audio_frame(NULL),
+ webm(nullptr),
+ video(nullptr),
+ audio(nullptr),
+ video_frames(nullptr),
+ audio_frame(nullptr),
video_frames_pos(0),
video_frames_capacity(0),
num_decoded_samples(0),
samples_offset(-1),
- mix_callback(NULL),
- mix_udata(NULL),
+ mix_callback(nullptr),
+ mix_udata(nullptr),
playing(false),
paused(false),
delay_compensation(0.0),
@@ -114,7 +114,7 @@ VideoStreamPlaybackWebm::VideoStreamPlaybackWebm() :
video_frame_delay(0.0),
video_pos(0.0),
texture(memnew(ImageTexture)),
- pcm(NULL) {}
+ pcm(nullptr) {}
VideoStreamPlaybackWebm::~VideoStreamPlaybackWebm() {
delete_pointers();
@@ -137,19 +137,22 @@ bool VideoStreamPlaybackWebm::open_file(const String &p_file) {
} else {
memdelete(audio);
- audio = NULL;
+ audio = nullptr;
}
frame_data.resize((webm->getWidth() * webm->getHeight()) << 2);
- texture->create(webm->getWidth(), webm->getHeight(), Image::FORMAT_RGBA8, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE);
+ Ref<Image> img;
+ img.instance();
+ img->create(webm->getWidth(), webm->getHeight(), false, Image::FORMAT_RGBA8);
+ texture->create_from_image(img);
return true;
}
memdelete(video);
- video = NULL;
+ video = nullptr;
}
memdelete(webm);
- webm = NULL;
+ webm = nullptr;
return false;
}
@@ -159,13 +162,13 @@ void VideoStreamPlaybackWebm::stop() {
delete_pointers();
- pcm = NULL;
+ pcm = nullptr;
- audio_frame = NULL;
- video_frames = NULL;
+ audio_frame = nullptr;
+ video_frames = nullptr;
- video = NULL;
- audio = NULL;
+ video = nullptr;
+ audio = nullptr;
open_file(file_name); //Should not fail here...
@@ -231,7 +234,7 @@ void VideoStreamPlaybackWebm::set_audio_track(int p_idx) {
audio_track = p_idx;
}
-Ref<Texture> VideoStreamPlaybackWebm::get_texture() const {
+Ref<Texture2D> VideoStreamPlaybackWebm::get_texture() const {
return texture;
}
@@ -312,12 +315,12 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
if (err == VPXDecoder::NO_ERROR && image.w == webm->getWidth() && image.h == webm->getHeight()) {
- PoolVector<uint8_t>::Write w = frame_data.write();
+ uint8_t *w = frame_data.ptrw();
bool converted = false;
if (image.chromaShiftW == 0 && image.chromaShiftH == 0 && image.cs == VPX_CS_SRGB) {
- uint8_t *wp = w.ptr();
+ uint8_t *wp = w;
unsigned char *rRow = image.planes[2];
unsigned char *gRow = image.planes[0];
unsigned char *bRow = image.planes[1];
@@ -335,17 +338,17 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
converted = true;
} else if (image.chromaShiftW == 1 && image.chromaShiftH == 1) {
- yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
+ yuv420_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
//libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) {
- yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
+ yuv422_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
//libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) {
- yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
+ yuv444_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
//libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) {
@@ -356,7 +359,7 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
if (converted) {
Ref<Image> img = memnew(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data));
- texture->set_data(img); //Zero copy send to visual server
+ texture->update(img); //Zero copy send to visual server
video_frame_done = true;
}
}
@@ -444,7 +447,7 @@ Ref<VideoStreamPlayback> VideoStreamWebm::instance_playback() {
pb->set_audio_track(audio_track);
if (pb->open_file(file))
return pb;
- return NULL;
+ return nullptr;
}
void VideoStreamWebm::set_file(const String &p_file) {
@@ -471,7 +474,7 @@ void VideoStreamWebm::set_audio_track(int p_track) {
////////////
-RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h
index e679196cf2..6677fb85aa 100644
--- a/modules/webm/video_stream_webm.h
+++ b/modules/webm/video_stream_webm.h
@@ -61,7 +61,7 @@ class VideoStreamPlaybackWebm : public VideoStreamPlayback {
double delay_compensation;
double time, video_frame_delay, video_pos;
- PoolVector<uint8_t> frame_data;
+ Vector<uint8_t> frame_data;
Ref<ImageTexture> texture;
float *pcm;
@@ -90,7 +90,7 @@ public:
virtual void set_audio_track(int p_idx);
- virtual Ref<Texture> get_texture() const;
+ virtual Ref<Texture2D> get_texture() const;
virtual void update(float p_delta);
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata);
@@ -128,7 +128,7 @@ public:
class ResourceFormatLoaderWebm : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/webp/SCsub b/modules/webp/SCsub
index 666628bb44..58f2bb35e6 100644
--- a/modules/webp/SCsub
+++ b/modules/webp/SCsub
@@ -1,12 +1,12 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_webp = env_modules.Clone()
# Thirdparty source files
-if env['builtin_libwebp']:
+if env["builtin_libwebp"]:
thirdparty_dir = "#thirdparty/libwebp/"
thirdparty_sources = [
"dec/alpha_dec.c",
diff --git a/modules/webp/config.py b/modules/webp/config.py
index 1c8cd12a2d..d22f9454ed 100644
--- a/modules/webp/config.py
+++ b/modules/webp/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 7f4afa9a08..0998977bb4 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -38,9 +38,9 @@
#include <webp/decode.h>
#include <webp/encode.h>
-static PoolVector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
+static Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
- ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), PoolVector<uint8_t>());
+ ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), Vector<uint8_t>());
Ref<Image> img = p_image->duplicate();
if (img->detect_alpha())
@@ -49,37 +49,37 @@ static PoolVector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_q
img->convert(Image::FORMAT_RGB8);
Size2 s(img->get_width(), img->get_height());
- PoolVector<uint8_t> data = img->get_data();
- PoolVector<uint8_t>::Read r = data.read();
+ Vector<uint8_t> data = img->get_data();
+ const uint8_t *r = data.ptr();
- uint8_t *dst_buff = NULL;
+ uint8_t *dst_buff = nullptr;
size_t dst_size = 0;
if (img->get_format() == Image::FORMAT_RGB8) {
- dst_size = WebPEncodeRGB(r.ptr(), s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
+ dst_size = WebPEncodeRGB(r, s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
} else {
- dst_size = WebPEncodeRGBA(r.ptr(), s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
+ dst_size = WebPEncodeRGBA(r, s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
}
- ERR_FAIL_COND_V(dst_size == 0, PoolVector<uint8_t>());
- PoolVector<uint8_t> dst;
+ ERR_FAIL_COND_V(dst_size == 0, Vector<uint8_t>());
+ Vector<uint8_t> dst;
dst.resize(4 + dst_size);
- PoolVector<uint8_t>::Write w = dst.write();
+ uint8_t *w = dst.ptrw();
w[0] = 'W';
w[1] = 'E';
w[2] = 'B';
w[3] = 'P';
copymem(&w[4], dst_buff, dst_size);
free(dst_buff);
- w.release();
+
return dst;
}
-static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
+static Ref<Image> _webp_lossy_unpack(const Vector<uint8_t> &p_buffer) {
int size = p_buffer.size() - 4;
ERR_FAIL_COND_V(size <= 0, Ref<Image>());
- PoolVector<uint8_t>::Read r = p_buffer.read();
+ const uint8_t *r = p_buffer.ptr();
ERR_FAIL_COND_V(r[0] != 'W' || r[1] != 'E' || r[2] != 'B' || r[3] != 'P', Ref<Image>());
WebPBitstreamFeatures features;
@@ -93,23 +93,21 @@ static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
print_line("alpha: "+itos(features.has_alpha));
*/
- PoolVector<uint8_t> dst_image;
+ Vector<uint8_t> dst_image;
int datasize = features.width * features.height * (features.has_alpha ? 4 : 3);
dst_image.resize(datasize);
- PoolVector<uint8_t>::Write dst_w = dst_image.write();
+ uint8_t *dst_w = dst_image.ptrw();
bool errdec = false;
if (features.has_alpha) {
- errdec = WebPDecodeRGBAInto(&r[4], size, dst_w.ptr(), datasize, 4 * features.width) == NULL;
+ errdec = WebPDecodeRGBAInto(&r[4], size, dst_w, datasize, 4 * features.width) == nullptr;
} else {
- errdec = WebPDecodeRGBInto(&r[4], size, dst_w.ptr(), datasize, 3 * features.width) == NULL;
+ errdec = WebPDecodeRGBInto(&r[4], size, dst_w, datasize, 3 * features.width) == nullptr;
}
ERR_FAIL_COND_V_MSG(errdec, Ref<Image>(), "Failed decoding WebP image.");
- dst_w.release();
-
Ref<Image> img = memnew(Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image));
return img;
}
@@ -123,18 +121,17 @@ Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
- PoolVector<uint8_t> dst_image;
+ Vector<uint8_t> dst_image;
int datasize = features.width * features.height * (features.has_alpha ? 4 : 3);
dst_image.resize(datasize);
- PoolVector<uint8_t>::Write dst_w = dst_image.write();
+ uint8_t *dst_w = dst_image.ptrw();
bool errdec = false;
if (features.has_alpha) {
- errdec = WebPDecodeRGBAInto(p_buffer, p_buffer_len, dst_w.ptr(), datasize, 4 * features.width) == NULL;
+ errdec = WebPDecodeRGBAInto(p_buffer, p_buffer_len, dst_w, datasize, 4 * features.width) == nullptr;
} else {
- errdec = WebPDecodeRGBInto(p_buffer, p_buffer_len, dst_w.ptr(), datasize, 3 * features.width) == NULL;
+ errdec = WebPDecodeRGBInto(p_buffer, p_buffer_len, dst_w, datasize, 3 * features.width) == nullptr;
}
- dst_w.release();
ERR_FAIL_COND_V_MSG(errdec, ERR_FILE_CORRUPT, "Failed decoding WebP image.");
@@ -154,18 +151,18 @@ static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) {
Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
- PoolVector<uint8_t> src_image;
+ Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
src_image.resize(src_image_len);
- PoolVector<uint8_t>::Write w = src_image.write();
+ uint8_t *w = src_image.ptrw();
f->get_buffer(&w[0], src_image_len);
f->close();
- Error err = webp_load_image_from_buffer(p_image.ptr(), w.ptr(), src_image_len);
+ Error err = webp_load_image_from_buffer(p_image.ptr(), w, src_image_len);
return err;
}
diff --git a/modules/webp/register_types.cpp b/modules/webp/register_types.cpp
index 12a0c05f44..fe945b01d4 100644
--- a/modules/webp/register_types.cpp
+++ b/modules/webp/register_types.cpp
@@ -32,7 +32,7 @@
#include "image_loader_webp.h"
-static ImageLoaderWEBP *image_loader_webp = NULL;
+static ImageLoaderWEBP *image_loader_webp = nullptr;
void register_webp_types() {
diff --git a/modules/webp/register_types.h b/modules/webp/register_types.h
index 9591b91558..d574d7be1d 100644
--- a/modules/webp/register_types.h
+++ b/modules/webp/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef WEBP_REGISTER_TYPES_H
+#define WEBP_REGISTER_TYPES_H
+
void register_webp_types();
void unregister_webp_types();
+
+#endif // WEBP_REGISTER_TYPES_H
diff --git a/modules/webrtc/SCsub b/modules/webrtc/SCsub
index 868553b879..20b4c8f8d2 100644
--- a/modules/webrtc/SCsub
+++ b/modules/webrtc/SCsub
@@ -1,15 +1,15 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
# Thirdparty source files
env_webrtc = env_modules.Clone()
use_gdnative = env_webrtc["module_gdnative_enabled"]
-if use_gdnative: # GDNative is retained in Javascript for export compatibility
- env_webrtc.Append(CPPDEFINES=['WEBRTC_GDNATIVE_ENABLED'])
+if use_gdnative: # GDNative is retained in Javascript for export compatibility
+ env_webrtc.Append(CPPDEFINES=["WEBRTC_GDNATIVE_ENABLED"])
env_webrtc.Prepend(CPPPATH=["#modules/gdnative/include/"])
env_webrtc.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/webrtc/config.py b/modules/webrtc/config.py
index 48b4c33c5d..0a075ccef1 100644
--- a/modules/webrtc/config.py
+++ b/modules/webrtc/config.py
@@ -1,15 +1,18 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"WebRTCPeerConnection",
"WebRTCDataChannel",
- "WebRTCMultiplayer"
+ "WebRTCMultiplayer",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/webrtc/register_types.h b/modules/webrtc/register_types.h
index e6b50506e5..8f5b9e8452 100644
--- a/modules/webrtc/register_types.h
+++ b/modules/webrtc/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef WEBRTC_REGISTER_TYPES_H
+#define WEBRTC_REGISTER_TYPES_H
+
void register_webrtc_types();
void unregister_webrtc_types();
+
+#endif // WEBRTC_REGISTER_TYPES_H
diff --git a/modules/webrtc/webrtc_data_channel_gdnative.cpp b/modules/webrtc/webrtc_data_channel_gdnative.cpp
index b0c4b473fc..67ad2c07ce 100644
--- a/modules/webrtc/webrtc_data_channel_gdnative.cpp
+++ b/modules/webrtc/webrtc_data_channel_gdnative.cpp
@@ -39,94 +39,94 @@ void WebRTCDataChannelGDNative::_bind_methods() {
}
WebRTCDataChannelGDNative::WebRTCDataChannelGDNative() {
- interface = NULL;
+ interface = nullptr;
}
WebRTCDataChannelGDNative::~WebRTCDataChannelGDNative() {
}
Error WebRTCDataChannelGDNative::poll() {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->poll(interface->data);
}
void WebRTCDataChannelGDNative::close() {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->close(interface->data);
}
void WebRTCDataChannelGDNative::set_write_mode(WriteMode p_mode) {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->set_write_mode(interface->data, p_mode);
}
WebRTCDataChannel::WriteMode WebRTCDataChannelGDNative::get_write_mode() const {
- ERR_FAIL_COND_V(interface == NULL, WRITE_MODE_BINARY);
+ ERR_FAIL_COND_V(interface == nullptr, WRITE_MODE_BINARY);
return (WriteMode)interface->get_write_mode(interface->data);
}
bool WebRTCDataChannelGDNative::was_string_packet() const {
- ERR_FAIL_COND_V(interface == NULL, false);
+ ERR_FAIL_COND_V(interface == nullptr, false);
return interface->was_string_packet(interface->data);
}
WebRTCDataChannel::ChannelState WebRTCDataChannelGDNative::get_ready_state() const {
- ERR_FAIL_COND_V(interface == NULL, STATE_CLOSED);
+ ERR_FAIL_COND_V(interface == nullptr, STATE_CLOSED);
return (ChannelState)interface->get_ready_state(interface->data);
}
String WebRTCDataChannelGDNative::get_label() const {
- ERR_FAIL_COND_V(interface == NULL, "");
+ ERR_FAIL_COND_V(interface == nullptr, "");
return String(interface->get_label(interface->data));
}
bool WebRTCDataChannelGDNative::is_ordered() const {
- ERR_FAIL_COND_V(interface == NULL, false);
+ ERR_FAIL_COND_V(interface == nullptr, false);
return interface->is_ordered(interface->data);
}
int WebRTCDataChannelGDNative::get_id() const {
- ERR_FAIL_COND_V(interface == NULL, -1);
+ ERR_FAIL_COND_V(interface == nullptr, -1);
return interface->get_id(interface->data);
}
int WebRTCDataChannelGDNative::get_max_packet_life_time() const {
- ERR_FAIL_COND_V(interface == NULL, -1);
+ ERR_FAIL_COND_V(interface == nullptr, -1);
return interface->get_max_packet_life_time(interface->data);
}
int WebRTCDataChannelGDNative::get_max_retransmits() const {
- ERR_FAIL_COND_V(interface == NULL, -1);
+ ERR_FAIL_COND_V(interface == nullptr, -1);
return interface->get_max_retransmits(interface->data);
}
String WebRTCDataChannelGDNative::get_protocol() const {
- ERR_FAIL_COND_V(interface == NULL, "");
+ ERR_FAIL_COND_V(interface == nullptr, "");
return String(interface->get_protocol(interface->data));
}
bool WebRTCDataChannelGDNative::is_negotiated() const {
- ERR_FAIL_COND_V(interface == NULL, false);
+ ERR_FAIL_COND_V(interface == nullptr, false);
return interface->is_negotiated(interface->data);
}
Error WebRTCDataChannelGDNative::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->get_packet(interface->data, r_buffer, &r_buffer_size);
}
Error WebRTCDataChannelGDNative::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->put_packet(interface->data, p_buffer, p_buffer_size);
}
int WebRTCDataChannelGDNative::get_max_packet_size() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_max_packet_size(interface->data);
}
int WebRTCDataChannelGDNative::get_available_packet_count() const {
- ERR_FAIL_COND_V(interface == NULL, 0);
+ ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_available_packet_count(interface->data);
}
diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp
index 37203a4ec9..1b360720a2 100644
--- a/modules/webrtc/webrtc_data_channel_js.cpp
+++ b/modules/webrtc/webrtc_data_channel_js.cpp
@@ -334,7 +334,7 @@ WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) {
stringToUTF8(str, ptr, len+1);
return ptr;
}, js_id);
- if(str != NULL) {
+ if(str != nullptr) {
_label.parse_utf8(str);
EM_ASM({ _free($0) }, str);
}
@@ -347,7 +347,7 @@ WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) {
stringToUTF8(str, ptr, len+1);
return ptr;
}, js_id);
- if(str != NULL) {
+ if(str != nullptr) {
_protocol.parse_utf8(str);
EM_ASM({ _free($0) }, str);
}
diff --git a/modules/webrtc/webrtc_multiplayer.cpp b/modules/webrtc/webrtc_multiplayer.cpp
index 9df2420bbc..78a4d1e61a 100644
--- a/modules/webrtc/webrtc_multiplayer.cpp
+++ b/modules/webrtc/webrtc_multiplayer.cpp
@@ -70,7 +70,7 @@ void WebRTCMultiplayer::poll() {
List<int> remove;
List<int> add;
- for (Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) {
Ref<ConnectedPeer> peer = E->get();
peer->connection->poll();
// Check peer state
@@ -89,7 +89,7 @@ void WebRTCMultiplayer::poll() {
}
// Check channels state
int ready = 0;
- for (List<Ref<WebRTCDataChannel> >::Element *C = peer->channels.front(); C && C->get().is_valid(); C = C->next()) {
+ for (List<Ref<WebRTCDataChannel>>::Element *C = peer->channels.front(); C && C->get().is_valid(); C = C->next()) {
Ref<WebRTCDataChannel> ch = C->get();
switch (ch->get_ready_state()) {
case WebRTCDataChannel::STATE_CONNECTING:
@@ -130,7 +130,7 @@ void WebRTCMultiplayer::poll() {
emit_signal("peer_connected", TARGET_PEER_SERVER);
emit_signal("connection_succeeded");
// Notify of all previously connected peers
- for (Map<int, Ref<ConnectedPeer> >::Element *F = peer_map.front(); F; F = F->next()) {
+ for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) {
if (F->key() != 1 && F->get()->connected)
emit_signal("peer_connected", F->key());
}
@@ -143,11 +143,11 @@ void WebRTCMultiplayer::poll() {
}
void WebRTCMultiplayer::_find_next_peer() {
- Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.find(next_packet_peer);
+ Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.find(next_packet_peer);
if (E) E = E->next();
// After last.
while (E) {
- for (List<Ref<WebRTCDataChannel> >::Element *F = E->get()->channels.front(); F; F = F->next()) {
+ for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) {
if (F->get()->get_available_packet_count()) {
next_packet_peer = E->key();
return;
@@ -158,7 +158,7 @@ void WebRTCMultiplayer::_find_next_peer() {
E = peer_map.front();
// Before last
while (E) {
- for (List<Ref<WebRTCDataChannel> >::Element *F = E->get()->channels.front(); F; F = F->next()) {
+ for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) {
if (F->get()->get_available_packet_count()) {
next_packet_peer = E->key();
return;
@@ -204,7 +204,7 @@ int WebRTCMultiplayer::get_unique_id() const {
void WebRTCMultiplayer::_peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dictionary &r_dict) {
Array channels;
- for (List<Ref<WebRTCDataChannel> >::Element *F = p_connected_peer->channels.front(); F; F = F->next()) {
+ for (List<Ref<WebRTCDataChannel>>::Element *F = p_connected_peer->channels.front(); F; F = F->next()) {
channels.push_back(F->get());
}
r_dict["connection"] = p_connected_peer->connection;
@@ -225,7 +225,7 @@ Dictionary WebRTCMultiplayer::get_peer(int p_peer_id) {
Dictionary WebRTCMultiplayer::get_peers() {
Dictionary out;
- for (Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) {
Dictionary d;
_peer_to_dict(E->get(), d);
out[E->key()] = d;
@@ -288,7 +288,7 @@ Error WebRTCMultiplayer::get_packet(const uint8_t **r_buffer, int &r_buffer_size
_find_next_peer();
ERR_FAIL_V(ERR_UNAVAILABLE);
}
- for (List<Ref<WebRTCDataChannel> >::Element *E = peer_map[next_packet_peer]->channels.front(); E; E = E->next()) {
+ for (List<Ref<WebRTCDataChannel>>::Element *E = peer_map[next_packet_peer]->channels.front(); E; E = E->next()) {
if (E->get()->get_available_packet_count()) {
Error err = E->get()->get_packet(r_buffer, r_buffer_size);
_find_next_peer();
@@ -316,7 +316,7 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
break;
}
- Map<int, Ref<ConnectedPeer> >::Element *E = NULL;
+ Map<int, Ref<ConnectedPeer>>::Element *E = nullptr;
if (target_peer > 0) {
@@ -330,7 +330,7 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
} else {
int exclude = -target_peer;
- for (Map<int, Ref<ConnectedPeer> >::Element *F = peer_map.front(); F; F = F->next()) {
+ for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) {
// Exclude packet. If target_peer == 0 then don't exclude any packets
if (target_peer != 0 && F->key() == exclude)
@@ -347,8 +347,8 @@ int WebRTCMultiplayer::get_available_packet_count() const {
if (next_packet_peer == 0)
return 0; // To be sure next call to get_packet works if size > 0 .
int size = 0;
- for (Map<int, Ref<ConnectedPeer> >::Element *E = peer_map.front(); E; E = E->next()) {
- for (List<Ref<WebRTCDataChannel> >::Element *F = E->get()->channels.front(); F; F = F->next()) {
+ for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) {
+ for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) {
size += F->get()->get_available_packet_count();
}
}
@@ -371,6 +371,7 @@ WebRTCMultiplayer::WebRTCMultiplayer() {
unique_id = 0;
next_packet_peer = 0;
target_peer = 0;
+ client_count = 0;
transfer_mode = TRANSFER_MODE_RELIABLE;
refuse_connections = false;
connection_status = CONNECTION_DISCONNECTED;
diff --git a/modules/webrtc/webrtc_multiplayer.h b/modules/webrtc/webrtc_multiplayer.h
index 66a3cd0ff5..0e1335b8a8 100644
--- a/modules/webrtc/webrtc_multiplayer.h
+++ b/modules/webrtc/webrtc_multiplayer.h
@@ -53,7 +53,7 @@ private:
public:
Ref<WebRTCPeerConnection> connection;
- List<Ref<WebRTCDataChannel> > channels;
+ List<Ref<WebRTCDataChannel>> channels;
bool connected;
ConnectedPeer() {
@@ -72,7 +72,7 @@ private:
int next_packet_peer;
bool server_compat;
- Map<int, Ref<ConnectedPeer> > peer_map;
+ Map<int, Ref<ConnectedPeer>> peer_map;
void _peer_to_dict(Ref<ConnectedPeer> p_connected_peer, Dictionary &r_dict);
void _find_next_peer();
diff --git a/modules/webrtc/webrtc_peer_connection.cpp b/modules/webrtc/webrtc_peer_connection.cpp
index 90c62e2495..399e4f09ff 100644
--- a/modules/webrtc/webrtc_peer_connection.cpp
+++ b/modules/webrtc/webrtc_peer_connection.cpp
@@ -30,7 +30,7 @@
#include "webrtc_peer_connection.h"
-WebRTCPeerConnection *(*WebRTCPeerConnection::_create)() = NULL;
+WebRTCPeerConnection *(*WebRTCPeerConnection::_create)() = nullptr;
Ref<WebRTCPeerConnection> WebRTCPeerConnection::create_ref() {
@@ -40,7 +40,7 @@ Ref<WebRTCPeerConnection> WebRTCPeerConnection::create_ref() {
WebRTCPeerConnection *WebRTCPeerConnection::create() {
if (!_create)
- return NULL;
+ return nullptr;
return _create();
}
diff --git a/modules/webrtc/webrtc_peer_connection_gdnative.cpp b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
index 411ad50275..f082646629 100644
--- a/modules/webrtc/webrtc_peer_connection_gdnative.cpp
+++ b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
@@ -36,12 +36,12 @@
#include "modules/gdnative/nativescript/nativescript.h"
#include "webrtc_data_channel_gdnative.h"
-const godot_net_webrtc_library *WebRTCPeerConnectionGDNative::default_library = NULL;
+const godot_net_webrtc_library *WebRTCPeerConnectionGDNative::default_library = nullptr;
Error WebRTCPeerConnectionGDNative::set_default_library(const godot_net_webrtc_library *p_lib) {
if (default_library) {
const godot_net_webrtc_library *old = default_library;
- default_library = NULL;
+ default_library = nullptr;
old->unregistered();
}
default_library = p_lib;
@@ -64,54 +64,54 @@ void WebRTCPeerConnectionGDNative::_bind_methods() {
}
WebRTCPeerConnectionGDNative::WebRTCPeerConnectionGDNative() {
- interface = NULL;
+ interface = nullptr;
}
WebRTCPeerConnectionGDNative::~WebRTCPeerConnectionGDNative() {
}
Error WebRTCPeerConnectionGDNative::initialize(Dictionary p_config) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->initialize(interface->data, (const godot_dictionary *)&p_config);
}
Ref<WebRTCDataChannel> WebRTCPeerConnectionGDNative::create_data_channel(String p_label, Dictionary p_options) {
- ERR_FAIL_COND_V(interface == NULL, NULL);
+ ERR_FAIL_COND_V(interface == nullptr, nullptr);
return (WebRTCDataChannel *)interface->create_data_channel(interface->data, p_label.utf8().get_data(), (const godot_dictionary *)&p_options);
}
Error WebRTCPeerConnectionGDNative::create_offer() {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->create_offer(interface->data);
}
Error WebRTCPeerConnectionGDNative::set_local_description(String p_type, String p_sdp) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->set_local_description(interface->data, p_type.utf8().get_data(), p_sdp.utf8().get_data());
}
Error WebRTCPeerConnectionGDNative::set_remote_description(String p_type, String p_sdp) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->set_remote_description(interface->data, p_type.utf8().get_data(), p_sdp.utf8().get_data());
}
Error WebRTCPeerConnectionGDNative::add_ice_candidate(String sdpMidName, int sdpMlineIndexName, String sdpName) {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->add_ice_candidate(interface->data, sdpMidName.utf8().get_data(), sdpMlineIndexName, sdpName.utf8().get_data());
}
Error WebRTCPeerConnectionGDNative::poll() {
- ERR_FAIL_COND_V(interface == NULL, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(interface == nullptr, ERR_UNCONFIGURED);
return (Error)interface->poll(interface->data);
}
void WebRTCPeerConnectionGDNative::close() {
- ERR_FAIL_COND(interface == NULL);
+ ERR_FAIL_COND(interface == nullptr);
interface->close(interface->data);
}
WebRTCPeerConnection::ConnectionState WebRTCPeerConnectionGDNative::get_connection_state() const {
- ERR_FAIL_COND_V(interface == NULL, STATE_DISCONNECTED);
+ ERR_FAIL_COND_V(interface == nullptr, STATE_DISCONNECTED);
return (ConnectionState)interface->get_connection_state(interface->data);
}
diff --git a/modules/webrtc/webrtc_peer_connection_js.cpp b/modules/webrtc/webrtc_peer_connection_js.cpp
index a84dabab72..593c3a5162 100644
--- a/modules/webrtc/webrtc_peer_connection_js.cpp
+++ b/modules/webrtc/webrtc_peer_connection_js.cpp
@@ -279,7 +279,7 @@ Ref<WebRTCDataChannel> WebRTCPeerConnectionJS::create_data_channel(String p_chan
}
}, _js_id, p_channel.utf8().get_data(), config.utf8().get_data());
/* clang-format on */
- ERR_FAIL_COND_V(id == 0, NULL);
+ ERR_FAIL_COND_V(id == 0, nullptr);
return memnew(WebRTCDataChannelJS(id));
}
diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub
index 033169411f..af60055855 100644
--- a/modules/websocket/SCsub
+++ b/modules/websocket/SCsub
@@ -1,13 +1,13 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
# Thirdparty source files
env_ws = env_modules.Clone()
-if env['builtin_wslay'] and not env["platform"] == "javascript": # already builtin for javascript
+if env["builtin_wslay"] and not env["platform"] == "javascript": # already builtin for javascript
wslay_dir = "#thirdparty/wslay/"
wslay_sources = [
"wslay_net.c",
diff --git a/modules/websocket/config.py b/modules/websocket/config.py
index f59ef432b4..9e27a1a0fe 100644
--- a/modules/websocket/config.py
+++ b/modules/websocket/config.py
@@ -1,16 +1,19 @@
def can_build(env, platform):
return True
+
def configure(env):
pass
+
def get_doc_classes():
return [
"WebSocketClient",
"WebSocketMultiplayerPeer",
"WebSocketPeer",
- "WebSocketServer"
+ "WebSocketServer",
]
+
def get_doc_path():
return "doc_classes"
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml
index 2549321db3..45db49c913 100644
--- a/modules/websocket/doc_classes/WebSocketClient.xml
+++ b/modules/websocket/doc_classes/WebSocketClient.xml
@@ -17,11 +17,11 @@
</return>
<argument index="0" name="url" type="String">
</argument>
- <argument index="1" name="protocols" type="PoolStringArray" default="PoolStringArray( )">
+ <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray( )">
</argument>
<argument index="2" name="gd_mp_api" type="bool" default="false">
</argument>
- <argument index="3" name="custom_headers" type="PoolStringArray" default="PoolStringArray( )">
+ <argument index="3" name="custom_headers" type="PackedStringArray" default="PackedStringArray( )">
</argument>
<description>
Connects to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. If the list empty (default), no sub-protocol will be requested.
diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml
index f66e1bf54b..f7805209e2 100644
--- a/modules/websocket/doc_classes/WebSocketServer.xml
+++ b/modules/websocket/doc_classes/WebSocketServer.xml
@@ -63,7 +63,7 @@
</return>
<argument index="0" name="port" type="int">
</argument>
- <argument index="1" name="protocols" type="PoolStringArray" default="PoolStringArray( )">
+ <argument index="1" name="protocols" type="PackedStringArray" default="PackedStringArray( )">
</argument>
<argument index="2" name="gd_mp_api" type="bool" default="false">
</argument>
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
index 7e68936fc3..bbe4d6dc5b 100644
--- a/modules/websocket/emws_client.cpp
+++ b/modules/websocket/emws_client.cpp
@@ -91,10 +91,14 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
int peer_sock = EM_ASM_INT({
var proto_str = UTF8ToString($2);
var socket = null;
- if (proto_str) {
- socket = new WebSocket(UTF8ToString($1), proto_str.split(","));
- } else {
- socket = new WebSocket(UTF8ToString($1));
+ try {
+ if (proto_str) {
+ socket = new WebSocket(UTF8ToString($1), proto_str.split(","));
+ } else {
+ socket = new WebSocket(UTF8ToString($1));
+ }
+ } catch (e) {
+ return -1;
}
var c_ptr = Module.IDHandler.get($0);
socket.binaryType = "arraybuffer";
@@ -174,8 +178,10 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
return Module.IDHandler.add(socket);
}, _js_id, str.utf8().get_data(), proto_string.utf8().get_data());
/* clang-format on */
+ if (peer_sock == -1)
+ return FAILED;
- static_cast<Ref<EMWSPeer> >(_peer)->set_sock(peer_sock, _in_buf_size, _in_pkt_size);
+ static_cast<Ref<EMWSPeer>>(_peer)->set_sock(peer_sock, _in_buf_size, _in_pkt_size);
return OK;
};
@@ -190,11 +196,11 @@ Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const {
NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const {
- if (_peer->is_connected_to_host())
+ if (_peer->is_connected_to_host()) {
+ if (_is_connecting)
+ return CONNECTION_CONNECTING;
return CONNECTION_CONNECTED;
-
- if (_is_connecting)
- return CONNECTION_CONNECTING;
+ }
return CONNECTION_DISCONNECTED;
};
diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp
index effed8e4d9..9472daa620 100644
--- a/modules/websocket/emws_peer.cpp
+++ b/modules/websocket/emws_peer.cpp
@@ -68,12 +68,17 @@ Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
bytes_array[i] = getValue($1+i, 'i8');
}
- if ($3) {
- sock.send(bytes_array.buffer);
- } else {
- var string = new TextDecoder("utf-8").decode(bytes_array);
- sock.send(string);
+ try {
+ if ($3) {
+ sock.send(bytes_array.buffer);
+ } else {
+ var string = new TextDecoder("utf-8").decode(bytes_array);
+ sock.send(string);
+ }
+ } catch (e) {
+ return 1;
}
+ return 0;
}, peer_sock, p_buffer, p_buffer_size, is_bin);
/* clang-format on */
@@ -85,12 +90,11 @@ Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
if (_in_buffer.packets_left() == 0)
return ERR_UNAVAILABLE;
- PoolVector<uint8_t>::Write rw = _packet_buffer.write();
int read = 0;
- Error err = _in_buffer.read_packet(rw.ptr(), _packet_buffer.size(), &_is_string, read);
+ Error err = _in_buffer.read_packet(_packet_buffer.ptrw(), _packet_buffer.size(), &_is_string, read);
ERR_FAIL_COND_V(err != OK, err);
- *r_buffer = rw.ptr();
+ *r_buffer = _packet_buffer.ptr();
r_buffer_size = read;
return OK;
diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h
index 43b42f9be6..6308ebe490 100644
--- a/modules/websocket/emws_peer.h
+++ b/modules/websocket/emws_peer.h
@@ -48,7 +48,7 @@ private:
int peer_sock;
WriteMode write_mode;
- PoolVector<uint8_t> _packet_buffer;
+ Vector<uint8_t> _packet_buffer;
PacketBuffer<uint8_t> _in_buffer;
uint8_t _is_string;
diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp
index 23faa05365..95cffb4775 100644
--- a/modules/websocket/emws_server.cpp
+++ b/modules/websocket/emws_server.cpp
@@ -50,11 +50,11 @@ bool EMWSServer::has_peer(int p_id) const {
}
Ref<WebSocketPeer> EMWSServer::get_peer(int p_id) const {
- return NULL;
+ return nullptr;
}
-PoolVector<String> EMWSServer::get_protocols() const {
- PoolVector<String> out;
+Vector<String> EMWSServer::get_protocols() const {
+ Vector<String> out;
return out;
}
diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h
index 869e59fe03..f273fd078f 100644
--- a/modules/websocket/emws_server.h
+++ b/modules/websocket/emws_server.h
@@ -53,7 +53,7 @@ public:
void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = "");
int get_max_packet_size() const;
virtual void poll();
- virtual PoolVector<String> get_protocols() const;
+ virtual Vector<String> get_protocols() const;
EMWSServer();
~EMWSServer();
diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h
index ea3658c827..5f5f0e20cd 100644
--- a/modules/websocket/packet_buffer.h
+++ b/modules/websocket/packet_buffer.h
@@ -63,7 +63,7 @@ public:
ERR_FAIL_COND_V(p_info && _packets.space_left() < 1, ERR_OUT_OF_MEMORY);
#endif
- // If p_info is NULL, only the payload is written
+ // If p_info is nullptr, only the payload is written
if (p_info) {
_Packet p;
p.size = p_size;
@@ -71,7 +71,7 @@ public:
_packets.write(p);
}
- // If p_payload is NULL, only the packet information is written.
+ // If p_payload is nullptr, only the packet information is written.
if (p_payload) {
_payload.write((const uint8_t *)p_payload, p_size);
}
diff --git a/modules/websocket/register_types.h b/modules/websocket/register_types.h
index b254b9dae8..bb7be57ab3 100644
--- a/modules/websocket/register_types.h
+++ b/modules/websocket/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef WEBSOCKET_REGISTER_TYPES_H
+#define WEBSOCKET_REGISTER_TYPES_H
+
void register_websocket_types();
void unregister_websocket_types();
+
+#endif // WEBSOCKET_REGISTER_TYPES_H
diff --git a/modules/websocket/websocket_macros.h b/modules/websocket/websocket_macros.h
index 8aa01a70ed..f7eafcff1f 100644
--- a/modules/websocket/websocket_macros.h
+++ b/modules/websocket/websocket_macros.h
@@ -56,13 +56,13 @@ public:\
static CNAME *create() {\
\
if (!_create)\
- return NULL;\
+ return nullptr;\
return _create();\
}\
protected:\
#define GDCINULL(CNAME) \
-CNAME *(*CNAME::_create)() = NULL;
+CNAME *(*CNAME::_create)() = nullptr;
#define GDCIIMPL(IMPNAME, CNAME) \
public:\
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
index 27ea50b524..9b71b32e33 100644
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ b/modules/websocket/websocket_multiplayer_peer.cpp
@@ -42,7 +42,7 @@ WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() {
_current_packet.source = 0;
_current_packet.destination = 0;
_current_packet.size = 0;
- _current_packet.data = NULL;
+ _current_packet.data = nullptr;
}
WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() {
@@ -74,12 +74,12 @@ int WebSocketMultiplayerPeer::_gen_unique_id() const {
void WebSocketMultiplayerPeer::_clear() {
_peer_map.clear();
- if (_current_packet.data != NULL)
+ if (_current_packet.data != nullptr)
memfree(_current_packet.data);
for (List<Packet>::Element *E = _incoming_packets.front(); E; E = E->next()) {
memfree(E->get().data);
- E->get().data = NULL;
+ E->get().data = nullptr;
}
_incoming_packets.clear();
@@ -109,9 +109,9 @@ Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buff
r_buffer_size = 0;
- if (_current_packet.data != NULL) {
+ if (_current_packet.data != nullptr) {
memfree(_current_packet.data);
- _current_packet.data = NULL;
+ _current_packet.data = nullptr;
}
_current_packet = _incoming_packets.front()->get();
@@ -127,12 +127,12 @@ Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer
ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI.");
- PoolVector<uint8_t> buffer = _make_pkt(SYS_NONE, get_unique_id(), _target_peer, p_buffer, p_buffer_size);
+ Vector<uint8_t> buffer = _make_pkt(SYS_NONE, get_unique_id(), _target_peer, p_buffer, p_buffer_size);
if (is_server()) {
- return _server_relay(1, _target_peer, &(buffer.read()[0]), buffer.size());
+ return _server_relay(1, _target_peer, &(buffer.ptr()[0]), buffer.size());
} else {
- return get_peer(1)->put_packet(&(buffer.read()[0]), buffer.size());
+ return get_peer(1)->put_packet(&(buffer.ptr()[0]), buffer.size());
}
}
@@ -183,16 +183,16 @@ void WebSocketMultiplayerPeer::_send_sys(Ref<WebSocketPeer> p_peer, uint8_t p_ty
ERR_FAIL_COND(!p_peer.is_valid());
ERR_FAIL_COND(!p_peer->is_connected_to_host());
- PoolVector<uint8_t> message = _make_pkt(p_type, 1, 0, (uint8_t *)&p_peer_id, 4);
- p_peer->put_packet(&(message.read()[0]), message.size());
+ Vector<uint8_t> message = _make_pkt(p_type, 1, 0, (uint8_t *)&p_peer_id, 4);
+ p_peer->put_packet(&(message.ptr()[0]), message.size());
}
-PoolVector<uint8_t> WebSocketMultiplayerPeer::_make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size) {
+Vector<uint8_t> WebSocketMultiplayerPeer::_make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size) {
- PoolVector<uint8_t> out;
+ Vector<uint8_t> out;
out.resize(PROTO_SIZE + p_data_size);
- PoolVector<uint8_t>::Write w = out.write();
+ uint8_t *w = out.ptrw();
copymem(&w[0], &p_type, 1);
copymem(&w[1], &p_from, 4);
copymem(&w[5], &p_to, 4);
@@ -209,7 +209,7 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) {
// Then send the server peer (which will trigger connection_succeded in client)
_send_sys(get_peer(p_peer_id), SYS_ADD, 1);
- for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
int32_t id = E->key();
if (p_peer_id == id)
continue; // Skip the newwly added peer (already confirmed)
@@ -222,7 +222,7 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) {
}
void WebSocketMultiplayerPeer::_send_del(int32_t p_peer_id) {
- for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
int32_t id = E->key();
if (p_peer_id != id)
_send_sys(get_peer(id), SYS_DEL, p_peer_id);
@@ -247,7 +247,7 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons
} else if (p_to == 0) {
- for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
if (E->key() != p_from)
E->get()->put_packet(p_buffer, p_buffer_size);
}
@@ -255,7 +255,7 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons
} else if (p_to < 0) {
- for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
if (E->key() != p_from && E->key() != -p_to)
E->get()->put_packet(p_buffer, p_buffer_size);
}
diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h
index 27cb6e4eb7..c6669c730c 100644
--- a/modules/websocket/websocket_multiplayer_peer.h
+++ b/modules/websocket/websocket_multiplayer_peer.h
@@ -41,7 +41,7 @@ class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer {
GDCLASS(WebSocketMultiplayerPeer, NetworkedMultiplayerPeer);
private:
- PoolVector<uint8_t> _make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size);
+ Vector<uint8_t> _make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size);
void _store_pkt(int32_t p_source, int32_t p_dest, const uint8_t *p_data, uint32_t p_data_size);
Error _server_relay(int32_t p_from, int32_t p_to, const uint8_t *p_buffer, uint32_t p_buffer_size);
@@ -63,7 +63,7 @@ protected:
};
List<Packet> _incoming_packets;
- Map<int, Ref<WebSocketPeer> > _peer_map;
+ Map<int, Ref<WebSocketPeer>> _peer_map;
Packet _current_packet;
bool _is_multiplayer;
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
index 088f266f18..9f05500eb9 100644
--- a/modules/websocket/wsl_client.cpp
+++ b/modules/websocket/wsl_client.cpp
@@ -253,7 +253,7 @@ void WSLClient::poll() {
}
_connection = ssl;
} else {
- ssl = static_cast<Ref<StreamPeerSSL> >(_connection);
+ ssl = static_cast<Ref<StreamPeerSSL>>(_connection);
ERR_FAIL_COND(ssl.is_null()); // Bug?
ssl->poll();
}
@@ -279,7 +279,7 @@ void WSLClient::poll() {
Ref<WebSocketPeer> WSLClient::get_peer(int p_peer_id) const {
- ERR_FAIL_COND_V(p_peer_id != 1, NULL);
+ ERR_FAIL_COND_V(p_peer_id != 1, nullptr);
return _peer;
}
@@ -298,7 +298,7 @@ NetworkedMultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() co
void WSLClient::disconnect_from_host(int p_code, String p_reason) {
_peer->close(p_code, p_reason);
- _connection = Ref<StreamPeer>(NULL);
+ _connection = Ref<StreamPeer>(nullptr);
_tcp = Ref<StreamPeerTCP>(memnew(StreamPeerTCP));
_key = "";
diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp
index 08079145e4..44b71f70f4 100644
--- a/modules/websocket/wsl_peer.cpp
+++ b/modules/websocket/wsl_peer.cpp
@@ -43,10 +43,10 @@ String WSLPeer::generate_key() {
// Random key
RandomNumberGenerator rng;
rng.set_seed(OS::get_singleton()->get_unix_time());
- PoolVector<uint8_t> bkey;
+ Vector<uint8_t> bkey;
int len = 16; // 16 bytes, as per RFC
bkey.resize(len);
- PoolVector<uint8_t>::Write w = bkey.write();
+ uint8_t *w = bkey.ptrw();
for (int i = 0; i < len; i++) {
w[i] = (uint8_t)rng.randi_range(0, 255);
}
@@ -69,7 +69,7 @@ void WSLPeer::_wsl_destroy(struct PeerData **p_data) {
}
wslay_event_context_free(data->ctx);
memdelete(data);
- *p_data = NULL;
+ *p_data = nullptr;
}
bool WSLPeer::_wsl_poll(struct PeerData *p_data) {
@@ -163,9 +163,9 @@ wslay_event_callbacks wsl_callbacks = {
wsl_recv_callback,
wsl_send_callback,
wsl_genmask_callback,
- NULL, /* on_frame_recv_start_callback */
- NULL, /* on_frame_recv_callback */
- NULL, /* on_frame_recv_end_callback */
+ nullptr, /* on_frame_recv_start_callback */
+ nullptr, /* on_frame_recv_callback */
+ nullptr, /* on_frame_recv_end_callback */
wsl_msg_recv_callback
};
@@ -199,8 +199,8 @@ Error WSLPeer::parse_message(const wslay_event_on_msg_recv_arg *arg) {
}
void WSLPeer::make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size, unsigned int p_out_pkt_size) {
- ERR_FAIL_COND(_data != NULL);
- ERR_FAIL_COND(p_data == NULL);
+ ERR_FAIL_COND(_data != nullptr);
+ ERR_FAIL_COND(p_data == nullptr);
_in_buffer.resize(p_in_pkt_size, p_in_buf_size);
_packet_buffer.resize((1 << MAX(p_in_buf_size, p_out_buf_size)));
@@ -229,7 +229,7 @@ void WSLPeer::poll() {
return;
if (_wsl_poll(_data)) {
- _data = NULL;
+ _data = nullptr;
}
}
@@ -260,10 +260,10 @@ Error WSLPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
return ERR_UNAVAILABLE;
int read = 0;
- PoolVector<uint8_t>::Write rw = _packet_buffer.write();
- _in_buffer.read_packet(rw.ptr(), _packet_buffer.size(), &_is_string, read);
+ uint8_t *rw = _packet_buffer.ptrw();
+ _in_buffer.read_packet(rw, _packet_buffer.size(), &_is_string, read);
- *r_buffer = rw.ptr();
+ *r_buffer = rw;
r_buffer_size = read;
return OK;
@@ -284,7 +284,7 @@ bool WSLPeer::was_string_packet() const {
bool WSLPeer::is_connected_to_host() const {
- return _data != NULL;
+ return _data != nullptr;
}
void WSLPeer::close_now() {
@@ -330,7 +330,7 @@ void WSLPeer::invalidate() {
}
WSLPeer::WSLPeer() {
- _data = NULL;
+ _data = nullptr;
_is_string = 0;
close_code = -1;
write_mode = WRITE_MODE_BINARY;
@@ -341,7 +341,7 @@ WSLPeer::~WSLPeer() {
close();
invalidate();
_wsl_destroy(&_data);
- _data = NULL;
+ _data = nullptr;
}
#endif // JAVASCRIPT_ENABLED
diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h
index f1c45ee859..3b0639831a 100644
--- a/modules/websocket/wsl_peer.h
+++ b/modules/websocket/wsl_peer.h
@@ -67,10 +67,10 @@ public:
valid = false;
is_server = false;
id = 1;
- ctx = NULL;
- obj = NULL;
+ ctx = nullptr;
+ obj = nullptr;
closing = false;
- peer = NULL;
+ peer = nullptr;
}
};
@@ -86,7 +86,7 @@ private:
// Our packet info is just a boolean (is_string), using uint8_t for it.
PacketBuffer<uint8_t> _in_buffer;
- PoolVector<uint8_t> _packet_buffer;
+ Vector<uint8_t> _packet_buffer;
WriteMode write_mode;
diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp
index 4db650a0c1..6f155a6ffa 100644
--- a/modules/websocket/wsl_server.cpp
+++ b/modules/websocket/wsl_server.cpp
@@ -103,7 +103,7 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) {
if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT)
return ERR_TIMEOUT;
if (use_ssl) {
- Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL> >(connection);
+ Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL>>(connection);
if (ssl.is_null())
return FAILED;
ssl->poll();
@@ -171,7 +171,7 @@ Error WSLServer::listen(int p_port, const Vector<String> p_protocols, bool gd_mp
void WSLServer::poll() {
List<int> remove_ids;
- for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr();
peer->poll();
if (!peer->is_connected_to_host()) {
@@ -184,8 +184,8 @@ void WSLServer::poll() {
}
remove_ids.clear();
- List<Ref<PendingPeer> > remove_peers;
- for (List<Ref<PendingPeer> >::Element *E = _pending.front(); E; E = E->next()) {
+ List<Ref<PendingPeer>> remove_peers;
+ for (List<Ref<PendingPeer>>::Element *E = _pending.front(); E; E = E->next()) {
Ref<PendingPeer> ppeer = E->get();
Error err = ppeer->do_handshake(_protocols);
if (err == ERR_BUSY) {
@@ -212,7 +212,7 @@ void WSLServer::poll() {
remove_peers.push_back(ppeer);
_on_connect(id, ppeer->protocol);
}
- for (List<Ref<PendingPeer> >::Element *E = remove_peers.front(); E; E = E->next()) {
+ for (List<Ref<PendingPeer>>::Element *E = remove_peers.front(); E; E = E->next()) {
_pending.erase(E->get());
}
remove_peers.clear();
@@ -251,7 +251,7 @@ int WSLServer::get_max_packet_size() const {
void WSLServer::stop() {
_server->stop();
- for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) {
+ for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr();
peer->close_now();
}
@@ -265,7 +265,7 @@ bool WSLServer::has_peer(int p_id) const {
}
Ref<WebSocketPeer> WSLServer::get_peer(int p_id) const {
- ERR_FAIL_COND_V(!has_peer(p_id), NULL);
+ ERR_FAIL_COND_V(!has_peer(p_id), nullptr);
return _peer_map[p_id];
}
diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h
index 649d1adee6..2e893d6727 100644
--- a/modules/websocket/wsl_server.h
+++ b/modules/websocket/wsl_server.h
@@ -76,7 +76,7 @@ private:
int _out_buf_size;
int _out_pkt_size;
- List<Ref<PendingPeer> > _pending;
+ List<Ref<PendingPeer>> _pending;
Ref<TCP_Server> _server;
Vector<String> _protocols;
diff --git a/modules/xatlas_unwrap/SCsub b/modules/xatlas_unwrap/SCsub
index b242fd4673..c659349d05 100644
--- a/modules/xatlas_unwrap/SCsub
+++ b/modules/xatlas_unwrap/SCsub
@@ -1,12 +1,12 @@
#!/usr/bin/env python
-Import('env')
-Import('env_modules')
+Import("env")
+Import("env_modules")
env_xatlas_unwrap = env_modules.Clone()
# Thirdparty source files
-if env['builtin_xatlas']:
+if env["builtin_xatlas"]:
thirdparty_dir = "#thirdparty/xatlas/"
thirdparty_sources = [
"xatlas.cpp",
diff --git a/modules/xatlas_unwrap/config.py b/modules/xatlas_unwrap/config.py
index bd092bdc16..2e73c51626 100644
--- a/modules/xatlas_unwrap/config.py
+++ b/modules/xatlas_unwrap/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return (env['tools'] and platform not in ["android", "ios"])
+ return env["tools"] and platform not in ["android", "ios"]
+
def configure(env):
pass
diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp
index c69b566525..e293dfd50c 100644
--- a/modules/xatlas_unwrap/register_types.cpp
+++ b/modules/xatlas_unwrap/register_types.cpp
@@ -52,7 +52,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
input_mesh.vertexPositionStride = sizeof(float) * 3;
input_mesh.vertexNormalData = p_normals;
input_mesh.vertexNormalStride = sizeof(uint32_t) * 3;
- input_mesh.vertexUvData = NULL;
+ input_mesh.vertexUvData = nullptr;
input_mesh.vertexUvStride = 0;
xatlas::ChartOptions chart_options;
@@ -68,7 +68,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
ERR_FAIL_COND_V_MSG(err != xatlas::AddMeshError::Enum::Success, false, xatlas::StringForEnum(err));
printf("Generate..\n");
- xatlas::Generate(atlas, chart_options, NULL, pack_options);
+ xatlas::Generate(atlas, chart_options, nullptr, pack_options);
*r_size_hint_x = atlas->width;
*r_size_hint_y = atlas->height;
diff --git a/modules/xatlas_unwrap/register_types.h b/modules/xatlas_unwrap/register_types.h
index 3f2181fa63..fe924bab96 100644
--- a/modules/xatlas_unwrap/register_types.h
+++ b/modules/xatlas_unwrap/register_types.h
@@ -28,5 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef XATLAS_UNWRAP_REGISTER_TYPES_H
+#define XATLAS_UNWRAP_REGISTER_TYPES_H
+
void register_xatlas_unwrap_types();
void unregister_xatlas_unwrap_types();
+
+#endif // XATLAS_UNWRAP_REGISTER_TYPES_H