summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/bmp/image_loader_bmp.h2
-rw-r--r--modules/bullet/SCsub2
-rw-r--r--modules/bullet/area_bullet.cpp10
-rw-r--r--modules/bullet/area_bullet.h1
-rw-r--r--modules/bullet/btRayShape.cpp2
-rw-r--r--modules/bullet/bullet_physics_server.cpp2
-rw-r--r--modules/bullet/bullet_physics_server.h4
-rw-r--r--modules/bullet/bullet_utilities.h2
-rw-r--r--modules/bullet/collision_object_bullet.cpp57
-rw-r--r--modules/bullet/collision_object_bullet.h19
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp7
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp14
-rw-r--r--modules/bullet/godot_collision_dispatcher.h2
-rw-r--r--modules/bullet/godot_result_callbacks.cpp8
-rw-r--r--modules/bullet/godot_result_callbacks.h8
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp12
-rw-r--r--modules/bullet/pin_joint_bullet.cpp3
-rw-r--r--modules/bullet/register_types.cpp4
-rw-r--r--modules/bullet/rigid_body_bullet.cpp36
-rw-r--r--modules/bullet/rigid_body_bullet.h1
-rw-r--r--modules/bullet/shape_bullet.cpp10
-rw-r--r--modules/bullet/shape_bullet.h2
-rw-r--r--modules/bullet/space_bullet.cpp72
-rw-r--r--modules/bullet/space_bullet.h2
-rw-r--r--modules/csg/csg.cpp8
-rw-r--r--modules/csg/csg.h16
-rw-r--r--modules/csg/csg_gizmos.cpp12
-rw-r--r--modules/csg/csg_shape.cpp8
-rw-r--r--modules/cvtt/image_compress_cvtt.cpp10
-rw-r--r--modules/cvtt/image_compress_cvtt.h2
-rw-r--r--modules/dds/texture_loader_dds.cpp2
-rw-r--r--modules/dds/texture_loader_dds.h2
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp6
-rw-r--r--modules/enet/networked_multiplayer_enet.h4
-rw-r--r--modules/enet/register_types.cpp2
-rw-r--r--modules/etc/image_etc.cpp8
-rw-r--r--modules/etc/texture_loader_pkm.cpp2
-rw-r--r--modules/etc/texture_loader_pkm.h2
-rw-r--r--modules/gdnative/gdnative.cpp10
-rw-r--r--modules/gdnative/gdnative.h10
-rw-r--r--modules/gdnative/gdnative/basis.cpp34
-rw-r--r--modules/gdnative/gdnative/dictionary.cpp6
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp16
-rw-r--r--modules/gdnative/gdnative/pool_arrays.cpp4
-rw-r--r--modules/gdnative/gdnative/quat.cpp12
-rw-r--r--modules/gdnative/gdnative/transform.cpp6
-rw-r--r--modules/gdnative/gdnative_api.json129
-rw-r--r--modules/gdnative/gdnative_builders.py49
-rw-r--r--modules/gdnative/include/gdnative/basis.h13
-rw-r--r--modules/gdnative/include/gdnative/dictionary.h2
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h4
-rw-r--r--modules/gdnative/include/gdnative/quat.h2
-rw-r--r--modules/gdnative/include/gdnative/transform.h1
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h2
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp2
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp10
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp68
-rw-r--r--modules/gdnative/nativescript/nativescript.h14
-rw-r--r--modules/gdnative/nativescript/register_types.cpp4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.cpp2
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.h4
-rw-r--r--modules/gdnative/pluginscript/register_types.cpp8
-rw-r--r--modules/gdnative/register_types.cpp4
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp4
-rw-r--r--modules/gdscript/gdscript.cpp47
-rw-r--r--modules/gdscript/gdscript.h6
-rw-r--r--modules/gdscript/gdscript_compiler.cpp28
-rw-r--r--modules/gdscript/gdscript_editor.cpp20
-rw-r--r--modules/gdscript/gdscript_function.cpp18
-rw-r--r--modules/gdscript/gdscript_function.h15
-rw-r--r--modules/gdscript/gdscript_functions.cpp18
-rw-r--r--modules/gdscript/gdscript_functions.h2
-rw-r--r--modules/gdscript/gdscript_parser.cpp55
-rw-r--r--modules/gdscript/gdscript_parser.h7
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp6
-rw-r--r--modules/gdscript/gdscript_tokenizer.h8
-rw-r--r--modules/gdscript/register_types.cpp6
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml5
-rw-r--r--modules/gridmap/grid_map.cpp16
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp6
-rw-r--r--modules/gridmap/register_types.cpp2
-rw-r--r--modules/hdr/image_loader_hdr.cpp4
-rw-r--r--modules/hdr/image_loader_hdr.h2
-rw-r--r--modules/jpg/image_loader_jpegd.cpp4
-rw-r--r--modules/jpg/image_loader_jpegd.h2
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.cpp2
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.h2
-rw-r--r--modules/mobile_vr/shaders/lens_distorted.glsl67
-rw-r--r--modules/mono/SCsub44
-rw-r--r--modules/mono/csharp_script.cpp419
-rw-r--r--modules/mono/csharp_script.h42
-rw-r--r--modules/mono/editor/bindings_generator.cpp486
-rw-r--r--modules/mono/editor/bindings_generator.h21
-rw-r--r--modules/mono/editor/csharp_project.cpp4
-rw-r--r--modules/mono/editor/csharp_project.h2
-rw-r--r--modules/mono/editor/godotsharp_builds.cpp24
-rw-r--r--modules/mono/editor/mono_bottom_panel.cpp6
-rw-r--r--modules/mono/editor/monodevelop_instance.h2
-rw-r--r--modules/mono/editor/net_solution.cpp4
-rw-r--r--modules/mono/editor/net_solution.h4
-rw-r--r--modules/mono/glue/base_object_glue.cpp154
-rw-r--r--modules/mono/glue/base_object_glue.h59
-rw-r--r--modules/mono/glue/collections_glue.cpp63
-rw-r--r--modules/mono/glue/collections_glue.h4
-rw-r--r--modules/mono/glue/cs_files/AABB.cs72
-rw-r--r--modules/mono/glue/cs_files/Array.cs85
-rw-r--r--modules/mono/glue/cs_files/Basis.cs92
-rw-r--r--modules/mono/glue/cs_files/Color.cs28
-rw-r--r--modules/mono/glue/cs_files/Dictionary.cs92
-rw-r--r--modules/mono/glue/cs_files/Extensions/ObjectExtensions.cs6
-rw-r--r--modules/mono/glue/cs_files/GD.cs78
-rw-r--r--modules/mono/glue/cs_files/GodotSynchronizationContext.cs32
-rw-r--r--modules/mono/glue/cs_files/GodotTaskScheduler.cs148
-rw-r--r--modules/mono/glue/cs_files/MarshalUtils.cs1
-rw-r--r--modules/mono/glue/cs_files/NodePath.cs147
-rw-r--r--modules/mono/glue/cs_files/Object.base.cs88
-rw-r--r--modules/mono/glue/cs_files/Quat.cs97
-rw-r--r--modules/mono/glue/cs_files/RID.cs76
-rw-r--r--modules/mono/glue/cs_files/SignalAwaiter.cs9
-rw-r--r--modules/mono/glue/cs_files/StringExtensions.cs235
-rw-r--r--modules/mono/glue/gd_glue.cpp202
-rw-r--r--modules/mono/glue/gd_glue.h74
-rw-r--r--modules/mono/glue/glue_header.h306
-rw-r--r--modules/mono/glue/nodepath_glue.cpp (renamed from modules/mono/glue/builtin_types_glue.h)51
-rw-r--r--modules/mono/glue/nodepath_glue.h68
-rw-r--r--modules/mono/glue/rid_glue.cpp61
-rw-r--r--modules/mono/glue/rid_glue.h53
-rw-r--r--modules/mono/glue/string_glue.cpp79
-rw-r--r--modules/mono/glue/string_glue.h56
-rw-r--r--modules/mono/godotsharp_defs.h1
-rw-r--r--modules/mono/godotsharp_dirs.cpp8
-rw-r--r--modules/mono/godotsharp_dirs.h2
-rw-r--r--modules/mono/mono_gc_handle.cpp23
-rw-r--r--modules/mono/mono_gc_handle.h24
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp180
-rw-r--r--modules/mono/mono_gd/gd_mono.h22
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_header.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono_log.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp63
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h6
-rw-r--r--modules/mono/register_types.cpp2
-rw-r--r--modules/mono/signal_awaiter_utils.cpp7
-rw-r--r--modules/mono/signal_awaiter_utils.h4
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp2
-rw-r--r--modules/mono/utils/mono_reg_utils.h2
-rw-r--r--modules/mono/utils/path_utils.cpp8
-rw-r--r--modules/mono/utils/path_utils.h2
-rw-r--r--modules/mono/utils/string_utils.h4
-rw-r--r--modules/opus/audio_stream_opus.h4
-rw-r--r--modules/pvr/texture_loader_pvr.cpp2
-rw-r--r--modules/pvr/texture_loader_pvr.h2
-rw-r--r--modules/recast/navigation_mesh_editor_plugin.cpp4
-rw-r--r--modules/recast/navigation_mesh_generator.h2
-rw-r--r--modules/regex/regex.cpp6
-rw-r--r--modules/regex/register_types.cpp2
-rw-r--r--modules/squish/image_compress_squish.cpp6
-rw-r--r--modules/squish/image_compress_squish.h2
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp2
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.h2
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.cpp4
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.h2
-rw-r--r--modules/svg/image_loader_svg.cpp7
-rw-r--r--modules/svg/image_loader_svg.h4
-rw-r--r--modules/tga/image_loader_tga.cpp4
-rw-r--r--modules/tga/image_loader_tga.h2
-rw-r--r--modules/thekla_unwrap/register_types.cpp2
-rw-r--r--modules/theora/video_stream_theora.cpp4
-rw-r--r--modules/theora/video_stream_theora.h10
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp85
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h2
-rw-r--r--modules/upnp/register_types.cpp4
-rw-r--r--modules/upnp/upnp.cpp6
-rw-r--r--modules/upnp/upnp.h6
-rw-r--r--modules/upnp/upnpdevice.cpp4
-rw-r--r--modules/upnp/upnpdevice.h2
-rw-r--r--modules/visual_script/register_types.cpp2
-rw-r--r--modules/visual_script/visual_script.cpp4
-rw-r--r--modules/visual_script/visual_script.h4
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp14
-rw-r--r--modules/visual_script/visual_script_editor.cpp16
-rw-r--r--modules/visual_script/visual_script_editor.h4
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp6
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp6
-rw-r--r--modules/visual_script/visual_script_nodes.cpp10
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp6
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp2
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.h6
-rw-r--r--modules/webm/libvpx/SCsub12
-rw-r--r--modules/webm/video_stream_webm.cpp6
-rw-r--r--modules/webm/video_stream_webm.h2
-rw-r--r--modules/webp/image_loader_webp.cpp6
-rw-r--r--modules/webp/image_loader_webp.h2
-rw-r--r--modules/websocket/emws_client.cpp18
-rw-r--r--modules/websocket/lws_client.cpp15
-rw-r--r--modules/websocket/lws_helper.h47
-rw-r--r--modules/websocket/lws_server.cpp3
-rw-r--r--modules/websocket/register_types.cpp2
201 files changed, 3576 insertions, 1887 deletions
diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h
index 3fa7481287..e0e50859fc 100644
--- a/modules/bmp/image_loader_bmp.h
+++ b/modules/bmp/image_loader_bmp.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_LOADER_BMP_H
#define IMAGE_LOADER_BMP_H
-#include "io/image_loader.h"
+#include "core/io/image_loader.h"
class ImageLoaderBMP : public ImageFormatLoader {
protected:
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub
index d8d0b930a5..2557e8cb1d 100644
--- a/modules/bullet/SCsub
+++ b/modules/bullet/SCsub
@@ -68,11 +68,13 @@ if env['builtin_bullet']:
, "BulletCollision/CollisionShapes/btEmptyShape.cpp"
, "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp"
, "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp"
+ , "BulletCollision/CollisionShapes/btMiniSDF.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"
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index 3668088590..3200b4a214 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -30,6 +30,7 @@
#include "area_bullet.h"
+#include "bullet_physics_server.h"
#include "bullet_types_converter.h"
#include "bullet_utilities.h"
#include "collision_object_bullet.h"
@@ -57,7 +58,7 @@ AreaBullet::AreaBullet() :
spOv_priority(0) {
btGhost = bulletnew(btGhostObject);
- btGhost->setCollisionShape(compoundShape);
+ btGhost->setCollisionShape(BulletPhysicsServer::get_empty_shape());
setupBulletCollisionObject(btGhost);
/// Collision objects with a callback still have collision response with dynamic rigid bodies.
/// In order to use collision objects as trigger, you have to disable the collision response.
@@ -162,6 +163,13 @@ bool AreaBullet::is_monitoring() const {
return get_godot_object_flags() & GOF_IS_MONITORING_AREA;
}
+void AreaBullet::main_shape_resetted() {
+ if (get_main_shape())
+ btGhost->setCollisionShape(get_main_shape());
+ else
+ btGhost->setCollisionShape(BulletPhysicsServer::get_empty_shape());
+}
+
void AreaBullet::reload_body() {
if (space) {
space->remove_area(this);
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index b2046c684e..a6bf73906c 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -142,6 +142,7 @@ public:
_FORCE_INLINE_ void set_spOv_priority(int p_priority) { spOv_priority = p_priority; }
_FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; }
+ virtual void main_shape_resetted();
virtual void reload_body();
virtual void set_space(SpaceBullet *p_space);
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp
index 8707096038..6cc63d79ce 100644
--- a/modules/bullet/btRayShape.cpp
+++ b/modules/bullet/btRayShape.cpp
@@ -30,7 +30,7 @@
#include "btRayShape.h"
-#include "math/math_funcs.h"
+#include "core/math/math_funcs.h"
#include <LinearMath/btAabbUtil2.h>
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index dbd27a3564..53a38967c3 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -31,8 +31,8 @@
#include "bullet_physics_server.h"
#include "bullet_utilities.h"
-#include "class_db.h"
#include "cone_twist_joint_bullet.h"
+#include "core/class_db.h"
#include "core/error_macros.h"
#include "core/ustring.h"
#include "generic_6dof_joint_bullet.h"
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index e9c568d605..4c52cace67 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -32,8 +32,8 @@
#define BULLET_PHYSICS_SERVER_H
#include "area_bullet.h"
+#include "core/rid.h"
#include "joint_bullet.h"
-#include "rid.h"
#include "rigid_body_bullet.h"
#include "servers/physics_server.h"
#include "shape_bullet.h"
@@ -61,7 +61,7 @@ class BulletPhysicsServer : public PhysicsServer {
mutable RID_Owner<JointBullet> joint_owner;
private:
- /// This is used when a collision shape is not active, so the bullet compound shapes index are always sync with godot index
+ /// This is used as replacement of collision shape inside a compound or main shape
static btEmptyShape *emptyShape;
public:
diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h
index 2841dfbe69..029eb6691a 100644
--- a/modules/bullet/bullet_utilities.h
+++ b/modules/bullet/bullet_utilities.h
@@ -35,8 +35,6 @@
@author AndreaCatania
*/
-#pragma once
-
#define bulletnew(cl) \
new cl
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index 271cdb0223..df67f8d7ab 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -53,10 +53,17 @@ void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform &p_trans
G_TO_B(p_transform, transform);
UNSCALE_BT_BASIS(transform);
}
+
void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_transform) {
transform = p_transform;
}
+void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_scale) {
+ if (!bt_shape) {
+ bt_shape = shape->create_bt_shape(scale * body_scale);
+ }
+}
+
CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
RIDBullet(),
space(NULL),
@@ -107,6 +114,7 @@ void CollisionObjectBullet::setupBulletCollisionObject(btCollisionObject *p_coll
bt_collision_object->setUserIndex(type);
// Force the enabling of collision and avoid problems
set_collision_enabled(collisionsEnabled);
+ p_collisionObject->setCollisionFlags(p_collisionObject->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
}
void CollisionObjectBullet::add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
@@ -186,13 +194,14 @@ const btTransform &CollisionObjectBullet::get_transform__bullet() const {
RigidCollisionObjectBullet::RigidCollisionObjectBullet(Type p_type) :
CollisionObjectBullet(p_type),
- compoundShape(bulletnew(btCompoundShape(enableDynamicAabbTree, initialChildCapacity))) {
+ mainShape(NULL) {
}
RigidCollisionObjectBullet::~RigidCollisionObjectBullet() {
remove_all_shapes(true);
- bt_collision_object->setCollisionShape(NULL);
- bulletdelete(compoundShape);
+ if (mainShape && mainShape->isCompound()) {
+ bulletdelete(mainShape);
+ }
}
/* Not used
@@ -277,6 +286,10 @@ btCollisionShape *RigidCollisionObjectBullet::get_bt_shape(int p_index) const {
return shapes[p_index].bt_shape;
}
+const btTransform &RigidCollisionObjectBullet::get_bt_shape_transform(int p_index) const {
+ return shapes[p_index].transform;
+}
+
Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const {
Transform trs;
B_TO_G(shapes[p_index].transform, trs);
@@ -294,33 +307,47 @@ void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_sha
}
void RigidCollisionObjectBullet::on_shapes_changed() {
- int i;
- // Remove all shapes, reverse order for performance reason (Array resize)
- for (i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
- compoundShape->removeChildShapeByIndex(i);
+ if (mainShape && mainShape->isCompound()) {
+ bulletdelete(mainShape);
}
+ mainShape = NULL;
ShapeWrapper *shpWrapper;
- const int shapes_size = shapes.size();
+ const int shape_count = shapes.size();
// Reset shape if required
if (force_shape_reset) {
- for (i = 0; i < shapes_size; ++i) {
+ for (int i(0); i < shape_count; ++i) {
shpWrapper = &shapes.write[i];
bulletdelete(shpWrapper->bt_shape);
}
force_shape_reset = false;
}
- // Insert all shapes
btVector3 body_scale(get_bt_body_scale());
- for (i = 0; i < shapes_size; ++i) {
+
+ if (!shape_count)
+ return;
+
+ // Try to optimize by not using compound
+ if (1 == shape_count) {
+ shpWrapper = &shapes.write[0];
+ if (shpWrapper->active && shpWrapper->transform.getOrigin().isZero() && shpWrapper->transform.getBasis() == shpWrapper->transform.getBasis().getIdentity()) {
+ shpWrapper->claim_bt_shape(body_scale);
+ mainShape = shpWrapper->bt_shape;
+ main_shape_resetted();
+ return;
+ }
+ }
+
+ btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, initialChildCapacity));
+
+ // Insert all shapes into compound
+ for (int i(0); i < shape_count; ++i) {
shpWrapper = &shapes.write[i];
if (shpWrapper->active) {
- if (!shpWrapper->bt_shape) {
- shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape(shpWrapper->scale * body_scale);
- }
+ shpWrapper->claim_bt_shape(body_scale);
btTransform scaled_shape_transform(shpWrapper->transform);
scaled_shape_transform.getOrigin() *= body_scale;
@@ -331,6 +358,8 @@ void RigidCollisionObjectBullet::on_shapes_changed() {
}
compoundShape->recalculateLocalAabb();
+ mainShape = compoundShape;
+ main_shape_resetted();
}
void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) {
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index 506976eabf..ea06cecb17 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -31,11 +31,11 @@
#ifndef COLLISION_OBJECT_BULLET_H
#define COLLISION_OBJECT_BULLET_H
+#include "core/math/transform.h"
+#include "core/math/vector3.h"
+#include "core/object.h"
#include "core/vset.h"
-#include "object.h"
#include "shape_owner_bullet.h"
-#include "transform.h"
-#include "vector3.h"
#include <LinearMath/btTransform.h>
@@ -109,6 +109,8 @@ public:
void set_transform(const Transform &p_transform);
void set_transform(const btTransform &p_transform);
+
+ void claim_bt_shape(const btVector3 &body_scale);
};
protected:
@@ -207,10 +209,8 @@ public:
class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet {
protected:
- /// This is required to combine some shapes together.
- /// Since Godot allow to have multiple shapes for each body with custom relative location,
- /// each body will attach the shapes using this class even if there is only one shape.
- btCompoundShape *compoundShape;
+ /// This could be a compound shape in case multi please collision are found
+ btCollisionShape *mainShape;
Vector<ShapeWrapper> shapes;
public:
@@ -231,15 +231,18 @@ public:
virtual void on_shape_changed(const ShapeBullet *const p_shape);
virtual void on_shapes_changed();
- _FORCE_INLINE_ btCompoundShape *get_compound_shape() const { return compoundShape; }
+ _FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; }
+
int get_shape_count() const;
ShapeBullet *get_shape(int p_index) const;
btCollisionShape *get_bt_shape(int p_index) const;
+ const btTransform &get_bt_shape_transform(int p_index) const;
Transform get_shape_transform(int p_index) const;
void set_shape_disabled(int p_index, bool p_disabled);
bool is_shape_disabled(int p_index);
+ virtual void main_shape_resetted() = 0;
virtual void on_body_scale_changed();
private:
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index 6b5438c60f..ecacce0bee 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -83,7 +83,9 @@ void ConeTwistJointBullet::set_param(PhysicsServer::ConeTwistJointParam p_param,
coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), coneConstraint->getBiasFactor(), p_value);
break;
default:
- WARN_PRINT("This parameter is not supported by Bullet engine");
+ ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
+ WARN_DEPRECATED
+ break;
}
}
@@ -100,7 +102,8 @@ real_t ConeTwistJointBullet::get_param(PhysicsServer::ConeTwistJointParam p_para
case PhysicsServer::CONE_TWIST_JOINT_RELAXATION:
return coneConstraint->getRelaxationFactor();
default:
- WARN_PRINT("This parameter is not supported by Bullet engine");
+ ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
+ WARN_DEPRECATED;
return 0;
}
}
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index 6275a0d2ed..a36f1123bc 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -153,7 +153,9 @@ void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer::G6DO
sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxMotorForce = p_value;
break;
default:
- WARN_PRINT("This parameter is not supported");
+ ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
+ WARN_DEPRECATED
+ break;
}
}
@@ -181,8 +183,9 @@ real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer::G6
case PhysicsServer::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT:
return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_maxMotorForce;
default:
- WARN_PRINT("This parameter is not supported");
- return 0.;
+ ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
+ WARN_DEPRECATED;
+ return 0;
}
}
@@ -213,8 +216,9 @@ void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOF
sixDOFConstraint->getTranslationalLimitMotor()->m_enableMotor[p_axis] = flags[p_axis][p_flag];
break;
default:
- WARN_PRINT("This flag is not supported by Bullet engine");
- return;
+ ERR_EXPLAIN("This flag " + itos(p_flag) + " is deprecated");
+ WARN_DEPRECATED
+ break;
}
}
diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h
index 2e5a6c2732..1faaa68626 100644
--- a/modules/bullet/godot_collision_dispatcher.h
+++ b/modules/bullet/godot_collision_dispatcher.h
@@ -31,7 +31,7 @@
#ifndef GODOT_COLLISION_DISPATCHER_H
#define GODOT_COLLISION_DISPATCHER_H
-#include "int_types.h"
+#include "core/int_types.h"
#include <btBulletDynamicsCommon.h>
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 534034d707..08d8b8c6f6 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -34,11 +34,19 @@
#include "bullet_types_converter.h"
#include "collision_object_bullet.h"
#include "rigid_body_bullet.h"
+#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
/**
@author AndreaCatania
*/
+bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
+ if (!colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound()) {
+ btAdjustInternalEdgeContacts(cp, colObj1Wrap, colObj0Wrap, partId1, index1);
+ }
+ return true;
+}
+
bool GodotFilterCallback::test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask) {
return body0_collision_layer & body1_collision_mask || body1_collision_layer & body0_collision_mask;
}
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 3948f43c00..8e70b72841 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -42,6 +42,9 @@
class RigidBodyBullet;
+/// This callback is injected inside bullet server and allow me to smooth contacts against trimesh
+bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1);
+
/// This class is required to implement custom collision behaviour in the broadphase
struct GodotFilterCallback : public btOverlapFilterCallback {
static bool test_collision_filters(uint32_t body0_collision_layer, uint32_t body0_collision_mask, uint32_t body1_collision_layer, uint32_t body1_collision_mask);
@@ -71,7 +74,10 @@ public:
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) {
- m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ if (rayResult.m_localShapeInfo)
+ m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ else
+ m_shapeId = 0;
return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
}
};
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index 07fde6efb9..86c6a632cd 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -95,11 +95,6 @@ real_t HingeJointBullet::get_hinge_angle() {
void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer::HINGE_JOINT_BIAS:
- if (0 < p_value) {
- WARN_PRINTS("HingeJoint doesn't support bias in the Bullet backend, so it's always 0.");
- }
- break;
case PhysicsServer::HINGE_JOINT_LIMIT_UPPER:
hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), p_value, hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor());
break;
@@ -122,7 +117,9 @@ void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t
hingeConstraint->setMaxMotorImpulse(p_value);
break;
default:
- WARN_PRINTS("HingeJoint doesn't support this parameter in the Bullet backend: " + itos(p_param) + ", value: " + itos(p_value));
+ ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
+ WARN_DEPRECATED
+ break;
}
}
@@ -146,7 +143,8 @@ real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const
case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE:
return hingeConstraint->getMaxMotorImpulse();
default:
- WARN_PRINTS("HingeJoint doesn't support this parameter in the Bullet backend: " + itos(p_param));
+ ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
+ WARN_DEPRECATED;
return 0;
}
}
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index c4e5b8cdbe..183a7e75b9 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -85,7 +85,8 @@ real_t PinJointBullet::get_param(PhysicsServer::PinJointParam p_param) const {
case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP:
return p2pConstraint->m_setting.m_impulseClamp;
default:
- WARN_PRINTS("This get parameter is not supported");
+ ERR_EXPLAIN("This parameter " + itos(p_param) + " is deprecated");
+ WARN_DEPRECATED
return 0;
}
}
diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp
index a76b0438b4..31e5f6784e 100644
--- a/modules/bullet/register_types.cpp
+++ b/modules/bullet/register_types.cpp
@@ -31,8 +31,8 @@
#include "register_types.h"
#include "bullet_physics_server.h"
-#include "class_db.h"
-#include "project_settings.h"
+#include "core/class_db.h"
+#include "core/project_settings.h"
/**
@author AndreaCatania
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 9c0e802be5..2d0e74eb6f 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -279,7 +279,7 @@ RigidBodyBullet::RigidBodyBullet() :
// Initial properties
const btVector3 localInertia(0, 0, 0);
- btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, compoundShape, localInertia);
+ btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, BulletPhysicsServer::get_empty_shape(), localInertia);
btBody = bulletnew(btRigidBody(cInfo));
setupBulletCollisionObject(btBody);
@@ -314,10 +314,19 @@ void RigidBodyBullet::destroy_kinematic_utilities() {
}
}
+void RigidBodyBullet::main_shape_resetted() {
+ if (get_main_shape())
+ btBody->setCollisionShape(get_main_shape());
+ else
+ btBody->setCollisionShape(BulletPhysicsServer::get_empty_shape());
+ set_continuous_collision_detection(is_continuous_collision_detection_enabled()); // Reset
+}
+
void RigidBodyBullet::reload_body() {
if (space) {
space->remove_rigid_body(this);
- space->add_rigid_body(this);
+ if (get_main_shape())
+ space->add_rigid_body(this);
}
}
@@ -711,15 +720,19 @@ void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) {
if (p_enable) {
// This threshold enable CCD if the object moves more than
// 1 meter in one simulation frame
- btBody->setCcdMotionThreshold(1);
+ btBody->setCcdMotionThreshold(0.1);
/// Calculate using the rule writte below the CCD swept sphere radius
/// CCD works on an embedded sphere of radius, make sure this radius
/// is embedded inside the convex objects, preferably smaller:
/// for an object of dimensions 1 meter, try 0.2
- btVector3 center;
btScalar radius;
- btBody->getCollisionShape()->getBoundingSphere(center, radius);
+ if (btBody->getCollisionShape()) {
+ btVector3 center;
+ btBody->getCollisionShape()->getBoundingSphere(center, radius);
+ } else {
+ radius = 0;
+ }
btBody->setCcdSweptSphereRadius(radius * 0.2);
} else {
btBody->setCcdMotionThreshold(0.);
@@ -728,7 +741,7 @@ void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) {
}
bool RigidBodyBullet::is_continuous_collision_detection_enabled() const {
- return 0. != btBody->getCcdMotionThreshold();
+ return 0. < btBody->getCcdMotionThreshold();
}
void RigidBodyBullet::set_linear_velocity(const Vector3 &p_velocity) {
@@ -783,9 +796,11 @@ void RigidBodyBullet::on_shapes_changed() {
const btScalar invMass = btBody->getInvMass();
const btScalar mass = invMass == 0 ? 0 : 1 / invMass;
- btVector3 inertia;
- btBody->getCollisionShape()->calculateLocalInertia(mass, inertia);
- btBody->setMassProps(mass, inertia);
+ if (mainShape) {
+ btVector3 inertia;
+ mainShape->calculateLocalInertia(mass, inertia);
+ btBody->setMassProps(mass, inertia);
+ }
btBody->updateInertiaTensor();
reload_kinematic_shapes();
@@ -986,7 +1001,8 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
return;
m_isStatic = false;
- compoundShape->calculateLocalInertia(p_mass, localInertia);
+ if (mainShape)
+ mainShape->calculateLocalInertia(p_mass, localInertia);
if (PhysicsServer::BODY_MODE_RIGID == mode) {
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index f03009bce9..cd2f215906 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -231,6 +231,7 @@ public:
_FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
+ virtual void main_shape_resetted();
virtual void reload_body();
virtual void set_space(SpaceBullet *p_space);
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index fab8d0cf3d..4a2263407c 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -36,6 +36,7 @@
#include "bullet_utilities.h"
#include "shape_owner_bullet.h"
+#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
#include <BulletCollision/CollisionShapes/btConvexPointCloudShape.h>
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include <btBulletCollisionCommon.h>
@@ -340,6 +341,9 @@ void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) {
}
btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) {
+ if (!vertices.size())
+ // This is necessary since 0 vertices
+ return prepare(ShapeBullet::create_shape_empty());
btCollisionShape *cs(ShapeBullet::create_shape_convex(vertices));
cs->setLocalScaling(p_implicit_scale);
prepare(cs);
@@ -355,7 +359,8 @@ ConcavePolygonShapeBullet::ConcavePolygonShapeBullet() :
ConcavePolygonShapeBullet::~ConcavePolygonShapeBullet() {
if (meshShape) {
delete meshShape->getMeshInterface();
- delete meshShape;
+ delete meshShape->getTriangleInfoMap();
+ bulletdelete(meshShape);
}
faces = PoolVector<Vector3>();
}
@@ -377,6 +382,7 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
if (meshShape) {
/// Clear previous created shape
delete meshShape->getMeshInterface();
+ delete meshShape->getTriangleInfoMap();
bulletdelete(meshShape);
}
int src_face_count = faces.size();
@@ -404,6 +410,8 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
const bool useQuantizedAabbCompression = true;
meshShape = bulletnew(btBvhTriangleMeshShape(shapeInterface, useQuantizedAabbCompression));
+ btTriangleInfoMap *triangleInfoMap = new btTriangleInfoMap();
+ btGenerateInternalEdgeInfo(meshShape, triangleInfoMap);
} else {
meshShape = NULL;
ERR_PRINT("The faces count are 0, the mesh shape cannot be created");
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index 638e044e6a..9a1c8f5bfa 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -31,8 +31,8 @@
#ifndef SHAPE_BULLET_H
#define SHAPE_BULLET_H
+#include "core/math/geometry.h"
#include "core/variant.h"
-#include "geometry.h"
#include "rid_bullet.h"
#include "servers/physics_server.h"
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index b5329bc347..5b220e1039 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -34,13 +34,13 @@
#include "bullet_types_converter.h"
#include "bullet_utilities.h"
#include "constraint_bullet.h"
+#include "core/project_settings.h"
+#include "core/ustring.h"
#include "godot_collision_configuration.h"
#include "godot_collision_dispatcher.h"
-#include "project_settings.h"
#include "rigid_body_bullet.h"
#include "servers/physics_server.h"
#include "soft_body_bullet.h"
-#include "ustring.h"
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
@@ -178,7 +178,9 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, 0.002);
if (btResult.hasHit()) {
- p_closest_safe = p_closest_unsafe = btResult.m_closestHitFraction;
+ const btScalar l = bt_motion.length();
+ p_closest_unsafe = btResult.m_closestHitFraction;
+ p_closest_safe = MAX(p_closest_unsafe - (1 - ((l - 0.01) / l)), 0);
if (r_info) {
if (btCollisionObject::CO_RIGID_BODY == btResult.m_hitCollisionObject->getInternalType()) {
B_TO_G(static_cast<const btRigidBody *>(btResult.m_hitCollisionObject)->getVelocityInLocalPoint(btResult.m_hitPointWorld), r_info->linear_velocity);
@@ -293,11 +295,10 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_
bool shapes_found = false;
- btCompoundShape *compound = rigid_object->get_compound_shape();
- for (int i = compound->getNumChildShapes() - 1; 0 <= i; --i) {
- shape = compound->getChildShape(i);
+ for (int i = rigid_object->get_shape_count() - 1; 0 <= i; --i) {
+ shape = rigid_object->get_bt_shape(i);
if (shape->isConvex()) {
- child_transform = compound->getChildTransform(i);
+ child_transform = rigid_object->get_bt_shape_transform(i);
convex_shape = static_cast<btConvexShape *>(shape);
input.m_transformB = body_transform * child_transform;
@@ -596,6 +597,7 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
godotFilterCallback = bulletnew(GodotFilterCallback);
gCalculateCombinedRestitutionCallback = &calculateGodotCombinedRestitution;
gCalculateCombinedFrictionCallback = &calculateGodotCombinedFriction;
+ gContactAddedCallback = &godotContactAddedCallback;
dynamicsWorld->setWorldUserInfo(this);
@@ -640,7 +642,7 @@ void SpaceBullet::destroy_world() {
void SpaceBullet::check_ghost_overlaps() {
/// Algorithm support variables
- btConvexShape *other_body_shape;
+ btCollisionShape *other_body_shape;
btConvexShape *area_shape;
btGjkPairDetector::ClosestPointInput gjk_input;
AreaBullet *area;
@@ -682,30 +684,52 @@ void SpaceBullet::check_ghost_overlaps() {
bool hasOverlap = false;
// For each area shape
- for (y = area->get_compound_shape()->getNumChildShapes() - 1; 0 <= y; --y) {
- if (!area->get_compound_shape()->getChildShape(y)->isConvex())
+ for (y = area->get_shape_count() - 1; 0 <= y; --y) {
+ if (!area->get_bt_shape(y)->isConvex())
continue;
- gjk_input.m_transformA = area->get_transform__bullet() * area->get_compound_shape()->getChildTransform(y);
- area_shape = static_cast<btConvexShape *>(area->get_compound_shape()->getChildShape(y));
+ gjk_input.m_transformA = area->get_transform__bullet() * area->get_bt_shape_transform(y);
+ area_shape = static_cast<btConvexShape *>(area->get_bt_shape(y));
// For each other object shape
- for (z = otherObject->get_compound_shape()->getNumChildShapes() - 1; 0 <= z; --z) {
+ for (z = otherObject->get_shape_count() - 1; 0 <= z; --z) {
- if (!otherObject->get_compound_shape()->getChildShape(z)->isConvex())
- continue;
+ other_body_shape = static_cast<btCollisionShape *>(otherObject->get_bt_shape(z));
+ gjk_input.m_transformB = otherObject->get_transform__bullet() * otherObject->get_bt_shape_transform(z);
- other_body_shape = static_cast<btConvexShape *>(otherObject->get_compound_shape()->getChildShape(z));
- gjk_input.m_transformB = otherObject->get_transform__bullet() * otherObject->get_compound_shape()->getChildTransform(z);
+ if (other_body_shape->isConvex()) {
- btPointCollector result;
- btGjkPairDetector gjk_pair_detector(area_shape, other_body_shape, gjk_simplex_solver, gjk_epa_pen_solver);
- gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
+ btPointCollector result;
+ btGjkPairDetector gjk_pair_detector(area_shape, static_cast<btConvexShape *>(other_body_shape), gjk_simplex_solver, gjk_epa_pen_solver);
+ gjk_pair_detector.getClosestPoints(gjk_input, result, 0);
- if (0 >= result.m_distance) {
- hasOverlap = true;
- goto collision_found;
+ if (0 >= result.m_distance) {
+ hasOverlap = true;
+ goto collision_found;
+ }
+
+ } 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);
+
+ btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CONTACT_POINT_ALGORITHMS);
+
+ if (!algorithm)
+ continue;
+
+ GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB);
+ algorithm->processCollision(&obA, &obB, dynamicsWorld->getDispatchInfo(), &contactPointResult);
+
+ algorithm->~btCollisionAlgorithm();
+ dispatcher->freeCollisionAlgorithm(algorithm);
+
+ if (contactPointResult.hasHit()) {
+ hasOverlap = true;
+ goto collision_found;
+ }
}
+
} // ~For each other object shape
} // ~For each area shape
@@ -978,7 +1002,7 @@ int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p
btVector3 recover_motion(0, 0, 0);
- int rays_found;
+ int rays_found = 0;
for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) {
int last_ray_index = recover_from_penetration_ray(p_body, body_transform, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, p_result_max, recover_motion, r_results);
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index 517ec67ffa..0649e1f7e3 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -65,6 +65,8 @@ class SpaceBullet;
class SoftBodyBullet;
class btGjkEpaPenetrationDepthSolver;
+extern ContactAddedCallback gContactAddedCallback;
+
class BulletPhysicsDirectSpaceState : public PhysicsDirectSpaceState {
GDCLASS(BulletPhysicsDirectSpaceState, PhysicsDirectSpaceState)
private:
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 87c2caec0d..0184018274 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -29,10 +29,10 @@
/*************************************************************************/
#include "csg.h"
-#include "face3.h"
-#include "geometry.h"
-#include "os/os.h"
-#include "sort.h"
+#include "core/math/face3.h"
+#include "core/math/geometry.h"
+#include "core/os/os.h"
+#include "core/sort.h"
#include "thirdparty/misc/triangulator.h"
void CSGBrush::clear() {
diff --git a/modules/csg/csg.h b/modules/csg/csg.h
index 2e07c23e28..5d6432eca8 100644
--- a/modules/csg/csg.h
+++ b/modules/csg/csg.h
@@ -31,15 +31,15 @@
#ifndef CSG_H
#define CSG_H
-#include "aabb.h"
-#include "dvector.h"
-#include "map.h"
-#include "oa_hash_map.h"
-#include "plane.h"
-#include "rect2.h"
+#include "core/dvector.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/vector3.h"
+#include "core/oa_hash_map.h"
#include "scene/resources/material.h"
-#include "transform.h"
-#include "vector3.h"
struct CSGBrush {
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index f9744c72af..07c33ed670 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -139,9 +139,9 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i
d = 0.001;
switch (p_idx) {
- case 0: s->set_width(d); break;
- case 1: s->set_height(d); break;
- case 2: s->set_depth(d); break;
+ case 0: s->set_width(d * 2); break;
+ case 1: s->set_height(d * 2); break;
+ case 2: s->set_depth(d * 2); break;
}
}
@@ -329,9 +329,9 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
CSGBox *s = Object::cast_to<CSGBox>(cs);
Vector<Vector3> handles;
- handles.push_back(Vector3(s->get_width(), 0, 0));
- handles.push_back(Vector3(0, s->get_height(), 0));
- handles.push_back(Vector3(0, 0, s->get_depth()));
+ handles.push_back(Vector3(s->get_width() * 0.5, 0, 0));
+ handles.push_back(Vector3(0, s->get_height() * 0.5, 0));
+ handles.push_back(Vector3(0, 0, s->get_depth() * 0.5));
p_gizmo->add_handles(handles, handles_material);
}
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 258c628d93..714be16db7 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -917,7 +917,7 @@ CSGBrush *CSGBox::_build_brush() {
int face = 0;
- Vector3 vertex_mul(width, height, depth);
+ Vector3 vertex_mul(width * 0.5, height * 0.5, depth * 0.5);
{
@@ -1051,9 +1051,9 @@ Ref<Material> CSGBox::get_material() const {
CSGBox::CSGBox() {
// defaults
- width = 1.0;
- height = 1.0;
- depth = 1.0;
+ width = 2.0;
+ height = 2.0;
+ depth = 2.0;
}
///////////////
diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp
index 3a371c8597..17af6bff09 100644
--- a/modules/cvtt/image_compress_cvtt.cpp
+++ b/modules/cvtt/image_compress_cvtt.cpp
@@ -30,9 +30,9 @@
#include "image_compress_cvtt.h"
-#include "os/os.h"
-#include "os/thread.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/os/thread.h"
+#include "core/print_string.h"
#include <ConvectionKernels.h>
@@ -247,8 +247,8 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS
}
dst_ofs += (MAX(4, bw) * MAX(4, bh)) >> shift;
- w >>= 1;
- h >>= 1;
+ w = MAX(w / 2, 1);
+ h = MAX(h / 2, 1);
}
if (num_job_threads > 0) {
diff --git a/modules/cvtt/image_compress_cvtt.h b/modules/cvtt/image_compress_cvtt.h
index 0e18b247e5..fe912ad3bb 100644
--- a/modules/cvtt/image_compress_cvtt.h
+++ b/modules/cvtt/image_compress_cvtt.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_COMPRESS_CVTT_H
#define IMAGE_COMPRESS_CVTT_H
-#include "image.h"
+#include "core/image.h"
void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressSource p_source);
void image_decompress_cvtt(Image *p_image);
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index 3cb24d0407..ff15aaa735 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "texture_loader_dds.h"
-#include "os/file_access.h"
+#include "core/os/file_access.h"
enum {
DDS_MAGIC = 0x20534444,
diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h
index 14d99ff506..4e2593c744 100644
--- a/modules/dds/texture_loader_dds.h
+++ b/modules/dds/texture_loader_dds.h
@@ -31,7 +31,7 @@
#ifndef TEXTURE_LOADER_DDS_H
#define TEXTURE_LOADER_DDS_H
-#include "io/resource_loader.h"
+#include "core/io/resource_loader.h"
#include "scene/resources/texture.h"
class ResourceFormatDDS : public ResourceFormatLoader {
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index 25b7f2472d..d99b28d178 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "networked_multiplayer_enet.h"
-#include "io/ip.h"
-#include "io/marshalls.h"
-#include "os/os.h"
+#include "core/io/ip.h"
+#include "core/io/marshalls.h"
+#include "core/os/os.h"
void NetworkedMultiplayerENet::set_transfer_mode(TransferMode p_mode) {
diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h
index 705807d429..a2b35f2395 100644
--- a/modules/enet/networked_multiplayer_enet.h
+++ b/modules/enet/networked_multiplayer_enet.h
@@ -31,8 +31,8 @@
#ifndef NETWORKED_MULTIPLAYER_ENET_H
#define NETWORKED_MULTIPLAYER_ENET_H
-#include "io/compression.h"
-#include "io/networked_multiplayer_peer.h"
+#include "core/io/compression.h"
+#include "core/io/networked_multiplayer_peer.h"
#include <enet/enet.h>
diff --git a/modules/enet/register_types.cpp b/modules/enet/register_types.cpp
index cabaeb692a..cde70e8d5c 100644
--- a/modules/enet/register_types.cpp
+++ b/modules/enet/register_types.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "register_types.h"
-#include "error_macros.h"
+#include "core/error_macros.h"
#include "networked_multiplayer_enet.h"
static bool enet_ok = false;
diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp
index f5c817c816..a534aec11b 100644
--- a/modules/etc/image_etc.cpp
+++ b/modules/etc/image_etc.cpp
@@ -31,10 +31,10 @@
#include "image_etc.h"
#include "Etc.h"
#include "EtcFilter.h"
-#include "image.h"
-#include "os/copymem.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/image.h"
+#include "core/os/copymem.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
static Image::Format _get_etc2_mode(Image::DetectChannels format) {
switch (format) {
diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index ac89259c9b..3041dde876 100644
--- a/modules/etc/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -30,7 +30,7 @@
#include "texture_loader_pkm.h"
-#include "os/file_access.h"
+#include "core/os/file_access.h"
#include <string.h>
struct ETC1Header {
diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h
index 3c6d9180bd..b5a95767c7 100644
--- a/modules/etc/texture_loader_pkm.h
+++ b/modules/etc/texture_loader_pkm.h
@@ -31,7 +31,7 @@
#ifndef TEXTURE_LOADER_PKM_H
#define TEXTURE_LOADER_PKM_H
-#include "io/resource_loader.h"
+#include "core/io/resource_loader.h"
#include "scene/resources/texture.h"
class ResourceFormatPKM : public ResourceFormatLoader {
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 0acd6c27d8..2a980c2dc8 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -30,11 +30,11 @@
#include "gdnative.h"
-#include "global_constants.h"
-#include "io/file_access_encrypted.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/global_constants.h"
+#include "core/io/file_access_encrypted.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "scene/main/scene_tree.h"
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 148f85723e..c5364a72ac 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -31,15 +31,15 @@
#ifndef GDNATIVE_H
#define GDNATIVE_H
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "os/thread_safe.h"
-#include "resource.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/thread_safe.h"
+#include "core/resource.h"
#include "gdnative/gdnative.h"
#include "gdnative_api_struct.gen.h"
-#include "io/config_file.h"
+#include "core/io/config_file.h"
class GDNativeLibraryResourceLoader;
class GDNative;
diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index 372bdf3fb1..70d2814577 100644
--- a/modules/gdnative/gdnative/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -113,6 +113,40 @@ godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self) {
return dest;
}
+godot_quat GDAPI godot_basis_get_quat(const godot_basis *p_self) {
+ godot_quat dest;
+ const Basis *self = (const Basis *)p_self;
+ *((Quat *)&dest) = self->get_quat();
+ return dest;
+}
+
+void GDAPI godot_basis_set_quat(godot_basis *p_self, const godot_quat *p_quat) {
+ Basis *self = (Basis *)p_self;
+ const Quat *quat = (const Quat *)p_quat;
+ self->set_quat(*quat);
+}
+
+void GDAPI godot_basis_set_axis_angle_scale(godot_basis *p_self, const godot_vector3 *p_axis, godot_real p_phi, const godot_vector3 *p_scale) {
+ Basis *self = (Basis *)p_self;
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ const Vector3 *scale = (const Vector3 *)p_scale;
+ self->set_axis_angle_scale(*axis, p_phi, *scale);
+}
+
+void GDAPI godot_basis_set_euler_scale(godot_basis *p_self, const godot_vector3 *p_euler, const godot_vector3 *p_scale) {
+ Basis *self = (Basis *)p_self;
+ const Vector3 *euler = (const Vector3 *)p_euler;
+ const Vector3 *scale = (const Vector3 *)p_scale;
+ self->set_euler_scale(*euler, *scale);
+}
+
+void GDAPI godot_basis_set_quat_scale(godot_basis *p_self, const godot_quat *p_quat, const godot_vector3 *p_scale) {
+ Basis *self = (Basis *)p_self;
+ const Quat *quat = (const Quat *)p_quat;
+ const Vector3 *scale = (const Vector3 *)p_scale;
+ self->set_quat_scale(*quat, *scale);
+}
+
godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self) {
godot_vector3 dest;
const Basis *self = (const Basis *)p_self;
diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp
index 786e614158..34cc91129e 100644
--- a/modules/gdnative/gdnative/dictionary.cpp
+++ b/modules/gdnative/gdnative/dictionary.cpp
@@ -155,6 +155,12 @@ godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self) {
return raw_dest;
}
+godot_bool GDAPI godot_dictionary_erase_with_return(godot_dictionary *p_self, const godot_variant *p_key) {
+ Dictionary *self = (Dictionary *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ return self->erase(*key);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 041990e137..8f10f116e6 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -30,12 +30,12 @@
#include "gdnative/gdnative.h"
-#include "class_db.h"
-#include "engine.h"
-#include "error_macros.h"
-#include "global_constants.h"
-#include "os/os.h"
-#include "variant.h"
+#include "core/class_db.h"
+#include "core/engine.h"
+#include "core/error_macros.h"
+#include "core/global_constants.h"
+#include "core/os/os.h"
+#include "core/variant.h"
#include "modules/gdnative/gdnative.h"
@@ -166,6 +166,10 @@ 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);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp
index 2b6b7a823a..d55d81b5b6 100644
--- a/modules/gdnative/gdnative/pool_arrays.cpp
+++ b/modules/gdnative/gdnative/pool_arrays.cpp
@@ -30,9 +30,9 @@
#include "gdnative/pool_arrays.h"
-#include "array.h"
+#include "core/array.h"
+#include "core/dvector.h"
#include "core/variant.h"
-#include "dvector.h"
#include "core/color.h"
#include "core/math/vector2.h"
diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp
index 56ff7fe3a8..ddec77edcd 100644
--- a/modules/gdnative/gdnative/quat.cpp
+++ b/modules/gdnative/gdnative/quat.cpp
@@ -49,6 +49,18 @@ void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector
*dest = Quat(*axis, p_angle);
}
+void GDAPI godot_quat_new_with_basis(godot_quat *r_dest, const godot_basis *p_basis) {
+ const Basis *basis = (const Basis *)p_basis;
+ Quat *dest = (Quat *)r_dest;
+ *dest = Quat(*basis);
+}
+
+void GDAPI godot_quat_new_with_euler(godot_quat *r_dest, const godot_vector3 *p_euler) {
+ const Vector3 *euler = (const Vector3 *)p_euler;
+ Quat *dest = (Quat *)r_dest;
+ *dest = Quat(*euler);
+}
+
godot_real GDAPI godot_quat_get_x(const godot_quat *p_self) {
const Quat *self = (const Quat *)p_self;
return self->x;
diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp
index 715f2e3c08..ee6140c7d0 100644
--- a/modules/gdnative/gdnative/transform.cpp
+++ b/modules/gdnative/gdnative/transform.cpp
@@ -56,6 +56,12 @@ void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_bas
*dest = Transform(*basis, *origin);
}
+void GDAPI godot_transform_new_with_quat(godot_transform *r_dest, const godot_quat *p_quat) {
+ const Quat *quat = (const Quat *)p_quat;
+ Transform *dest = (Transform *)r_dest;
+ *dest = Transform(*quat);
+}
+
godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self) {
godot_basis dest;
const Transform *self = (const Transform *)p_self;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index e326d11a84..dce3d7e96b 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -5,7 +5,98 @@
"major": 1,
"minor": 0
},
- "next": null,
+ "next": {
+ "type": "CORE",
+ "version": {
+ "major": 1,
+ "minor": 1
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_basis_get_quat",
+ "return_type": "godot_quat",
+ "arguments": [
+ ["const godot_basis *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_basis_set_quat",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "p_self"],
+ ["const godot_quat *", "p_quat"]
+ ]
+ },
+ {
+ "name": "godot_basis_set_axis_angle_scale",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_axis"],
+ ["godot_real", "p_phi"],
+ ["const godot_vector3 *", "p_scale"]
+ ]
+ },
+ {
+ "name": "godot_basis_set_euler_scale",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "p_self"],
+ ["const godot_vector3 *", "p_euler"],
+ ["const godot_vector3 *", "p_scale"]
+ ]
+ },
+ {
+ "name": "godot_basis_set_quat_scale",
+ "return_type": "void",
+ "arguments": [
+ ["godot_basis *", "p_self"],
+ ["const godot_quat *", "p_quat"],
+ ["const godot_vector3 *", "p_scale"]
+ ]
+ },
+ {
+ "name": "godot_dictionary_erase_with_return",
+ "return_type": "bool",
+ "arguments": [
+ ["godot_dictionary *", "p_self"],
+ ["const godot_variant *", "p_key"]
+ ]
+ },
+ {
+ "name": "godot_is_instance_valid",
+ "return_type": "bool",
+ "arguments": [
+ ["const godot_object *", "p_object"]
+ ]
+ },
+ {
+ "name": "godot_quat_new_with_basis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "r_dest"],
+ ["const godot_basis *", "p_basis"]
+ ]
+ },
+ {
+ "name": "godot_quat_new_with_euler",
+ "return_type": "void",
+ "arguments": [
+ ["godot_quat *", "r_dest"],
+ ["const godot_vector3 *", "p_euler"]
+ ]
+ },
+ {
+ "name": "godot_transform_new_with_quat",
+ "return_type": "void",
+ "arguments": [
+ ["godot_transform *", "r_dest"],
+ ["const godot_quat *", "p_quat"]
+ ]
+ }
+ ]
+ },
"api": [
{
"name": "godot_color_new_rgba",
@@ -4484,7 +4575,7 @@
]
},
{
- "name": "godot_string_wide_str",
+ "name": "godot_string_wide_str",
"return_type": "const wchar_t *",
"arguments": [
["const godot_string *", "p_self"]
@@ -5253,21 +5344,21 @@
"name": "godot_string_ascii",
"return_type": "godot_char_string",
"arguments": [
- ["const godot_string *", "p_self"]
+ ["const godot_string *", "p_self"]
]
},
{
"name": "godot_string_ascii_extended",
"return_type": "godot_char_string",
"arguments": [
- ["const godot_string *", "p_self"]
+ ["const godot_string *", "p_self"]
]
},
{
"name": "godot_string_utf8",
"return_type": "godot_char_string",
"arguments": [
- ["const godot_string *", "p_self"]
+ ["const godot_string *", "p_self"]
]
},
{
@@ -5765,15 +5856,15 @@
"minor": 0
},
"next": {
- "type": "NATIVESCRIPT",
- "version": {
- "major": 1,
- "minor": 1
- },
- "next": null,
- "api": [
+ "type": "NATIVESCRIPT",
+ "version": {
+ "major": 1,
+ "minor": 1
+ },
+ "next": null,
+ "api": [
{
- "name": "godot_nativescript_set_method_argument_information",
+ "name": "godot_nativescript_set_method_argument_information",
"return_type": "void",
"arguments": [
["void *", "p_gdnative_handle"],
@@ -5784,7 +5875,7 @@
]
},
{
- "name": "godot_nativescript_set_class_documentation",
+ "name": "godot_nativescript_set_class_documentation",
"return_type": "void",
"arguments": [
["void *", "p_gdnative_handle"],
@@ -5793,7 +5884,7 @@
]
},
{
- "name": "godot_nativescript_set_method_documentation",
+ "name": "godot_nativescript_set_method_documentation",
"return_type": "void",
"arguments": [
["void *", "p_gdnative_handle"],
@@ -5803,7 +5894,7 @@
]
},
{
- "name": "godot_nativescript_set_property_documentation",
+ "name": "godot_nativescript_set_property_documentation",
"return_type": "void",
"arguments": [
["void *", "p_gdnative_handle"],
@@ -5813,7 +5904,7 @@
]
},
{
- "name": "godot_nativescript_set_signal_documentation",
+ "name": "godot_nativescript_set_signal_documentation",
"return_type": "void",
"arguments": [
["void *", "p_gdnative_handle"],
@@ -5874,7 +5965,7 @@
"return_type": "void *",
"arguments": [
["int", "p_idx"],
- ["godot_object *", "p_object"]
+ ["godot_object *", "p_object"]
]
},
{
@@ -5885,7 +5976,7 @@
["uint64_t", "p_line"]
]
}
- ]
+ ]
},
"api": [
{
diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py
index 8a1cd049af..f9d1ed9dc5 100644
--- a/modules/gdnative/gdnative_builders.py
+++ b/modules/gdnative/gdnative_builders.py
@@ -82,10 +82,35 @@ def _build_gdnative_api_struct_header(api):
return ret_val
+
+ def generate_core_extension_struct(core):
+ ret_val = []
+ 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;',
+ ]
+
+ 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;', '']
+
+ return ret_val
+
+
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'])
+
out += [
'typedef struct godot_gdnative_core_api_struct {',
'\tunsigned int type;',
@@ -146,6 +171,27 @@ def _build_gdnative_api_struct_source(api):
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'])
+
+ 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['version']['major'], core['version']['minor']))) + ','
+ ]
+
+ for funcdef in core['api']:
+ ret_val.append('\t%s,' % funcdef['name'])
+
+ ret_val += ['};\n']
+
+ return ret_val
for ext in api['extensions']:
name = ext['name']
@@ -158,6 +204,9 @@ def _build_gdnative_api_struct_source(api):
out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,']
out += ['};\n']
+
+ if api['core']['next']:
+ out += get_core_struct_definition(api['core']['next'])
out += [
'extern const godot_gdnative_core_api_struct api_struct = {',
diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h
index 53e950b4a2..ebe2b1125b 100644
--- a/modules/gdnative/include/gdnative/basis.h
+++ b/modules/gdnative/include/gdnative/basis.h
@@ -62,6 +62,7 @@ extern "C" {
void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis);
void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi);
void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler);
+void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler);
godot_string GDAPI godot_basis_as_string(const godot_basis *p_self);
@@ -81,6 +82,16 @@ godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self);
godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self);
+godot_quat GDAPI godot_basis_get_quat(const godot_basis *p_self);
+
+void GDAPI godot_basis_set_quat(godot_basis *p_self, const godot_quat *p_quat);
+
+void GDAPI godot_basis_set_axis_angle_scale(godot_basis *p_self, const godot_vector3 *p_axis, godot_real p_phi, const godot_vector3 *p_scale);
+
+void GDAPI godot_basis_set_euler_scale(godot_basis *p_self, const godot_vector3 *p_euler, const godot_vector3 *p_scale);
+
+void GDAPI godot_basis_set_quat_scale(godot_basis *p_self, const godot_quat *p_quat, const godot_vector3 *p_scale);
+
godot_real GDAPI godot_basis_tdotx(const godot_basis *p_self, const godot_vector3 *p_with);
godot_real GDAPI godot_basis_tdoty(const godot_basis *p_self, const godot_vector3 *p_with);
@@ -95,8 +106,6 @@ godot_int GDAPI godot_basis_get_orthogonal_index(const godot_basis *p_self);
void GDAPI godot_basis_new(godot_basis *r_dest);
-void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler);
-
// p_elements is a pointer to an array of 3 (!!) vector3
void GDAPI godot_basis_get_elements(const godot_basis *p_self, godot_vector3 *p_elements);
diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h
index a86d60dc72..faace818ee 100644
--- a/modules/gdnative/include/gdnative/dictionary.h
+++ b/modules/gdnative/include/gdnative/dictionary.h
@@ -94,6 +94,8 @@ godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self,
godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self);
+godot_bool GDAPI godot_dictionary_erase_with_return(godot_dictionary *p_self, const godot_variant *p_key);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 4cf6e99b06..616c305f25 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -282,6 +282,10 @@ 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);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h
index 4e86960aaf..b1290f745c 100644
--- a/modules/gdnative/include/gdnative/quat.h
+++ b/modules/gdnative/include/gdnative/quat.h
@@ -60,6 +60,8 @@ extern "C" {
void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w);
void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle);
+void GDAPI godot_quat_new_with_basis(godot_quat *r_dest, const godot_basis *p_basis);
+void GDAPI godot_quat_new_with_euler(godot_quat *r_dest, const godot_vector3 *p_euler);
godot_real GDAPI godot_quat_get_x(const godot_quat *p_self);
void GDAPI godot_quat_set_x(godot_quat *p_self, const godot_real val);
diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform.h
index a646da146a..880f21c88a 100644
--- a/modules/gdnative/include/gdnative/transform.h
+++ b/modules/gdnative/include/gdnative/transform.h
@@ -62,6 +62,7 @@ extern "C" {
void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin);
void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin);
+void GDAPI godot_transform_new_with_quat(godot_transform *r_dest, const godot_quat *p_quat);
godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self);
void GDAPI godot_transform_set_basis(godot_transform *p_self, const godot_basis *p_v);
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index 29bd9eec5a..d6a729be47 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -229,6 +229,8 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object);
typedef struct {
GDCALLINGCONV void *(*alloc_instance_binding_data)(void *, const void *, godot_object *);
GDCALLINGCONV void (*free_instance_binding_data)(void *, void *);
+ GDCALLINGCONV void (*refcount_incremented_instance_binding)(void *, godot_object *);
+ GDCALLINGCONV bool (*refcount_decremented_instance_binding)(void *, godot_object *);
void *data;
GDCALLINGCONV void (*free_func)(void *);
} godot_instance_binding_functions;
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 70ca8d68b8..0983c12619 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -35,8 +35,8 @@
#include "core/class_db.h"
#include "core/engine.h"
#include "core/global_constants.h"
+#include "core/os/file_access.h"
#include "core/pair.h"
-#include "os/file_access.h"
// helper stuff
diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index 72606c8340..c39efe126f 100644
--- a/modules/gdnative/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -30,12 +30,12 @@
#include "nativescript/godot_nativescript.h"
-#include "class_db.h"
-#include "error_macros.h"
+#include "core/class_db.h"
+#include "core/error_macros.h"
+#include "core/global_constants.h"
+#include "core/project_settings.h"
+#include "core/variant.h"
#include "gdnative/gdnative.h"
-#include "global_constants.h"
-#include "project_settings.h"
-#include "variant.h"
#include "nativescript.h"
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 608c7aa4a5..ea968fb0b1 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -33,10 +33,10 @@
#include "gdnative/gdnative.h"
#include "core/global_constants.h"
+#include "core/io/file_access_encrypted.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
#include "core/project_settings.h"
-#include "io/file_access_encrypted.h"
-#include "os/file_access.h"
-#include "os/os.h"
#include "scene/main/scene_tree.h"
#include "scene/resources/scene_format_text.h"
@@ -44,7 +44,7 @@
#include <stdlib.h>
#ifndef NO_THREADS
-#include "os/thread.h"
+#include "core/os/thread.h"
#endif
#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED)
@@ -1370,6 +1370,54 @@ void NativeScriptLanguage::free_instance_binding_data(void *p_data) {
delete &binding_data;
}
+void NativeScriptLanguage::refcount_incremented_instance_binding(Object *p_object) {
+
+ void *data = p_object->get_script_instance_binding(lang_idx);
+
+ if (!data)
+ return;
+
+ Vector<void *> &binding_data = *(Vector<void *> *)data;
+
+ for (int i = 0; i < binding_data.size(); i++) {
+ if (!binding_data[i])
+ continue;
+
+ if (!binding_functions[i].first)
+ continue;
+
+ if (binding_functions[i].second.refcount_incremented_instance_binding) {
+ binding_functions[i].second.refcount_incremented_instance_binding(binding_data[i], p_object);
+ }
+ }
+}
+
+bool NativeScriptLanguage::refcount_decremented_instance_binding(Object *p_object) {
+
+ void *data = p_object->get_script_instance_binding(lang_idx);
+
+ if (!data)
+ return true;
+
+ Vector<void *> &binding_data = *(Vector<void *> *)data;
+
+ bool can_die = true;
+
+ for (int i = 0; i < binding_data.size(); i++) {
+ if (!binding_data[i])
+ continue;
+
+ if (!binding_functions[i].first)
+ continue;
+
+ if (binding_functions[i].second.refcount_decremented_instance_binding) {
+ can_die = can_die && binding_functions[i].second.refcount_decremented_instance_binding(binding_data[i], p_object);
+ }
+ }
+
+ return can_die;
+}
+
void NativeScriptLanguage::set_global_type_tag(int p_idx, StringName p_class_name, const void *p_type_tag) {
if (!global_type_tags.has(p_idx)) {
global_type_tags.insert(p_idx, HashMap<StringName, const void *>());
@@ -1537,12 +1585,16 @@ bool NativeScriptLanguage::handles_global_class_type(const String &p_type) const
String NativeScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript");
if (script.is_valid()) {
- *r_base_type = script->get_instance_base_type();
- *r_icon_path = script->get_script_class_icon_path();
+ if (r_base_type)
+ *r_base_type = script->get_instance_base_type();
+ if (r_icon_path)
+ *r_icon_path = script->get_script_class_icon_path();
return script->get_script_class_name();
}
- *r_base_type = String();
- *r_icon_path = String();
+ if (r_base_type)
+ *r_base_type = String();
+ if (r_icon_path)
+ *r_icon_path = String();
return String();
}
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index 6f18e2db27..a96fe5c5e3 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -31,21 +31,21 @@
#ifndef NATIVE_SCRIPT_H
#define NATIVE_SCRIPT_H
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/oa_hash_map.h"
+#include "core/ordered_hash_map.h"
+#include "core/os/thread_safe.h"
#include "core/resource.h"
#include "core/script_language.h"
#include "core/self_list.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "oa_hash_map.h"
-#include "ordered_hash_map.h"
-#include "os/thread_safe.h"
#include "scene/main/node.h"
#include "modules/gdnative/gdnative.h"
#include <nativescript/godot_nativescript.h>
#ifndef NO_THREADS
-#include "os/mutex.h"
+#include "core/os/mutex.h"
#endif
struct NativeScriptDesc {
@@ -353,6 +353,8 @@ public:
virtual void *alloc_instance_binding_data(Object *p_object);
virtual void free_instance_binding_data(void *p_data);
+ virtual void refcount_incremented_instance_binding(Object *p_object);
+ virtual bool refcount_decremented_instance_binding(Object *p_object);
void set_global_type_tag(int p_idx, StringName p_class_name, const void *p_type_tag);
const void *get_global_type_tag(int p_idx, StringName p_class_name) const;
diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp
index 9a0e764391..4433c0a638 100644
--- a/modules/gdnative/nativescript/register_types.cpp
+++ b/modules/gdnative/nativescript/register_types.cpp
@@ -30,8 +30,8 @@
#include "register_types.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
#include "nativescript.h"
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp
index acba297fa0..52d5b2b595 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
// Godot imports
-#include "os/file_access.h"
+#include "core/os/file_access.h"
// Pythonscript imports
#include "pluginscript_language.h"
#include "pluginscript_loader.h"
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h
index 9276ea3ef9..5c17bb932e 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.h
+++ b/modules/gdnative/pluginscript/pluginscript_loader.h
@@ -32,9 +32,9 @@
#define PYTHONSCRIPT_PY_LOADER_H
// Godot imports
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
#include "core/script_language.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
class PluginScriptLanguage;
diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp
index 924abf29df..e677bc9867 100644
--- a/modules/gdnative/pluginscript/register_types.cpp
+++ b/modules/gdnative/pluginscript/register_types.cpp
@@ -30,11 +30,11 @@
#include "register_types.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/dir_access.h"
+#include "core/os/os.h"
#include "core/project_settings.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "os/dir_access.h"
-#include "os/os.h"
#include "scene/main/scene_tree.h"
#include "pluginscript_language.h"
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index ae1a218392..48c0fc8aef 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -33,8 +33,8 @@
#include "gdnative.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
#include "arvr/register_types.h"
#include "nativescript/register_types.h"
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index f2a1a5b50c..a1163b5d8d 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -121,8 +121,8 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
is_hex_notation = false;
}
- // check for dot or underscore or 'x' for hex notation in floating point number
- if ((str[j] == '.' || str[j] == 'x' || str[j] == '_') && !in_word && prev_is_number && !is_number) {
+ // check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation
+ if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
is_number = true;
is_symbol = false;
is_char = false;
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index e05bc7d591..737374af4b 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -30,13 +30,13 @@
#include "gdscript.h"
-#include "engine.h"
+#include "core/engine.h"
+#include "core/global_constants.h"
+#include "core/io/file_access_encrypted.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "gdscript_compiler.h"
-#include "global_constants.h"
-#include "io/file_access_encrypted.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "project_settings.h"
///////////////////////////
@@ -126,7 +126,10 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
GDScriptLanguage::singleton->lock->unlock();
#endif
- ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
+ if (r_error.error != Variant::CallError::CALL_OK) {
+ memdelete(instance);
+ ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing
+ }
}
//@TODO make thread safe
@@ -719,22 +722,36 @@ Error GDScript::load_byte_code(const String &p_path) {
FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V(!fa, ERR_CANT_OPEN);
+
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
ERR_FAIL_COND_V(!fae, ERR_CANT_OPEN);
+
Vector<uint8_t> key;
key.resize(32);
for (int i = 0; i < key.size(); i++) {
key.write[i] = script_encryption_key[i];
}
+
Error err = fae->open_and_parse(fa, key, FileAccessEncrypted::MODE_READ);
- ERR_FAIL_COND_V(err, err);
+
+ if (err) {
+ fa->close();
+ memdelete(fa);
+ memdelete(fae);
+
+ ERR_FAIL_COND_V(err, err);
+ }
+
bytecode.resize(fae->get_len());
fae->get_buffer(bytecode.ptrw(), bytecode.size());
+ fae->close();
memdelete(fae);
+
} else {
bytecode = FileAccess::get_file_as_array(p_path);
}
+
ERR_FAIL_COND_V(bytecode.size() == 0, ERR_PARSE_ERROR);
path = p_path;
@@ -2095,23 +2112,14 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_ori
script->set_script_path(p_original_path); // script needs this.
script->set_path(p_original_path);
Error err = script->load_byte_code(p_path);
-
- if (err != OK) {
-
- ERR_FAIL_COND_V(err != OK, RES());
- }
+ ERR_FAIL_COND_V(err != OK, RES());
} else {
Error err = script->load_source_code(p_path);
-
- if (err != OK) {
-
- ERR_FAIL_COND_V(err != OK, RES());
- }
+ ERR_FAIL_COND_V(err != OK, RES());
script->set_script_path(p_original_path); // script needs this.
script->set_path(p_original_path);
- //script->set_name(p_path.get_file());
script->reload();
}
@@ -2120,6 +2128,7 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_ori
return scriptres;
}
+
void ResourceFormatLoaderGDScript::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("gd");
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index d400230f43..85379a8902 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -31,10 +31,10 @@
#ifndef GDSCRIPT_H
#define GDSCRIPT_H
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/script_language.h"
#include "gdscript_function.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "script_language.h"
class GDScriptNativeClass : public Reference {
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 1403184557..006fbece53 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1253,6 +1253,25 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
} break;
+ case GDScriptParser::OperatorNode::OP_IS_BUILTIN: {
+ ERR_FAIL_COND_V(on->arguments.size() != 2, false);
+ ERR_FAIL_COND_V(on->arguments[1]->type != GDScriptParser::Node::TYPE_TYPE, false);
+
+ int slevel = p_stack_level;
+
+ int src_address_a = _parse_expression(codegen, on->arguments[0], slevel);
+ if (src_address_a < 0)
+ return -1;
+
+ if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)
+ slevel++; //uses stack for return, increase stack
+
+ const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(on->arguments[1]);
+
+ codegen.opcodes.push_back(GDScriptFunction::OPCODE_IS_BUILTIN); // perform operator
+ codegen.opcodes.push_back(src_address_a); // argument 1
+ codegen.opcodes.push_back((int)tn->vtype); // argument 2 (unary only takes one parameter)
+ } break;
default: {
ERR_EXPLAIN("Bug in bytecode compiler, unexpected operator #" + itos(on->op) + " in parse tree while parsing expression.");
@@ -1322,6 +1341,8 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
int ret = _parse_expression(codegen, op, p_stack_level);
if (ret < 0) {
+ memdelete(id);
+ memdelete(op);
return ERR_PARSE_ERROR;
}
@@ -1341,6 +1362,8 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
// compile the condition
int ret = _parse_expression(codegen, branch.compiled_pattern, p_stack_level);
if (ret < 0) {
+ memdelete(id);
+ memdelete(op);
return ERR_PARSE_ERROR;
}
@@ -1353,6 +1376,8 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
Error err = _parse_block(codegen, branch.body, p_stack_level, p_break_addr, continue_addr);
if (err) {
+ memdelete(id);
+ memdelete(op);
return ERR_PARSE_ERROR;
}
@@ -1364,6 +1389,9 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
codegen.opcodes.write[break_addr + 1] = codegen.opcodes.size();
+ memdelete(id);
+ memdelete(op);
+
} break;
case GDScriptParser::ControlFlowNode::CF_IF: {
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 30400f01e9..59b0c4d492 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -31,16 +31,16 @@
#include "gdscript.h"
#include "core/engine.h"
+#include "core/global_constants.h"
+#include "core/os/file_access.h"
#include "editor/editor_settings.h"
#include "gdscript_compiler.h"
-#include "global_constants.h"
-#include "os/file_access.h"
#ifdef TOOLS_ENABLED
+#include "core/engine.h"
#include "core/reference.h"
#include "editor/editor_file_system.h"
#include "editor/editor_settings.h"
-#include "engine.h"
#endif
void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
@@ -63,8 +63,8 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
String _template = "extends %BASE%\n"
"\n"
"# Declare member variables here. Examples:\n"
- "# var a %INT_TYPE%= 2\n"
- "# var b %STRING_TYPE%= \"text\"\n"
+ "# var a%INT_TYPE% = 2\n"
+ "# var b%STRING_TYPE% = \"text\"\n"
"\n"
"# Called when the node enters the scene tree for the first time.\n"
"func _ready()%VOID_RETURN%:\n"
@@ -76,9 +76,9 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
#ifdef TOOLS_ENABLED
if (EDITOR_DEF("text_editor/completion/add_type_hints", false)) {
- _template = _template.replace("%INT_TYPE%", ": int ");
- _template = _template.replace("%STRING_TYPE%", ": String ");
- _template = _template.replace("%FLOAT_TYPE%", " : float");
+ _template = _template.replace("%INT_TYPE%", ": int");
+ _template = _template.replace("%STRING_TYPE%", ": String");
+ _template = _template.replace("%FLOAT_TYPE%", ": float");
_template = _template.replace("%VOID_RETURN%", " -> void");
} else {
_template = _template.replace("%INT_TYPE%", "");
@@ -466,7 +466,7 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na
if (th) {
String type = p_args[i].get_slice(":", 1);
if (!type.empty() && type != "var") {
- s += " : " + type;
+ s += ": " + type;
}
}
}
@@ -2596,7 +2596,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
}
method_hint += arg;
if (use_type_hint && mi.arguments[i].type != Variant::NIL) {
- method_hint += " : ";
+ method_hint += ": ";
if (mi.arguments[i].type == Variant::OBJECT && mi.arguments[i].class_name != StringName()) {
method_hint += mi.arguments[i].class_name.operator String();
} else {
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index bae3f48923..abd08d13ff 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -30,9 +30,9 @@
#include "gdscript_function.h"
+#include "core/os/os.h"
#include "gdscript.h"
#include "gdscript_functions.h"
-#include "os/os.h"
Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const {
@@ -191,6 +191,7 @@ static String _get_var_type(const Variant *p_type) {
static const void *switch_table_ops[] = { \
&&OPCODE_OPERATOR, \
&&OPCODE_EXTENDS_TEST, \
+ &&OPCODE_IS_BUILTIN, \
&&OPCODE_SET, \
&&OPCODE_GET, \
&&OPCODE_SET_NAMED, \
@@ -536,6 +537,21 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
+ OPCODE(OPCODE_IS_BUILTIN) {
+
+ CHECK_SPACE(4);
+
+ GET_VARIANT_PTR(value, 1);
+ Variant::Type var_type = (Variant::Type)_code_ptr[ip + 2];
+ GET_VARIANT_PTR(dst, 3);
+
+ GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX);
+
+ *dst = value->get_type() == var_type;
+ ip += 4;
+ }
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET) {
CHECK_SPACE(3);
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 3ce84290fd..bfb6d673f1 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -31,13 +31,13 @@
#ifndef GDSCRIPT_FUNCTION_H
#define GDSCRIPT_FUNCTION_H
-#include "os/thread.h"
-#include "pair.h"
-#include "reference.h"
-#include "script_language.h"
-#include "self_list.h"
-#include "string_db.h"
-#include "variant.h"
+#include "core/os/thread.h"
+#include "core/pair.h"
+#include "core/reference.h"
+#include "core/script_language.h"
+#include "core/self_list.h"
+#include "core/string_db.h"
+#include "core/variant.h"
class GDScriptInstance;
class GDScript;
@@ -136,6 +136,7 @@ public:
enum Opcode {
OPCODE_OPERATOR,
OPCODE_EXTENDS_TEST,
+ OPCODE_IS_BUILTIN,
OPCODE_SET,
OPCODE_GET,
OPCODE_SET_NAMED,
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index d9c20868bd..c469defb01 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -30,15 +30,15 @@
#include "gdscript_functions.h"
-#include "class_db.h"
-#include "func_ref.h"
+#include "core/class_db.h"
+#include "core/func_ref.h"
+#include "core/io/json.h"
+#include "core/io/marshalls.h"
+#include "core/math/math_funcs.h"
+#include "core/os/os.h"
+#include "core/reference.h"
+#include "core/variant_parser.h"
#include "gdscript.h"
-#include "io/json.h"
-#include "io/marshalls.h"
-#include "math_funcs.h"
-#include "os/os.h"
-#include "reference.h"
-#include "variant_parser.h"
const char *GDScriptFunctions::get_func_name(Function p_func) {
@@ -1853,7 +1853,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case GET_STACK: {
MethodInfo mi("get_stack");
- mi.return_val.type = Variant::NIL;
+ mi.return_val.type = Variant::ARRAY;
return mi;
} break;
diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h
index a29f06e839..e920dd4ece 100644
--- a/modules/gdscript/gdscript_functions.h
+++ b/modules/gdscript/gdscript_functions.h
@@ -31,7 +31,7 @@
#ifndef GDSCRIPT_FUNCTIONS_H
#define GDSCRIPT_FUNCTIONS_H
-#include "variant.h"
+#include "core/variant.h"
class GDScriptFunctions {
public:
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index a3f5e1819e..9182e42c90 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -32,14 +32,13 @@
#include "core/core_string_names.h"
#include "core/engine.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
+#include "core/print_string.h"
#include "core/project_settings.h"
#include "core/reference.h"
+#include "core/script_language.h"
#include "gdscript.h"
-#include "io/resource_loader.h"
-#include "os/file_access.h"
-#include "print_string.h"
-#include "project_settings.h"
-#include "script_language.h"
template <class T>
T *GDScriptParser::alloc_node() {
@@ -861,6 +860,20 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
op->arguments.push_back(subexpr);
expr=op;*/
+ } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_IS && tokenizer->get_token(1) == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
+ // 'is' operator with built-in type
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op = OperatorNode::OP_IS_BUILTIN;
+ op->arguments.push_back(expr);
+
+ tokenizer->advance();
+
+ TypeNode *tn = alloc_node<TypeNode>();
+ tn->vtype = tokenizer->get_token_type();
+ op->arguments.push_back(tn);
+ tokenizer->advance();
+
+ expr = op;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_OPEN) {
// array
tokenizer->advance();
@@ -1071,6 +1084,15 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = op;
+ } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && expression.size() > 0 && expression[expression.size() - 1].is_op && expression[expression.size() - 1].op == OperatorNode::OP_IS) {
+ Expression e = expression[expression.size() - 1];
+ e.op = OperatorNode::OP_IS_BUILTIN;
+ expression.write[expression.size() - 1] = e;
+
+ TypeNode *tn = alloc_node<TypeNode>();
+ tn->vtype = tokenizer->get_token_type();
+ expr = tn;
+ tokenizer->advance();
} else {
//find list [ or find dictionary {
@@ -1329,6 +1351,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
switch (expression[i].op) {
case OperatorNode::OP_IS:
+ case OperatorNode::OP_IS_BUILTIN:
priority = -1;
break; //before anything
@@ -3915,14 +3938,15 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") {
- //current_export.hint=PROPERTY_HINT_ALL_FLAGS;
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ ERR_EXPLAIN("Exporting bit flags hint requires string constants.");
+ WARN_DEPRECATED
break;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
- _set_error("Expected ')' or ',' in bit flags hint.");
+ _set_error("Expected ',' in bit flags hint.");
return;
}
@@ -5793,6 +5817,13 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case Node::TYPE_CONSTANT: {
node_type = _type_from_variant(static_cast<ConstantNode *>(p_node)->value);
} break;
+ case Node::TYPE_TYPE: {
+ TypeNode *tn = static_cast<TypeNode *>(p_node);
+ node_type.has_type = true;
+ node_type.is_meta_type = true;
+ node_type.kind = DataType::BUILTIN;
+ node_type.builtin_type = tn->vtype;
+ } break;
case Node::TYPE_ARRAY: {
node_type.has_type = true;
node_type.kind = DataType::BUILTIN;
@@ -5896,7 +5927,8 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
// yield can return anything
node_type.has_type = false;
} break;
- case OperatorNode::OP_IS: {
+ case OperatorNode::OP_IS:
+ case OperatorNode::OP_IS_BUILTIN: {
if (op->arguments.size() != 2) {
_set_error("Parser bug: binary operation without 2 arguments.", op->line);
@@ -5913,8 +5945,11 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
}
type_type.is_meta_type = false; // Test the actual type
if (!_is_type_compatible(type_type, value_type) && !_is_type_compatible(value_type, type_type)) {
- // TODO: Make this a warning?
- _set_error("A value of type '" + value_type.to_string() + "' will never be an instance of '" + type_type.to_string() + "'.", op->line);
+ if (op->op == OperatorNode::OP_IS) {
+ _set_error("A value of type '" + value_type.to_string() + "' will never be an instance of '" + type_type.to_string() + "'.", op->line);
+ } else {
+ _set_error("A value of type '" + value_type.to_string() + "' will never be of type '" + type_type.to_string() + "'.", op->line);
+ }
return DataType();
}
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index dbe523a0b9..cd68072499 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -31,11 +31,11 @@
#ifndef GDSCRIPT_PARSER_H
#define GDSCRIPT_PARSER_H
+#include "core/map.h"
+#include "core/object.h"
+#include "core/script_language.h"
#include "gdscript_functions.h"
#include "gdscript_tokenizer.h"
-#include "map.h"
-#include "object.h"
-#include "script_language.h"
struct GDScriptDataType;
struct GDScriptWarning;
@@ -345,6 +345,7 @@ public:
OP_PARENT_CALL,
OP_YIELD,
OP_IS,
+ OP_IS_BUILTIN,
//indexing operator
OP_INDEX,
OP_INDEX_NAMED,
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 6e7842f190..941f5dbecc 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -30,10 +30,10 @@
#include "gdscript_tokenizer.h"
+#include "core/io/marshalls.h"
+#include "core/map.h"
+#include "core/print_string.h"
#include "gdscript_functions.h"
-#include "io/marshalls.h"
-#include "map.h"
-#include "print_string.h"
const char *GDScriptTokenizer::token_names[TK_MAX] = {
"Empty",
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 11a291cb2e..01b1ac5bf2 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -32,11 +32,11 @@
#define GDSCRIPT_TOKENIZER_H
#include "core/pair.h"
+#include "core/string_db.h"
+#include "core/ustring.h"
+#include "core/variant.h"
+#include "core/vmap.h"
#include "gdscript_functions.h"
-#include "string_db.h"
-#include "ustring.h"
-#include "variant.h"
-#include "vmap.h"
class GDScriptTokenizer {
public:
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 422223370b..26dcbdcf89 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -30,12 +30,12 @@
#include "register_types.h"
+#include "core/io/file_access_encrypted.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
#include "editor/gdscript_highlighter.h"
#include "gdscript.h"
#include "gdscript_tokenizer.h"
-#include "io/file_access_encrypted.h"
-#include "io/resource_loader.h"
-#include "os/file_access.h"
GDScriptLanguage *script_language_gd = NULL;
ResourceFormatLoaderGDScript *resource_loader_gd = NULL;
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index d5f9563600..09e8e39796 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -212,9 +212,12 @@
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask">
</member>
- <member name="theme" type="MeshLibrary" setter="set_theme" getter="get_theme">
+ <member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library">
The assigned [MeshLibrary].
</member>
+ <member name="theme" type="MeshLibrary" setter="set_theme" getter="get_theme">
+ Deprecated, use [member mesh_library] instead.
+ </member>
</members>
<constants>
<constant name="INVALID_CELL_ITEM" value="-1">
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 776c18da64..a480c4183e 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -29,13 +29,13 @@
/*************************************************************************/
#include "grid_map.h"
-#include "message_queue.h"
+#include "core/message_queue.h"
#include "scene/3d/light.h"
#include "scene/resources/surface_tool.h"
#include "servers/visual_server.h"
-#include "io/marshalls.h"
-#include "os/os.h"
+#include "core/io/marshalls.h"
+#include "core/os/os.h"
#include "scene/resources/mesh_library.h"
#include "scene/scene_string_names.h"
@@ -211,13 +211,17 @@ bool GridMap::get_collision_layer_bit(int p_bit) const {
#ifndef DISABLE_DEPRECATED
void GridMap::set_theme(const Ref<MeshLibrary> &p_theme) {
- WARN_PRINTS("GridMap.theme/set_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/set_mesh_library() instead.");
+ ERR_EXPLAIN("GridMap.theme/set_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/set_mesh_library() instead.");
+ WARN_DEPRECATED
+
set_mesh_library(p_theme);
}
Ref<MeshLibrary> GridMap::get_theme() const {
- WARN_PRINTS("GridMap.theme/get_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/get_mesh_library() instead.");
+ ERR_EXPLAIN("GridMap.theme/get_theme() is deprecated and will be removed in a future version. Use GridMap.mesh_library/get_mesh_library() instead.");
+ WARN_DEPRECATED
+
return get_mesh_library();
}
#endif // DISABLE_DEPRECATED
@@ -903,7 +907,7 @@ void GridMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_baked_meshes", "gen_lightmap_uv", "lightmap_uv_texel_size"), &GridMap::make_baked_meshes, DEFVAL(false), DEFVAL(0.1));
#ifndef DISABLE_DEPRECATED
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary", PROPERTY_USAGE_NOEDITOR), "set_theme", "get_theme");
+ ADD_PROPERTYNO(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary", 0), "set_theme", "get_theme");
#endif // DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh_library", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"), "set_mesh_library", "get_mesh_library");
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 90e28129cc..e6eaabd9ce 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -29,14 +29,14 @@
/*************************************************************************/
#include "grid_map_editor_plugin.h"
+#include "core/os/input.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/plugins/spatial_editor_plugin.h"
-#include "os/input.h"
#include "scene/3d/camera.h"
-#include "geometry.h"
-#include "os/keyboard.h"
+#include "core/math/geometry.h"
+#include "core/os/keyboard.h"
void GridMapEditor::_node_removed(Node *p_node) {
diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp
index a3ceea10af..030286d651 100644
--- a/modules/gridmap/register_types.cpp
+++ b/modules/gridmap/register_types.cpp
@@ -30,7 +30,7 @@
#include "register_types.h"
#ifndef _3D_DISABLED
-#include "class_db.h"
+#include "core/class_db.h"
#include "grid_map.h"
#include "grid_map_editor_plugin.h"
#endif
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index d592c19b97..fc6779ce86 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -30,8 +30,8 @@
#include "image_loader_hdr.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
#include "thirdparty/tinyexr/tinyexr.h"
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index 3cce483745..7175b38cc8 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_LOADER_HDR_H
#define IMAGE_LOADER_HDR_H
-#include "io/image_loader.h"
+#include "core/io/image_loader.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp
index 437c0d57fa..a49137ae73 100644
--- a/modules/jpg/image_loader_jpegd.cpp
+++ b/modules/jpg/image_loader_jpegd.cpp
@@ -30,8 +30,8 @@
#include "image_loader_jpegd.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
#include <jpgd.h>
#include <string.h>
diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h
index 3e3ac5217f..b5f0637c9b 100644
--- a/modules/jpg/image_loader_jpegd.h
+++ b/modules/jpg/image_loader_jpegd.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_LOADER_JPG_H
#define IMAGE_LOADER_JPG_H
-#include "io/image_loader.h"
+#include "core/io/image_loader.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp
index 884c26ddfe..3398957775 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.cpp
+++ b/modules/mbedtls/stream_peer_mbed_tls.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "stream_peer_mbed_tls.h"
+#include "core/os/file_access.h"
#include "mbedtls/platform_util.h"
-#include "os/file_access.h"
static void my_debug(void *ctx, int level,
const char *file, int line,
diff --git a/modules/mbedtls/stream_peer_mbed_tls.h b/modules/mbedtls/stream_peer_mbed_tls.h
index 7f4e5a4513..0cf893eacf 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.h
+++ b/modules/mbedtls/stream_peer_mbed_tls.h
@@ -31,7 +31,7 @@
#ifndef STREAM_PEER_OPEN_SSL_H
#define STREAM_PEER_OPEN_SSL_H
-#include "io/stream_peer_ssl.h"
+#include "core/io/stream_peer_ssl.h"
#include "mbedtls/config.h"
#include "mbedtls/ctr_drbg.h"
diff --git a/modules/mobile_vr/shaders/lens_distorted.glsl b/modules/mobile_vr/shaders/lens_distorted.glsl
index 5a2975d737..92604c891c 100644
--- a/modules/mobile_vr/shaders/lens_distorted.glsl
+++ b/modules/mobile_vr/shaders/lens_distorted.glsl
@@ -1,7 +1,9 @@
+/* clang-format off */
[vertex]
-layout(location=0) in highp vec4 vertex_attrib;
-layout(location=4) in vec2 uv_in;
+layout(location = 0) in highp vec4 vertex_attrib;
+/* clang-format on */
+layout(location = 4) in vec2 uv_in;
uniform float offset_x;
@@ -9,13 +11,15 @@ out vec2 uv_interp;
void main() {
- uv_interp = uv_in;
- gl_Position = vec4(vertex_attrib.x + offset_x, vertex_attrib.y, 0.0, 1.0);
+ uv_interp = uv_in;
+ gl_Position = vec4(vertex_attrib.x + offset_x, vertex_attrib.y, 0.0, 1.0);
}
+/* clang-format off */
[fragment]
uniform sampler2D source; //texunit:0
+/* clang-format on */
uniform vec2 eye_center;
uniform float k1;
@@ -28,32 +32,31 @@ in vec2 uv_interp;
layout(location = 0) out vec4 frag_color;
void main() {
- vec2 coords = uv_interp;
- vec2 offset = coords - eye_center;
-
- // take aspect ratio into account
- offset.y /= aspect_ratio;
-
- // distort
- vec2 offset_sq = offset * offset;
- float radius_sq = offset_sq.x + offset_sq.y;
- float radius_s4 = radius_sq * radius_sq;
- float distortion_scale = 1.0 + (k1 * radius_sq) + (k2 * radius_s4);
- offset *= distortion_scale;
-
- // reapply aspect ratio
- offset.y *= aspect_ratio;
-
- // add our eye center back in
- coords = offset + eye_center;
- coords /= upscale;
-
- // and check our color
- if (coords.x < -1.0 || coords.y < -1.0 || coords.x > 1.0 || coords.y > 1.0) {
- frag_color = vec4(0.0, 0.0, 0.0, 1.0);
- } else {
- coords = (coords + vec2(1.0)) / vec2(2.0);
- frag_color = textureLod(source, coords, 0.0);
- }
+ vec2 coords = uv_interp;
+ vec2 offset = coords - eye_center;
+
+ // take aspect ratio into account
+ offset.y /= aspect_ratio;
+
+ // distort
+ vec2 offset_sq = offset * offset;
+ float radius_sq = offset_sq.x + offset_sq.y;
+ float radius_s4 = radius_sq * radius_sq;
+ float distortion_scale = 1.0 + (k1 * radius_sq) + (k2 * radius_s4);
+ offset *= distortion_scale;
+
+ // reapply aspect ratio
+ offset.y *= aspect_ratio;
+
+ // add our eye center back in
+ coords = offset + eye_center;
+ coords /= upscale;
+
+ // and check our color
+ if (coords.x < -1.0 || coords.y < -1.0 || coords.x > 1.0 || coords.y > 1.0) {
+ frag_color = vec4(0.0, 0.0, 0.0, 1.0);
+ } else {
+ coords = (coords + vec2(1.0)) / vec2(2.0);
+ frag_color = textureLod(source, coords, 0.0);
+ }
}
-
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index f3cf4c9c5d..a8e19db022 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -7,21 +7,24 @@ env_mono = env_modules.Clone()
# TODO move functions to their own modules
-def make_cs_files_header(src, dst):
+def make_cs_files_header(src, dst, version_dst):
from compat import byte_to_str
with open(dst, 'w') as header:
- header.write('/* This is an automatically generated file; DO NOT EDIT! OK THX */\n')
- header.write('#ifndef _CS_FILES_DATA_H\n')
- header.write('#define _CS_FILES_DATA_H\n\n')
- header.write('#include "map.h"\n')
- header.write('#include "ustring.h"\n')
+ header.write('/* THIS FILE IS GENERATED DO NOT EDIT */\n')
+ header.write('#ifndef CS_COMPRESSED_H\n')
+ header.write('#define CS_COMPRESSED_H\n\n')
+ header.write('#ifdef TOOLS_ENABLED\n\n')
+ header.write('#include "core/map.h"\n')
+ header.write('#include "core/ustring.h"\n')
inserted_files = ''
import os
latest_mtime = 0
+ cs_file_count = 0
for root, _, files in os.walk(src):
files = [f for f in files if f.endswith('.cs')]
for file in files:
+ cs_file_count += 1
filepath = os.path.join(root, file)
filepath_src_rel = os.path.relpath(filepath, src)
mtime = os.path.getmtime(filepath)
@@ -31,8 +34,10 @@ def make_cs_files_header(src, dst):
decomp_size = len(buf)
import zlib
buf = zlib.compress(buf)
- name = os.path.splitext(os.path.normpath(filepath_src_rel))[0].strip(os.sep).replace(os.sep, '_').replace('.', '_dotto_')
- header.write('\nstatic const int _cs_' + name + '_compressed_size = ' + str(len(buf)) + ';\n')
+ name = str(cs_file_count)
+ header.write('\n')
+ header.write('// ' + filepath_src_rel + '\n')
+ header.write('static const int _cs_' + name + '_compressed_size = ' + str(len(buf)) + ';\n')
header.write('static const int _cs_' + name + '_uncompressed_size = ' + str(decomp_size) + ';\n')
header.write('static const unsigned char _cs_' + name + '_compressed[] = { ')
for i, buf_idx in enumerate(range(len(buf))):
@@ -44,8 +49,6 @@ def make_cs_files_header(src, dst):
'_cs_' + name + '_uncompressed_size, ' \
'_cs_' + name + '_compressed));\n'
header.write(' };\n')
- glue_version = int(latest_mtime) # The latest modified time will do for now
- header.write('\n#define CS_GLUE_VERSION UINT32_C(' + str(glue_version) + ')\n')
header.write('\nstruct CompressedFile\n' '{\n'
'\tint compressed_size;\n' '\tint uncompressed_size;\n' '\tconst unsigned char* data;\n'
'\n\tCompressedFile(int p_comp_size, int p_uncomp_size, const unsigned char* p_data)\n'
@@ -53,17 +56,28 @@ def make_cs_files_header(src, dst):
'\t\tdata = p_data;\n' '\t}\n' '\n\tCompressedFile() {}\n' '};\n'
'\nvoid get_compressed_files(Map<String, CompressedFile>& r_files)\n' '{\n' + inserted_files + '}\n'
)
- header.write('#endif // _CS_FILES_DATA_H')
+ header.write('\n#endif // TOOLS_ENABLED\n')
+ header.write('\n#endif // CS_COMPRESSED_H\n')
+
+ glue_version = int(latest_mtime) # The latest modified time will do for now
+
+ with open(version_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')
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')
if env['tools']:
env_mono.add_source_files(env.modules_sources, 'editor/*.cpp')
- # NOTE: It is safe to generate this file here, since this is still execute serially
- make_cs_files_header('glue/cs_files', 'glue/cs_compressed.gen.h')
+ # NOTE: It is safe to generate this file here, since this is still executed serially
+ make_cs_files_header('glue/cs_files', 'glue/cs_compressed.gen.h', 'glue/cs_glue_version.gen.h')
vars = Variables()
vars.Add(BoolVariable('mono_glue', 'Build with the mono glue sources', True))
@@ -72,9 +86,7 @@ vars.Update(env_mono)
# Glue sources
if env_mono['mono_glue']:
- env_mono.add_source_files(env.modules_sources, 'glue/*.cpp')
-else:
- env_mono.Append(CPPDEFINES=['MONO_GLUE_DISABLED'])
+ env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED'])
if ARGUMENTS.get('yolo_copy', False):
env_mono.Append(CPPDEFINES=['YOLO_COPY'])
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index b8b77924f7..f15114ef1d 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -32,10 +32,10 @@
#include <mono/metadata/threads.h>
-#include "os/file_access.h"
-#include "os/os.h"
-#include "os/thread.h"
-#include "project_settings.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/os/thread.h"
+#include "core/project_settings.h"
#ifdef TOOLS_ENABLED
#include "editor/bindings_generator.h"
@@ -107,7 +107,7 @@ void CSharpLanguage::init() {
gdmono = memnew(GDMono);
gdmono->initialize();
-#ifdef MONO_GLUE_DISABLED
+#ifndef MONO_GLUE_ENABLED
WARN_PRINT("This binary is built with `mono_glue=no` and cannot be used for scripting");
#endif
@@ -138,7 +138,7 @@ void CSharpLanguage::finish() {
#endif
// Release gchandle bindings before finalizing mono runtime
- gchandle_bindings.clear();
+ script_bindings.clear();
if (gdmono) {
memdelete(gdmono);
@@ -551,22 +551,22 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
void CSharpLanguage::frame() {
- const Ref<MonoGCHandle> &task_scheduler_handle = GDMonoUtils::mono_cache.task_scheduler_handle;
+ if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != NULL) {
+ const Ref<MonoGCHandle> &task_scheduler_handle = GDMonoUtils::mono_cache.task_scheduler_handle;
- if (task_scheduler_handle.is_valid()) {
- MonoObject *task_scheduler = task_scheduler_handle->get_target();
+ if (task_scheduler_handle.is_valid()) {
+ MonoObject *task_scheduler = task_scheduler_handle->get_target();
- if (task_scheduler) {
- GDMonoUtils::GodotTaskScheduler_Activate thunk = CACHED_METHOD_THUNK(GodotTaskScheduler, Activate);
+ if (task_scheduler) {
+ GDMonoUtils::GodotTaskScheduler_Activate thunk = CACHED_METHOD_THUNK(GodotTaskScheduler, Activate);
- ERR_FAIL_NULL(thunk);
+ MonoException *exc = NULL;
+ thunk(task_scheduler, (MonoObject **)&exc);
- MonoException *exc = NULL;
- thunk(task_scheduler, (MonoObject **)&exc);
-
- if (exc) {
- GDMonoUtils::debug_unhandled_exception(exc);
- _UNREACHABLE_();
+ if (exc) {
+ GDMonoUtils::debug_unhandled_exception(exc);
+ _UNREACHABLE_();
+ }
}
}
}
@@ -892,6 +892,48 @@ void CSharpLanguage::set_language_index(int p_idx) {
lang_idx = p_idx;
}
+void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) {
+
+ if (!p_gchandle->is_released()) { // Do not locking unnecessarily
+#ifndef NO_THREADS
+ get_singleton()->script_gchandle_release_lock->lock();
+#endif
+
+ p_gchandle->release();
+
+#ifndef NO_THREADS
+ get_singleton()->script_gchandle_release_lock->unlock();
+#endif
+ }
+}
+
+void CSharpLanguage::release_script_gchandle(MonoObject *p_pinned_expected_obj, Ref<MonoGCHandle> &p_gchandle) {
+
+ uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_pinned_expected_obj); // we might lock after this, so pin it
+
+ if (!p_gchandle->is_released()) { // Do not locking unnecessarily
+#ifndef NO_THREADS
+ get_singleton()->script_gchandle_release_lock->lock();
+#endif
+
+ 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_pinned_expected_obj || target == NULL) {
+ p_gchandle->release();
+ }
+
+#ifndef NO_THREADS
+ get_singleton()->script_gchandle_release_lock->unlock();
+#endif
+ }
+
+ MonoGCHandle::free_handle(pinned_gchandle);
+}
+
CSharpLanguage::CSharpLanguage() {
ERR_FAIL_COND(singleton);
@@ -904,9 +946,11 @@ CSharpLanguage::CSharpLanguage() {
#ifdef NO_THREADS
lock = NULL;
gchandle_bind_lock = NULL;
+ script_gchandle_release_lock = NULL;
#else
lock = Mutex::create();
script_bind_lock = Mutex::create();
+ script_gchandle_release_lock = Mutex::create();
#endif
lang_idx = -1;
@@ -926,6 +970,11 @@ CSharpLanguage::~CSharpLanguage() {
script_bind_lock = NULL;
}
+ if (script_gchandle_release_lock) {
+ memdelete(script_gchandle_release_lock);
+ script_gchandle_release_lock = NULL;
+ }
+
singleton = NULL;
}
@@ -954,30 +1003,34 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
ERR_FAIL_NULL_V(mono_object, NULL);
- // Tie managed to unmanaged
- Reference *ref = Object::cast_to<Reference>(p_object);
+ CSharpScriptBinding script_binding;
- if (ref) {
- // Unsafe refcount increment. The managed instance also counts as a reference.
- // This way if the unmanaged world has no references to our owner
- // but the managed instance is alive, the refcount will be 1 instead of 0.
- // See: _GodotSharp::_dispose_object(Object *p_object)
-
- ref->reference();
- }
-
- Ref<MonoGCHandle> gchandle = MonoGCHandle::create_strong(mono_object);
+ script_binding.type_name = type_name;
+ script_binding.wrapper_class = type_class; // cache
+ script_binding.gchandle = MonoGCHandle::create_strong(mono_object);
#ifndef NO_THREADS
script_bind_lock->lock();
#endif
- void *data = (void *)gchandle_bindings.insert(p_object, gchandle);
+ void *data = (void *)script_bindings.insert(p_object, script_binding);
#ifndef NO_THREADS
script_bind_lock->unlock();
#endif
+ // Tie managed to unmanaged
+ Reference *ref = Object::cast_to<Reference>(p_object);
+
+ if (ref) {
+ // Unsafe refcount increment. The managed instance also counts as a reference.
+ // This way if the unmanaged world has no references to our owner
+ // but the managed instance is alive, the refcount will be 1 instead of 0.
+ // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr)
+
+ ref->reference();
+ }
+
return data;
}
@@ -985,7 +1038,7 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
if (GDMono::get_singleton() == NULL) {
#ifdef DEBUG_ENABLED
- CRASH_COND(!gchandle_bindings.empty());
+ CRASH_COND(!script_bindings.empty());
#endif
// Mono runtime finalized, all the gchandle bindings were already released
return;
@@ -998,21 +1051,84 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
script_bind_lock->lock();
#endif
- Map<Object *, Ref<MonoGCHandle> >::Element *data = (Map<Object *, Ref<MonoGCHandle> >::Element *)p_data;
+ Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data;
// Set the native instance field to IntPtr.Zero, if not yet garbage collected
- MonoObject *mono_object = data->value()->get_target();
+ MonoObject *mono_object = data->value().gchandle->get_target();
if (mono_object) {
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, NULL);
}
- gchandle_bindings.erase(data);
+ script_bindings.erase(data);
#ifndef NO_THREADS
script_bind_lock->unlock();
#endif
}
+void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
+
+ Reference *ref_owner = Object::cast_to<Reference>(p_object);
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!ref_owner);
+#endif
+
+ void *data = p_object->get_script_instance_binding(get_language_index());
+ if (!data)
+ return;
+ Ref<MonoGCHandle> &gchandle = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get().gchandle;
+
+ if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ // 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();
+ 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);
+ }
+}
+
+bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
+
+ Reference *ref_owner = Object::cast_to<Reference>(p_object);
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!ref_owner);
+#endif
+
+ int refcount = ref_owner->reference_get_count();
+
+ void *data = p_object->get_script_instance_binding(get_language_index());
+ if (!data)
+ return refcount == 0;
+ Ref<MonoGCHandle> &gchandle = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get().gchandle;
+
+ if (refcount == 1 && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ // 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();
+ 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);
+
+ return false;
+ }
+
+ return refcount == 0;
+}
+
CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref<MonoGCHandle> &p_gchandle) {
CSharpInstance *instance = memnew(CSharpInstance);
@@ -1033,9 +1149,8 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS
}
MonoObject *CSharpInstance::get_mono_object() const {
-#ifdef DEBUG_ENABLED
- CRASH_COND(gchandle.is_null());
-#endif
+
+ ERR_FAIL_COND_V(gchandle.is_null(), NULL);
return gchandle->get_target();
}
@@ -1263,10 +1378,12 @@ void CSharpInstance::call_multilevel_reversed(const StringName &p_method, const
call_multilevel(p_method, p_args, p_argcount);
}
-void CSharpInstance::_reference_owner_unsafe() {
+bool CSharpInstance::_reference_owner_unsafe() {
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
+ CRASH_COND(owner == NULL);
+ CRASH_COND(unsafe_referenced); // already referenced
#endif
// Unsafe refcount increment. The managed instance also counts as a reference.
@@ -1275,66 +1392,142 @@ void CSharpInstance::_reference_owner_unsafe() {
// See: _unreference_owner_unsafe()
// May not me referenced yet, so we must use init_ref() instead of reference()
- Object::cast_to<Reference>(owner)->init_ref();
+ bool success = Object::cast_to<Reference>(owner)->init_ref();
+ unsafe_referenced = success;
+ return success;
}
-void CSharpInstance::_unreference_owner_unsafe() {
+bool CSharpInstance::_unreference_owner_unsafe() {
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
+ CRASH_COND(owner == NULL);
#endif
+ if (!unsafe_referenced)
+ return false; // Already unreferenced
+
// Called from CSharpInstance::mono_object_disposed() or ~CSharpInstance()
// Unsafe refcount decrement. The managed instance also counts as a reference.
// See: _reference_owner_unsafe()
- if (Object::cast_to<Reference>(owner)->unreference()) {
+ bool die = static_cast<Reference *>(owner)->unreference();
+
+ if (die) {
memdelete(owner);
owner = NULL;
}
+
+ return die;
}
-void CSharpInstance::mono_object_disposed() {
+MonoObject *CSharpInstance::_internal_new_managed() {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!gchandle.is_valid());
+#endif
+
+ CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
+
+ ERR_FAIL_NULL_V(owner, NULL);
+ ERR_FAIL_COND_V(script.is_null(), NULL);
if (base_ref)
- _unreference_owner_unsafe();
+ _reference_owner_unsafe();
+
+ MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, script->script_class->get_mono_ptr());
+
+ if (!mono_object) {
+ script = Ref<CSharpScript>();
+ owner->set_script_instance(NULL);
+ ERR_EXPLAIN("Failed to allocate memory for the object");
+ ERR_FAIL_V(NULL);
+ }
+
+ CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, owner);
+
+ // Construct
+ GDMonoMethod *ctor = script->script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
+ ctor->invoke_raw(mono_object, NULL);
+
+ // Tie managed to unmanaged
+ gchandle = MonoGCHandle::create_strong(mono_object);
+
+ return mono_object;
+}
+
+bool CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(base_ref == true);
+ CRASH_COND(gchandle.is_null());
+#endif
+ CSharpLanguage::get_singleton()->release_script_gchandle(p_obj, gchandle);
+}
+
+bool CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_owner_deleted) {
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(base_ref == false);
+ CRASH_COND(gchandle.is_null());
+#endif
+ if (_unreference_owner_unsafe()) {
+ r_owner_deleted = true;
+ } else {
+ r_owner_deleted = false;
+ CSharpLanguage::get_singleton()->release_script_gchandle(p_obj, gchandle);
+ if (p_is_finalizer) {
+ // If the native instance is still alive, then it was
+ // referenced from another thread before the finalizer could
+ // unreference it and delete it, so we want to keep it.
+ // GC.ReRegisterForFinalize(this) is not safe because the objects
+ // referenced by this could have already been collected.
+ // Instead we will create a new managed instance here.
+ _internal_new_managed();
+ }
+ }
}
void CSharpInstance::refcount_incremented() {
+#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
+ CRASH_COND(owner == NULL);
+#endif
Reference *ref_owner = Object::cast_to<Reference>(owner);
- if (ref_owner->reference_get_count() > 1) { // 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
// 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.
// Release the current weak handle and replace it with a strong handle.
- uint32_t strong_gchandle = MonoGCHandle::make_strong_handle(gchandle->get_target());
+ uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(gchandle->get_target());
gchandle->release();
- gchandle->set_handle(strong_gchandle);
+ gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE);
}
}
bool CSharpInstance::refcount_decremented() {
+#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
+ CRASH_COND(owner == NULL);
+#endif
Reference *ref_owner = Object::cast_to<Reference>(owner);
int refcount = ref_owner->reference_get_count();
- if (refcount == 1) { // 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
// 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::make_weak_handle(gchandle->get_target());
+ uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(gchandle->get_target());
gchandle->release();
- gchandle->set_handle(weak_gchandle);
+ gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE);
return false;
}
@@ -1403,25 +1596,64 @@ MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variab
void CSharpInstance::notification(int p_notification) {
- MonoObject *mono_object = get_mono_object();
-
if (p_notification == Object::NOTIFICATION_PREDELETE) {
- if (mono_object != NULL) { // otherwise it was collected, and the finalizer already called NOTIFICATION_PREDELETE
- call_notification_no_check(mono_object, p_notification);
- // Set the native instance field to IntPtr.Zero
- CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, NULL);
+ // When NOTIFICATION_PREDELETE is sent, we also take the chance to call Dispose().
+ // It's safe to call Dispose() multiple times and NOTIFICATION_PREDELETE is guaranteed
+ // to be sent at least once, which happens right before the call to the destructor.
+
+ if (base_ref) {
+ // It's not safe to proceed if the owner derives Reference and the refcount reached 0.
+ // At this point, Dispose() was already called (manually or from the finalizer) so
+ // that's not a problem. The refcount wouldn't have reached 0 otherwise, since the
+ // managed side references it and Dispose() needs to be called to release it.
+ // However, this means C# Reference scripts can't receive NOTIFICATION_PREDELETE, but
+ // this is likely the case with GDScript as well: https://github.com/godotengine/godot/issues/6784
+ return;
+ }
+
+ _call_notification(p_notification);
+
+ MonoObject *mono_object = get_mono_object();
+ ERR_FAIL_NULL(mono_object);
+
+ GDMonoUtils::GodotObject_Dispose thunk = CACHED_METHOD_THUNK(GodotObject, Dispose);
+
+ MonoException *exc = NULL;
+ thunk(mono_object, (MonoObject **)&exc);
+
+ if (exc) {
+ GDMonoUtils::set_pending_exception(exc);
}
+
return;
}
- call_notification_no_check(mono_object, p_notification);
+ _call_notification(p_notification);
}
-void CSharpInstance::call_notification_no_check(MonoObject *p_mono_object, int p_notification) {
- Variant value = p_notification;
- const Variant *args[1] = { &value };
+void CSharpInstance::_call_notification(int p_notification) {
+
+ MonoObject *mono_object = get_mono_object();
+ ERR_FAIL_NULL(mono_object);
+
+ // Custom version of _call_multilevel, optimized for _notification
+
+ uint32_t arg = p_notification;
+ void *args[1] = { &arg };
+ StringName method_name = CACHED_STRING_NAME(_notification);
- _call_multilevel(p_mono_object, CACHED_STRING_NAME(_notification), args, 1);
+ GDMonoClass *top = script->script_class;
+
+ while (top && top != script->native) {
+ GDMonoMethod *method = top->get_method(method_name, 1);
+
+ if (method) {
+ method->invoke_raw(mono_object, args);
+ return;
+ }
+
+ top = top->get_parent_class();
+ }
}
Ref<Script> CSharpInstance::get_script() const {
@@ -1434,11 +1666,11 @@ ScriptLanguage *CSharpInstance::get_language() {
return CSharpLanguage::get_singleton();
}
-CSharpInstance::CSharpInstance() {
-
- owner = NULL;
- base_ref = false;
- ref_dying = false;
+CSharpInstance::CSharpInstance() :
+ owner(NULL),
+ base_ref(false),
+ ref_dying(false),
+ unsafe_referenced(false) {
}
CSharpInstance::~CSharpInstance() {
@@ -1447,10 +1679,7 @@ CSharpInstance::~CSharpInstance() {
gchandle->release(); // Make sure it's released
}
- if (base_ref && !ref_dying) { // it may be called from the owner's destructor
-#ifdef DEBUG_ENABLED
- CRASH_COND(!owner); // dunno, just in case
-#endif
+ if (base_ref && !ref_dying && owner) { // it may be called from the owner's destructor
_unreference_owner_unsafe();
}
@@ -1519,26 +1748,27 @@ bool CSharpScript::_update_exports() {
exported_members_cache.clear();
exported_members_defval_cache.clear();
- // We are creating a temporary new instance of the class here to get the default value
- // TODO Workaround. Should be replaced with IL opcodes analysis
+ // Here we create a temporary managed instance of the class to get the initial values
MonoObject *tmp_object = mono_object_new(SCRIPTS_DOMAIN, script_class->get_mono_ptr());
- if (tmp_object) {
- CACHED_FIELD(GodotObject, ptr)->set_value_raw(tmp_object, tmp_object); // FIXME WTF is this workaround
+ if (!tmp_object) {
+ ERR_PRINT("Failed to create temporary MonoObject");
+ return false;
+ }
- GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
- MonoException *exc = NULL;
- ctor->invoke(tmp_object, NULL, &exc);
+ uint32_t tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed)
- if (exc) {
- ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
- GDMonoUtils::debug_print_unhandled_exception(exc);
- tmp_object = NULL;
- ERR_FAIL_V(false);
- }
- } else {
- ERR_PRINT("Failed to create temporary MonoObject");
+ GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
+ MonoException *ctor_exc = NULL;
+ ctor->invoke(tmp_object, NULL, &ctor_exc);
+
+ if (ctor_exc) {
+ MonoGCHandle::free_handle(tmp_pinned_gchandle);
+ tmp_object = NULL;
+
+ ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
+ GDMonoUtils::debug_print_unhandled_exception(ctor_exc);
return false;
}
@@ -1599,6 +1829,21 @@ bool CSharpScript::_update_exports() {
top = top->get_parent_class();
}
+
+ // Dispose the temporary managed instance
+
+ GDMonoUtils::GodotObject_Dispose thunk = CACHED_METHOD_THUNK(GodotObject, Dispose);
+
+ MonoException *exc = NULL;
+ thunk(tmp_object, (MonoObject **)&exc);
+
+ if (exc) {
+ ERR_PRINT("Exception thrown from method Dispose() of temporary MonoObject:");
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ }
+
+ MonoGCHandle::free_handle(tmp_pinned_gchandle);
+ tmp_object = NULL;
}
if (placeholders.size()) {
@@ -1945,6 +2190,8 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
ERR_FAIL_V(NULL);
}
+ uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(mono_object); // we might lock after this, so pin it
+
#ifndef NO_THREADS
CSharpLanguage::singleton->lock->lock();
#endif
@@ -1966,6 +2213,8 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
/* STEP 3, PARTY */
+ MonoGCHandle::free_handle(pinned_gchandle);
+
//@TODO make thread safe
return instance;
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 53644eafae..fa399bb187 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -31,10 +31,10 @@
#ifndef CSHARP_SCRIPT_H
#define CSHARP_SCRIPT_H
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "script_language.h"
-#include "self_list.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/script_language.h"
+#include "core/self_list.h"
#include "mono_gc_handle.h"
#include "mono_gd/gd_mono.h"
@@ -48,6 +48,8 @@ class CSharpLanguage;
#ifdef NO_SAFE_CAST
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;
}
#else
@@ -177,14 +179,19 @@ class CSharpInstance : public ScriptInstance {
friend class CSharpScript;
friend class CSharpLanguage;
+
Object *owner;
- Ref<CSharpScript> script;
- Ref<MonoGCHandle> gchandle;
bool base_ref;
bool ref_dying;
+ bool unsafe_referenced;
+
+ Ref<CSharpScript> script;
+ Ref<MonoGCHandle> gchandle;
- void _reference_owner_unsafe();
- void _unreference_owner_unsafe();
+ bool _reference_owner_unsafe();
+ bool _unreference_owner_unsafe();
+
+ MonoObject *_internal_new_managed();
// Do not use unless you know what you are doing
friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *);
@@ -208,7 +215,8 @@ public:
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();
+ bool mono_object_disposed(MonoObject *p_obj);
+ bool mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_owner_deleted);
virtual void refcount_incremented();
virtual bool refcount_decremented();
@@ -217,7 +225,7 @@ public:
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
virtual void notification(int p_notification);
- void call_notification_no_check(MonoObject *p_mono_object, int p_notification);
+ void _call_notification(int p_notification);
virtual Ref<Script> get_script() const;
@@ -227,6 +235,12 @@ public:
~CSharpInstance();
};
+struct CSharpScriptBinding {
+ StringName type_name;
+ GDMonoClass *wrapper_class;
+ Ref<MonoGCHandle> gchandle;
+};
+
class CSharpLanguage : public ScriptLanguage {
friend class CSharpScript;
@@ -241,10 +255,11 @@ class CSharpLanguage : public ScriptLanguage {
Mutex *lock;
Mutex *script_bind_lock;
+ Mutex *script_gchandle_release_lock;
Map<Ref<CSharpScript>, Map<ObjectID, List<Pair<StringName, Variant> > > > to_reload;
- Map<Object *, Ref<MonoGCHandle> > gchandle_bindings;
+ Map<Object *, CSharpScriptBinding> script_bindings;
struct StringNameCache {
@@ -270,6 +285,9 @@ public:
_FORCE_INLINE_ static CSharpLanguage *get_singleton() { return singleton; }
+ static void release_script_gchandle(Ref<MonoGCHandle> &p_gchandle);
+ static void release_script_gchandle(MonoObject *p_pinned_expected_obj, Ref<MonoGCHandle> &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);
@@ -346,6 +364,8 @@ public:
// Don't use these. I'm watching you
virtual void *alloc_instance_binding_data(Object *p_object);
virtual void free_instance_binding_data(void *p_data);
+ virtual void refcount_incremented_instance_binding(Object *p_object);
+ virtual bool refcount_decremented_instance_binding(Object *p_object);
#ifdef DEBUG_ENABLED
Vector<StackInfo> stack_trace_get_info(MonoObject *p_stack_trace);
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index b97bb5e95f..308c54ecb3 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -32,15 +32,16 @@
#ifdef DEBUG_METHODS_ENABLED
-#include "engine.h"
-#include "global_constants.h"
-#include "io/compression.h"
-#include "os/dir_access.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "ucaps.h"
+#include "core/engine.h"
+#include "core/global_constants.h"
+#include "core/io/compression.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/ucaps.h"
#include "../glue/cs_compressed.gen.h"
+#include "../glue/cs_glue_version.gen.h"
#include "../godotsharp_defs.h"
#include "../mono_gd/gd_mono_marshal.h"
#include "../utils/path_utils.h"
@@ -48,7 +49,7 @@
#include "csharp_project.h"
#include "net_solution.h"
-#define CS_INDENT " "
+#define CS_INDENT " " // 4 whitespaces
#define INDENT1 CS_INDENT
#define INDENT2 INDENT1 INDENT1
@@ -68,23 +69,18 @@
#define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK
#define CLOSE_BLOCK_L4 INDENT4 CLOSE_BLOCK
-#define LOCAL_RET "ret"
-
#define CS_FIELD_MEMORYOWN "memoryOwn"
#define CS_PARAM_METHODBIND "method"
#define CS_PARAM_INSTANCE "ptr"
#define CS_SMETHOD_GETINSTANCE "GetPtr"
-#define CS_FIELD_SINGLETON "instance"
-#define CS_PROP_SINGLETON "Instance"
-#define CS_CLASS_SIGNALAWAITER "SignalAwaiter"
#define CS_METHOD_CALL "Call"
#define GLUE_HEADER_FILE "glue_header.h"
#define ICALL_PREFIX "godot_icall_"
#define SINGLETON_ICALL_SUFFIX "_get_singleton"
-#define ICALL_GET_METHODBIND ICALL_PREFIX "ClassDB_get_method"
-#define ICALL_CONNECT_SIGNAL_AWAITER ICALL_PREFIX "Object_connect_signal_awaiter"
-#define ICALL_OBJECT_DTOR ICALL_PREFIX "Object_Dtor"
+#define ICALL_GET_METHODBIND ICALL_PREFIX "Object_ClassDB_get_method"
+
+#define C_LOCAL_RET "ret"
#define C_LOCAL_PTRCALL_ARGS "call_args"
#define C_MACRO_OBJECT_CONSTRUCT "GODOTSHARP_INSTANCE_OBJECT"
@@ -101,7 +97,7 @@
#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 BINDINGS_GENERATOR_VERSION UINT32_C(2)
+#define BINDINGS_GENERATOR_VERSION UINT32_C(3)
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n";
@@ -196,48 +192,6 @@ String BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
return front->get().name.substr(0, candidate_len);
}
-void BindingsGenerator::_generate_header_icalls() {
-
- core_custom_icalls.clear();
-
- core_custom_icalls.push_back(InternalCall(ICALL_GET_METHODBIND, "IntPtr", "string type, string method"));
- core_custom_icalls.push_back(InternalCall(ICALL_OBJECT_DTOR, "void", "object obj, IntPtr ptr"));
-
- core_custom_icalls.push_back(InternalCall(ICALL_CONNECT_SIGNAL_AWAITER, "Error",
- "IntPtr source, string signal, IntPtr target, " CS_CLASS_SIGNALAWAITER " awaiter"));
-
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "NodePath_Ctor", "IntPtr", "string path"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "NodePath_Dtor", "void", "IntPtr ptr"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "NodePath_operator_String", "string", "IntPtr ptr"));
-
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "RID_Ctor", "IntPtr", "IntPtr from"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "RID_Dtor", "void", "IntPtr ptr"));
-
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "String_md5_buffer", "byte[]", "string str"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "String_md5_text", "string", "string str"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "String_rfind", "int", "string str, string what, int from"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "String_rfindn", "int", "string str, string what, int from"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "String_sha256_buffer", "byte[]", "string str"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "String_sha256_text", "string", "string str"));
-
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_bytes2var", "object", "byte[] bytes"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_convert", "object", "object what, int type"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_hash", "int", "object var"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_instance_from_id", "Object", "int instance_id"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_print", "void", "object[] what"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_printerr", "void", "object[] what"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_printraw", "void", "object[] what"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_prints", "void", "object[] what"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_printt", "void", "object[] what"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_seed", "void", "int seed"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_str", "string", "object[] what"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_str2var", "object", "string str"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_type_exists", "bool", "string type"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_var2bytes", "byte[]", "object what"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_var2str", "string", "object var"));
- core_custom_icalls.push_back(InternalCall(ICALL_PREFIX "Godot_weakref", "WeakRef", "IntPtr obj"));
-}
-
void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
for (const List<MethodInterface>::Element *E = p_itype.methods.front(); E; E = E->next()) {
@@ -248,13 +202,8 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
const TypeInterface *return_type = _get_type_or_placeholder(imethod.return_type);
- String im_sig;
- String im_unique_sig;
-
- if (p_itype.is_object_type) {
- im_sig += "IntPtr " CS_PARAM_METHODBIND ", ";
- im_unique_sig += imethod.return_type.cname.operator String() + ",IntPtr,IntPtr";
- }
+ String im_sig = "IntPtr " CS_PARAM_METHODBIND ", ";
+ String im_unique_sig = imethod.return_type.cname.operator String() + ",IntPtr,IntPtr";
im_sig += "IntPtr " CS_PARAM_INSTANCE;
@@ -268,37 +217,28 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
im_sig += " arg";
im_sig += itos(i + 1);
- if (p_itype.is_object_type) {
- im_unique_sig += ",";
- im_unique_sig += get_unique_sig(*arg_type);
- }
+ im_unique_sig += ",";
+ im_unique_sig += get_unique_sig(*arg_type);
i++;
}
+ // godot_icall_{argc}_{icallcount}
String icall_method = ICALL_PREFIX;
-
- if (p_itype.is_object_type) {
- icall_method += itos(imethod.arguments.size()) + "_" + itos(method_icalls.size()); // godot_icall_{argc}_{icallcount}
- } else {
- icall_method += p_itype.name + "_" + imethod.name; // godot_icall_{Type}_{method}
- }
+ icall_method += itos(imethod.arguments.size());
+ icall_method += "_";
+ icall_method += itos(method_icalls.size());
InternalCall im_icall = InternalCall(p_itype.api_type, icall_method, return_type->im_type_out, im_sig, im_unique_sig);
- if (p_itype.is_object_type) {
- List<InternalCall>::Element *match = method_icalls.find(im_icall);
+ List<InternalCall>::Element *match = method_icalls.find(im_icall);
- if (match) {
- if (p_itype.api_type != ClassDB::API_EDITOR)
- match->get().editor_only = false;
- method_icalls_map.insert(&E->get(), &match->get());
- } else {
- List<InternalCall>::Element *added = method_icalls.push_back(im_icall);
- method_icalls_map.insert(&E->get(), &added->get());
- }
+ if (match) {
+ if (p_itype.api_type != ClassDB::API_EDITOR)
+ match->get().editor_only = false;
+ method_icalls_map.insert(&E->get(), &match->get());
} else {
- List<InternalCall>::Element *added = builtin_method_icalls.push_back(im_icall);
+ List<InternalCall>::Element *added = method_icalls.push_back(im_icall);
method_icalls_map.insert(&E->get(), &added->get());
}
}
@@ -483,20 +423,6 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo
compile_items.push_back(output_file);
}
-#define GENERATE_BUILTIN_TYPE(m_name) \
- { \
- String output_file = path_join(core_dir, #m_name ".cs"); \
- Error err = _generate_cs_type(builtin_types[#m_name], output_file); \
- if (err != OK) \
- return err; \
- compile_items.push_back(output_file); \
- }
-
- GENERATE_BUILTIN_TYPE(NodePath);
- GENERATE_BUILTIN_TYPE(RID);
-
-#undef GENERATE_BUILTIN_TYPE
-
// Generate sources from compressed files
Map<String, CompressedFile> compressed_files;
@@ -533,34 +459,30 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo
cs_icalls_content.push_back("using System;\n"
"using System.Runtime.CompilerServices;\n"
- "using System.Collections.Generic;\n"
"\n");
cs_icalls_content.push_back("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
cs_icalls_content.push_back(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 OPEN_BLOCK);
- cs_icalls_content.push_back(INDENT2 "internal static ulong godot_api_hash = ");
+ cs_icalls_content.push_back(MEMBER_BEGIN "internal static ulong godot_api_hash = ");
cs_icalls_content.push_back(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + ";\n");
- cs_icalls_content.push_back(INDENT2 "internal static uint bindings_version = ");
+ cs_icalls_content.push_back(MEMBER_BEGIN "internal static uint bindings_version = ");
cs_icalls_content.push_back(String::num_uint64(BINDINGS_GENERATOR_VERSION) + ";\n");
- cs_icalls_content.push_back(INDENT2 "internal static uint cs_glue_version = ");
+ cs_icalls_content.push_back(MEMBER_BEGIN "internal static uint cs_glue_version = ");
cs_icalls_content.push_back(String::num_uint64(CS_GLUE_VERSION) + ";\n");
- cs_icalls_content.push_back("\n");
-#define ADD_INTERNAL_CALL(m_icall) \
- if (!m_icall.editor_only) { \
- cs_icalls_content.push_back(INDENT2 "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \
- cs_icalls_content.push_back(INDENT2 "internal extern static "); \
- cs_icalls_content.push_back(m_icall.im_type_out + " "); \
- cs_icalls_content.push_back(m_icall.name + "("); \
- cs_icalls_content.push_back(m_icall.im_sig + ");\n"); \
+#define ADD_INTERNAL_CALL(m_icall) \
+ if (!m_icall.editor_only) { \
+ cs_icalls_content.push_back(MEMBER_BEGIN "[MethodImpl(MethodImplOptions.InternalCall)]\n"); \
+ cs_icalls_content.push_back(INDENT2 "internal extern static "); \
+ cs_icalls_content.push_back(m_icall.im_type_out + " "); \
+ cs_icalls_content.push_back(m_icall.name + "("); \
+ cs_icalls_content.push_back(m_icall.im_sig + ");\n"); \
}
for (const List<InternalCall>::Element *E = core_custom_icalls.front(); E; E = E->next())
ADD_INTERNAL_CALL(E->get());
for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next())
ADD_INTERNAL_CALL(E->get());
- for (const List<InternalCall>::Element *E = builtin_method_icalls.front(); E; E = E->next())
- ADD_INTERNAL_CALL(E->get());
#undef ADD_INTERNAL_CALL
@@ -638,7 +560,6 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir,
cs_icalls_content.push_back("using System;\n"
"using System.Runtime.CompilerServices;\n"
- "using System.Collections.Generic;\n"
"\n");
cs_icalls_content.push_back("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
cs_icalls_content.push_back(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS_EDITOR "\n" INDENT1 OPEN_BLOCK);
@@ -660,8 +581,6 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir,
cs_icalls_content.push_back(m_icall.im_sig + ");\n"); \
}
- // No need to add builtin_method_icalls. Builtin types are core only
-
for (const List<InternalCall>::Element *E = editor_custom_icalls.front(); E; E = E->next())
ADD_INTERNAL_CALL(E->get());
for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next())
@@ -695,26 +614,40 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir,
return OK;
}
-// TODO: there are constants that hide inherited members. must explicitly use `new` to avoid warnings
-// e.g.: warning CS0108: 'SpriteBase3D.FLAG_MAX' hides inherited member 'GeometryInstance.FLAG_MAX'. Use the new keyword if hiding was intended.
+// FIXME: There are some members that hide other inherited members.
+// - In the case of both members being the same kind, the new one must be declared
+// explicitly as `new` to avoid the warning (and we must print a message about it).
+// - In the case of both members being of a different kind, then the new one must
+// be renamed to avoid the name collision (and we must print a warning about it).
+// - Csc warning e.g.:
+// ObjectType/LineEdit.cs(140,38): warning CS0108: 'LineEdit.FocusMode' hides inherited member 'Control.FocusMode'. Use the new keyword if hiding was intended.
Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const String &p_output_file) {
+ CRASH_COND(!itype.is_object_type);
+
bool is_derived_type = itype.base_name != StringName();
+ if (!is_derived_type) {
+ // Some Godot.Object assertions
+ CRASH_COND(itype.cname != name_cache.type_Object);
+ CRASH_COND(!itype.is_instantiable);
+ CRASH_COND(itype.api_type != ClassDB::API_CORE);
+ CRASH_COND(itype.is_reference);
+ CRASH_COND(itype.is_singleton);
+ }
+
List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls;
if (verbose_output)
OS::get_singleton()->print(String("Generating " + itype.proxy_name + ".cs...\n").utf8());
- String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor");
+ String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor"); // Used only for derived types
List<String> output;
output.push_back("using System;\n"); // IntPtr
-
- if (itype.requires_collections)
- output.push_back("using System.Collections.Generic;\n"); // Dictionary
-
+ output.push_back("\n#pragma warning disable CS1591 // Disable warning: "
+ "'Missing XML comment for publicly visible type or member'\n");
output.push_back("\nnamespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
const DocData::ClassDoc *class_doc = itype.class_doc;
@@ -737,21 +670,24 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
output.push_back(INDENT1 "public ");
- bool is_abstract = itype.is_object_type && !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled'
- output.push_back(itype.is_singleton ? "static partial class " : (is_abstract ? "abstract partial class " : "partial class "));
+ if (itype.is_singleton) {
+ output.push_back("static partial class ");
+ } else {
+ output.push_back(itype.is_instantiable ? "partial class " : "abstract partial class ");
+ }
output.push_back(itype.proxy_name);
if (itype.is_singleton) {
output.push_back("\n");
- } else if (!is_derived_type || !itype.is_object_type /* assuming only object types inherit */) {
- output.push_back(" : IDisposable\n");
- } else if (obj_types.has(itype.base_name)) {
- output.push_back(" : ");
- output.push_back(obj_types[itype.base_name].proxy_name);
- output.push_back("\n");
- } else {
- ERR_PRINTS("Base type '" + itype.base_name.operator String() + "' does not exist, for class " + itype.name);
- return ERR_INVALID_DATA;
+ } else if (is_derived_type) {
+ if (obj_types.has(itype.base_name)) {
+ output.push_back(" : ");
+ output.push_back(obj_types[itype.base_name].proxy_name);
+ output.push_back("\n");
+ } else {
+ ERR_PRINTS("Base type '" + itype.base_name.operator String() + "' does not exist, for class " + itype.name);
+ return ERR_INVALID_DATA;
+ }
}
output.push_back(INDENT1 "{");
@@ -848,9 +784,6 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.push_back(INDENT2 CLOSE_BLOCK);
}
- if (itype.enums.size())
- output.push_back("\n");
-
// Add properties
for (const List<PropertyInterface>::Element *E = itype.properties.front(); E; E = E->next()) {
@@ -862,43 +795,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
ERR_FAIL_V(prop_err);
}
}
-
- if (class_doc->properties.size())
- output.push_back("\n");
}
- if (!itype.is_object_type) {
- output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"" + itype.name + "\";\n");
- output.push_back(MEMBER_BEGIN "private bool disposed = false;\n");
- output.push_back(MEMBER_BEGIN "internal IntPtr " BINDINGS_PTR_FIELD ";\n");
-
- output.push_back(MEMBER_BEGIN "internal static IntPtr " CS_SMETHOD_GETINSTANCE "(");
- output.push_back(itype.proxy_name);
- output.push_back(" instance)\n" OPEN_BLOCK_L2 "return instance == null ? IntPtr.Zero : instance." BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
-
- // Add Destructor
- output.push_back(MEMBER_BEGIN "~");
- output.push_back(itype.proxy_name);
- output.push_back("()\n" OPEN_BLOCK_L2 "Dispose(false);\n" CLOSE_BLOCK_L2);
-
- // Add the Dispose from IDisposable
- output.push_back(MEMBER_BEGIN "public void Dispose()\n" OPEN_BLOCK_L2 "Dispose(true);\n" INDENT3 "GC.SuppressFinalize(this);\n" CLOSE_BLOCK_L2);
-
- // Add the virtual Dispose
- output.push_back(MEMBER_BEGIN "protected virtual void Dispose(bool disposing)\n" OPEN_BLOCK_L2
- "if (disposed) return;\n" INDENT3
- "if (" BINDINGS_PTR_FIELD " != IntPtr.Zero)\n" OPEN_BLOCK_L3 "NativeCalls.godot_icall_");
- output.push_back(itype.proxy_name);
- output.push_back("_Dtor(" BINDINGS_PTR_FIELD ");\n" INDENT5 BINDINGS_PTR_FIELD " = IntPtr.Zero;\n" CLOSE_BLOCK_L3 INDENT3
- "GC.SuppressFinalize(this);\n" INDENT3 "disposed = true;\n" CLOSE_BLOCK_L2);
-
- output.push_back(MEMBER_BEGIN "internal ");
- output.push_back(itype.proxy_name);
- output.push_back("(IntPtr " BINDINGS_PTR_FIELD ")\n" OPEN_BLOCK_L2 "this." BINDINGS_PTR_FIELD " = " BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
-
- output.push_back(MEMBER_BEGIN "public IntPtr NativeInstance\n" OPEN_BLOCK_L2
- "get { return " BINDINGS_PTR_FIELD "; }\n" CLOSE_BLOCK_L2);
- } else if (itype.is_singleton) {
+ if (itype.is_singleton) {
// Add the type name and the singleton pointer as static fields
output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
@@ -910,21 +809,13 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.push_back("." ICALL_PREFIX);
output.push_back(itype.name);
output.push_back(SINGLETON_ICALL_SUFFIX "();\n");
- } else {
+ } else if (is_derived_type) {
// Add member fields
output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
output.push_back(itype.name);
output.push_back("\";\n");
- // Only the base class stores the pointer to the native object
- // This pointer is expected to be and must be of type Object*
- if (!is_derived_type) {
- output.push_back(MEMBER_BEGIN "private bool disposed = false;\n");
- output.push_back(INDENT2 "internal IntPtr " BINDINGS_PTR_FIELD ";\n");
- output.push_back(INDENT2 "internal bool " CS_FIELD_MEMORYOWN ";\n");
- }
-
// Add default constructor
if (itype.is_instantiable) {
output.push_back(MEMBER_BEGIN "public ");
@@ -949,67 +840,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// Add.. em.. trick constructor. Sort of.
output.push_back(MEMBER_BEGIN "internal ");
output.push_back(itype.proxy_name);
- if (is_derived_type) {
- output.push_back("(bool " CS_FIELD_MEMORYOWN ") : base(" CS_FIELD_MEMORYOWN ") {}\n");
- } else {
- output.push_back("(bool " CS_FIELD_MEMORYOWN ")\n" OPEN_BLOCK_L2
- "this." CS_FIELD_MEMORYOWN " = " CS_FIELD_MEMORYOWN ";\n" CLOSE_BLOCK_L2);
- }
-
- // Add methods
-
- if (!is_derived_type) {
- output.push_back(MEMBER_BEGIN "public IntPtr NativeInstance\n" OPEN_BLOCK_L2
- "get { return " BINDINGS_PTR_FIELD "; }\n" CLOSE_BLOCK_L2);
-
- output.push_back(MEMBER_BEGIN "internal static IntPtr " CS_SMETHOD_GETINSTANCE "(Object instance)\n" OPEN_BLOCK_L2
- "return instance == null ? IntPtr.Zero : instance." BINDINGS_PTR_FIELD ";\n" CLOSE_BLOCK_L2);
- }
-
- if (!is_derived_type) {
- // Add destructor
- output.push_back(MEMBER_BEGIN "~");
- output.push_back(itype.proxy_name);
- output.push_back("()\n" OPEN_BLOCK_L2 "Dispose(false);\n" CLOSE_BLOCK_L2);
-
- // Add the Dispose from IDisposable
- output.push_back(MEMBER_BEGIN "public void Dispose()\n" OPEN_BLOCK_L2 "Dispose(true);\n" INDENT3 "GC.SuppressFinalize(this);\n" CLOSE_BLOCK_L2);
-
- // Add the virtual Dispose
- output.push_back(MEMBER_BEGIN "protected virtual void Dispose(bool disposing)\n" OPEN_BLOCK_L2
- "if (disposed) return;\n" INDENT3
- "if (" BINDINGS_PTR_FIELD " != IntPtr.Zero)\n" OPEN_BLOCK_L3
- "if (" CS_FIELD_MEMORYOWN ")\n" OPEN_BLOCK_L4 CS_FIELD_MEMORYOWN
- " = false;\n" INDENT5 BINDINGS_CLASS_NATIVECALLS "." ICALL_OBJECT_DTOR
- "(this, " BINDINGS_PTR_FIELD ");\n" CLOSE_BLOCK_L4 CLOSE_BLOCK_L3 INDENT3
- "this." BINDINGS_PTR_FIELD " = IntPtr.Zero;\n" INDENT3
- "GC.SuppressFinalize(this);\n" INDENT3 "disposed = true;\n" CLOSE_BLOCK_L2);
-
- Map<StringName, TypeInterface>::Element *array_itype = builtin_types.find(name_cache.type_Array);
-
- if (!array_itype) {
- ERR_PRINT("BUG: Array type interface not found!");
- return ERR_BUG;
- }
-
- OrderedHashMap<StringName, TypeInterface>::Element object_itype = obj_types.find("Object");
-
- if (!object_itype) {
- ERR_PRINT("BUG: Object type interface not found!");
- return ERR_BUG;
- }
-
- output.push_back(MEMBER_BEGIN "public " CS_CLASS_SIGNALAWAITER " ToSignal(");
- output.push_back(object_itype.get().cs_type);
- output.push_back(" source, string signal)\n" OPEN_BLOCK_L2
- "return new " CS_CLASS_SIGNALAWAITER "(source, signal, this);\n" CLOSE_BLOCK_L2);
- }
+ output.push_back("(bool " CS_FIELD_MEMORYOWN ") : base(" CS_FIELD_MEMORYOWN ") {}\n");
}
- Map<StringName, String>::Element *extra_member = extra_members.find(itype.cname);
- if (extra_member)
- output.push_back(extra_member->get());
-
int method_bind_count = 0;
for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get();
@@ -1027,14 +860,17 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
custom_icalls.push_back(singleton_icall);
}
- if (itype.is_instantiable) {
+ if (is_derived_type && itype.is_instantiable) {
InternalCall ctor_icall = InternalCall(itype.api_type, ctor_method, "IntPtr", itype.proxy_name + " obj");
if (!find_icall_by_name(ctor_icall.name, custom_icalls))
custom_icalls.push_back(ctor_icall);
}
- output.push_back(INDENT1 CLOSE_BLOCK CLOSE_BLOCK);
+ output.push_back(INDENT1 CLOSE_BLOCK /* class */
+ CLOSE_BLOCK /* namespace */);
+
+ output.push_back("\n#pragma warning restore CS1591\n");
return _save_file(p_output_file, output);
}
@@ -1172,9 +1008,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
String arguments_sig;
String cs_in_statements;
- String icall_params;
- if (p_itype.is_object_type)
- icall_params += method_bind_field + ", ";
+ String icall_params = method_bind_field + ", ";
icall_params += sformat(p_itype.cs_in, "this");
List<String> default_args_doc;
@@ -1251,9 +1085,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
// Generate method
{
- if (p_itype.is_object_type && !p_imethod.is_virtual && !p_imethod.requires_object_call) {
+ if (!p_imethod.is_virtual && !p_imethod.requires_object_call) {
p_output.push_back(MEMBER_BEGIN "private static IntPtr ");
- p_output.push_back(method_bind_field + " = " BINDINGS_CLASS_NATIVECALLS "." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \"");
+ p_output.push_back(method_bind_field + " = Object." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \"");
p_output.push_back(p_imethod.name);
p_output.push_back("\");\n");
}
@@ -1366,19 +1200,31 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
List<String> output;
- output.push_back("#include \"" GLUE_HEADER_FILE "\"\n"
- "\n");
+ output.push_back("/* THIS FILE IS GENERATED DO NOT EDIT */\n");
+ output.push_back("#include \"" GLUE_HEADER_FILE "\"\n");
+ output.push_back("\n#ifdef MONO_GLUE_ENABLED\n");
generated_icall_funcs.clear();
for (OrderedHashMap<StringName, TypeInterface>::Element type_elem = obj_types.front(); type_elem; type_elem = type_elem.next()) {
const TypeInterface &itype = type_elem.get();
+ bool is_derived_type = itype.base_name != StringName();
+
+ if (!is_derived_type) {
+ // Some Object assertions
+ CRASH_COND(itype.cname != name_cache.type_Object);
+ CRASH_COND(!itype.is_instantiable);
+ CRASH_COND(itype.api_type != ClassDB::API_CORE);
+ CRASH_COND(itype.is_reference);
+ CRASH_COND(itype.is_singleton);
+ }
+
List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls;
OS::get_singleton()->print(String("Generating " + itype.name + "...\n").utf8());
- String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor");
+ String ctor_method(ICALL_PREFIX + itype.proxy_name + "_Ctor"); // Used only for derived types
for (const List<MethodInterface>::Element *E = itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get();
@@ -1403,7 +1249,7 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
output.push_back("\");\n" CLOSE_BLOCK "\n");
}
- if (itype.is_instantiable) {
+ if (is_derived_type && itype.is_instantiable) {
InternalCall ctor_icall = InternalCall(itype.api_type, ctor_method, "IntPtr", itype.proxy_name + " obj");
if (!find_icall_by_name(ctor_icall.name, custom_icalls))
@@ -1420,7 +1266,7 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
}
}
- output.push_back("namespace GodotSharpBindings\n" OPEN_BLOCK);
+ output.push_back("namespace GodotSharpBindings\n" OPEN_BLOCK "\n");
output.push_back("uint64_t get_core_api_hash() { return ");
output.push_back(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + "; }\n");
@@ -1432,11 +1278,9 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
output.push_back("uint32_t get_bindings_version() { return ");
output.push_back(String::num_uint64(BINDINGS_GENERATOR_VERSION) + "; }\n");
- output.push_back("uint32_t get_cs_glue_version() { return ");
- output.push_back(String::num_uint64(CS_GLUE_VERSION) + "; }\n");
- output.push_back("void register_generated_icalls() " OPEN_BLOCK);
- output.push_back("\tgodot_register_header_icalls();");
+ output.push_back("\nvoid register_generated_icalls() " OPEN_BLOCK);
+ output.push_back("\tgodot_register_glue_header_icalls();\n");
#define ADD_INTERNAL_CALL_REGISTRATION(m_icall) \
{ \
@@ -1499,12 +1343,11 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
output.push_back("#endif\n");
}
- for (const List<InternalCall>::Element *E = builtin_method_icalls.front(); E; E = E->next())
- ADD_INTERNAL_CALL_REGISTRATION(E->get());
-
#undef ADD_INTERNAL_CALL_REGISTRATION
- output.push_back(CLOSE_BLOCK "}\n");
+ output.push_back(CLOSE_BLOCK "\n} // namespace GodotSharpBindings\n");
+
+ output.push_back("\n#endif // MONO_GLUE_ENABLED\n");
Error save_err = _save_file(path_join(p_output_dir, "mono_glue.gen.cpp"), output);
if (save_err != OK)
@@ -1519,10 +1362,6 @@ uint32_t BindingsGenerator::get_version() {
return BINDINGS_GENERATOR_VERSION;
}
-uint32_t BindingsGenerator::get_cs_glue_version() {
- return CS_GLUE_VERSION;
-}
-
Error BindingsGenerator::_save_file(const String &p_path, const List<String> &p_content) {
FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);
@@ -1585,9 +1424,6 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
i++;
}
- if (!p_itype.is_object_type)
- return OK; // no auto-generated icall functions for builtin types
-
const Map<const MethodInterface *, const InternalCall *>::Element *match = method_icalls_map.find(&p_imethod);
ERR_FAIL_NULL_V(match, ERR_BUG);
@@ -1622,7 +1458,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
}
p_output.push_back("\t" + ptrcall_return_type);
- p_output.push_back(" " LOCAL_RET);
+ p_output.push_back(" " C_LOCAL_RET);
p_output.push_back(initialization + ";\n");
p_output.push_back("\tERR_FAIL_NULL_V(" CS_PARAM_INSTANCE);
p_output.push_back(fail_ret);
@@ -1672,7 +1508,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
p_output.push_back("\tVariant::CallError vcall_error;\n\t");
if (!ret_void)
- p_output.push_back(LOCAL_RET " = ");
+ p_output.push_back(C_LOCAL_RET " = ");
p_output.push_back(CS_PARAM_METHODBIND "->call(" CS_PARAM_INSTANCE ", ");
p_output.push_back(p_imethod.arguments.size() ? "(const Variant**)" C_LOCAL_PTRCALL_ARGS ".ptr()" : "NULL");
@@ -1680,14 +1516,14 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
} else {
p_output.push_back("\t" CS_PARAM_METHODBIND "->ptrcall(" CS_PARAM_INSTANCE ", ");
p_output.push_back(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ", " : "NULL, ");
- p_output.push_back(!ret_void ? "&" LOCAL_RET ");\n" : "NULL);\n");
+ p_output.push_back(!ret_void ? "&" C_LOCAL_RET ");\n" : "NULL);\n");
}
if (!ret_void) {
if (return_type->c_out.empty())
- p_output.push_back("\treturn " LOCAL_RET ";\n");
+ p_output.push_back("\treturn " C_LOCAL_RET ";\n");
else
- p_output.push_back(sformat(return_type->c_out, return_type->c_type_out, LOCAL_RET, return_type->name));
+ p_output.push_back(sformat(return_type->c_out, return_type->c_type_out, C_LOCAL_RET, return_type->name));
}
p_output.push_back(CLOSE_BLOCK "\n");
@@ -1746,9 +1582,6 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placehol
return &placeholder_types.insert(placeholder.cname, placeholder)->get();
}
-static void _create_constant_interface_from(const StringName &p_constant, const DocData::ClassDoc &p_classdoc) {
-}
-
void BindingsGenerator::_populate_object_type_interfaces() {
obj_types.clear();
@@ -1883,9 +1716,6 @@ void BindingsGenerator::_populate_object_type_interfaces() {
if (virtual_method_list.find(method_info)) {
// A virtual method without the virtual flag. This is a special case.
- // This type of method can only be found in Object derived types.
- ERR_FAIL_COND(!itype.is_object_type);
-
// There is no method bind, so let's fallback to Godot's object.Call(string, params)
imethod.requires_object_call = true;
@@ -1922,9 +1752,6 @@ void BindingsGenerator::_populate_object_type_interfaces() {
imethod.return_type.cname = Variant::get_type_name(return_info.type);
}
- if (!itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary)
- itype.requires_collections = true;
-
for (int i = 0; i < argc; i++) {
PropertyInfo arginfo = method_info.arguments[i];
@@ -1946,9 +1773,6 @@ void BindingsGenerator::_populate_object_type_interfaces() {
iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
- if (!itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary)
- itype.requires_collections = true;
-
if (m && m->has_default_argument(i)) {
_default_argument_from_variant(m->get_default_argument(i), iarg);
}
@@ -2273,13 +2097,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.cs_out = "return new %1(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
- _populate_builtin_type(itype, Variant::NODE_PATH);
- extra_members.insert(itype.cname, MEMBER_BEGIN "public NodePath() : this(string.Empty) {}\n" MEMBER_BEGIN "public NodePath(string path)\n" OPEN_BLOCK_L2
- "this." BINDINGS_PTR_FIELD " = NativeCalls.godot_icall_NodePath_Ctor(path);\n" CLOSE_BLOCK_L2
- MEMBER_BEGIN "public static implicit operator NodePath(string from)\n" OPEN_BLOCK_L2 "return new NodePath(from);\n" CLOSE_BLOCK_L2
- MEMBER_BEGIN "public static implicit operator string(NodePath from)\n" OPEN_BLOCK_L2
- "return NativeCalls." ICALL_PREFIX "NodePath_operator_String(NodePath." CS_SMETHOD_GETINSTANCE "(from));\n" CLOSE_BLOCK_L2
- MEMBER_BEGIN "public override string ToString()\n" OPEN_BLOCK_L2 "return (string)this;\n" CLOSE_BLOCK_L2);
builtin_types.insert(itype.cname, itype);
// RID
@@ -2296,9 +2113,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.cs_out = "return new %1(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
- _populate_builtin_type(itype, Variant::_RID);
- extra_members.insert(itype.cname, MEMBER_BEGIN "internal RID()\n" OPEN_BLOCK_L2
- "this." BINDINGS_PTR_FIELD " = IntPtr.Zero;\n" CLOSE_BLOCK_L2);
builtin_types.insert(itype.cname, itype);
// Variant
@@ -2371,14 +2185,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype = TypeInterface();
itype.name = "Array";
itype.cname = itype.name;
- itype.proxy_name = "Array";
+ itype.proxy_name = itype.name;
itype.c_out = "\treturn memnew(Array(%1));\n";
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_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name;
itype.cs_in = "%0." CS_SMETHOD_GETINSTANCE "()";
- itype.cs_out = "return new Array(%0);";
+ itype.cs_out = "return new " + itype.cs_type + "(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
builtin_types.insert(itype.cname, itype);
@@ -2387,14 +2201,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype = TypeInterface();
itype.name = "Dictionary";
itype.cname = itype.name;
- itype.proxy_name = "Dictionary";
+ itype.proxy_name = itype.name;
itype.c_out = "\treturn memnew(Dictionary(%1));\n";
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_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name;
itype.cs_in = "%0." CS_SMETHOD_GETINSTANCE "()";
- itype.cs_out = "return new Dictionary(%0);";
+ itype.cs_out = "return new " + itype.cs_type + "(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
builtin_types.insert(itype.cname, itype);
@@ -2413,66 +2227,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
builtin_types.insert(itype.cname, itype);
}
-void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant::Type vtype) {
-
- Variant::CallError cerror;
- Variant v = Variant::construct(vtype, NULL, 0, cerror);
-
- List<MethodInfo> method_list;
- v.get_method_list(&method_list);
- method_list.sort();
-
- for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) {
- MethodInfo &mi = E->get();
- MethodInterface imethod;
-
- imethod.name = mi.name;
- imethod.cname = imethod.name;
- imethod.proxy_name = escape_csharp_keyword(snake_to_pascal_case(mi.name));
-
- for (int i = 0; i < mi.arguments.size(); i++) {
- ArgumentInterface iarg;
- PropertyInfo pi = mi.arguments[i];
-
- iarg.name = pi.name;
-
- if (pi.type == Variant::NIL)
- iarg.type.cname = name_cache.type_Variant;
- else
- iarg.type.cname = Variant::get_type_name(pi.type);
-
- if (!r_itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary)
- r_itype.requires_collections = true;
-
- if ((mi.default_arguments.size() - mi.arguments.size() + i) >= 0)
- _default_argument_from_variant(Variant::construct(pi.type, NULL, 0, cerror), iarg);
-
- imethod.add_argument(iarg);
- }
-
- if (mi.return_val.type == Variant::NIL) {
- if (mi.return_val.name != "")
- imethod.return_type.cname = name_cache.type_Variant;
- } else {
- imethod.return_type.cname = Variant::get_type_name(mi.return_val.type);
- }
-
- if (!r_itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary)
- r_itype.requires_collections = true;
-
- if (r_itype.class_doc) {
- for (int i = 0; i < r_itype.class_doc->methods.size(); i++) {
- if (r_itype.class_doc->methods[i].name == imethod.name) {
- imethod.method_doc = &r_itype.class_doc->methods[i];
- break;
- }
- }
- }
-
- r_itype.methods.push_back(imethod);
- }
-}
-
void BindingsGenerator::_populate_global_constants() {
int global_constants_count = GlobalConstants::get_global_constant_count();
@@ -2570,15 +2324,13 @@ void BindingsGenerator::initialize() {
_populate_global_constants();
- // Populate internal calls (after populating type interfaces and global constants)
+ // Generate internal calls (after populating type interfaces and global constants)
- _generate_header_icalls();
+ core_custom_icalls.clear();
+ editor_custom_icalls.clear();
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next())
_generate_method_icalls(E.get());
-
- _generate_method_icalls(builtin_types["NodePath"]);
- _generate_method_icalls(builtin_types["RID"]);
}
void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) {
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 5b33a0e53f..ad89255ba5 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -31,13 +31,13 @@
#ifndef BINDINGS_GENERATOR_H
#define BINDINGS_GENERATOR_H
-#include "class_db.h"
+#include "core/class_db.h"
#include "editor/doc/doc_data.h"
#include "editor/editor_help.h"
#ifdef DEBUG_METHODS_ENABLED
-#include "ustring.h"
+#include "core/ustring.h"
class BindingsGenerator {
@@ -192,7 +192,7 @@ class BindingsGenerator {
/**
* Used only by Object-derived types.
- * Determines if this type is not virtual (incomplete).
+ * Determines if this type is not abstract (incomplete).
* e.g.: CanvasItem cannot be instantiated.
*/
bool is_instantiable;
@@ -204,12 +204,6 @@ class BindingsGenerator {
*/
bool memory_own;
- /**
- * Determines if the file must have a using directive for System.Collections.Generic
- * e.g.: When the generated class makes use of Dictionary
- */
- bool requires_collections;
-
// !! The comments of the following fields make reference to other fields via square brackets, e.g.: [field_name]
// !! When renaming those fields, make sure to rename their references in the comments
@@ -295,7 +289,7 @@ class BindingsGenerator {
/**
* Type used for method signatures, both for parameters and the return type.
- * Same as [proxy_name] except for variable arguments (VarArg).
+ * Same as [proxy_name] except for variable arguments (VarArg) and collections (which include the namespace).
*/
String cs_type;
@@ -414,7 +408,6 @@ class BindingsGenerator {
is_instantiable = false;
memory_own = false;
- requires_collections = false;
c_arg_in = "%s";
@@ -463,10 +456,7 @@ class BindingsGenerator {
List<EnumInterface> global_enums;
List<ConstantInterface> global_constants;
- Map<StringName, String> extra_members;
-
List<InternalCall> method_icalls;
- List<InternalCall> builtin_method_icalls;
Map<const MethodInterface *, const InternalCall *> method_icalls_map;
List<const InternalCall *> generated_icall_funcs;
@@ -525,14 +515,12 @@ class BindingsGenerator {
String _determine_enum_prefix(const EnumInterface &p_ienum);
- void _generate_header_icalls();
void _generate_method_icalls(const TypeInterface &p_itype);
const TypeInterface *_get_type_or_null(const TypeReference &p_typeref);
const TypeInterface *_get_type_or_placeholder(const TypeReference &p_typeref);
void _default_argument_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
- void _populate_builtin_type(TypeInterface &r_itype, Variant::Type vtype);
void _populate_object_type_interfaces();
void _populate_builtin_type_interfaces();
@@ -564,7 +552,6 @@ public:
Error generate_glue(const String &p_output_dir);
static uint32_t get_version();
- static uint32_t get_cs_glue_version();
void initialize();
diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp
index bc95607743..4764cbe941 100644
--- a/modules/mono/editor/csharp_project.cpp
+++ b/modules/mono/editor/csharp_project.cpp
@@ -30,8 +30,8 @@
#include "csharp_project.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_marshal.h"
diff --git a/modules/mono/editor/csharp_project.h b/modules/mono/editor/csharp_project.h
index 381dd17e02..d852139de0 100644
--- a/modules/mono/editor/csharp_project.h
+++ b/modules/mono/editor/csharp_project.h
@@ -31,7 +31,7 @@
#ifndef CSHARP_PROJECT_H
#define CSHARP_PROJECT_H
-#include "ustring.h"
+#include "core/ustring.h"
namespace CSharpProject {
diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp
index 2faab1718d..b01f8e66c3 100644
--- a/modules/mono/editor/godotsharp_builds.cpp
+++ b/modules/mono/editor/godotsharp_builds.cpp
@@ -30,8 +30,10 @@
#include "godotsharp_builds.h"
+#include "core/vector.h"
#include "main/main.h"
+#include "../glue/cs_glue_version.gen.h"
#include "../godotsharp_dirs.h"
#include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_marshal.h"
@@ -50,6 +52,16 @@ void godot_icall_BuildInstance_ExitCallback(MonoString *p_solution, MonoString *
GodotSharpBuilds::get_singleton()->build_exit_callback(MonoBuildInfo(solution, config), p_exit_code);
}
+static Vector<const char *> _get_msbuild_hint_dirs() {
+ Vector<const char *> ret;
+#ifdef OSX_ENABLED
+ ret.push_back("/Library/Frameworks/Mono.framework/Versions/Current/bin/");
+ ret.push_back("/usr/local/var/homebrew/linked/mono/bin/");
+#endif
+ ret.push_back("/opt/novell/mono/bin/");
+ return ret;
+}
+
#ifdef UNIX_ENABLED
String _find_build_engine_on_unix(const String &p_name) {
String ret = path_which(p_name);
@@ -61,15 +73,9 @@ String _find_build_engine_on_unix(const String &p_name) {
if (ret_fallback.length())
return ret_fallback;
- const char *locations[] = {
-#ifdef OSX_ENABLED
- "/Library/Frameworks/Mono.framework/Versions/Current/bin/",
- "/usr/local/var/homebrew/linked/mono/bin/",
-#endif
- "/opt/novell/mono/bin/"
- };
+ static Vector<const char *> locations = _get_msbuild_hint_dirs();
- for (int i = 0; i < sizeof(locations) / sizeof(const char *); i++) {
+ for (int i = 0; i < locations.size(); i++) {
String hint_path = locations[i] + p_name;
if (FileAccess::exists(hint_path)) {
@@ -263,7 +269,7 @@ String GodotSharpBuilds::_api_folder_name(APIAssembly::Type p_api_type) {
GDMono::get_singleton()->get_api_editor_hash();
return String::num_uint64(api_hash) +
"_" + String::num_uint64(BindingsGenerator::get_version()) +
- "_" + String::num_uint64(BindingsGenerator::get_cs_glue_version());
+ "_" + String::num_uint64(CS_GLUE_VERSION);
}
bool GodotSharpBuilds::make_api_sln(APIAssembly::Type p_api_type) {
diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp
index 9317550d28..ecc3e4c59e 100644
--- a/modules/mono/editor/mono_bottom_panel.cpp
+++ b/modules/mono/editor/mono_bottom_panel.cpp
@@ -53,9 +53,9 @@ void MonoBottomPanel::_update_build_tabs_list() {
build_tabs_list->add_item(item_name, tab->get_icon_texture());
- String item_tooltip = String("Solution: ") + tab->build_info.solution;
- item_tooltip += String("\nConfiguration: ") + tab->build_info.configuration;
- item_tooltip += String("\nStatus: ");
+ String item_tooltip = "Solution: " + tab->build_info.solution;
+ item_tooltip += "\nConfiguration: " + tab->build_info.configuration;
+ item_tooltip += "\nStatus: ";
if (tab->build_exited) {
item_tooltip += tab->build_result == MonoBuildTab::RESULT_SUCCESS ? "Succeeded" : "Errored";
diff --git a/modules/mono/editor/monodevelop_instance.h b/modules/mono/editor/monodevelop_instance.h
index 552c10a61d..73cf0f54cc 100644
--- a/modules/mono/editor/monodevelop_instance.h
+++ b/modules/mono/editor/monodevelop_instance.h
@@ -31,7 +31,7 @@
#ifndef MONODEVELOP_INSTANCE_H
#define MONODEVELOP_INSTANCE_H
-#include "reference.h"
+#include "core/reference.h"
#include "../mono_gc_handle.h"
#include "../mono_gd/gd_mono_method.h"
diff --git a/modules/mono/editor/net_solution.cpp b/modules/mono/editor/net_solution.cpp
index dab96e44e9..8bbd376c9a 100644
--- a/modules/mono/editor/net_solution.cpp
+++ b/modules/mono/editor/net_solution.cpp
@@ -30,8 +30,8 @@
#include "net_solution.h"
-#include "os/dir_access.h"
-#include "os/file_access.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
#include "../utils/path_utils.h"
#include "../utils/string_utils.h"
diff --git a/modules/mono/editor/net_solution.h b/modules/mono/editor/net_solution.h
index 293e86917a..bdff24af0b 100644
--- a/modules/mono/editor/net_solution.h
+++ b/modules/mono/editor/net_solution.h
@@ -31,8 +31,8 @@
#ifndef NET_SOLUTION_H
#define NET_SOLUTION_H
-#include "map.h"
-#include "ustring.h"
+#include "core/map.h"
+#include "core/ustring.h"
struct NETSolution {
String name;
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
new file mode 100644
index 0000000000..d718c3cc61
--- /dev/null
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -0,0 +1,154 @@
+/*************************************************************************/
+/* base_object_glue.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 "base_object_glue.h"
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/reference.h"
+#include "core/string_db.h"
+
+#include "../csharp_script.h"
+#include "../mono_gd/gd_mono_internals.h"
+#include "../mono_gd/gd_mono_utils.h"
+#include "../signal_awaiter_utils.h"
+
+Object *godot_icall_Object_Ctor(MonoObject *p_obj) {
+ Object *instance = memnew(Object);
+ GDMonoInternals::tie_managed_to_unmanaged(p_obj, instance);
+ return instance;
+}
+
+void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(p_ptr == NULL);
+#endif
+
+ if (p_ptr->get_script_instance()) {
+ CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(p_ptr->get_script_instance());
+ if (cs_instance) {
+ cs_instance->mono_object_disposed(p_obj);
+ p_ptr->set_script_instance(NULL);
+ return;
+ }
+ }
+
+ void *data = p_ptr->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
+
+ if (data) {
+ Ref<MonoGCHandle> &gchandle = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get().gchandle;
+ if (gchandle.is_valid()) {
+ CSharpLanguage::release_script_gchandle(p_obj, gchandle);
+ }
+ }
+}
+
+void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, bool p_is_finalizer) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(p_ptr == NULL);
+ // This is only called with Reference derived classes
+ CRASH_COND(!Object::cast_to<Reference>(p_ptr));
+#endif
+
+ Reference *ref = static_cast<Reference *>(p_ptr);
+
+ if (ref->get_script_instance()) {
+ CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(ref->get_script_instance());
+ if (cs_instance) {
+ bool r_owner_deleted;
+ cs_instance->mono_object_disposed_baseref(p_obj, p_is_finalizer, r_owner_deleted);
+ if (!r_owner_deleted && !p_is_finalizer) {
+ // If the native instance is still alive and Dispose() was called
+ // (instead of the finalizer), then we remove the script instance.
+ ref->set_script_instance(NULL);
+ }
+ return;
+ }
+ }
+
+ // Unsafe refcount decrement. The managed instance also counts as a reference.
+ // See: CSharpLanguage::alloc_instance_binding_data(Object *p_object)
+ if (ref->unreference()) {
+ memdelete(ref);
+ } else {
+ void *data = ref->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
+
+ if (data) {
+ Ref<MonoGCHandle> &gchandle = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get().gchandle;
+ if (gchandle.is_valid()) {
+ CSharpLanguage::release_script_gchandle(p_obj, gchandle);
+ }
+ }
+ }
+}
+
+MethodBind *godot_icall_Object_ClassDB_get_method(MonoString *p_type, MonoString *p_method) {
+ StringName type(GDMonoMarshal::mono_string_to_godot(p_type));
+ 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;
+
+ Ref<WeakRef> wref;
+ Reference *ref = Object::cast_to<Reference>(p_obj);
+
+ if (ref) {
+ REF r = ref;
+ if (!r.is_valid())
+ return NULL;
+
+ wref.instance();
+ wref->set_ref(r);
+ } else {
+ wref.instance();
+ wref->set_obj(p_obj);
+ }
+
+ return GDMonoUtils::create_managed_for_godot_object(CACHED_CLASS(WeakRef), Reference::get_class_static(), Object::cast_to<Object>(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);
+}
+
+void godot_register_object_icalls() {
+ mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor);
+ mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed);
+ mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed);
+ mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method);
+ mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref);
+ mono_add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", (void *)godot_icall_SignalAwaiter_connect);
+}
+
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/base_object_glue.h b/modules/mono/glue/base_object_glue.h
new file mode 100644
index 0000000000..2d4d66ebb8
--- /dev/null
+++ b/modules/mono/glue/base_object_glue.h
@@ -0,0 +1,59 @@
+/*************************************************************************/
+/* base_object_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 BASE_OBJECT_GLUE_H
+#define BASE_OBJECT_GLUE_H
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/class_db.h"
+#include "core/object.h"
+
+#include "../mono_gd/gd_mono_marshal.h"
+
+Object *godot_icall_Object_Ctor(MonoObject *p_obj);
+
+void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr);
+
+void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, bool p_is_finalizer);
+
+MethodBind *godot_icall_Object_ClassDB_get_method(MonoString *p_type, MonoString *p_method);
+
+MonoObject *godot_icall_Object_weakref(Object *p_obj);
+
+Error godot_icall_SignalAwaiter_connect(Object *p_source, MonoString *p_signal, Object *p_target, MonoObject *p_awaiter);
+
+// Register internal calls
+
+void godot_register_object_icalls();
+
+#endif // MONO_GLUE_ENABLED
+
+#endif // BASE_OBJECT_GLUE_H
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index 148bb32398..d9dba1c60d 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -30,9 +30,12 @@
#include "collections_glue.h"
+#ifdef MONO_GLUE_ENABLED
+
#include <mono/metadata/exception.h>
#include "../mono_gd/gd_mono_class.h"
+#include "../mono_gd/gd_mono_utils.h"
Array *godot_icall_Array_Ctor() {
return memnew(Array);
@@ -209,32 +212,34 @@ bool godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoOb
}
void godot_register_collections_icalls() {
- mono_add_internal_call("Godot.Array::godot_icall_Array_Ctor", (void *)godot_icall_Array_Ctor);
- mono_add_internal_call("Godot.Array::godot_icall_Array_Dtor", (void *)godot_icall_Array_Dtor);
- mono_add_internal_call("Godot.Array::godot_icall_Array_At", (void *)godot_icall_Array_At);
- mono_add_internal_call("Godot.Array::godot_icall_Array_SetAt", (void *)godot_icall_Array_SetAt);
- mono_add_internal_call("Godot.Array::godot_icall_Array_Count", (void *)godot_icall_Array_Count);
- mono_add_internal_call("Godot.Array::godot_icall_Array_Add", (void *)godot_icall_Array_Add);
- mono_add_internal_call("Godot.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
- mono_add_internal_call("Godot.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
- mono_add_internal_call("Godot.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
- mono_add_internal_call("Godot.Array::godot_icall_Array_IndexOf", (void *)godot_icall_Array_IndexOf);
- mono_add_internal_call("Godot.Array::godot_icall_Array_Insert", (void *)godot_icall_Array_Insert);
- mono_add_internal_call("Godot.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove);
- mono_add_internal_call("Godot.Array::godot_icall_Array_RemoveAt", (void *)godot_icall_Array_RemoveAt);
-
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Ctor", (void *)godot_icall_Dictionary_Ctor);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Dtor", (void *)godot_icall_Dictionary_Dtor);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_GetValue", (void *)godot_icall_Dictionary_GetValue);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_SetValue", (void *)godot_icall_Dictionary_SetValue);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Keys", (void *)godot_icall_Dictionary_Keys);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Values", (void *)godot_icall_Dictionary_Values);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Count", (void *)godot_icall_Dictionary_Count);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Add", (void *)godot_icall_Dictionary_Add);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Clear", (void *)godot_icall_Dictionary_Clear);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Contains", (void *)godot_icall_Dictionary_Contains);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_ContainsKey", (void *)godot_icall_Dictionary_ContainsKey);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_RemoveKey", (void *)godot_icall_Dictionary_RemoveKey);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Remove", (void *)godot_icall_Dictionary_Remove);
- mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_TryGetValue", (void *)godot_icall_Dictionary_TryGetValue);
-}
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", (void *)godot_icall_Array_Ctor);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Dtor", (void *)godot_icall_Array_Dtor);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At", (void *)godot_icall_Array_At);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_SetAt", (void *)godot_icall_Array_SetAt);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", (void *)godot_icall_Array_Count);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", (void *)godot_icall_Array_Add);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_IndexOf", (void *)godot_icall_Array_IndexOf);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", (void *)godot_icall_Array_Insert);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", (void *)godot_icall_Array_RemoveAt);
+
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Ctor", (void *)godot_icall_Dictionary_Ctor);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Dtor", (void *)godot_icall_Dictionary_Dtor);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue", (void *)godot_icall_Dictionary_GetValue);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_SetValue", (void *)godot_icall_Dictionary_SetValue);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Keys", (void *)godot_icall_Dictionary_Keys);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", (void *)godot_icall_Dictionary_Values);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Count", (void *)godot_icall_Dictionary_Count);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Add", (void *)godot_icall_Dictionary_Add);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", (void *)godot_icall_Dictionary_Clear);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", (void *)godot_icall_Dictionary_Contains);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ContainsKey", (void *)godot_icall_Dictionary_ContainsKey);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", (void *)godot_icall_Dictionary_RemoveKey);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", (void *)godot_icall_Dictionary_Remove);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", (void *)godot_icall_Dictionary_TryGetValue);
+}
+
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/collections_glue.h b/modules/mono/glue/collections_glue.h
index eb5ecfb725..fa8e4c28aa 100644
--- a/modules/mono/glue/collections_glue.h
+++ b/modules/mono/glue/collections_glue.h
@@ -31,6 +31,8 @@
#ifndef COLLECTIONS_GLUE_H
#define COLLECTIONS_GLUE_H
+#ifdef MONO_GLUE_ENABLED
+
#include "core/array.h"
#include "../mono_gd/gd_mono_marshal.h"
@@ -97,4 +99,6 @@ bool godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoOb
void godot_register_collections_icalls();
+#endif // MONO_GLUE_ENABLED
+
#endif // COLLECTIONS_GLUE_H
diff --git a/modules/mono/glue/cs_files/AABB.cs b/modules/mono/glue/cs_files/AABB.cs
index 0df2e615f1..66490b5e25 100644
--- a/modules/mono/glue/cs_files/AABB.cs
+++ b/modules/mono/glue/cs_files/AABB.cs
@@ -51,24 +51,24 @@ namespace Godot
src_max.z > dst_max.z;
}
- public AABB Expand(Vector3 to_point)
+ public AABB Expand(Vector3 point)
{
Vector3 begin = _position;
Vector3 end = _position + _size;
- if (to_point.x < begin.x)
- begin.x = to_point.x;
- if (to_point.y < begin.y)
- begin.y = to_point.y;
- if (to_point.z < begin.z)
- begin.z = to_point.z;
+ if (point.x < begin.x)
+ begin.x = point.x;
+ if (point.y < begin.y)
+ begin.y = point.y;
+ if (point.z < begin.z)
+ begin.z = point.z;
- if (to_point.x > end.x)
- end.x = to_point.x;
- if (to_point.y > end.y)
- end.y = to_point.y;
- if (to_point.z > end.z)
- end.z = to_point.z;
+ if (point.x > end.x)
+ end.x = point.x;
+ if (point.y > end.y)
+ end.y = point.y;
+ if (point.z > end.z)
+ end.z = point.z;
return new AABB(begin, end - begin);
}
@@ -347,29 +347,29 @@ namespace Godot
for (int i = 0; i < 3; i++)
{
- real_t seg_from = from[i];
- real_t seg_to = to[i];
- real_t box_begin = _position[i];
- real_t box_end = box_begin + _size[i];
+ real_t segFrom = from[i];
+ real_t segTo = to[i];
+ real_t boxBegin = _position[i];
+ real_t boxEnd = boxBegin + _size[i];
real_t cmin, cmax;
- if (seg_from < seg_to)
+ if (segFrom < segTo)
{
- if (seg_from > box_end || seg_to < box_begin)
+ if (segFrom > boxEnd || segTo < boxBegin)
return false;
- real_t length = seg_to - seg_from;
- cmin = seg_from < box_begin ? (box_begin - seg_from) / length : 0f;
- cmax = seg_to > box_end ? (box_end - seg_from) / length : 1f;
+ real_t length = segTo - segFrom;
+ cmin = segFrom < boxBegin ? (boxBegin - segFrom) / length : 0f;
+ cmax = segTo > boxEnd ? (boxEnd - segFrom) / length : 1f;
}
else
{
- if (seg_to > box_end || seg_from < box_begin)
+ if (segTo > boxEnd || segFrom < boxBegin)
return false;
- real_t length = seg_to - seg_from;
- cmin = seg_from > box_end ? (box_end - seg_from) / length : 0f;
- cmax = seg_to < box_begin ? (box_begin - seg_from) / length : 1f;
+ real_t length = segTo - segFrom;
+ cmin = segFrom > boxEnd ? (boxEnd - segFrom) / length : 0f;
+ cmax = segTo < boxBegin ? (boxBegin - segFrom) / length : 1f;
}
if (cmin > min)
@@ -388,21 +388,21 @@ namespace Godot
public AABB Merge(AABB with)
{
- Vector3 beg_1 = _position;
- Vector3 beg_2 = with._position;
- var end_1 = new Vector3(_size.x, _size.y, _size.z) + beg_1;
- var end_2 = new Vector3(with._size.x, with._size.y, with._size.z) + beg_2;
+ Vector3 beg1 = _position;
+ Vector3 beg2 = with._position;
+ var end1 = new Vector3(_size.x, _size.y, _size.z) + beg1;
+ var end2 = new Vector3(with._size.x, with._size.y, with._size.z) + beg2;
var min = new Vector3(
- beg_1.x < beg_2.x ? beg_1.x : beg_2.x,
- beg_1.y < beg_2.y ? beg_1.y : beg_2.y,
- beg_1.z < beg_2.z ? beg_1.z : beg_2.z
+ beg1.x < beg2.x ? beg1.x : beg2.x,
+ beg1.y < beg2.y ? beg1.y : beg2.y,
+ beg1.z < beg2.z ? beg1.z : beg2.z
);
var max = new Vector3(
- end_1.x > end_2.x ? end_1.x : end_2.x,
- end_1.y > end_2.y ? end_1.y : end_2.y,
- end_1.z > end_2.z ? end_1.z : end_2.z
+ end1.x > end2.x ? end1.x : end2.x,
+ end1.y > end2.y ? end1.y : end2.y,
+ end1.z > end2.z ? end1.z : end2.z
);
return new AABB(min, max - min);
diff --git a/modules/mono/glue/cs_files/Array.cs b/modules/mono/glue/cs_files/Array.cs
index 1ec4d7d20a..c80cb7cc83 100644
--- a/modules/mono/glue/cs_files/Array.cs
+++ b/modules/mono/glue/cs_files/Array.cs
@@ -4,7 +4,7 @@ using System.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-namespace Godot
+namespace Godot.Collections
{
class ArraySafeHandle : SafeHandle
{
@@ -30,45 +30,6 @@ namespace Godot
public class Array : IList<object>, ICollection<object>, IEnumerable<object>, IDisposable
{
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Array_Ctor();
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Dtor(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_Array_At(IntPtr ptr, int index);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_SetAt(IntPtr ptr, int index, object value);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_Array_Count(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Add(IntPtr ptr, object item);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Clear(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Array_Contains(IntPtr ptr, object item);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_CopyTo(IntPtr ptr, object[] array, int arrayIndex);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_Array_IndexOf(IntPtr ptr, object item);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_Insert(IntPtr ptr, int index, object item);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Array_Remove(IntPtr ptr, object item);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Array_RemoveAt(IntPtr ptr, int index);
-
ArraySafeHandle safeHandle;
bool disposed = false;
@@ -94,11 +55,6 @@ namespace Godot
public void Dispose()
{
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
if (disposed)
return;
@@ -200,6 +156,45 @@ namespace Godot
{
return GetEnumerator();
}
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Array_Ctor();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Dtor(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_Array_At(IntPtr ptr, int index);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_SetAt(IntPtr ptr, int index, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_Array_Count(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Add(IntPtr ptr, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Clear(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Array_Contains(IntPtr ptr, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_CopyTo(IntPtr ptr, object[] array, int arrayIndex);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_Array_IndexOf(IntPtr ptr, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Insert(IntPtr ptr, int index, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Array_Remove(IntPtr ptr, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_RemoveAt(IntPtr ptr, int index);
}
public class Array<T> : IList<T>, ICollection<T>, IEnumerable<T>
diff --git a/modules/mono/glue/cs_files/Basis.cs b/modules/mono/glue/cs_files/Basis.cs
index c280d32c61..ec96a9e2fa 100644
--- a/modules/mono/glue/cs_files/Basis.cs
+++ b/modules/mono/glue/cs_files/Basis.cs
@@ -378,55 +378,55 @@ namespace Godot
);
}
- public Quat Quat() {
- real_t trace = _x[0] + _y[1] + _z[2];
-
- if (trace > 0.0f) {
- real_t s = Mathf.Sqrt(trace + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quat(
- (_z[1] - _y[2]) * inv_s,
- (_x[2] - _z[0]) * inv_s,
- (_y[0] - _x[1]) * inv_s,
- s * 0.25f
- );
- }
-
- if (_x[0] > _y[1] && _x[0] > _z[2]) {
- real_t s = Mathf.Sqrt(_x[0] - _y[1] - _z[2] + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quat(
- s * 0.25f,
- (_x[1] + _y[0]) * inv_s,
- (_x[2] + _z[0]) * inv_s,
- (_z[1] - _y[2]) * inv_s
- );
- }
-
- if (_y[1] > _z[2]) {
- real_t s = Mathf.Sqrt(-_x[0] + _y[1] - _z[2] + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quat(
- (_x[1] + _y[0]) * inv_s,
- s * 0.25f,
- (_y[2] + _z[1]) * inv_s,
- (_x[2] - _z[0]) * inv_s
- );
- } else {
- real_t s = Mathf.Sqrt(-_x[0] - _y[1] + _z[2] + 1.0f) * 2f;
- real_t inv_s = 1f / s;
- return new Quat(
- (_x[2] + _z[0]) * inv_s,
- (_y[2] + _z[1]) * inv_s,
- s * 0.25f,
- (_y[0] - _x[1]) * inv_s
- );
- }
- }
+ public Quat Quat() {
+ real_t trace = _x[0] + _y[1] + _z[2];
+
+ if (trace > 0.0f) {
+ real_t s = Mathf.Sqrt(trace + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quat(
+ (_z[1] - _y[2]) * inv_s,
+ (_x[2] - _z[0]) * inv_s,
+ (_y[0] - _x[1]) * inv_s,
+ s * 0.25f
+ );
+ }
+
+ if (_x[0] > _y[1] && _x[0] > _z[2]) {
+ real_t s = Mathf.Sqrt(_x[0] - _y[1] - _z[2] + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quat(
+ s * 0.25f,
+ (_x[1] + _y[0]) * inv_s,
+ (_x[2] + _z[0]) * inv_s,
+ (_z[1] - _y[2]) * inv_s
+ );
+ }
+
+ if (_y[1] > _z[2]) {
+ real_t s = Mathf.Sqrt(-_x[0] + _y[1] - _z[2] + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quat(
+ (_x[1] + _y[0]) * inv_s,
+ s * 0.25f,
+ (_y[2] + _z[1]) * inv_s,
+ (_x[2] - _z[0]) * inv_s
+ );
+ } else {
+ real_t s = Mathf.Sqrt(-_x[0] - _y[1] + _z[2] + 1.0f) * 2f;
+ real_t inv_s = 1f / s;
+ return new Quat(
+ (_x[2] + _z[0]) * inv_s,
+ (_y[2] + _z[1]) * inv_s,
+ s * 0.25f,
+ (_y[0] - _x[1]) * inv_s
+ );
+ }
+ }
public Basis(Quat quat)
{
- real_t s = 2.0f / quat.LengthSquared();
+ real_t s = 2.0f / quat.LengthSquared;
real_t xs = quat.x * s;
real_t ys = quat.y * s;
diff --git a/modules/mono/glue/cs_files/Color.cs b/modules/mono/glue/cs_files/Color.cs
index 49e04b333a..88cb8524b8 100644
--- a/modules/mono/glue/cs_files/Color.cs
+++ b/modules/mono/glue/cs_files/Color.cs
@@ -370,12 +370,12 @@ namespace Godot
{
var txt = string.Empty;
- txt += _to_hex(r);
- txt += _to_hex(g);
- txt += _to_hex(b);
+ txt += ToHex32(r);
+ txt += ToHex32(g);
+ txt += ToHex32(b);
if (include_alpha)
- txt = _to_hex(a) + txt;
+ txt = ToHex32(a) + txt;
return txt;
}
@@ -411,7 +411,7 @@ namespace Godot
r = (rgba & 0xFFFF) / 65535.0f;
}
- private static int _parse_col(string str, int ofs)
+ private static int ParseCol8(string str, int ofs)
{
int ig = 0;
@@ -448,7 +448,7 @@ namespace Godot
return ig;
}
- private String _to_hex(float val)
+ private String ToHex32(float val)
{
int v = Mathf.RoundToInt(Mathf.Clamp(val * 255, 0, 255));
@@ -490,17 +490,17 @@ namespace Godot
if (alpha)
{
- if (_parse_col(color, 0) < 0)
+ if (ParseCol8(color, 0) < 0)
return false;
}
int from = alpha ? 2 : 0;
- if (_parse_col(color, from + 0) < 0)
+ if (ParseCol8(color, from + 0) < 0)
return false;
- if (_parse_col(color, from + 2) < 0)
+ if (ParseCol8(color, from + 2) < 0)
return false;
- if (_parse_col(color, from + 4) < 0)
+ if (ParseCol8(color, from + 4) < 0)
return false;
return true;
@@ -542,7 +542,7 @@ namespace Godot
if (alpha)
{
- a = _parse_col(rgba, 0) / 255f;
+ a = ParseCol8(rgba, 0) / 255f;
if (a < 0)
throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba);
@@ -554,17 +554,17 @@ namespace Godot
int from = alpha ? 2 : 0;
- r = _parse_col(rgba, from + 0) / 255f;
+ r = ParseCol8(rgba, from + 0) / 255f;
if (r < 0)
throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba);
- g = _parse_col(rgba, from + 2) / 255f;
+ g = ParseCol8(rgba, from + 2) / 255f;
if (g < 0)
throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba);
- b = _parse_col(rgba, from + 4) / 255f;
+ b = ParseCol8(rgba, from + 4) / 255f;
if (b < 0)
throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba);
diff --git a/modules/mono/glue/cs_files/Dictionary.cs b/modules/mono/glue/cs_files/Dictionary.cs
index 30d17c2a59..523e48c31a 100644
--- a/modules/mono/glue/cs_files/Dictionary.cs
+++ b/modules/mono/glue/cs_files/Dictionary.cs
@@ -4,7 +4,7 @@ using System.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-namespace Godot
+namespace Godot.Collections
{
class DictionarySafeHandle : SafeHandle
{
@@ -34,48 +34,6 @@ namespace Godot
IEnumerable<KeyValuePair<object, object>>,
IDisposable
{
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Dictionary_Ctor();
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_Dtor(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static object godot_icall_Dictionary_GetValue(IntPtr ptr, object key);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Dictionary_Keys(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static IntPtr godot_icall_Dictionary_Values(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static int godot_icall_Dictionary_Count(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static void godot_icall_Dictionary_Clear(IntPtr ptr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_Contains(IntPtr ptr, object key, object value);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_ContainsKey(IntPtr ptr, object key);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_RemoveKey(IntPtr ptr, object key);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_Remove(IntPtr ptr, object key, object value);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern static bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value);
-
DictionarySafeHandle safeHandle;
bool disposed = false;
@@ -101,11 +59,6 @@ namespace Godot
public void Dispose()
{
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
if (disposed)
return;
@@ -240,8 +193,49 @@ namespace Godot
{
return GetEnumerator();
}
- }
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Dictionary_Ctor();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_Dtor(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_Dictionary_GetValue(IntPtr ptr, object key);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Dictionary_Keys(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Dictionary_Values(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_Dictionary_Count(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_Clear(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_Contains(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_ContainsKey(IntPtr ptr, object key);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_RemoveKey(IntPtr ptr, object key);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_Remove(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value);
+ }
public class Dictionary<TKey, TValue> :
IDictionary<TKey, TValue>,
diff --git a/modules/mono/glue/cs_files/Extensions/ObjectExtensions.cs b/modules/mono/glue/cs_files/Extensions/ObjectExtensions.cs
index 5c9e6609f4..9ef0959750 100644
--- a/modules/mono/glue/cs_files/Extensions/ObjectExtensions.cs
+++ b/modules/mono/glue/cs_files/Extensions/ObjectExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
namespace Godot
{
@@ -11,7 +12,10 @@ namespace Godot
public static WeakRef WeakRef(Object obj)
{
- return NativeCalls.godot_icall_Godot_weakref(Object.GetPtr(obj));
+ return godot_icall_Object_weakref(Object.GetPtr(obj));
}
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static WeakRef godot_icall_Object_weakref(IntPtr obj);
}
}
diff --git a/modules/mono/glue/cs_files/GD.cs b/modules/mono/glue/cs_files/GD.cs
index 0a5d703f27..264be23588 100644
--- a/modules/mono/glue/cs_files/GD.cs
+++ b/modules/mono/glue/cs_files/GD.cs
@@ -1,11 +1,12 @@
using System;
+using System.Runtime.CompilerServices;
#if REAL_T_IS_DOUBLE
using real_t = System.Double;
#else
using real_t = System.Single;
#endif
-// TODO: Add comments describing what this class does. It is not obvious.
+// TODO: Add comments describing what this class does. It is not obvious.
namespace Godot
{
@@ -13,12 +14,12 @@ namespace Godot
{
public static object Bytes2Var(byte[] bytes)
{
- return NativeCalls.godot_icall_Godot_bytes2var(bytes);
+ return godot_icall_GD_bytes2var(bytes);
}
public static object Convert(object what, int type)
{
- return NativeCalls.godot_icall_Godot_convert(what, type);
+ return godot_icall_GD_convert(what, type);
}
public static real_t Db2Linear(real_t db)
@@ -46,12 +47,12 @@ namespace Godot
public static int Hash(object var)
{
- return NativeCalls.godot_icall_Godot_hash(var);
+ return godot_icall_GD_hash(var);
}
public static Object InstanceFromId(int instanceId)
{
- return NativeCalls.godot_icall_Godot_instance_from_id(instanceId);
+ return godot_icall_GD_instance_from_id(instanceId);
}
public static real_t Linear2Db(real_t linear)
@@ -71,7 +72,7 @@ namespace Godot
public static void Print(params object[] what)
{
- NativeCalls.godot_icall_Godot_print(what);
+ godot_icall_GD_print(what);
}
public static void PrintStack()
@@ -81,22 +82,22 @@ namespace Godot
public static void PrintErr(params object[] what)
{
- NativeCalls.godot_icall_Godot_printerr(what);
+ godot_icall_GD_printerr(what);
}
public static void PrintRaw(params object[] what)
{
- NativeCalls.godot_icall_Godot_printraw(what);
+ godot_icall_GD_printraw(what);
}
public static void PrintS(params object[] what)
{
- NativeCalls.godot_icall_Godot_prints(what);
+ godot_icall_GD_prints(what);
}
public static void PrintT(params object[] what)
{
- NativeCalls.godot_icall_Godot_printt(what);
+ godot_icall_GD_printt(what);
}
public static int[] Range(int length)
@@ -165,32 +166,77 @@ namespace Godot
public static void Seed(int seed)
{
- NativeCalls.godot_icall_Godot_seed(seed);
+ godot_icall_GD_seed(seed);
}
public static string Str(params object[] what)
{
- return NativeCalls.godot_icall_Godot_str(what);
+ return godot_icall_GD_str(what);
}
public static object Str2Var(string str)
{
- return NativeCalls.godot_icall_Godot_str2var(str);
+ return godot_icall_GD_str2var(str);
}
public static bool TypeExists(string type)
{
- return NativeCalls.godot_icall_Godot_type_exists(type);
+ return godot_icall_GD_type_exists(type);
}
public static byte[] Var2Bytes(object var)
{
- return NativeCalls.godot_icall_Godot_var2bytes(var);
+ return godot_icall_GD_var2bytes(var);
}
public static string Var2Str(object var)
{
- return NativeCalls.godot_icall_Godot_var2str(var);
+ return godot_icall_GD_var2str(var);
}
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_GD_bytes2var(byte[] bytes);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_GD_convert(object what, int type);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_GD_hash(object var);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static Object godot_icall_GD_instance_from_id(int instance_id);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_print(object[] what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_printerr(object[] what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_printraw(object[] what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_prints(object[] what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_printt(object[] what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_GD_seed(int seed);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static string godot_icall_GD_str(object[] what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_GD_str2var(string str);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_GD_type_exists(string type);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static byte[] godot_icall_GD_var2bytes(object what);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static string godot_icall_GD_var2str(object var);
}
}
diff --git a/modules/mono/glue/cs_files/GodotSynchronizationContext.cs b/modules/mono/glue/cs_files/GodotSynchronizationContext.cs
index da3c7bac83..e727781d63 100644
--- a/modules/mono/glue/cs_files/GodotSynchronizationContext.cs
+++ b/modules/mono/glue/cs_files/GodotSynchronizationContext.cs
@@ -4,22 +4,22 @@ using System.Threading;
namespace Godot
{
- public class GodotSynchronizationContext : SynchronizationContext
- {
- private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> queue = new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
+ public class GodotSynchronizationContext : SynchronizationContext
+ {
+ private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> queue = new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>();
- public override void Post(SendOrPostCallback d, object state)
- {
- queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
- }
+ public override void Post(SendOrPostCallback d, object state)
+ {
+ queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state));
+ }
- public void ExecutePendingContinuations()
- {
- KeyValuePair<SendOrPostCallback, object> workItem;
- while (queue.TryTake(out workItem))
- {
- workItem.Key(workItem.Value);
- }
- }
- }
+ public void ExecutePendingContinuations()
+ {
+ KeyValuePair<SendOrPostCallback, object> workItem;
+ while (queue.TryTake(out workItem))
+ {
+ workItem.Key(workItem.Value);
+ }
+ }
+ }
}
diff --git a/modules/mono/glue/cs_files/GodotTaskScheduler.cs b/modules/mono/glue/cs_files/GodotTaskScheduler.cs
index 3d23ec10f1..9a40fef5a9 100644
--- a/modules/mono/glue/cs_files/GodotTaskScheduler.cs
+++ b/modules/mono/glue/cs_files/GodotTaskScheduler.cs
@@ -6,89 +6,89 @@ using System.Threading.Tasks;
namespace Godot
{
- public class GodotTaskScheduler : TaskScheduler
- {
- private GodotSynchronizationContext Context { get; set; }
- private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
+ public class GodotTaskScheduler : TaskScheduler
+ {
+ private GodotSynchronizationContext Context { get; set; }
+ private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
- public GodotTaskScheduler()
- {
- Context = new GodotSynchronizationContext();
- SynchronizationContext.SetSynchronizationContext(Context);
- }
+ public GodotTaskScheduler()
+ {
+ Context = new GodotSynchronizationContext();
+ SynchronizationContext.SetSynchronizationContext(Context);
+ }
- protected sealed override void QueueTask(Task task)
- {
- lock (_tasks)
- {
- _tasks.AddLast(task);
- }
- }
+ protected sealed override void QueueTask(Task task)
+ {
+ lock (_tasks)
+ {
+ _tasks.AddLast(task);
+ }
+ }
- protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
- {
- if (SynchronizationContext.Current != Context)
- {
- return false;
- }
+ protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+ {
+ if (SynchronizationContext.Current != Context)
+ {
+ return false;
+ }
- if (taskWasPreviouslyQueued)
- {
- TryDequeue(task);
- }
+ if (taskWasPreviouslyQueued)
+ {
+ TryDequeue(task);
+ }
- return TryExecuteTask(task);
- }
+ return TryExecuteTask(task);
+ }
- protected sealed override bool TryDequeue(Task task)
- {
- lock (_tasks)
- {
- return _tasks.Remove(task);
- }
- }
+ protected sealed override bool TryDequeue(Task task)
+ {
+ lock (_tasks)
+ {
+ return _tasks.Remove(task);
+ }
+ }
- protected sealed override IEnumerable<Task> GetScheduledTasks()
- {
- lock (_tasks)
- {
- return _tasks.ToArray();
- }
- }
+ protected sealed override IEnumerable<Task> GetScheduledTasks()
+ {
+ lock (_tasks)
+ {
+ return _tasks.ToArray();
+ }
+ }
- public void Activate()
- {
- ExecuteQueuedTasks();
- Context.ExecutePendingContinuations();
- }
+ public void Activate()
+ {
+ ExecuteQueuedTasks();
+ Context.ExecutePendingContinuations();
+ }
- private void ExecuteQueuedTasks()
- {
- while (true)
- {
- Task task;
+ private void ExecuteQueuedTasks()
+ {
+ while (true)
+ {
+ Task task;
- lock (_tasks)
- {
- if (_tasks.Any())
- {
- task = _tasks.First.Value;
- _tasks.RemoveFirst();
- }
- else
- {
- break;
- }
- }
+ lock (_tasks)
+ {
+ if (_tasks.Any())
+ {
+ task = _tasks.First.Value;
+ _tasks.RemoveFirst();
+ }
+ else
+ {
+ break;
+ }
+ }
- if (task != null)
- {
- if (!TryExecuteTask(task))
- {
- throw new InvalidOperationException();
- }
- }
- }
- }
- }
+ if (task != null)
+ {
+ if (!TryExecuteTask(task))
+ {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+ }
+ }
}
diff --git a/modules/mono/glue/cs_files/MarshalUtils.cs b/modules/mono/glue/cs_files/MarshalUtils.cs
index 6ad4b3dcb2..f7699a15bf 100644
--- a/modules/mono/glue/cs_files/MarshalUtils.cs
+++ b/modules/mono/glue/cs_files/MarshalUtils.cs
@@ -1,4 +1,5 @@
using System;
+using Godot.Collections;
namespace Godot
{
diff --git a/modules/mono/glue/cs_files/NodePath.cs b/modules/mono/glue/cs_files/NodePath.cs
new file mode 100644
index 0000000000..2c89bec87f
--- /dev/null
+++ b/modules/mono/glue/cs_files/NodePath.cs
@@ -0,0 +1,147 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Godot
+{
+ public partial class NodePath : IDisposable
+ {
+ private bool disposed = false;
+
+ internal IntPtr ptr;
+
+ internal static IntPtr GetPtr(NodePath instance)
+ {
+ return instance == null ? IntPtr.Zero : instance.ptr;
+ }
+
+ ~NodePath()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (ptr != IntPtr.Zero)
+ {
+ godot_icall_NodePath_Dtor(ptr);
+ ptr = IntPtr.Zero;
+ }
+
+ disposed = true;
+ }
+
+ internal NodePath(IntPtr ptr)
+ {
+ 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);
+ }
+
+ public static implicit operator NodePath(string from)
+ {
+ return new NodePath(from);
+ }
+
+ public static implicit operator string(NodePath from)
+ {
+ return godot_icall_NodePath_operator_String(NodePath.GetPtr(from));
+ }
+
+ public override string ToString()
+ {
+ return (string)this;
+ }
+
+ public NodePath GetAsPropertyPath()
+ {
+ return new NodePath(godot_icall_NodePath_get_as_property_path(NodePath.GetPtr(this)));
+ }
+
+ public string GetConcatenatedSubnames()
+ {
+ return godot_icall_NodePath_get_concatenated_subnames(NodePath.GetPtr(this));
+ }
+
+ public string GetName(int idx)
+ {
+ return godot_icall_NodePath_get_name(NodePath.GetPtr(this), idx);
+ }
+
+ public int GetNameCount()
+ {
+ return godot_icall_NodePath_get_name_count(NodePath.GetPtr(this));
+ }
+
+ public string GetSubname(int idx)
+ {
+ return godot_icall_NodePath_get_subname(NodePath.GetPtr(this), idx);
+ }
+
+ public int GetSubnameCount()
+ {
+ return godot_icall_NodePath_get_subname_count(NodePath.GetPtr(this));
+ }
+
+ public bool IsAbsolute()
+ {
+ return godot_icall_NodePath_is_absolute(NodePath.GetPtr(this));
+ }
+
+ public bool IsEmpty()
+ {
+ return godot_icall_NodePath_is_empty(NodePath.GetPtr(this));
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_NodePath_Ctor(string path);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_NodePath_Dtor(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static string godot_icall_NodePath_operator_String(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static 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);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static 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);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static 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);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_NodePath_is_absolute(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_NodePath_is_empty(IntPtr ptr);
+ }
+}
diff --git a/modules/mono/glue/cs_files/Object.base.cs b/modules/mono/glue/cs_files/Object.base.cs
new file mode 100644
index 0000000000..30490a715f
--- /dev/null
+++ b/modules/mono/glue/cs_files/Object.base.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Godot
+{
+ public partial class Object : IDisposable
+ {
+ private bool disposed = false;
+
+ private const string nativeName = "Object";
+
+ internal IntPtr ptr;
+ internal bool memoryOwn;
+
+ public Object() : this(false)
+ {
+ if (ptr == IntPtr.Zero)
+ ptr = godot_icall_Object_Ctor(this);
+ }
+
+ internal Object(bool memoryOwn)
+ {
+ this.memoryOwn = memoryOwn;
+ }
+
+ public IntPtr NativeInstance
+ {
+ get { return ptr; }
+ }
+
+ internal static IntPtr GetPtr(Object instance)
+ {
+ return instance == null ? IntPtr.Zero : instance.ptr;
+ }
+
+ ~Object()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (ptr != IntPtr.Zero)
+ {
+ if (memoryOwn)
+ {
+ memoryOwn = false;
+ godot_icall_Reference_Disposed(this, ptr, !disposing);
+ }
+ else
+ {
+ godot_icall_Object_Disposed(this, ptr);
+ }
+
+ this.ptr = IntPtr.Zero;
+ }
+
+ disposed = true;
+ }
+
+ public SignalAwaiter ToSignal(Object source, string signal)
+ {
+ return new SignalAwaiter(source, signal, this);
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Object_Ctor(Object obj);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Object_Disposed(Object obj, IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Reference_Disposed(Object obj, IntPtr ptr, bool isFinalizer);
+
+ // Used by the generated API
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Object_ClassDB_get_method(string type, string method);
+ }
+}
diff --git a/modules/mono/glue/cs_files/Quat.cs b/modules/mono/glue/cs_files/Quat.cs
index c69c55d997..eaa027eb69 100644
--- a/modules/mono/glue/cs_files/Quat.cs
+++ b/modules/mono/glue/cs_files/Quat.cs
@@ -11,18 +11,11 @@ namespace Godot
[StructLayout(LayoutKind.Sequential)]
public struct Quat : IEquatable<Quat>
{
- private static readonly Quat identity = new Quat(0f, 0f, 0f, 1f);
-
public real_t x;
public real_t y;
public real_t z;
public real_t w;
- public static Quat Identity
- {
- get { return identity; }
- }
-
public real_t this[int index]
{
get
@@ -63,6 +56,16 @@ namespace Godot
}
}
+ public real_t Length
+ {
+ get { return Mathf.Sqrt(LengthSquared); }
+ }
+
+ public real_t LengthSquared
+ {
+ get { return Dot(this); }
+ }
+
public Quat CubicSlerp(Quat b, Quat preA, Quat postB, real_t t)
{
real_t t2 = (1.0f - t) * t * 2f;
@@ -76,24 +79,20 @@ namespace Godot
return x * b.x + y * b.y + z * b.z + w * b.w;
}
- public Quat Inverse()
- {
- return new Quat(-x, -y, -z, w);
- }
-
- public real_t Length()
+ public Vector3 GetEuler()
{
- return Mathf.Sqrt(LengthSquared());
+ var basis = new Basis(this);
+ return basis.GetEuler();
}
- public real_t LengthSquared()
+ public Quat Inverse()
{
- return Dot(this);
+ return new Quat(-x, -y, -z, w);
}
public Quat Normalized()
{
- return this / Length();
+ return this / Length;
}
public void Set(real_t x, real_t y, real_t z, real_t w)
@@ -103,12 +102,20 @@ namespace Godot
this.z = z;
this.w = w;
}
+
public void Set(Quat q)
{
- x = q.x;
- y = q.y;
- z = q.z;
- w = q.w;
+ this = q;
+ }
+
+ public void SetAxisAngle(Vector3 axis, real_t angle)
+ {
+ this = new Quat(axis, angle);
+ }
+
+ public void SetEuler(Vector3 eulerYXZ)
+ {
+ this = new Quat(eulerYXZ);
}
public Quat Slerp(Quat b, real_t t)
@@ -192,6 +199,9 @@ namespace Godot
return new Vector3(q.x, q.y, q.z);
}
+ // Static Readonly Properties
+ public static Quat Identity { get; } = new Quat(0f, 0f, 0f, 1f);
+
// Constructors
public Quat(real_t x, real_t y, real_t z, real_t w)
{
@@ -199,15 +209,46 @@ namespace Godot
this.y = y;
this.z = z;
this.w = w;
- }
+ }
+
+ public bool IsNormalized()
+ {
+ return Mathf.Abs(LengthSquared - 1) <= Mathf.Epsilon;
+ }
+
public Quat(Quat q)
- {
- x = q.x;
- y = q.y;
- z = q.z;
- w = q.w;
+ {
+ this = q;
+ }
+
+ public Quat(Basis basis)
+ {
+ this = basis.Quat();
}
-
+
+ public Quat(Vector3 eulerYXZ)
+ {
+ real_t half_a1 = eulerYXZ.y * (real_t)0.5;
+ real_t half_a2 = eulerYXZ.x * (real_t)0.5;
+ real_t half_a3 = eulerYXZ.z * (real_t)0.5;
+
+ // R = Y(a1).X(a2).Z(a3) convention for Euler angles.
+ // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
+ // a3 is the angle of the first rotation, following the notation in this reference.
+
+ real_t cos_a1 = Mathf.Cos(half_a1);
+ real_t sin_a1 = Mathf.Sin(half_a1);
+ real_t cos_a2 = Mathf.Cos(half_a2);
+ real_t sin_a2 = Mathf.Sin(half_a2);
+ real_t cos_a3 = Mathf.Cos(half_a3);
+ real_t sin_a3 = Mathf.Sin(half_a3);
+
+ x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
+ y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
+ z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
+ w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
+ }
+
public Quat(Vector3 axis, real_t angle)
{
real_t d = axis.Length();
diff --git a/modules/mono/glue/cs_files/RID.cs b/modules/mono/glue/cs_files/RID.cs
new file mode 100644
index 0000000000..b862b8cac0
--- /dev/null
+++ b/modules/mono/glue/cs_files/RID.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Godot
+{
+ public partial class RID : IDisposable
+ {
+ private bool disposed = false;
+
+ internal IntPtr ptr;
+
+ internal static IntPtr GetPtr(RID instance)
+ {
+ return instance == null ? IntPtr.Zero : instance.ptr;
+ }
+
+ ~RID()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (ptr != IntPtr.Zero)
+ {
+ godot_icall_RID_Dtor(ptr);
+ ptr = IntPtr.Zero;
+ }
+
+ disposed = true;
+ }
+
+ internal RID(IntPtr ptr)
+ {
+ this.ptr = ptr;
+ }
+
+ public IntPtr NativeInstance
+ {
+ get { return ptr; }
+ }
+
+ internal RID()
+ {
+ this.ptr = IntPtr.Zero;
+ }
+
+ public RID(Object from)
+ {
+ this.ptr = godot_icall_RID_Ctor(Object.GetPtr(from));
+ }
+
+ public int GetId()
+ {
+ return godot_icall_RID_get_id(RID.GetPtr(this));
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_RID_Ctor(IntPtr from);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_RID_Dtor(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_RID_get_id(IntPtr ptr);
+ }
+}
diff --git a/modules/mono/glue/cs_files/SignalAwaiter.cs b/modules/mono/glue/cs_files/SignalAwaiter.cs
index c06f6b05c9..9483b6ffb4 100644
--- a/modules/mono/glue/cs_files/SignalAwaiter.cs
+++ b/modules/mono/glue/cs_files/SignalAwaiter.cs
@@ -1,4 +1,5 @@
using System;
+using System.Runtime.CompilerServices;
namespace Godot
{
@@ -10,12 +11,12 @@ namespace Godot
public SignalAwaiter(Object source, string signal, Object target)
{
- NativeCalls.godot_icall_Object_connect_signal_awaiter(
- Object.GetPtr(source),
- signal, Object.GetPtr(target), this
- );
+ godot_icall_SignalAwaiter_connect(Object.GetPtr(source), signal, Object.GetPtr(target), this);
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static Error godot_icall_SignalAwaiter_connect(IntPtr source, string signal, IntPtr target, SignalAwaiter awaiter);
+
public bool IsCompleted
{
get
diff --git a/modules/mono/glue/cs_files/StringExtensions.cs b/modules/mono/glue/cs_files/StringExtensions.cs
index b58f8bc6a8..21c9be98c1 100644
--- a/modules/mono/glue/cs_files/StringExtensions.cs
+++ b/modules/mono/glue/cs_files/StringExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
@@ -26,7 +27,7 @@ namespace Godot
return slices;
}
- private static string GetSlicec(this string instance, char splitter, int slice)
+ private static string GetSliceCharacter(this string instance, char splitter, int slice)
{
if (!instance.Empty() && slice >= 0)
{
@@ -36,12 +37,18 @@ namespace Godot
while (true)
{
- if (instance[i] == 0 || instance[i] == splitter)
+ bool end = instance.Length <= i;
+
+ if (end || instance[i] == splitter)
{
if (slice == count)
{
return instance.Substring(prev, i - prev);
}
+ else if (end)
+ {
+ return string.Empty;
+ }
count++;
prev = i + 1;
@@ -57,7 +64,7 @@ namespace Godot
// <summary>
// If the string is a path to a file, return the path to the file without the extension.
// </summary>
- public static string Basename(this string instance)
+ public static string BaseName(this string instance)
{
int index = instance.LastIndexOf('.');
@@ -144,7 +151,7 @@ namespace Godot
for (int i = 0; i < aux.GetSliceCount(" "); i++)
{
- string slice = aux.GetSlicec(' ', i);
+ string slice = aux.GetSliceCharacter(' ', i);
if (slice.Length > 0)
{
slice = char.ToUpper(slice[0]) + slice.Substring(1);
@@ -162,30 +169,59 @@ namespace Godot
// </summary>
public static int CasecmpTo(this string instance, string to)
{
+ return instance.CompareTo(to, true);
+ }
+
+ // <summary>
+ // Perform a comparison to another string, return -1 if less, 0 if equal and +1 if greater.
+ // </summary>
+ public static int CompareTo(this string instance, string to, bool caseSensitive = true)
+ {
if (instance.Empty())
return to.Empty() ? 0 : -1;
if (to.Empty())
return 1;
- int instance_idx = 0;
- int to_idx = 0;
-
- while (true)
+ int instanceIndex = 0;
+ int toIndex = 0;
+
+ if (caseSensitive) // Outside while loop to avoid checking multiple times, despite some code duplication.
{
- if (to[to_idx] == 0 && instance[instance_idx] == 0)
- return 0; // We're equal
- if (instance[instance_idx] == 0)
- return -1; // If this is empty, and the other one is not, then we're less... I think?
- if (to[to_idx] == 0)
- return 1; // Otherwise the other one is smaller...
- if (instance[instance_idx] < to[to_idx]) // More than
- return -1;
- if (instance[instance_idx] > to[to_idx]) // Less than
- return 1;
-
- instance_idx++;
- to_idx++;
+ while (true)
+ {
+ if (to[toIndex] == 0 && instance[instanceIndex] == 0)
+ return 0; // We're equal
+ if (instance[instanceIndex] == 0)
+ return -1; // If this is empty, and the other one is not, then we're less... I think?
+ if (to[toIndex] == 0)
+ return 1; // Otherwise the other one is smaller...
+ if (instance[instanceIndex] < to[toIndex]) // More than
+ return -1;
+ if (instance[instanceIndex] > to[toIndex]) // Less than
+ return 1;
+
+ instanceIndex++;
+ toIndex++;
+ }
+ } else
+ {
+ while (true)
+ {
+ if (to[toIndex] == 0 && instance[instanceIndex] == 0)
+ return 0; // We're equal
+ if (instance[instanceIndex] == 0)
+ return -1; // If this is empty, and the other one is not, then we're less... I think?
+ if (to[toIndex] == 0)
+ return 1; // Otherwise the other one is smaller..
+ if (char.ToUpper(instance[instanceIndex]) < char.ToUpper(to[toIndex])) // More than
+ return -1;
+ if (char.ToUpper(instance[instanceIndex]) > char.ToUpper(to[toIndex])) // Less than
+ return 1;
+
+ instanceIndex++;
+ toIndex++;
+ }
}
}
@@ -361,7 +397,7 @@ namespace Godot
// <summary>
// Check whether this string is a subsequence of the given string.
// </summary>
- public static bool IsSubsequenceOf(this string instance, string text, bool case_insensitive)
+ public static bool IsSubsequenceOf(this string instance, string text, bool caseSensitive = true)
{
int len = instance.Length;
@@ -371,50 +407,42 @@ namespace Godot
if (len > text.Length)
return false;
- int src = 0;
- int tgt = 0;
+ int source = 0;
+ int target = 0;
- while (instance[src] != 0 && text[tgt] != 0)
+ while (instance[source] != 0 && text[target] != 0)
{
bool match;
- if (case_insensitive)
+ if (!caseSensitive)
{
- char srcc = char.ToLower(instance[src]);
- char tgtc = char.ToLower(text[tgt]);
- match = srcc == tgtc;
+ char sourcec = char.ToLower(instance[source]);
+ char targetc = char.ToLower(text[target]);
+ match = sourcec == targetc;
}
else
{
- match = instance[src] == text[tgt];
+ match = instance[source] == text[target];
}
if (match)
{
- src++;
- if (instance[src] == 0)
+ source++;
+ if (instance[source] == 0)
return true;
}
- tgt++;
+ target++;
}
return false;
}
// <summary>
- // Check whether this string is a subsequence of the given string, considering case.
- // </summary>
- public static bool IsSubsequenceOf(this string instance, string text)
- {
- return instance.IsSubsequenceOf(text, false);
- }
-
- // <summary>
- // Check whether this string is a subsequence of the given string, without considering case.
+ // Check whether this string is a subsequence of the given string, ignoring case differences.
// </summary>
public static bool IsSubsequenceOfI(this string instance, string text)
{
- return instance.IsSubsequenceOf(text, true);
+ return instance.IsSubsequenceOf(text, false);
}
// <summary>
@@ -452,12 +480,12 @@ namespace Godot
return false; // Don't start with number plz
}
- bool valid_char = instance[i] >= '0' &&
+ bool validChar = instance[i] >= '0' &&
instance[i] <= '9' || instance[i] >= 'a' &&
instance[i] <= 'z' || instance[i] >= 'A' &&
instance[i] <= 'Z' || instance[i] == '_';
- if (!valid_char)
+ if (!validChar)
return false;
}
@@ -476,8 +504,9 @@ namespace Godot
// <summary>
// Check whether the string contains a valid IP address.
// </summary>
- public static bool IsValidIpAddress(this string instance)
+ public static bool IsValidIPAddress(this string instance)
{
+ // TODO: Support IPv6 addresses
string[] ip = instance.Split(".");
if (ip.Length != 4)
@@ -500,7 +529,7 @@ namespace Godot
// <summary>
// Return a copy of the string with special characters escaped using the JSON standard.
// </summary>
- public static string JsonEscape(this string instance)
+ public static string JSONEscape(this string instance)
{
var sb = new StringBuilder(string.Copy(instance));
@@ -563,15 +592,15 @@ namespace Godot
// <summary>
// Do a simple case sensitive expression match, using ? and * wildcards (see [method expr_match]).
// </summary>
- public static bool Match(this string instance, string expr)
+ public static bool Match(this string instance, string expr, bool caseSensitive = true)
{
- return instance.ExprMatch(expr, true);
+ return instance.ExprMatch(expr, caseSensitive);
}
// <summary>
// Do a simple case insensitive expression match, using ? and * wildcards (see [method expr_match]).
// </summary>
- public static bool Matchn(this string instance, string expr)
+ public static bool MatchN(this string instance, string expr)
{
return instance.ExprMatch(expr, false);
}
@@ -579,49 +608,31 @@ namespace Godot
// <summary>
// Return the MD5 hash of the string as an array of bytes.
// </summary>
- public static byte[] Md5Buffer(this string instance)
+ public static byte[] MD5Buffer(this string instance)
{
- return NativeCalls.godot_icall_String_md5_buffer(instance);
+ return godot_icall_String_md5_buffer(instance);
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static byte[] godot_icall_String_md5_buffer(string str);
+
// <summary>
// Return the MD5 hash of the string as a string.
// </summary>
- public static string Md5Text(this string instance)
+ public static string MD5Text(this string instance)
{
- return NativeCalls.godot_icall_String_md5_text(instance);
+ return godot_icall_String_md5_text(instance);
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static string godot_icall_String_md5_text(string str);
+
// <summary>
// Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
// </summary>
public static int NocasecmpTo(this string instance, string to)
{
- if (instance.Empty())
- return to.Empty() ? 0 : -1;
-
- if (to.Empty())
- return 1;
-
- int instance_idx = 0;
- int to_idx = 0;
-
- while (true)
- {
- if (to[to_idx] == 0 && instance[instance_idx] == 0)
- return 0; // We're equal
- if (instance[instance_idx] == 0)
- return -1; // If this is empty, and the other one is not, then we're less... I think?
- if (to[to_idx] == 0)
- return 1; // Otherwise the other one is smaller..
- if (char.ToUpper(instance[instance_idx]) < char.ToUpper(to[to_idx])) // More than
- return -1;
- if (char.ToUpper(instance[instance_idx]) > char.ToUpper(to[to_idx])) // Less than
- return 1;
-
- instance_idx++;
- to_idx++;
- }
+ return instance.CompareTo(to, false);
}
// <summary>
@@ -738,7 +749,7 @@ namespace Godot
// <summary>
// Replace occurrences of a substring for different ones inside the string, but search case-insensitive.
// </summary>
- public static string Replacen(this string instance, string what, string forwhat)
+ public static string ReplaceN(this string instance, string what, string forwhat)
{
return Regex.Replace(instance, what, forwhat, RegexOptions.IgnoreCase);
}
@@ -746,19 +757,25 @@ namespace Godot
// <summary>
// Perform a search for a substring, but start from the end of the string instead of the beginning.
// </summary>
- public static int Rfind(this string instance, string what, int from = -1)
+ public static int RFind(this string instance, string what, int from = -1)
{
- return NativeCalls.godot_icall_String_rfind(instance, what, from);
+ return godot_icall_String_rfind(instance, what, from);
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_String_rfind(string str, string what, int from);
+
// <summary>
// Perform a search for a substring, but start from the end of the string instead of the beginning. Also search case-insensitive.
// </summary>
- public static int Rfindn(this string instance, string what, int from = -1)
+ public static int RFindN(this string instance, string what, int from = -1)
{
- return NativeCalls.godot_icall_String_rfindn(instance, what, from);
+ return godot_icall_String_rfindn(instance, what, from);
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_String_rfindn(string str, string what, int from);
+
// <summary>
// Return the right side of the string from a given position.
// </summary>
@@ -773,19 +790,25 @@ namespace Godot
return instance.Substring(pos, instance.Length - pos);
}
- public static byte[] Sha256Buffer(this string instance)
+ public static byte[] SHA256Buffer(this string instance)
{
- return NativeCalls.godot_icall_String_sha256_buffer(instance);
+ return godot_icall_String_sha256_buffer(instance);
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static byte[] godot_icall_String_sha256_buffer(string str);
+
// <summary>
// Return the SHA-256 hash of the string as a string.
// </summary>
- public static string Sha256Text(this string instance)
+ public static string SHA256Text(this string instance)
{
- return NativeCalls.godot_icall_String_sha256_text(instance);
+ return godot_icall_String_sha256_text(instance);
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static string godot_icall_String_sha256_text(string str);
+
// <summary>
// Return the similarity index of the text compared to this string. 1 means totally similar and 0 means totally dissimilar.
// </summary>
@@ -802,20 +825,20 @@ namespace Godot
return 0.0f;
}
- string[] srcBigrams = instance.Bigrams();
- string[] tgtBigrams = text.Bigrams();
+ string[] sourceBigrams = instance.Bigrams();
+ string[] targetBigrams = text.Bigrams();
- int src_size = srcBigrams.Length;
- int tgt_size = tgtBigrams.Length;
+ int sourceSize = sourceBigrams.Length;
+ int targetSize = targetBigrams.Length;
- float sum = src_size + tgt_size;
+ float sum = sourceSize + targetSize;
float inter = 0;
- for (int i = 0; i < src_size; i++)
+ for (int i = 0; i < sourceSize; i++)
{
- for (int j = 0; j < tgt_size; j++)
+ for (int j = 0; j < targetSize; j++)
{
- if (srcBigrams[i] == tgtBigrams[j])
+ if (sourceBigrams[i] == targetBigrams[j])
{
inter++;
break;
@@ -829,7 +852,7 @@ namespace Godot
// <summary>
// Split the string by a divisor string, return an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
// </summary>
- public static string[] Split(this string instance, string divisor, bool allow_empty = true)
+ public static string[] Split(this string instance, string divisor, bool allowEmpty = true)
{
return instance.Split(new[] { divisor }, StringSplitOptions.RemoveEmptyEntries);
}
@@ -837,7 +860,7 @@ namespace Godot
// <summary>
// Split the string in floats by using a divisor string, return an array of the substrings. Example "1,2.5,3" will return [1,2.5,3] if split by ",".
// </summary>
- public static float[] SplitFloats(this string instance, string divisor, bool allow_empty = true)
+ public static float[] SplitFloats(this string instance, string divisor, bool allowEmpty = true)
{
var ret = new List<float>();
int from = 0;
@@ -848,7 +871,7 @@ namespace Godot
int end = instance.Find(divisor, from);
if (end < 0)
end = len;
- if (allow_empty || end > from)
+ if (allowEmpty || end > from)
ret.Add(float.Parse(instance.Substring(from)));
if (end == len)
break;
@@ -859,7 +882,7 @@ namespace Godot
return ret.ToArray();
}
- private static readonly char[] non_printable = {
+ private static readonly char[] _nonPrintable = {
(char)00, (char)01, (char)02, (char)03, (char)04, (char)05,
(char)06, (char)07, (char)08, (char)09, (char)10, (char)11,
(char)12, (char)13, (char)14, (char)15, (char)16, (char)17,
@@ -876,11 +899,11 @@ namespace Godot
if (left)
{
if (right)
- return instance.Trim(non_printable);
- return instance.TrimStart(non_printable);
+ return instance.Trim(_nonPrintable);
+ return instance.TrimStart(_nonPrintable);
}
- return instance.TrimEnd(non_printable);
+ return instance.TrimEnd(_nonPrintable);
}
// <summary>
@@ -934,7 +957,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().
// </summary>
- public static byte[] ToUtf8(this string instance)
+ public static byte[] ToUTF8(this string instance)
{
return Encoding.UTF8.GetBytes(instance);
}
@@ -942,7 +965,7 @@ namespace Godot
// <summary>
// Return a copy of the string with special characters escaped using the XML standard.
// </summary>
- public static string XmlEscape(this string instance)
+ public static string XMLEscape(this string instance)
{
return SecurityElement.Escape(instance);
}
@@ -950,7 +973,7 @@ namespace Godot
// <summary>
// Return a copy of the string with escaped characters replaced by their meanings according to the XML standard.
// </summary>
- public static string XmlUnescape(this string instance)
+ public static string XMLUnescape(this string instance)
{
return SecurityElement.FromString(instance).Text;
}
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
new file mode 100644
index 0000000000..051f42b966
--- /dev/null
+++ b/modules/mono/glue/gd_glue.cpp
@@ -0,0 +1,202 @@
+/*************************************************************************/
+/* gd_glue.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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_glue.h"
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/array.h"
+#include "core/io/marshalls.h"
+#include "core/os/os.h"
+#include "core/ustring.h"
+#include "core/variant.h"
+#include "core/variant_parser.h"
+
+#include "../mono_gd/gd_mono_utils.h"
+
+MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes) {
+ 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);
+ if (err != OK) {
+ ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
+ }
+ return GDMonoMarshal::variant_to_mono_object(ret);
+}
+
+MonoObject *godot_icall_GD_convert(MonoObject *p_what, int p_type) {
+ Variant what = GDMonoMarshal::mono_object_to_variant(p_what);
+ const Variant *args[1] = { &what };
+ Variant::CallError ce;
+ Variant ret = Variant::construct(Variant::Type(p_type), args, 1, ce);
+ ERR_FAIL_COND_V(ce.error != Variant::CallError::CALL_OK, NULL);
+ return GDMonoMarshal::variant_to_mono_object(ret);
+}
+
+int godot_icall_GD_hash(MonoObject *p_var) {
+ return GDMonoMarshal::mono_object_to_variant(p_var).hash();
+}
+
+MonoObject *godot_icall_GD_instance_from_id(int p_instance_id) {
+ return GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(p_instance_id));
+}
+
+void godot_icall_GD_print(MonoArray *p_what) {
+ Array what = GDMonoMarshal::mono_array_to_Array(p_what);
+ String str;
+ for (int i = 0; i < what.size(); i++)
+ str += what[i].operator String();
+ print_line(str);
+}
+
+void godot_icall_GD_printerr(MonoArray *p_what) {
+ Array what = GDMonoMarshal::mono_array_to_Array(p_what);
+ String str;
+ for (int i = 0; i < what.size(); i++)
+ str += what[i].operator String();
+ OS::get_singleton()->printerr("%s\n", str.utf8().get_data());
+}
+
+void godot_icall_GD_printraw(MonoArray *p_what) {
+ Array what = GDMonoMarshal::mono_array_to_Array(p_what);
+ String str;
+ for (int i = 0; i < what.size(); i++)
+ str += what[i].operator String();
+ OS::get_singleton()->print("%s", str.utf8().get_data());
+}
+
+void godot_icall_GD_prints(MonoArray *p_what) {
+ Array what = GDMonoMarshal::mono_array_to_Array(p_what);
+ String str;
+ for (int i = 0; i < what.size(); i++) {
+ if (i)
+ str += " ";
+ str += what[i].operator String();
+ }
+ print_line(str);
+}
+
+void godot_icall_GD_printt(MonoArray *p_what) {
+ Array what = GDMonoMarshal::mono_array_to_Array(p_what);
+ String str;
+ for (int i = 0; i < what.size(); i++) {
+ if (i)
+ str += "\t";
+ str += what[i].operator String();
+ }
+ print_line(str);
+}
+
+void godot_icall_GD_seed(int p_seed) {
+ Math::seed(p_seed);
+}
+
+MonoString *godot_icall_GD_str(MonoArray *p_what) {
+ String str;
+ Array what = GDMonoMarshal::mono_array_to_Array(p_what);
+
+ for (int i = 0; i < what.size(); i++) {
+ String os = what[i].operator String();
+
+ if (i == 0)
+ str = os;
+ else
+ str += os;
+ }
+
+ return GDMonoMarshal::mono_string_from_godot(str);
+}
+
+MonoObject *godot_icall_GD_str2var(MonoString *p_str) {
+ Variant ret;
+
+ VariantParser::StreamString ss;
+ ss.s = GDMonoMarshal::mono_string_to_godot(p_str);
+
+ String errs;
+ int line;
+ Error err = VariantParser::parse(&ss, ret, errs, line);
+ if (err != OK) {
+ String err_str = "Parse error at line " + itos(line) + ": " + errs;
+ ERR_PRINTS(err_str);
+ ret = err_str;
+ }
+
+ return GDMonoMarshal::variant_to_mono_object(ret);
+}
+
+bool godot_icall_GD_type_exists(MonoString *p_type) {
+ return ClassDB::class_exists(GDMonoMarshal::mono_string_to_godot(p_type));
+}
+
+MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var) {
+ Variant var = GDMonoMarshal::mono_object_to_variant(p_var);
+
+ PoolByteArray barr;
+ int len;
+ Error err = encode_variant(var, NULL, len);
+ ERR_EXPLAIN("Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
+ ERR_FAIL_COND_V(err != OK, NULL);
+
+ barr.resize(len);
+ {
+ PoolByteArray::Write w = barr.write();
+ encode_variant(var, w.ptr(), len);
+ }
+
+ return GDMonoMarshal::PoolByteArray_to_mono_array(barr);
+}
+
+MonoString *godot_icall_GD_var2str(MonoObject *p_var) {
+ String vars;
+ VariantWriter::write_to_string(GDMonoMarshal::mono_object_to_variant(p_var), vars);
+ return GDMonoMarshal::mono_string_from_godot(vars);
+}
+
+void godot_register_gd_icalls() {
+ mono_add_internal_call("Godot.GD::godot_icall_GD_bytes2var", (void *)godot_icall_GD_bytes2var);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_convert", (void *)godot_icall_GD_convert);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_hash", (void *)godot_icall_GD_hash);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_instance_from_id", (void *)godot_icall_GD_instance_from_id);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_print", (void *)godot_icall_GD_print);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_printerr", (void *)godot_icall_GD_printerr);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_printraw", (void *)godot_icall_GD_printraw);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_prints", (void *)godot_icall_GD_prints);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_printt", (void *)godot_icall_GD_printt);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_seed", (void *)godot_icall_GD_seed);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_str", (void *)godot_icall_GD_str);
+ mono_add_internal_call("Godot.GD::godot_icall_GD_str2var", (void *)godot_icall_GD_str2var);
+ 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);
+}
+
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/gd_glue.h b/modules/mono/glue/gd_glue.h
new file mode 100644
index 0000000000..6f846f221d
--- /dev/null
+++ b/modules/mono/glue/gd_glue.h
@@ -0,0 +1,74 @@
+/*************************************************************************/
+/* gd_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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_GLUE_H
+#define GD_GLUE_H
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "../mono_gd/gd_mono_marshal.h"
+
+MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes);
+
+MonoObject *godot_icall_GD_convert(MonoObject *p_what, int p_type);
+
+int godot_icall_GD_hash(MonoObject *p_var);
+
+MonoObject *godot_icall_GD_instance_from_id(int p_instance_id);
+
+void godot_icall_GD_print(MonoArray *p_what);
+
+void godot_icall_GD_printerr(MonoArray *p_what);
+
+void godot_icall_GD_printraw(MonoArray *p_what);
+
+void godot_icall_GD_prints(MonoArray *p_what);
+
+void godot_icall_GD_printt(MonoArray *p_what);
+
+void godot_icall_GD_seed(int p_seed);
+
+MonoString *godot_icall_GD_str(MonoArray *p_what);
+
+MonoObject *godot_icall_GD_str2var(MonoString *p_str);
+
+bool godot_icall_GD_type_exists(MonoString *p_type);
+
+MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var);
+
+MonoString *godot_icall_GD_var2str(MonoObject *p_var);
+
+// Register internal calls
+
+void godot_register_gd_icalls();
+
+#endif // MONO_GLUE_ENABLED
+
+#endif // GD_GLUE_H
diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h
index 6a6f3062b4..69c5c6dcdb 100644
--- a/modules/mono/glue/glue_header.h
+++ b/modules/mono/glue/glue_header.h
@@ -28,27 +28,44 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "builtin_types_glue.h"
+#ifdef MONO_GLUE_ENABLED
+
+#include "base_object_glue.h"
#include "collections_glue.h"
+#include "gd_glue.h"
+#include "nodepath_glue.h"
+#include "rid_glue.h"
+#include "string_glue.h"
+
+/**
+ * Registers internal calls that were not generated. This function is called
+ * from the generated GodotSharpBindings::register_generated_icalls() function.
+ */
+void godot_register_glue_header_icalls() {
+ godot_register_collections_icalls();
+ godot_register_gd_icalls();
+ godot_register_nodepath_icalls();
+ godot_register_object_icalls();
+ godot_register_rid_icalls();
+ godot_register_string_icalls();
+}
+
+// Used by the generated glue
+
+#include "core/array.h"
+#include "core/class_db.h"
+#include "core/dictionary.h"
+#include "core/engine.h"
+#include "core/method_bind.h"
+#include "core/node_path.h"
+#include "core/object.h"
+#include "core/reference.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
-#include "../csharp_script.h"
#include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_internals.h"
-#include "../mono_gd/gd_mono_marshal.h"
-#include "../signal_awaiter_utils.h"
-
-#include "bind/core_bind.h"
-#include "class_db.h"
-#include "engine.h"
-#include "io/marshalls.h"
-#include "object.h"
-#include "os/os.h"
-#include "reference.h"
-#include "variant_parser.h"
-
-#ifdef TOOLS_ENABLED
-#include "editor/editor_node.h"
-#endif
+#include "../mono_gd/gd_mono_utils.h"
#define GODOTSHARP_INSTANCE_OBJECT(m_instance, m_type) \
static ClassDB::ClassInfo *ci = NULL; \
@@ -57,257 +74,4 @@
} \
Object *m_instance = ci->creation_func();
-void godot_icall_Object_Dtor(MonoObject *obj, Object *ptr) {
-#ifdef DEBUG_ENABLED
- CRASH_COND(ptr == NULL);
-#endif
- _GodotSharp::get_singleton()->queue_dispose(obj, ptr);
-}
-
-// -- ClassDB --
-
-MethodBind *godot_icall_ClassDB_get_method(MonoString *p_type, MonoString *p_method) {
- StringName type(GDMonoMarshal::mono_string_to_godot(p_type));
- StringName method(GDMonoMarshal::mono_string_to_godot(p_method));
- return ClassDB::get_method(type, method);
-}
-
-// -- SignalAwaiter --
-
-Error godot_icall_Object_connect_signal_awaiter(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);
-}
-
-// -- NodePath --
-
-NodePath *godot_icall_NodePath_Ctor(MonoString *p_path) {
- return memnew(NodePath(GDMonoMarshal::mono_string_to_godot(p_path)));
-}
-
-void godot_icall_NodePath_Dtor(NodePath *p_ptr) {
- ERR_FAIL_NULL(p_ptr);
- _GodotSharp::get_singleton()->queue_dispose(p_ptr);
-}
-
-MonoString *godot_icall_NodePath_operator_String(NodePath *p_np) {
- return GDMonoMarshal::mono_string_from_godot(p_np->operator String());
-}
-
-// -- RID --
-
-RID *godot_icall_RID_Ctor(Object *p_from) {
- Resource *res_from = Object::cast_to<Resource>(p_from);
-
- if (res_from)
- return memnew(RID(res_from->get_rid()));
-
- return memnew(RID);
-}
-
-void godot_icall_RID_Dtor(RID *p_ptr) {
- ERR_FAIL_NULL(p_ptr);
- _GodotSharp::get_singleton()->queue_dispose(p_ptr);
-}
-
-// -- String --
-
-MonoArray *godot_icall_String_md5_buffer(MonoString *p_str) {
- Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_buffer();
- // TODO Check possible Array/Vector<uint8_t> problem?
- return GDMonoMarshal::Array_to_mono_array(Variant(ret));
-}
-
-MonoString *godot_icall_String_md5_text(MonoString *p_str) {
- String ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_text();
- return GDMonoMarshal::mono_string_from_godot(ret);
-}
-
-int godot_icall_String_rfind(MonoString *p_str, MonoString *p_what, int p_from) {
- String what = GDMonoMarshal::mono_string_to_godot(p_what);
- return GDMonoMarshal::mono_string_to_godot(p_str).rfind(what, p_from);
-}
-
-int godot_icall_String_rfindn(MonoString *p_str, MonoString *p_what, int p_from) {
- String what = GDMonoMarshal::mono_string_to_godot(p_what);
- return GDMonoMarshal::mono_string_to_godot(p_str).rfindn(what, p_from);
-}
-
-MonoArray *godot_icall_String_sha256_buffer(MonoString *p_str) {
- Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).sha256_buffer();
- return GDMonoMarshal::Array_to_mono_array(Variant(ret));
-}
-
-MonoString *godot_icall_String_sha256_text(MonoString *p_str) {
- String ret = GDMonoMarshal::mono_string_to_godot(p_str).sha256_text();
- return GDMonoMarshal::mono_string_from_godot(ret);
-}
-
-// -- Global Scope --
-
-MonoObject *godot_icall_Godot_bytes2var(MonoArray *p_bytes) {
- 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);
- if (err != OK) {
- ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
- }
- return GDMonoMarshal::variant_to_mono_object(ret);
-}
-
-MonoObject *godot_icall_Godot_convert(MonoObject *p_what, int p_type) {
- Variant what = GDMonoMarshal::mono_object_to_variant(p_what);
- const Variant *args[1] = { &what };
- Variant::CallError ce;
- Variant ret = Variant::construct(Variant::Type(p_type), args, 1, ce);
- ERR_FAIL_COND_V(ce.error != Variant::CallError::CALL_OK, NULL);
- return GDMonoMarshal::variant_to_mono_object(ret);
-}
-
-int godot_icall_Godot_hash(MonoObject *p_var) {
- return GDMonoMarshal::mono_object_to_variant(p_var).hash();
-}
-
-MonoObject *godot_icall_Godot_instance_from_id(int p_instance_id) {
- return GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(p_instance_id));
-}
-
-void godot_icall_Godot_print(MonoArray *p_what) {
- Array what = GDMonoMarshal::mono_array_to_Array(p_what);
- String str;
- for (int i = 0; i < what.size(); i++)
- str += what[i].operator String();
- print_line(str);
-}
-
-void godot_icall_Godot_printerr(MonoArray *p_what) {
- Array what = GDMonoMarshal::mono_array_to_Array(p_what);
- String str;
- for (int i = 0; i < what.size(); i++)
- str += what[i].operator String();
- OS::get_singleton()->printerr("%s\n", str.utf8().get_data());
-}
-
-void godot_icall_Godot_printraw(MonoArray *p_what) {
- Array what = GDMonoMarshal::mono_array_to_Array(p_what);
- String str;
- for (int i = 0; i < what.size(); i++)
- str += what[i].operator String();
- OS::get_singleton()->print("%s", str.utf8().get_data());
-}
-
-void godot_icall_Godot_prints(MonoArray *p_what) {
- Array what = GDMonoMarshal::mono_array_to_Array(p_what);
- String str;
- for (int i = 0; i < what.size(); i++) {
- if (i)
- str += " ";
- str += what[i].operator String();
- }
- print_line(str);
-}
-
-void godot_icall_Godot_printt(MonoArray *p_what) {
- Array what = GDMonoMarshal::mono_array_to_Array(p_what);
- String str;
- for (int i = 0; i < what.size(); i++) {
- if (i)
- str += "\t";
- str += what[i].operator String();
- }
- print_line(str);
-}
-
-void godot_icall_Godot_seed(int p_seed) {
- Math::seed(p_seed);
-}
-
-MonoString *godot_icall_Godot_str(MonoArray *p_what) {
- String str;
- Array what = GDMonoMarshal::mono_array_to_Array(p_what);
-
- for (int i = 0; i < what.size(); i++) {
- String os = what[i].operator String();
-
- if (i == 0)
- str = os;
- else
- str += os;
- }
-
- return GDMonoMarshal::mono_string_from_godot(str);
-}
-
-MonoObject *godot_icall_Godot_str2var(MonoString *p_str) {
- Variant ret;
-
- VariantParser::StreamString ss;
- ss.s = GDMonoMarshal::mono_string_to_godot(p_str);
-
- String errs;
- int line;
- Error err = VariantParser::parse(&ss, ret, errs, line);
- if (err != OK) {
- String err_str = "Parse error at line " + itos(line) + ": " + errs;
- ERR_PRINTS(err_str);
- ret = err_str;
- }
-
- return GDMonoMarshal::variant_to_mono_object(ret);
-}
-
-bool godot_icall_Godot_type_exists(MonoString *p_type) {
- return ClassDB::class_exists(GDMonoMarshal::mono_string_to_godot(p_type));
-}
-
-MonoArray *godot_icall_Godot_var2bytes(MonoObject *p_var) {
- Variant var = GDMonoMarshal::mono_object_to_variant(p_var);
-
- PoolByteArray barr;
- int len;
- Error err = encode_variant(var, NULL, len);
- ERR_EXPLAIN("Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
- ERR_FAIL_COND_V(err != OK, NULL);
-
- barr.resize(len);
- {
- PoolByteArray::Write w = barr.write();
- encode_variant(var, w.ptr(), len);
- }
-
- return GDMonoMarshal::PoolByteArray_to_mono_array(barr);
-}
-
-MonoString *godot_icall_Godot_var2str(MonoObject *p_var) {
- String vars;
- VariantWriter::write_to_string(GDMonoMarshal::mono_object_to_variant(p_var), vars);
- return GDMonoMarshal::mono_string_from_godot(vars);
-}
-
-MonoObject *godot_icall_Godot_weakref(Object *p_obj) {
- if (!p_obj)
- return NULL;
-
- Ref<WeakRef> wref;
- Reference *ref = Object::cast_to<Reference>(p_obj);
-
- if (ref) {
- REF r = ref;
- if (!r.is_valid())
- return NULL;
-
- wref.instance();
- wref->set_ref(r);
- } else {
- wref.instance();
- wref->set_obj(p_obj);
- }
-
- return GDMonoUtils::create_managed_for_godot_object(CACHED_CLASS(WeakRef), Reference::get_class_static(), Object::cast_to<Object>(wref.ptr()));
-}
-
-void godot_register_header_icalls() {
- godot_register_builtin_type_icalls();
- godot_register_collections_icalls();
-}
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/builtin_types_glue.h b/modules/mono/glue/nodepath_glue.cpp
index ef9f152682..4b7648a4f9 100644
--- a/modules/mono/glue/builtin_types_glue.h
+++ b/modules/mono/glue/nodepath_glue.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* builtin_types_glue.h */
+/* nodepath_glue.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,15 +28,24 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef BUILTIN_TYPES_GLUE_H
-#define BUILTIN_TYPES_GLUE_H
+#include "nodepath_glue.h"
-#include "core/node_path.h"
-#include "core/rid.h"
+#ifdef MONO_GLUE_ENABLED
-#include <mono/metadata/object.h>
+#include "core/ustring.h"
-#include "../mono_gd/gd_mono_marshal.h"
+NodePath *godot_icall_NodePath_Ctor(MonoString *p_path) {
+ return memnew(NodePath(GDMonoMarshal::mono_string_to_godot(p_path)));
+}
+
+void godot_icall_NodePath_Dtor(NodePath *p_ptr) {
+ ERR_FAIL_NULL(p_ptr);
+ _GodotSharp::get_singleton()->queue_dispose(p_ptr);
+}
+
+MonoString *godot_icall_NodePath_operator_String(NodePath *p_np) {
+ return GDMonoMarshal::mono_string_from_godot(p_np->operator String());
+}
MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr) {
return (MonoBoolean)p_ptr->is_absolute();
@@ -70,20 +79,18 @@ MonoBoolean godot_icall_NodePath_is_empty(NodePath *p_ptr) {
return (MonoBoolean)p_ptr->is_empty();
}
-uint32_t godot_icall_RID_get_id(RID *p_ptr) {
- return p_ptr->get_id();
-}
-
-void godot_register_builtin_type_icalls() {
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_get_as_property_path", (void *)godot_icall_NodePath_get_as_property_path);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_get_concatenated_subnames", (void *)godot_icall_NodePath_get_concatenated_subnames);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_get_name", (void *)godot_icall_NodePath_get_name);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_get_name_count", (void *)godot_icall_NodePath_get_name_count);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_get_subname", (void *)godot_icall_NodePath_get_subname);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_get_subname_count", (void *)godot_icall_NodePath_get_subname_count);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_is_absolute", (void *)godot_icall_NodePath_is_absolute);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_NodePath_is_empty", (void *)godot_icall_NodePath_is_empty);
- mono_add_internal_call("Godot.NativeCalls::godot_icall_RID_get_id", (void *)godot_icall_RID_get_id);
+void godot_register_nodepath_icalls() {
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_Ctor", (void *)godot_icall_NodePath_Ctor);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_Dtor", (void *)godot_icall_NodePath_Dtor);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_operator_String", (void *)godot_icall_NodePath_operator_String);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_as_property_path", (void *)godot_icall_NodePath_get_as_property_path);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_subnames", (void *)godot_icall_NodePath_get_concatenated_subnames);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name", (void *)godot_icall_NodePath_get_name);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name_count", (void *)godot_icall_NodePath_get_name_count);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname", (void *)godot_icall_NodePath_get_subname);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname_count", (void *)godot_icall_NodePath_get_subname_count);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_is_absolute", (void *)godot_icall_NodePath_is_absolute);
+ mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_is_empty", (void *)godot_icall_NodePath_is_empty);
}
-#endif // BUILTIN_TYPES_GLUE_H
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/nodepath_glue.h b/modules/mono/glue/nodepath_glue.h
new file mode 100644
index 0000000000..92579399a6
--- /dev/null
+++ b/modules/mono/glue/nodepath_glue.h
@@ -0,0 +1,68 @@
+/*************************************************************************/
+/* nodepath_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 NODEPATH_GLUE_H
+#define NODEPATH_GLUE_H
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/node_path.h"
+
+#include "../mono_gd/gd_mono_marshal.h"
+
+NodePath *godot_icall_NodePath_Ctor(MonoString *p_path);
+
+void godot_icall_NodePath_Dtor(NodePath *p_ptr);
+
+MonoString *godot_icall_NodePath_operator_String(NodePath *p_np);
+
+MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr);
+
+uint32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr);
+
+MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx);
+
+uint32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr);
+
+MonoString *godot_icall_NodePath_get_subname(NodePath *p_ptr, uint32_t p_idx);
+
+MonoString *godot_icall_NodePath_get_concatenated_subnames(NodePath *p_ptr);
+
+NodePath *godot_icall_NodePath_get_as_property_path(NodePath *p_ptr);
+
+MonoBoolean godot_icall_NodePath_is_empty(NodePath *p_ptr);
+
+// Register internal calls
+
+void godot_register_nodepath_icalls();
+
+#endif // MONO_GLUE_ENABLED
+
+#endif // NODEPATH_GLUE_H
diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp
new file mode 100644
index 0000000000..5d66b8aa6f
--- /dev/null
+++ b/modules/mono/glue/rid_glue.cpp
@@ -0,0 +1,61 @@
+/*************************************************************************/
+/* rid_glue.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 "rid_glue.h"
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/resource.h"
+
+RID *godot_icall_RID_Ctor(Object *p_from) {
+ Resource *res_from = Object::cast_to<Resource>(p_from);
+
+ if (res_from)
+ return memnew(RID(res_from->get_rid()));
+
+ return memnew(RID);
+}
+
+void godot_icall_RID_Dtor(RID *p_ptr) {
+ ERR_FAIL_NULL(p_ptr);
+ _GodotSharp::get_singleton()->queue_dispose(p_ptr);
+}
+
+uint32_t godot_icall_RID_get_id(RID *p_ptr) {
+ return p_ptr->get_id();
+}
+
+void godot_register_rid_icalls() {
+ mono_add_internal_call("Godot.RID::godot_icall_RID_Ctor", (void *)godot_icall_RID_Ctor);
+ mono_add_internal_call("Godot.RID::godot_icall_RID_Dtor", (void *)godot_icall_RID_Dtor);
+ mono_add_internal_call("Godot.RID::godot_icall_RID_get_id", (void *)godot_icall_RID_get_id);
+}
+
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/rid_glue.h b/modules/mono/glue/rid_glue.h
new file mode 100644
index 0000000000..c725a9b5de
--- /dev/null
+++ b/modules/mono/glue/rid_glue.h
@@ -0,0 +1,53 @@
+/*************************************************************************/
+/* rid_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 RID_GLUE_H
+#define RID_GLUE_H
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/object.h"
+#include "core/rid.h"
+
+#include "../mono_gd/gd_mono_marshal.h"
+
+RID *godot_icall_RID_Ctor(Object *p_from);
+
+void godot_icall_RID_Dtor(RID *p_ptr);
+
+uint32_t godot_icall_RID_get_id(RID *p_ptr);
+
+// Register internal calls
+
+void godot_register_rid_icalls();
+
+#endif // MONO_GLUE_ENABLED
+
+#endif // RID_GLUE_H
diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp
new file mode 100644
index 0000000000..e1a2f1affd
--- /dev/null
+++ b/modules/mono/glue/string_glue.cpp
@@ -0,0 +1,79 @@
+/*************************************************************************/
+/* string_glue.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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_glue.h"
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "core/ustring.h"
+#include "core/variant.h"
+#include "core/vector.h"
+
+MonoArray *godot_icall_String_md5_buffer(MonoString *p_str) {
+ Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_buffer();
+ // TODO Check possible Array/Vector<uint8_t> problem?
+ return GDMonoMarshal::Array_to_mono_array(Variant(ret));
+}
+
+MonoString *godot_icall_String_md5_text(MonoString *p_str) {
+ String ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_text();
+ return GDMonoMarshal::mono_string_from_godot(ret);
+}
+
+int godot_icall_String_rfind(MonoString *p_str, MonoString *p_what, int p_from) {
+ String what = GDMonoMarshal::mono_string_to_godot(p_what);
+ return GDMonoMarshal::mono_string_to_godot(p_str).rfind(what, p_from);
+}
+
+int godot_icall_String_rfindn(MonoString *p_str, MonoString *p_what, int p_from) {
+ String what = GDMonoMarshal::mono_string_to_godot(p_what);
+ return GDMonoMarshal::mono_string_to_godot(p_str).rfindn(what, p_from);
+}
+
+MonoArray *godot_icall_String_sha256_buffer(MonoString *p_str) {
+ Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).sha256_buffer();
+ return GDMonoMarshal::Array_to_mono_array(Variant(ret));
+}
+
+MonoString *godot_icall_String_sha256_text(MonoString *p_str) {
+ String ret = GDMonoMarshal::mono_string_to_godot(p_str).sha256_text();
+ return GDMonoMarshal::mono_string_from_godot(ret);
+}
+
+void godot_register_string_icalls() {
+ mono_add_internal_call("Godot.String::godot_icall_String_md5_buffer", (void *)godot_icall_String_md5_buffer);
+ mono_add_internal_call("Godot.String::godot_icall_String_md5_text", (void *)godot_icall_String_md5_text);
+ mono_add_internal_call("Godot.String::godot_icall_String_rfind", (void *)godot_icall_String_rfind);
+ mono_add_internal_call("Godot.String::godot_icall_String_rfindn", (void *)godot_icall_String_rfindn);
+ mono_add_internal_call("Godot.String::godot_icall_String_sha256_buffer", (void *)godot_icall_String_sha256_buffer);
+ mono_add_internal_call("Godot.String::godot_icall_String_sha256_text", (void *)godot_icall_String_sha256_text);
+}
+
+#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/string_glue.h b/modules/mono/glue/string_glue.h
new file mode 100644
index 0000000000..8b1553e28b
--- /dev/null
+++ b/modules/mono/glue/string_glue.h
@@ -0,0 +1,56 @@
+/*************************************************************************/
+/* string_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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_GLUE_H
+#define STRING_GLUE_H
+
+#ifdef MONO_GLUE_ENABLED
+
+#include "../mono_gd/gd_mono_marshal.h"
+
+MonoArray *godot_icall_String_md5_buffer(MonoString *p_str);
+
+MonoString *godot_icall_String_md5_text(MonoString *p_str);
+
+int godot_icall_String_rfind(MonoString *p_str, MonoString *p_what, int p_from);
+
+int godot_icall_String_rfindn(MonoString *p_str, MonoString *p_what, int p_from);
+
+MonoArray *godot_icall_String_sha256_buffer(MonoString *p_str);
+
+MonoString *godot_icall_String_sha256_text(MonoString *p_str);
+
+// Register internal calls
+
+void godot_register_string_icalls();
+
+#endif // MONO_GLUE_ENABLED
+
+#endif // STRING_GLUE_H
diff --git a/modules/mono/godotsharp_defs.h b/modules/mono/godotsharp_defs.h
index f604464e8f..39d608de9f 100644
--- a/modules/mono/godotsharp_defs.h
+++ b/modules/mono/godotsharp_defs.h
@@ -32,6 +32,7 @@
#define GODOTSHARP_DEFS_H
#define BINDINGS_NAMESPACE "Godot"
+#define BINDINGS_NAMESPACE_COLLECTIONS BINDINGS_NAMESPACE ".Collections"
#define BINDINGS_GLOBAL_SCOPE_CLASS "GD"
#define BINDINGS_PTR_FIELD "ptr"
#define BINDINGS_NATIVE_NAME_FIELD "nativeName"
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 92c5cdc5c1..2570e68f13 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -30,13 +30,13 @@
#include "godotsharp_dirs.h"
-#include "os/os.h"
+#include "core/os/os.h"
#ifdef TOOLS_ENABLED
+#include "core/os/dir_access.h"
+#include "core/project_settings.h"
+#include "core/version.h"
#include "editor/editor_settings.h"
-#include "os/dir_access.h"
-#include "project_settings.h"
-#include "version.h"
#endif
namespace GodotSharpDirs {
diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h
index e87b5a4150..3466cb271d 100644
--- a/modules/mono/godotsharp_dirs.h
+++ b/modules/mono/godotsharp_dirs.h
@@ -31,7 +31,7 @@
#ifndef GODOTSHARP_DIRS_H
#define GODOTSHARP_DIRS_H
-#include "ustring.h"
+#include "core/ustring.h"
namespace GodotSharpDirs {
diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp
index 12109045e0..f695bddfeb 100644
--- a/modules/mono/mono_gc_handle.cpp
+++ b/modules/mono/mono_gc_handle.cpp
@@ -32,24 +32,34 @@
#include "mono_gd/gd_mono.h"
-uint32_t MonoGCHandle::make_strong_handle(MonoObject *p_object) {
+uint32_t MonoGCHandle::new_strong_handle(MonoObject *p_object) {
return mono_gchandle_new(p_object, /* pinned: */ false);
}
-uint32_t MonoGCHandle::make_weak_handle(MonoObject *p_object) {
+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) {
+
+ mono_gchandle_free(p_gchandle);
+}
+
Ref<MonoGCHandle> MonoGCHandle::create_strong(MonoObject *p_object) {
- return memnew(MonoGCHandle(make_strong_handle(p_object)));
+ return memnew(MonoGCHandle(new_strong_handle(p_object), STRONG_HANDLE));
}
Ref<MonoGCHandle> MonoGCHandle::create_weak(MonoObject *p_object) {
- return memnew(MonoGCHandle(make_weak_handle(p_object)));
+ return memnew(MonoGCHandle(new_weak_handle(p_object), WEAK_HANDLE));
}
void MonoGCHandle::release() {
@@ -59,14 +69,15 @@ void MonoGCHandle::release() {
#endif
if (!released && GDMono::get_singleton()->is_runtime_initialized()) {
- mono_gchandle_free(handle);
+ free_handle(handle);
released = true;
}
}
-MonoGCHandle::MonoGCHandle(uint32_t p_handle) {
+MonoGCHandle::MonoGCHandle(uint32_t p_handle, HandleType p_handle_type) {
released = false;
+ weak = p_handle_type == WEAK_HANDLE;
handle = p_handle;
}
diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h
index 9cb3ef0fbb..e5aa04e2b8 100644
--- a/modules/mono/mono_gc_handle.h
+++ b/modules/mono/mono_gc_handle.h
@@ -33,31 +33,43 @@
#include <mono/jit/jit.h>
-#include "reference.h"
+#include "core/reference.h"
class MonoGCHandle : public Reference {
GDCLASS(MonoGCHandle, Reference)
bool released;
+ bool weak;
uint32_t handle;
public:
- static uint32_t make_strong_handle(MonoObject *p_object);
- static uint32_t make_weak_handle(MonoObject *p_object);
+ enum HandleType {
+ STRONG_HANDLE,
+ 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);
static Ref<MonoGCHandle> create_strong(MonoObject *p_object);
static Ref<MonoGCHandle> create_weak(MonoObject *p_object);
+ _FORCE_INLINE_ bool is_released() { return released; }
+ _FORCE_INLINE_ bool is_weak() { return weak; }
+
_FORCE_INLINE_ MonoObject *get_target() const { return released ? NULL : mono_gchandle_get_target(handle); }
- _FORCE_INLINE_ void set_handle(uint32_t p_handle) {
- handle = p_handle;
+ _FORCE_INLINE_ void set_handle(uint32_t p_handle, HandleType p_handle_type) {
released = false;
+ weak = p_handle_type == WEAK_HANDLE;
+ handle = p_handle;
}
void release();
- MonoGCHandle(uint32_t p_handle);
+ MonoGCHandle(uint32_t p_handle, HandleType p_handle_type);
~MonoGCHandle();
};
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index fadac941e9..b2b5a90507 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -35,13 +35,14 @@
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/mono-gc.h>
-#include "os/dir_access.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "os/thread.h"
-#include "project_settings.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/os/thread.h"
+#include "core/project_settings.h"
#include "../csharp_script.h"
+#include "../glue/cs_glue_version.gen.h"
#include "../godotsharp_dirs.h"
#include "../utils/path_utils.h"
#include "gd_mono_class.h"
@@ -177,6 +178,30 @@ void GDMono::initialize() {
mono_set_dirs(assembly_dir.length() ? assembly_dir.get_data() : NULL,
config_dir.length() ? config_dir.get_data() : NULL);
+#elif OSX_ENABLED
+ mono_set_dirs(NULL, NULL);
+
+ {
+ const char *assembly_rootdir = mono_assembly_getrootdir();
+ const char *config_dir = mono_get_config_dir();
+
+ if (!assembly_rootdir || !config_dir || !DirAccess::exists(assembly_rootdir) || !DirAccess::exists(config_dir)) {
+ Vector<const char *> locations;
+ locations.push_back("/Library/Frameworks/Mono.framework/Versions/Current/");
+ locations.push_back("/usr/local/var/homebrew/linked/mono/");
+
+ for (int i = 0; i < locations.size(); i++) {
+ String hint_assembly_rootdir = path_join(locations[i], "lib");
+ String hint_mscorlib_path = path_join(hint_assembly_rootdir, "mono", "4.5", "mscorlib.dll");
+ String hint_config_dir = path_join(locations[i], "etc");
+
+ if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) {
+ mono_set_dirs(hint_assembly_rootdir.utf8().get_data(), hint_config_dir.utf8().get_data());
+ break;
+ }
+ }
+ }
+ }
#else
mono_set_dirs(NULL, NULL);
#endif
@@ -232,7 +257,7 @@ void GDMono::initialize() {
_register_internal_calls();
// The following assemblies are not required at initialization
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
if (_load_api_assemblies()) {
if (!core_api_assembly_out_of_sync && !editor_api_assembly_out_of_sync && GDMonoUtils::mono_cache.godot_api_cache_updated) {
// Everything is fine with the api assemblies, load the project assembly
@@ -275,7 +300,7 @@ void GDMono::initialize() {
print_verbose("Mono: INITIALIZED");
}
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
namespace GodotSharpBindings {
uint64_t get_core_api_hash();
@@ -283,14 +308,13 @@ uint64_t get_core_api_hash();
uint64_t get_editor_api_hash();
#endif // TOOLS_ENABLED
uint32_t get_bindings_version();
-uint32_t get_cs_glue_version();
void register_generated_icalls();
} // namespace GodotSharpBindings
#endif
void GDMono::_register_internal_calls() {
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
GodotSharpBindings::register_generated_icalls();
#endif
@@ -304,7 +328,7 @@ void GDMono::_initialize_and_check_api_hashes() {
api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE);
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
if (api_core_hash != GodotSharpBindings::get_core_api_hash()) {
ERR_PRINT("Mono: Core API hash mismatch!");
}
@@ -313,7 +337,7 @@ void GDMono::_initialize_and_check_api_hashes() {
#ifdef TOOLS_ENABLED
api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
if (api_editor_hash != GodotSharpBindings::get_editor_api_hash()) {
ERR_PRINT("Mono: Editor API hash mismatch!");
}
@@ -431,11 +455,11 @@ bool GDMono::_load_core_api_assembly() {
bool success = load_assembly(API_ASSEMBLY_NAME, &core_api_assembly);
if (success) {
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(core_api_assembly, APIAssembly::API_CORE);
core_api_assembly_out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash ||
GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version ||
- GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version;
+ CS_GLUE_VERSION != api_assembly_ver.cs_glue_version;
#endif
GDMonoUtils::update_godot_api_cache();
}
@@ -457,11 +481,11 @@ bool GDMono::_load_editor_api_assembly() {
bool success = load_assembly(EDITOR_API_ASSEMBLY_NAME, &editor_api_assembly);
if (success) {
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(editor_api_assembly, APIAssembly::API_EDITOR);
editor_api_assembly_out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash ||
GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version ||
- GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version;
+ CS_GLUE_VERSION != api_assembly_ver.cs_glue_version;
#endif
}
@@ -615,9 +639,7 @@ Error GDMono::_unload_scripts_domain() {
mono_gc_collect(mono_gc_max_generation());
- finalizing_scripts_domain = true;
mono_domain_finalize(scripts_domain, 2000);
- finalizing_scripts_domain = false;
mono_gc_collect(mono_gc_max_generation());
@@ -684,7 +706,7 @@ Error GDMono::reload_scripts_domain() {
return err;
}
-#ifndef MONO_GLUE_DISABLED
+#ifdef MONO_GLUE_ENABLED
if (!_load_api_assemblies()) {
return ERR_CANT_OPEN;
}
@@ -698,13 +720,15 @@ Error GDMono::reload_scripts_domain() {
// so we invalidate the version in the metadata and unload the script domain.
if (core_api_assembly_out_of_sync) {
+ ERR_PRINT("The loaded Core API assembly is out of sync");
metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true);
} else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) {
- ERR_PRINT("Core API assembly is in sync, but the cache update failed");
+ ERR_PRINT("The loaded Core API assembly is in sync, but the cache update failed");
metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true);
}
if (editor_api_assembly_out_of_sync) {
+ ERR_PRINT("The loaded Editor API assembly is out of sync");
metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true);
}
@@ -813,7 +837,6 @@ GDMono::GDMono() {
gdmono_log = memnew(GDMonoLog);
runtime_initialized = false;
- finalizing_scripts_domain = false;
root_domain = NULL;
scripts_domain = NULL;
@@ -842,7 +865,7 @@ GDMono::GDMono() {
GDMono::~GDMono() {
- if (runtime_initialized) {
+ if (is_runtime_initialized()) {
if (scripts_domain) {
@@ -867,8 +890,9 @@ GDMono::~GDMono() {
print_verbose("Mono: Runtime cleanup...");
- runtime_initialized = false;
mono_jit_cleanup(root_domain);
+
+ runtime_initialized = false;
}
if (gdmono_log)
@@ -879,33 +903,12 @@ GDMono::~GDMono() {
_GodotSharp *_GodotSharp::singleton = NULL;
-void _GodotSharp::_dispose_object(Object *p_object) {
-
- if (p_object->get_script_instance()) {
- CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(p_object->get_script_instance());
- if (cs_instance) {
- cs_instance->mono_object_disposed();
- return;
- }
- }
-
- // Unsafe refcount decrement. The managed instance also counts as a reference.
- // See: CSharpLanguage::alloc_instance_binding_data(Object *p_object)
- if (Object::cast_to<Reference>(p_object)->unreference()) {
- memdelete(p_object);
- }
-}
-
void _GodotSharp::_dispose_callback() {
#ifndef NO_THREADS
queue_mutex->lock();
#endif
- for (List<Object *>::Element *E = obj_delete_queue.front(); E; E = E->next()) {
- _dispose_object(E->get());
- }
-
for (List<NodePath *>::Element *E = np_delete_queue.front(); E; E = E->next()) {
memdelete(E->get());
}
@@ -914,7 +917,6 @@ void _GodotSharp::_dispose_callback() {
memdelete(E->get());
}
- obj_delete_queue.clear();
np_delete_queue.clear();
rid_delete_queue.clear();
queue_empty = true;
@@ -934,52 +936,69 @@ void _GodotSharp::detach_thread() {
GDMonoUtils::detach_current_thread();
}
-bool _GodotSharp::is_finalizing_domain() {
+int32_t _GodotSharp::get_domain_id() {
- return GDMono::get_singleton()->is_finalizing_scripts_domain();
+ MonoDomain *domain = mono_domain_get();
+ CRASH_COND(!domain); // User must check if runtime is initialized before calling this method
+ return mono_domain_get_id(domain);
}
-bool _GodotSharp::is_domain_loaded() {
+int32_t _GodotSharp::get_scripts_domain_id() {
- return GDMono::get_singleton()->get_scripts_domain() != NULL;
+ MonoDomain *domain = SCRIPTS_DOMAIN;
+ CRASH_COND(!domain); // User must check if scripts domain is loaded before calling this method
+ return mono_domain_get_id(domain);
}
-#define ENQUEUE_FOR_DISPOSAL(m_queue, m_inst) \
- m_queue.push_back(m_inst); \
- if (queue_empty) { \
- queue_empty = false; \
- if (!is_finalizing_domain()) { /* call_deferred may not be safe here */ \
- call_deferred("_dispose_callback"); \
- } \
- }
+bool _GodotSharp::is_scripts_domain_loaded() {
-void _GodotSharp::queue_dispose(MonoObject *p_mono_object, Object *p_object) {
+ return GDMono::get_singleton()->is_runtime_initialized() && SCRIPTS_DOMAIN != NULL;
+}
- if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
- _dispose_object(p_object);
- } else {
-#ifndef NO_THREADS
- queue_mutex->lock();
-#endif
+bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) {
- // This is our last chance to invoke notification predelete (this is being called from the finalizer)
- // We must use the MonoObject* passed by the finalizer, because the weak GC handle target returns NULL at this point
- CSharpInstance *si = CAST_CSHARP_INSTANCE(p_object->get_script_instance());
- if (si) {
- si->call_notification_no_check(p_mono_object, Object::NOTIFICATION_PREDELETE);
- }
+ return is_domain_finalizing_for_unload(p_domain_id);
+}
- ENQUEUE_FOR_DISPOSAL(obj_delete_queue, p_object);
+bool _GodotSharp::is_domain_finalizing_for_unload() {
-#ifndef NO_THREADS
- queue_mutex->unlock();
-#endif
- }
+ return is_domain_finalizing_for_unload(mono_domain_get());
+}
+
+bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) {
+
+ return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id));
+}
+
+bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) {
+
+ if (!p_domain)
+ return true;
+ return mono_domain_is_unloading(p_domain);
+}
+
+bool _GodotSharp::is_runtime_shutting_down() {
+
+ return mono_runtime_is_shutting_down();
}
+bool _GodotSharp::is_runtime_initialized() {
+
+ return GDMono::get_singleton()->is_runtime_initialized();
+}
+
+#define ENQUEUE_FOR_DISPOSAL(m_queue, m_inst) \
+ m_queue.push_back(m_inst); \
+ if (queue_empty) { \
+ queue_empty = false; \
+ if (!is_domain_finalizing_for_unload(SCRIPTS_DOMAIN)) { /* call_deferred may not be safe here */ \
+ call_deferred("_dispose_callback"); \
+ } \
+ }
+
void _GodotSharp::queue_dispose(NodePath *p_node_path) {
- if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+ if (GDMonoUtils::is_main_thread() && !is_domain_finalizing_for_unload(SCRIPTS_DOMAIN)) {
memdelete(p_node_path);
} else {
#ifndef NO_THREADS
@@ -996,7 +1015,7 @@ void _GodotSharp::queue_dispose(NodePath *p_node_path) {
void _GodotSharp::queue_dispose(RID *p_rid) {
- if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) {
+ if (GDMonoUtils::is_main_thread() && !is_domain_finalizing_for_unload(SCRIPTS_DOMAIN)) {
memdelete(p_rid);
} else {
#ifndef NO_THREADS
@@ -1016,8 +1035,13 @@ void _GodotSharp::_bind_methods() {
ClassDB::bind_method(D_METHOD("attach_thread"), &_GodotSharp::attach_thread);
ClassDB::bind_method(D_METHOD("detach_thread"), &_GodotSharp::detach_thread);
- ClassDB::bind_method(D_METHOD("is_finalizing_domain"), &_GodotSharp::is_finalizing_domain);
- ClassDB::bind_method(D_METHOD("is_domain_loaded"), &_GodotSharp::is_domain_loaded);
+ ClassDB::bind_method(D_METHOD("get_domain_id"), &_GodotSharp::get_domain_id);
+ ClassDB::bind_method(D_METHOD("get_scripts_domain_id"), &_GodotSharp::get_scripts_domain_id);
+ ClassDB::bind_method(D_METHOD("is_scripts_domain_loaded"), &_GodotSharp::is_scripts_domain_loaded);
+ ClassDB::bind_method(D_METHOD("is_domain_finalizing_for_unload", "domain_id"), &_GodotSharp::_is_domain_finalizing_for_unload);
+
+ ClassDB::bind_method(D_METHOD("is_runtime_shutting_down"), &_GodotSharp::is_runtime_shutting_down);
+ ClassDB::bind_method(D_METHOD("is_runtime_initialized"), &_GodotSharp::is_runtime_initialized);
ClassDB::bind_method(D_METHOD("_dispose_callback"), &_GodotSharp::_dispose_callback);
}
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index e0ec6ced5e..0c5503d28e 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -170,8 +170,7 @@ public:
void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly);
GDMonoAssembly **get_loaded_assembly(const String &p_name);
- _FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized; }
- _FORCE_INLINE_ bool is_finalizing_scripts_domain() const { return finalizing_scripts_domain; }
+ _FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; }
_FORCE_INLINE_ MonoDomain *get_scripts_domain() { return scripts_domain; }
#ifdef TOOLS_ENABLED
@@ -236,11 +235,10 @@ class _GodotSharp : public Object {
friend class GDMono;
- void _dispose_object(Object *p_object);
-
void _dispose_callback();
- List<Object *> obj_delete_queue;
+ bool _is_domain_finalizing_for_unload(int32_t p_domain_id);
+
List<NodePath *> np_delete_queue;
List<RID *> rid_delete_queue;
@@ -260,10 +258,18 @@ public:
void attach_thread();
void detach_thread();
- bool is_finalizing_domain();
- bool is_domain_loaded();
+ int32_t get_domain_id();
+ int32_t get_scripts_domain_id();
+
+ bool is_scripts_domain_loaded();
+
+ bool is_domain_finalizing_for_unload();
+ bool is_domain_finalizing_for_unload(int32_t p_domain_id);
+ bool is_domain_finalizing_for_unload(MonoDomain *p_domain);
+
+ bool is_runtime_shutting_down();
+ bool is_runtime_initialized();
- void queue_dispose(MonoObject *p_mono_object, Object *p_object);
void queue_dispose(NodePath *p_node_path);
void queue_dispose(RID *p_rid);
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index 2c6d367fc6..0ba11ac412 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -34,10 +34,10 @@
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
+#include "core/hash_map.h"
+#include "core/map.h"
+#include "core/ustring.h"
#include "gd_mono_utils.h"
-#include "hash_map.h"
-#include "map.h"
-#include "ustring.h"
class GDMonoAssembly {
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index f4e386549a..477305d503 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -33,8 +33,8 @@
#include <mono/metadata/debug-helpers.h>
-#include "map.h"
-#include "ustring.h"
+#include "core/map.h"
+#include "core/ustring.h"
#include "gd_mono_field.h"
#include "gd_mono_header.h"
diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h
index 72a5439044..2fe05006f1 100644
--- a/modules/mono/mono_gd/gd_mono_header.h
+++ b/modules/mono/mono_gd/gd_mono_header.h
@@ -31,7 +31,7 @@
#ifndef GD_MONO_HEADER_H
#define GD_MONO_HEADER_H
-#include "int_types.h"
+#include "core/int_types.h"
class GDMonoAssembly;
class GDMonoClass;
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index 5224d309de..b7bb2cb2d6 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -33,8 +33,8 @@
#include <mono/utils/mono-logger.h>
#include <stdlib.h> // abort
-#include "os/dir_access.h"
-#include "os/os.h"
+#include "core/os/dir_access.h"
+#include "core/os/os.h"
#include "../godotsharp_dirs.h"
diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h
index a7e374858c..3b4ff07b7b 100644
--- a/modules/mono/mono_gd/gd_mono_log.h
+++ b/modules/mono/mono_gd/gd_mono_log.h
@@ -31,7 +31,7 @@
#ifndef GD_MONO_LOG_H
#define GD_MONO_LOG_H
-#include "os/file_access.h"
+#include "core/os/file_access.h"
class GDMonoLog {
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 464f584a0a..1ad0a4a6ea 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -31,9 +31,9 @@
#ifndef GDMONOMARSHAL_H
#define GDMONOMARSHAL_H
+#include "core/variant.h"
#include "gd_mono.h"
#include "gd_mono_utils.h"
-#include "variant.h"
namespace GDMonoMarshal {
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index bebc3b863f..cc5b5652f8 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -32,10 +32,10 @@
#include <mono/metadata/exception.h>
-#include "os/dir_access.h"
-#include "os/os.h"
-#include "project_settings.h"
-#include "reference.h"
+#include "core/os/dir_access.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
+#include "core/reference.h"
#include "../csharp_script.h"
#include "../utils/macros.h"
@@ -138,6 +138,7 @@ void MonoCache::clear_members() {
field_Image_ptr = NULL;
field_RID_ptr = NULL;
+ methodthunk_GodotObject_Dispose = NULL;
methodthunk_Array_GetPtr = NULL;
methodthunk_Dictionary_GetPtr = NULL;
methodthunk_MarshalUtils_IsArrayGenericType = NULL;
@@ -156,6 +157,7 @@ void MonoCache::cleanup() {
}
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
+#define GODOT_API_NS_CLAS(m_ns, m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(m_ns, #m_class))
void update_corlib_cache() {
@@ -206,8 +208,8 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(Control, GODOT_API_CLASS(Control));
CACHE_CLASS_AND_CHECK(Spatial, GODOT_API_CLASS(Spatial));
CACHE_CLASS_AND_CHECK(WeakRef, GODOT_API_CLASS(WeakRef));
- CACHE_CLASS_AND_CHECK(Array, GODOT_API_CLASS(Array));
- CACHE_CLASS_AND_CHECK(Dictionary, GODOT_API_CLASS(Dictionary));
+ CACHE_CLASS_AND_CHECK(Array, GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Array));
+ CACHE_CLASS_AND_CHECK(Dictionary, GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary));
CACHE_CLASS_AND_CHECK(MarshalUtils, GODOT_API_CLASS(MarshalUtils));
#ifdef DEBUG_ENABLED
@@ -234,8 +236,9 @@ void update_godot_api_cache() {
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));
- CACHE_METHOD_THUNK_AND_CHECK(Array, GetPtr, (Array_GetPtr)GODOT_API_CLASS(Array)->get_method_thunk("GetPtr", 0));
- CACHE_METHOD_THUNK_AND_CHECK(Dictionary, GetPtr, (Dictionary_GetPtr)GODOT_API_CLASS(Dictionary)->get_method_thunk("GetPtr", 0));
+ CACHE_METHOD_THUNK_AND_CHECK(GodotObject, Dispose, (GodotObject_Dispose)CACHED_CLASS(GodotObject)->get_method_thunk("Dispose", 0));
+ CACHE_METHOD_THUNK_AND_CHECK(Array, GetPtr, (Array_GetPtr)GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Array)->get_method_thunk("GetPtr", 0));
+ CACHE_METHOD_THUNK_AND_CHECK(Dictionary, GetPtr, (Dictionary_GetPtr)GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary)->get_method_thunk("GetPtr", 0));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IsArrayGenericType, (IsArrayGenericType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("IsArrayGenericType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IsDictionaryGenericType, (IsDictionaryGenericType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("IsDictionaryGenericType", 1));
CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, (SignalAwaiter_SignalCallback)GODOT_API_CLASS(SignalAwaiter)->get_method_thunk("SignalCallback", 1));
@@ -246,7 +249,7 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, (DebugUtils_StackFrameInfo)GODOT_API_CLASS(DebuggingUtils)->get_method_thunk("GetStackFrameInfo", 4));
#endif
- // TODO Move to CSharpLanguage::init()
+ // TODO Move to CSharpLanguage::init() and do handle disposal
MonoObject *task_scheduler = mono_object_new(SCRIPTS_DOMAIN, GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr());
GDMonoUtils::runtime_object_init(task_scheduler);
mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler);
@@ -269,11 +272,48 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
}
}
- // Only called if the owner does not have a CSharpInstance
+ // If the owner does not have a CSharpInstance...
+
void *data = unmanaged->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
if (data) {
- return ((Map<Object *, Ref<MonoGCHandle> >::Element *)data)->value()->get_target();
+ CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
+
+ Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
+ ERR_FAIL_COND_V(gchandle.is_null(), NULL);
+
+ MonoObject *target = gchandle->get_target();
+
+ if (target)
+ return target;
+
+ CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
+
+ // Create a new one
+
+#ifdef DEBUG_ENABLED
+ CRASH_COND(script_binding.type_name == StringName());
+ CRASH_COND(script_binding.wrapper_class == NULL);
+#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);
+
+ gchandle->set_handle(MonoGCHandle::new_strong_handle(mono_object), MonoGCHandle::STRONG_HANDLE);
+
+ // Tie managed to unmanaged
+ Reference *ref = Object::cast_to<Reference>(unmanaged);
+
+ if (ref) {
+ // Unsafe refcount increment. The managed instance also counts as a reference.
+ // This way if the unmanaged world has no references to our owner
+ // but the managed instance is alive, the refcount will be 1 instead of 0.
+ // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr)
+
+ ref->reference();
+ }
+
+ return mono_object;
}
}
@@ -303,6 +343,7 @@ MonoThread *get_current_thread() {
void runtime_object_init(MonoObject *p_this_obj) {
GD_MONO_BEGIN_RUNTIME_INVOKE;
+ // FIXME: Do not use mono_runtime_object_init, it aborts if an exception is thrown
mono_runtime_object_init(p_this_obj);
GD_MONO_END_RUNTIME_INVOKE;
}
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index bf8860c85a..c8e23f071f 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -38,8 +38,8 @@
#include "../utils/thread_local.h"
#include "gd_mono_header.h"
-#include "object.h"
-#include "reference.h"
+#include "core/object.h"
+#include "core/reference.h"
#define UNLIKELY_UNHANDLED_EXCEPTION(m_exc) \
if (unlikely(m_exc != NULL)) { \
@@ -49,6 +49,7 @@
namespace GDMonoUtils {
+typedef void (*GodotObject_Dispose)(MonoObject *, MonoObject **);
typedef Array *(*Array_GetPtr)(MonoObject *, MonoObject **);
typedef Dictionary *(*Dictionary_GetPtr)(MonoObject *, MonoObject **);
typedef MonoObject *(*SignalAwaiter_SignalCallback)(MonoObject *, MonoArray *, MonoObject **);
@@ -141,6 +142,7 @@ struct MonoCache {
GDMonoField *field_Image_ptr;
GDMonoField *field_RID_ptr;
+ GodotObject_Dispose methodthunk_GodotObject_Dispose;
Array_GetPtr methodthunk_Array_GetPtr;
Dictionary_GetPtr methodthunk_Dictionary_GetPtr;
IsArrayGenericType methodthunk_MarshalUtils_IsArrayGenericType;
diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp
index 4410996546..f6cb143e8e 100644
--- a/modules/mono/register_types.cpp
+++ b/modules/mono/register_types.cpp
@@ -30,7 +30,7 @@
#include "register_types.h"
-#include "engine.h"
+#include "core/engine.h"
#include "csharp_script.h"
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index 54720652fa..b4c78df538 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -42,8 +42,7 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
ERR_FAIL_NULL_V(p_source, ERR_INVALID_DATA);
ERR_FAIL_NULL_V(p_target, ERR_INVALID_DATA);
- uint32_t awaiter_handle = MonoGCHandle::make_strong_handle(p_awaiter);
- Ref<SignalAwaiterHandle> sa_con = memnew(SignalAwaiterHandle(awaiter_handle));
+ Ref<SignalAwaiterHandle> sa_con = memnew(SignalAwaiterHandle(p_awaiter));
#ifdef DEBUG_ENABLED
sa_con->set_connection_target(p_target);
#endif
@@ -119,8 +118,8 @@ void SignalAwaiterHandle::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &SignalAwaiterHandle::_signal_callback, MethodInfo("_signal_callback"));
}
-SignalAwaiterHandle::SignalAwaiterHandle(uint32_t p_managed_handle) :
- MonoGCHandle(p_managed_handle) {
+SignalAwaiterHandle::SignalAwaiterHandle(MonoObject *p_managed) :
+ MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) {
#ifdef DEBUG_ENABLED
conn_target_id = 0;
diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h
index a6a205ff8d..4ec860537b 100644
--- a/modules/mono/signal_awaiter_utils.h
+++ b/modules/mono/signal_awaiter_utils.h
@@ -31,8 +31,8 @@
#ifndef SIGNAL_AWAITER_UTILS_H
#define SIGNAL_AWAITER_UTILS_H
+#include "core/reference.h"
#include "mono_gc_handle.h"
-#include "reference.h"
namespace SignalAwaiterUtils {
@@ -64,7 +64,7 @@ public:
}
#endif
- SignalAwaiterHandle(uint32_t p_managed_handle);
+ SignalAwaiterHandle(MonoObject *p_managed);
~SignalAwaiterHandle();
};
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index 7b23cd7579..8116df5f51 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -32,7 +32,7 @@
#ifdef WINDOWS_ENABLED
-#include "os/os.h"
+#include "core/os/os.h"
// Here, after os/os.h
#include <windows.h>
diff --git a/modules/mono/utils/mono_reg_utils.h b/modules/mono/utils/mono_reg_utils.h
index edf31f5a07..26f7e2d3c2 100644
--- a/modules/mono/utils/mono_reg_utils.h
+++ b/modules/mono/utils/mono_reg_utils.h
@@ -33,7 +33,7 @@
#ifdef WINDOWS_ENABLED
-#include "ustring.h"
+#include "core/ustring.h"
struct MonoRegInfo {
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index 4b77aeb54e..ea942a9a8e 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -30,10 +30,10 @@
#include "path_utils.h"
-#include "os/dir_access.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#ifdef WINDOWS_ENABLED
#define ENV_PATH_SEP ";"
diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h
index 184cacfac7..3c7b36c0d4 100644
--- a/modules/mono/utils/path_utils.h
+++ b/modules/mono/utils/path_utils.h
@@ -31,7 +31,7 @@
#ifndef PATH_UTILS_H
#define PATH_UTILS_H
-#include "ustring.h"
+#include "core/ustring.h"
_FORCE_INLINE_ String path_join(const String &e1, const String &e2) {
return e1.plus_file(e2);
diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h
index 5dddaee6e8..f2df2340ae 100644
--- a/modules/mono/utils/string_utils.h
+++ b/modules/mono/utils/string_utils.h
@@ -31,8 +31,8 @@
#ifndef STRING_FORMAT_H
#define STRING_FORMAT_H
-#include "ustring.h"
-#include "variant.h"
+#include "core/ustring.h"
+#include "core/variant.h"
String sformat(const String &p_text, const Variant &p1 = Variant(), const Variant &p2 = Variant(), const Variant &p3 = Variant(), const Variant &p4 = Variant(), const Variant &p5 = Variant());
diff --git a/modules/opus/audio_stream_opus.h b/modules/opus/audio_stream_opus.h
index 3ffdaf2c18..c004adeb77 100644
--- a/modules/opus/audio_stream_opus.h
+++ b/modules/opus/audio_stream_opus.h
@@ -31,8 +31,8 @@
#ifndef AUDIO_STREAM_OPUS_H
#define AUDIO_STREAM_OPUS_H
-#include "io/resource_loader.h"
-#include "os/file_access.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
#include "scene/resources/audio_stream.h"
#include <opus/opusfile.h>
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 6ec44023c1..e6718eb4a2 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -31,7 +31,7 @@
#include "texture_loader_pvr.h"
#include "PvrTcEncoder.h"
#include "RgbaBitmap.h"
-#include "os/file_access.h"
+#include "core/os/file_access.h"
#include <string.h>
static void _pvrtc_decompress(Image *p_img);
diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h
index 9369178336..c859a4cdda 100644
--- a/modules/pvr/texture_loader_pvr.h
+++ b/modules/pvr/texture_loader_pvr.h
@@ -31,7 +31,7 @@
#ifndef TEXTURE_LOADER_PVR_H
#define TEXTURE_LOADER_PVR_H
-#include "io/resource_loader.h"
+#include "core/io/resource_loader.h"
#include "scene/resources/texture.h"
class ResourceFormatPVR : public ResourceFormatLoader {
diff --git a/modules/recast/navigation_mesh_editor_plugin.cpp b/modules/recast/navigation_mesh_editor_plugin.cpp
index 8556b7aa0a..98351fbaee 100644
--- a/modules/recast/navigation_mesh_editor_plugin.cpp
+++ b/modules/recast/navigation_mesh_editor_plugin.cpp
@@ -30,8 +30,8 @@
#include "navigation_mesh_editor_plugin.h"
-#include "io/marshalls.h"
-#include "io/resource_saver.h"
+#include "core/io/marshalls.h"
+#include "core/io/resource_saver.h"
#include "scene/3d/mesh_instance.h"
#include "scene/gui/box_container.h"
diff --git a/modules/recast/navigation_mesh_generator.h b/modules/recast/navigation_mesh_generator.h
index 3588539ef1..2f2f57d721 100644
--- a/modules/recast/navigation_mesh_generator.h
+++ b/modules/recast/navigation_mesh_generator.h
@@ -31,9 +31,9 @@
#ifndef NAVIGATION_MESH_GENERATOR_H
#define NAVIGATION_MESH_GENERATOR_H
+#include "core/os/thread.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
-#include "os/thread.h"
#include "scene/3d/mesh_instance.h"
#include "scene/3d/navigation_mesh.h"
#include "scene/resources/shape.h"
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp
index 733f32277b..bdd3e31eb8 100644
--- a/modules/regex/regex.cpp
+++ b/modules/regex/regex.cpp
@@ -205,6 +205,8 @@ Error RegEx::compile(const String &p_pattern) {
code = pcre2_compile_16(p, pattern.length(), flags, &err, &offset, cctx);
+ pcre2_compile_context_free_16(cctx);
+
if (!code) {
PCRE2_UCHAR16 buf[256];
pcre2_get_error_message_16(err, buf, 256);
@@ -221,6 +223,8 @@ Error RegEx::compile(const String &p_pattern) {
code = pcre2_compile_32(p, pattern.length(), flags, &err, &offset, cctx);
+ pcre2_compile_context_free_32(cctx);
+
if (!code) {
PCRE2_UCHAR32 buf[256];
pcre2_get_error_message_32(err, buf, 256);
@@ -285,6 +289,8 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
if (res < 0) {
pcre2_match_data_free_32(match);
+ pcre2_match_context_free_32(mctx);
+
return NULL;
}
diff --git a/modules/regex/register_types.cpp b/modules/regex/register_types.cpp
index 14eba69ee0..73e2c5022d 100644
--- a/modules/regex/register_types.cpp
+++ b/modules/regex/register_types.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "register_types.h"
-#include "class_db.h"
+#include "core/class_db.h"
#include "regex.h"
void register_regex_types() {
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index 653dd82351..26cb76011c 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -30,7 +30,7 @@
#include "image_compress_squish.h"
-#include "print_string.h"
+#include "core/print_string.h"
#include <squish.h>
@@ -193,8 +193,8 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres
int src_ofs = p_image->get_mipmap_offset(i);
squish::CompressImage(&rb[src_ofs], w, h, &wb[dst_ofs], squish_comp);
dst_ofs += (MAX(4, bw) * MAX(4, bh)) >> shift;
- w >>= 1;
- h >>= 1;
+ w = MAX(w / 2, 1);
+ h = MAX(h / 2, 1);
}
rb = PoolVector<uint8_t>::Read();
diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h
index 6da947beea..dfebdc955f 100644
--- a/modules/squish/image_compress_squish.h
+++ b/modules/squish/image_compress_squish.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_COMPRESS_SQUISH_H
#define IMAGE_COMPRESS_SQUISH_H
-#include "image.h"
+#include "core/image.h"
void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source);
void image_decompress_squish(Image *p_image);
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 0e533d3978..57b6b5343e 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -30,7 +30,7 @@
#include "audio_stream_ogg_vorbis.h"
-#include "os/file_access.h"
+#include "core/os/file_access.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
index d7bc7cc0d7..71a957a6af 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
@@ -31,7 +31,7 @@
#ifndef AUDIO_STREAM_STB_VORBIS_H
#define AUDIO_STREAM_STB_VORBIS_H
-#include "io/resource_loader.h"
+#include "core/io/resource_loader.h"
#include "servers/audio/audio_stream.h"
#define STB_VORBIS_HEADER_ONLY
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
index c8acdb689a..74f2e68206 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
@@ -30,8 +30,8 @@
#include "resource_importer_ogg_vorbis.h"
-#include "io/resource_saver.h"
-#include "os/file_access.h"
+#include "core/io/resource_saver.h"
+#include "core/os/file_access.h"
#include "scene/resources/texture.h"
String ResourceImporterOGGVorbis::get_importer_name() const {
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h
index a1847545aa..82a03cd207 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.h
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h
@@ -32,7 +32,7 @@
#define RESOURCEIMPORTEROGGVORBIS_H
#include "audio_stream_ogg_vorbis.h"
-#include "io/resource_import.h"
+#include "core/io/resource_import.h"
class ResourceImporterOGGVorbis : public ResourceImporter {
GDCLASS(ResourceImporterOGGVorbis, ResourceImporter)
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 8ccd229f3d..ccb7d93885 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -30,10 +30,9 @@
#include "image_loader_svg.h"
-#include "os/os.h"
-#include "print_string.h"
-
-#include <ustring.h>
+#include "core/os/os.h"
+#include "core/print_string.h"
+#include "core/ustring.h"
void SVGRasterizer::rasterize(NSVGimage *p_image, float p_tx, float p_ty, float p_scale, unsigned char *p_dst, int p_w, int p_h, int p_stride) {
nsvgRasterize(rasterizer, p_image, p_tx, p_ty, p_scale, p_dst, p_w, p_h, p_stride);
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index 63854da2f6..ff361ad800 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -31,8 +31,8 @@
#ifndef IMAGE_LOADER_SVG_H
#define IMAGE_LOADER_SVG_H
-#include "io/image_loader.h"
-#include "ustring.h"
+#include "core/io/image_loader.h"
+#include "core/ustring.h"
#include <nanosvg.h>
#include <nanosvgrast.h>
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index d4fa88afa7..9bc24017fc 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -30,8 +30,8 @@
#include "image_loader_tga.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
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;
diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h
index c4b10b7f49..0fe83a54a1 100644
--- a/modules/tga/image_loader_tga.h
+++ b/modules/tga/image_loader_tga.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_LOADER_TGA_H
#define IMAGE_LOADER_TGA_H
-#include "io/image_loader.h"
+#include "core/io/image_loader.h"
/**
@author SaracenOne
diff --git a/modules/thekla_unwrap/register_types.cpp b/modules/thekla_unwrap/register_types.cpp
index c74cbd9d18..8e733d1ad2 100644
--- a/modules/thekla_unwrap/register_types.cpp
+++ b/modules/thekla_unwrap/register_types.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "register_types.h"
-#include "error_macros.h"
+#include "core/error_macros.h"
#include "thirdparty/thekla_atlas/thekla/thekla_atlas.h"
#include <stdio.h>
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 68087ac01f..44052d473f 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -30,8 +30,8 @@
#include "video_stream_theora.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "thirdparty/misc/yuv2rgb.h"
diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h
index 1aba3f56da..4be723f85b 100644
--- a/modules/theora/video_stream_theora.h
+++ b/modules/theora/video_stream_theora.h
@@ -31,11 +31,11 @@
#ifndef VIDEO_STREAM_THEORA_H
#define VIDEO_STREAM_THEORA_H
-#include "io/resource_loader.h"
-#include "os/file_access.h"
-#include "os/semaphore.h"
-#include "os/thread.h"
-#include "ring_buffer.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
+#include "core/ring_buffer.h"
#include "scene/resources/video_stream.h"
#include "servers/audio_server.h"
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 0abefe11ee..63f0781028 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -30,8 +30,8 @@
#include "image_loader_tinyexr.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
#include "thirdparty/tinyexr/tinyexr.h"
@@ -129,15 +129,45 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
PoolVector<uint8_t> imgdata;
Image::Format format;
+ int output_channels = 0;
if (idxA > 0) {
imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16
format = Image::FORMAT_RGBAH;
+ output_channels = 4;
} else {
imgdata.resize(exr_image.width * exr_image.height * 6); //RGB16
format = Image::FORMAT_RGBH;
+ output_channels = 3;
+ }
+
+ EXRTile single_image_tile;
+ int num_tiles;
+ int tile_width = 0;
+ int tile_height = 0;
+
+ const EXRTile *exr_tiles;
+
+ if (!exr_header.tiled) {
+ single_image_tile.images = exr_image.images;
+ single_image_tile.width = exr_image.width;
+ single_image_tile.height = exr_image.height;
+ single_image_tile.level_x = exr_image.width;
+ single_image_tile.level_y = exr_image.height;
+ single_image_tile.offset_x = 0;
+ single_image_tile.offset_y = 0;
+
+ exr_tiles = &single_image_tile;
+ num_tiles = 1;
+ tile_width = exr_image.width;
+ tile_height = exr_image.height;
+ } else {
+ tile_width = exr_header.tile_size_x;
+ tile_height = exr_header.tile_size_y;
+ num_tiles = exr_image.num_tiles;
+ exr_tiles = exr_image.tiles;
}
{
@@ -145,22 +175,51 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
uint16_t *iw = (uint16_t *)wd.ptr();
// Assume `out_rgba` have enough memory allocated.
- for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ for (int tile_index = 0; tile_index < num_tiles; tile_index++) {
- Color color(
- reinterpret_cast<float **>(exr_image.images)[idxR][i],
- reinterpret_cast<float **>(exr_image.images)[idxG][i],
- reinterpret_cast<float **>(exr_image.images)[idxB][i]);
+ const EXRTile &tile = exr_tiles[tile_index];
- if (p_force_linear)
- color = color.to_linear();
+ int tw = tile.width;
+ int th = tile.height;
- *iw++ = Math::make_half_float(color.r);
- *iw++ = Math::make_half_float(color.g);
- *iw++ = Math::make_half_float(color.b);
+ 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;
if (idxA > 0) {
- *iw++ = Math::make_half_float(reinterpret_cast<float **>(exr_image.images)[idxA][i]);
+ a_channel_start = reinterpret_cast<const float *>(tile.images[idxA]);
+ }
+
+ uint16_t *first_row_w = iw + (tile.offset_y * tile_height * exr_image.width + tile.offset_x * tile_width) * output_channels;
+
+ for (int y = 0; y < th; y++) {
+ 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;
+
+ if (a_channel_start) {
+ a_channel = a_channel_start + y * tile_width;
+ }
+
+ uint16_t *row_w = first_row_w + (y * exr_image.width * output_channels);
+
+ for (int x = 0; x < tw; x++) {
+
+ Color color(*r_channel++, *g_channel++, *b_channel++);
+
+ if (p_force_linear)
+ color = color.to_linear();
+
+ *row_w++ = Math::make_half_float(color.r);
+ *row_w++ = Math::make_half_float(color.g);
+ *row_w++ = Math::make_half_float(color.b);
+
+ if (idxA > 0) {
+ *row_w++ = Math::make_half_float(*a_channel++);
+ }
+ }
}
}
}
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index 6706e0972a..a6ef9000e5 100644
--- a/modules/tinyexr/image_loader_tinyexr.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_LOADER_TINYEXR_H
#define IMAGE_LOADER_TINYEXR_H
-#include "io/image_loader.h"
+#include "core/io/image_loader.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/modules/upnp/register_types.cpp b/modules/upnp/register_types.cpp
index c79155c4d2..13088c94dd 100644
--- a/modules/upnp/register_types.cpp
+++ b/modules/upnp/register_types.cpp
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "register_types.h"
-#include "error_macros.h"
+
+#include "core/error_macros.h"
+
#include "upnp.h"
#include "upnpdevice.h"
diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp
index 32fdfe22f8..69e054f5c5 100644
--- a/modules/upnp/upnp.cpp
+++ b/modules/upnp/upnp.cpp
@@ -29,8 +29,10 @@
/*************************************************************************/
#include "upnp.h"
-#include "miniupnpc/miniwget.h"
-#include "upnpcommands.h"
+
+#include <miniupnpc/miniwget.h>
+#include <miniupnpc/upnpcommands.h>
+
#include <stdlib.h>
bool UPNP::is_common_device(const String &dev) const {
diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h
index fb0c0f30a0..8f0a972c22 100644
--- a/modules/upnp/upnp.h
+++ b/modules/upnp/upnp.h
@@ -31,9 +31,11 @@
#ifndef GODOT_UPNP_H
#define GODOT_UPNP_H
-#include "miniupnpc/miniupnpc.h"
+#include "core/reference.h"
+
#include "upnpdevice.h"
-#include <reference.h>
+
+#include <miniupnpc/miniupnpc.h>
class UPNP : public Reference {
diff --git a/modules/upnp/upnpdevice.cpp b/modules/upnp/upnpdevice.cpp
index a5959cf649..8f935fbd82 100644
--- a/modules/upnp/upnpdevice.cpp
+++ b/modules/upnp/upnpdevice.cpp
@@ -29,8 +29,10 @@
/*************************************************************************/
#include "upnpdevice.h"
+
#include "upnp.h"
-#include "upnpcommands.h"
+
+#include <miniupnpc/upnpcommands.h>
String UPNPDevice::query_external_address() const {
ERR_FAIL_COND_V(!is_valid_gateway(), "");
diff --git a/modules/upnp/upnpdevice.h b/modules/upnp/upnpdevice.h
index 25c9fe1ba3..e4c5eb691d 100644
--- a/modules/upnp/upnpdevice.h
+++ b/modules/upnp/upnpdevice.h
@@ -31,7 +31,7 @@
#ifndef GODOT_UPNPDEVICE_H
#define GODOT_UPNPDEVICE_H
-#include <reference.h>
+#include "core/reference.h"
class UPNPDevice : public Reference {
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index 11401c0460..6e081817f1 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -31,7 +31,7 @@
#include "register_types.h"
#include "core/engine.h"
-#include "io/resource_loader.h"
+#include "core/io/resource_loader.h"
#include "visual_script.h"
#include "visual_script_builtin_funcs.h"
#include "visual_script_editor.h"
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index bbdec7195f..ff97c21fd9 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -30,8 +30,8 @@
#include "visual_script.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "scene/main/node.h"
#include "visual_script_nodes.h"
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 13a8b909b0..ea99ce4970 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -31,8 +31,8 @@
#ifndef VISUAL_SCRIPT_H
#define VISUAL_SCRIPT_H
-#include "os/thread.h"
-#include "script_language.h"
+#include "core/os/thread.h"
+#include "core/script_language.h"
class VisualScriptInstance;
class VisualScriptNodeInstance;
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index 8e98b08b22..e7a4e0c31f 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -30,13 +30,13 @@
#include "visual_script_builtin_funcs.h"
-#include "class_db.h"
-#include "func_ref.h"
-#include "io/marshalls.h"
-#include "math_funcs.h"
-#include "os/os.h"
-#include "reference.h"
-#include "variant_parser.h"
+#include "core/class_db.h"
+#include "core/func_ref.h"
+#include "core/io/marshalls.h"
+#include "core/math/math_funcs.h"
+#include "core/os/os.h"
+#include "core/reference.h"
+#include "core/variant_parser.h"
const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX] = {
"sin",
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 4471fbd0c4..c9b52a221a 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -30,13 +30,13 @@
#include "visual_script_editor.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 "object.h"
-#include "os/input.h"
-#include "os/keyboard.h"
-#include "variant.h"
#include "visual_script_expression.h"
#include "visual_script_flow_control.h"
#include "visual_script_func_nodes.h"
@@ -321,7 +321,7 @@ protected:
p_list->push_back(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt));
p_list->push_back(PropertyInfo(script->get_variable_info(var).type, "value", script->get_variable_info(var).hint, script->get_variable_info(var).hint_string, PROPERTY_USAGE_DEFAULT));
// Update this when PropertyHint changes
- p_list->push_back(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,Flags,Layers2dRender,Layers2dPhysics,Layer3dRender,Layer3dPhysics,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText,ColorNoAlpha,ImageCompressLossy,ImageCompressLossLess,ObjectId,String,NodePathToEditedNode,MethodOfVariantType,MethodOfBaseType,MethodOfInstance,MethodOfScript,PropertyOfVariantType,PropertyOfBaseType,PropertyOfInstance,PropertyOfScript,ObjectTooBig"));
+ p_list->push_back(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,Flags,Layers2dRender,Layers2dPhysics,Layer3dRender,Layer3dPhysics,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText,PlaceholderText,ColorNoAlpha,ImageCompressLossy,ImageCompressLossLess,ObjectId,String,NodePathToEditedNode,MethodOfVariantType,MethodOfBaseType,MethodOfInstance,MethodOfScript,PropertyOfVariantType,PropertyOfBaseType,PropertyOfInstance,PropertyOfScript,ObjectTooBig,NodePathValidTypes"));
p_list->push_back(PropertyInfo(Variant::STRING, "hint_string"));
p_list->push_back(PropertyInfo(Variant::BOOL, "export"));
}
@@ -3615,8 +3615,7 @@ VisualScriptEditor::VisualScriptEditor() {
edit_signal_dialog->set_title(TTR("Edit Signal Arguments:"));
signal_editor = memnew(VisualScriptEditorSignalEdit);
- edit_signal_edit = memnew(PropertyEditor);
- edit_signal_edit->hide_top_label();
+ edit_signal_edit = memnew(EditorInspector);
edit_signal_dialog->add_child(edit_signal_edit);
edit_signal_edit->edit(signal_editor);
@@ -3627,8 +3626,7 @@ VisualScriptEditor::VisualScriptEditor() {
edit_variable_dialog->set_title(TTR("Edit Variable:"));
variable_editor = memnew(VisualScriptEditorVariableEdit);
- edit_variable_edit = memnew(PropertyEditor);
- edit_variable_edit->hide_top_label();
+ edit_variable_edit = memnew(EditorInspector);
edit_variable_dialog->add_child(edit_variable_edit);
edit_variable_edit->edit(variable_editor);
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 8bfd147519..b0bf971630 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -93,7 +93,7 @@ class VisualScriptEditor : public ScriptEditorBase {
VisualScriptEditorSignalEdit *signal_editor;
AcceptDialog *edit_signal_dialog;
- PropertyEditor *edit_signal_edit;
+ EditorInspector *edit_signal_edit;
VisualScriptPropertySelector *method_select;
VisualScriptPropertySelector *new_connect_node_select;
@@ -102,7 +102,7 @@ class VisualScriptEditor : public ScriptEditorBase {
VisualScriptEditorVariableEdit *variable_editor;
AcceptDialog *edit_variable_dialog;
- PropertyEditor *edit_variable_edit;
+ EditorInspector *edit_variable_edit;
CustomPropertyEditor *default_value_edit;
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index 7535f37ffc..c3ab949d24 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -30,9 +30,9 @@
#include "visual_script_flow_control.h"
-#include "io/resource_loader.h"
-#include "os/keyboard.h"
-#include "project_settings.h"
+#include "core/io/resource_loader.h"
+#include "core/os/keyboard.h"
+#include "core/project_settings.h"
//////////////////////////////////////////
////////////////RETURN////////////////////
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index f926d4e2eb..1913bfd8c7 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -30,9 +30,9 @@
#include "visual_script_func_nodes.h"
-#include "engine.h"
-#include "io/resource_loader.h"
-#include "os/os.h"
+#include "core/engine.h"
+#include "core/io/resource_loader.h"
+#include "core/os/os.h"
#include "scene/main/node.h"
#include "scene/main/scene_tree.h"
#include "visual_script_nodes.h"
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index d499512d93..99f242e974 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -30,11 +30,11 @@
#include "visual_script_nodes.h"
-#include "engine.h"
-#include "global_constants.h"
-#include "os/input.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/engine.h"
+#include "core/global_constants.h"
+#include "core/os/input.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "scene/main/node.h"
#include "scene/main/scene_tree.h"
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index f79c81ad88..39997d14c4 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -30,13 +30,13 @@
#include "visual_script_property_selector.h"
+#include "core/os/keyboard.h"
#include "editor_scale.h"
#include "modules/visual_script/visual_script.h"
#include "modules/visual_script/visual_script_builtin_funcs.h"
#include "modules/visual_script/visual_script_flow_control.h"
#include "modules/visual_script/visual_script_func_nodes.h"
#include "modules/visual_script/visual_script_nodes.h"
-#include "os/keyboard.h"
#include "scene/main/node.h"
#include "scene/main/viewport.h"
@@ -191,10 +191,10 @@ void VisualScriptPropertySelector::_update_search() {
if (type_filter.size() && type_filter.find(E->get().type) == -1)
continue;
- String get_text_raw = String(TTR("Get")) + String(" ") + E->get().name;
+ String get_text_raw = String(vformat(TTR("Get %s"), E->get().name));
String get_text = get_text_raw.capitalize();
- String set_text_raw = String(TTR("Set ")) + String(" ") + E->get().name;
+ String set_text_raw = String(vformat(TTR("Set %s"), E->get().name));
String set_text = set_text_raw.capitalize();
String input = search_box->get_text().capitalize();
if (input == String() ||
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index a96e8408c0..a21fff67fe 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -30,7 +30,7 @@
#include "visual_script_yield_nodes.h"
-#include "os/os.h"
+#include "core/os/os.h"
#include "scene/main/node.h"
#include "scene/main/scene_tree.h"
#include "visual_script_nodes.h"
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h
index 01de8a3143..73c4b5f3f4 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/vorbis/audio_stream_ogg_vorbis.h
@@ -31,9 +31,9 @@
#ifndef AUDIO_STREAM_OGG_VORBIS_H
#define AUDIO_STREAM_OGG_VORBIS_H
-#include "io/resource_loader.h"
-#include "os/file_access.h"
-#include "os/thread_safe.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>
diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub
index c681e2b34f..2daf8c282f 100644
--- a/modules/webm/libvpx/SCsub
+++ b/modules/webm/libvpx/SCsub
@@ -38,7 +38,6 @@ libvpx_sources = [
"vp8/decoder/decodemv.c",
"vp8/decoder/detokenize.c",
"vp8/decoder/onyxd_if.c",
- "vp8/decoder/threading.c",
"vp9/vp9_dx_iface.c",
@@ -102,6 +101,10 @@ libvpx_sources = [
"vpx_util/vpx_thread.c"
]
+libvpx_sources_mt = [
+ "vp8/decoder/threading.c",
+]
+
libvpx_sources_intrin_x86 = [
"vp8/common/x86/filter_x86.c",
"vp8/common/x86/loopfilter_x86.c",
@@ -231,6 +234,7 @@ libvpx_sources_arm_neon_gas_apple = [
]
libvpx_sources = [libvpx_dir + file for file in libvpx_sources]
+libvpx_sources_mt = [libvpx_dir + file for file in libvpx_sources_mt]
libvpx_sources_intrin_x86 = [libvpx_dir + file for file in libvpx_sources_intrin_x86]
libvpx_sources_intrin_x86_mmx = [libvpx_dir + file for file in libvpx_sources_intrin_x86_mmx]
libvpx_sources_intrin_x86_sse2 = [libvpx_dir + file for file in libvpx_sources_intrin_x86_sse2]
@@ -253,6 +257,8 @@ env_webm.Append(CPPPATH=[libvpx_dir])
env_libvpx = env.Clone()
env_libvpx.Append(CPPPATH=[libvpx_dir])
+webm_multithread = env["platform"] != 'javascript'
+
cpu_bits = env["bits"]
webm_cpu_x86 = False
webm_cpu_arm = False
@@ -338,6 +344,10 @@ if webm_simd_optimizations == False:
print("WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!")
env_libvpx.add_source_files(env.modules_sources, libvpx_sources)
+
+if webm_multithread:
+ env_libvpx.add_source_files(env.modules_sources, libvpx_sources_mt)
+
if webm_cpu_x86:
is_clang_or_gcc = ('gcc' in env["CC"]) or ('clang' in env["CC"]) or ("OSXCROSS_ROOT" in os.environ)
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 1bb9a43886..d9a6ece085 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -35,9 +35,9 @@
#include "mkvparser/mkvparser.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
#include "thirdparty/misc/yuv2rgb.h"
diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h
index dcf88092c5..3739a73114 100644
--- a/modules/webm/video_stream_webm.h
+++ b/modules/webm/video_stream_webm.h
@@ -31,7 +31,7 @@
#ifndef VIDEO_STREAM_WEBM_H
#define VIDEO_STREAM_WEBM_H
-#include "io/resource_loader.h"
+#include "core/io/resource_loader.h"
#include "scene/resources/video_stream.h"
class WebMFrame;
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 42b2c77777..6734ae90d9 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -30,9 +30,9 @@
#include "image_loader_webp.h"
-#include "io/marshalls.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/io/marshalls.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
#include <stdlib.h>
#include <webp/decode.h>
diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h
index f051fed4b8..256c787a16 100644
--- a/modules/webp/image_loader_webp.h
+++ b/modules/webp/image_loader_webp.h
@@ -31,7 +31,7 @@
#ifndef IMAGE_LOADER_WEBP_H
#define IMAGE_LOADER_WEBP_H
-#include "io/image_loader.h"
+#include "core/io/image_loader.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
index 00c36ebb47..836b564de8 100644
--- a/modules/websocket/emws_client.cpp
+++ b/modules/websocket/emws_client.cpp
@@ -62,25 +62,23 @@ EMSCRIPTEN_KEEPALIVE void _esws_on_close(void *obj, int code, char *reason, int
Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) {
+ String proto_string = p_protocols.join(",");
String str = "ws://";
- String proto_string = "";
if (p_ssl)
str = "wss://";
str += p_host + ":" + itos(p_port) + p_path;
- for (int i = 0; i < p_protocols.size(); i++) {
- proto_string += p_protocols[i];
- proto_string += ",";
- }
- if (proto_string == "")
- proto_string = "binary,";
-
- proto_string = proto_string.substr(0, proto_string.length() - 1);
_is_connecting = true;
/* clang-format off */
int peer_sock = EM_ASM_INT({
- var socket = new WebSocket(UTF8ToString($1), UTF8ToString($2).split(","));
+ 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));
+ }
var c_ptr = Module.IDHandler.get($0);
socket.binaryType = "arraybuffer";
diff --git a/modules/websocket/lws_client.cpp b/modules/websocket/lws_client.cpp
index ac31daa108..09f6422058 100644
--- a/modules/websocket/lws_client.cpp
+++ b/modules/websocket/lws_client.cpp
@@ -48,12 +48,10 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
ERR_FAIL_COND_V(!addr.is_valid(), ERR_INVALID_PARAMETER);
- // prepare protocols
- if (p_protocols.size() == 0) // default to binary protocol
- p_protocols.append("binary");
+ // Prepare protocols
_lws_make_protocols(this, &LWSClient::_lws_gd_callback, p_protocols, &_lws_ref);
- // init lws client
+ // Init lws client
struct lws_context_creation_info info;
struct lws_client_connect_info i;
@@ -87,7 +85,10 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
strncpy(pbuf, p_path.utf8().get_data(), 2048);
i.context = context;
- i.protocol = _lws_ref->lws_names;
+ if (p_protocols.size() > 0)
+ i.protocol = _lws_ref->lws_names;
+ else
+ i.protocol = NULL;
i.address = abuf;
i.host = hbuf;
i.path = pbuf;
@@ -134,13 +135,13 @@ int LWSClient::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
_on_error();
destroy_context();
- return -1; // we should close the connection (would probably happen anyway)
+ return -1; // We should close the connection (would probably happen anyway)
case LWS_CALLBACK_CLIENT_CLOSED:
peer->close();
destroy_context();
_on_disconnect();
- return 0; // we can end here
+ return 0; // We can end here
case LWS_CALLBACK_CLIENT_RECEIVE:
peer->read_wsi(in, len);
diff --git a/modules/websocket/lws_helper.h b/modules/websocket/lws_helper.h
index 85a1e3769f..70256ccf16 100644
--- a/modules/websocket/lws_helper.h
+++ b/modules/websocket/lws_helper.h
@@ -105,53 +105,54 @@ static bool _lws_poll(struct lws_context *context, _LWSRef *ref) {
}
/*
- * prepare the protocol_structs to be fed to context
- * also prepare the protocol string used by the client
+ * Prepare the protocol_structs to be fed to context.
+ * Also prepare the protocol string used by the client.
*/
static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref) {
- /* the input strings might go away after this call,
- * we need to copy them. Will clear them when
- * destroying the context */
+ // The input strings might go away after this call, we need to copy them.
+ // We will clear them when destroying the context.
int i;
int len = p_names.size();
size_t data_size = sizeof(struct LWSPeer::PeerData);
PoolVector<String>::Read pnr = p_names.read();
- /*
- * This is a reference connecting the object with lws
- * keep track of status, mallocs, etc.
- * Must survive as long the context
- * Must be freed manually when context creation fails.
- */
+ // This is a reference connecting the object with lws keep track of status, mallocs, etc.
+ // Must survive as long the context.
+ // Must be freed manually when context creation fails.
_LWSRef *ref = _lws_create_ref(p_obj);
- /* LWS protocol structs */
+ // LWS protocol structs.
ref->lws_structs = (struct lws_protocols *)memalloc(sizeof(struct lws_protocols) * (len + 2));
memset(ref->lws_structs, 0, sizeof(struct lws_protocols) * (len + 2));
CharString strings = p_names.join(",").ascii();
int str_len = strings.length();
- /* Joined string of protocols, double the size: comma separated first, NULL separated last */
- ref->lws_names = (char *)memalloc((str_len + 1) * 2); /* plus the terminator */
+ // Joined string of protocols, double the size: comma separated first, NULL separated last
+ ref->lws_names = (char *)memalloc((str_len + 1) * 2); // Plus the terminator
char *names_ptr = ref->lws_names;
struct lws_protocols *structs_ptr = ref->lws_structs;
- copymem(names_ptr, strings.get_data(), str_len);
- names_ptr[str_len] = '\0'; /* NULL terminator */
- /* NULL terminated strings to be used in protocol structs */
- copymem(&names_ptr[str_len + 1], strings.get_data(), str_len);
- names_ptr[(str_len * 2) + 1] = '\0'; /* NULL terminator */
+ // Comma separated protocols string to be used in client Sec-WebSocket-Protocol header
+ if (str_len > 0)
+ copymem(names_ptr, strings.get_data(), str_len);
+ names_ptr[str_len] = '\0'; // NULL terminator
+
+ // NULL terminated protocol strings to be used in protocol structs
+ if (str_len > 0)
+ copymem(&names_ptr[str_len + 1], strings.get_data(), str_len);
+ names_ptr[(str_len * 2) + 1] = '\0'; // NULL terminator
int pos = str_len + 1;
- /* the first protocol is always http-only */
- structs_ptr[0].name = "http-only";
+ // The first protocol is the default for any http request (before upgrade).
+ // It is also used as the websocket protocol when no subprotocol is specified.
+ structs_ptr[0].name = "default";
structs_ptr[0].callback = p_callback;
structs_ptr[0].per_session_data_size = data_size;
structs_ptr[0].rx_buffer_size = LWS_BUF_SIZE;
structs_ptr[0].tx_packet_size = LWS_PACKET_SIZE;
- /* add user defined protocols */
+ // Add user defined protocols
for (i = 0; i < len; i++) {
structs_ptr[i + 1].name = (const char *)&names_ptr[pos];
structs_ptr[i + 1].callback = p_callback;
@@ -161,7 +162,7 @@ static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback,
pos += pnr[i].ascii().length() + 1;
names_ptr[pos - 1] = '\0';
}
- /* add protocols terminator */
+ // Add protocols terminator
structs_ptr[len + 1].name = NULL;
structs_ptr[len + 1].callback = NULL;
structs_ptr[len + 1].per_session_data_size = 0;
diff --git a/modules/websocket/lws_server.cpp b/modules/websocket/lws_server.cpp
index bb724bce9c..4a614f6933 100644
--- a/modules/websocket/lws_server.cpp
+++ b/modules/websocket/lws_server.cpp
@@ -41,9 +41,6 @@ Error LWSServer::listen(int p_port, PoolVector<String> p_protocols, bool gd_mp_a
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);
- if (p_protocols.size() == 0) // default to binary protocol
- p_protocols.append(String("binary"));
-
// Prepare lws protocol structs
_lws_make_protocols(this, &LWSServer::_lws_gd_callback, p_protocols, &_lws_ref);
diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp
index 721f3cc330..538cd40454 100644
--- a/modules/websocket/register_types.cpp
+++ b/modules/websocket/register_types.cpp
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_types.h"
-#include "error_macros.h"
+#include "core/error_macros.h"
#ifdef JAVASCRIPT_ENABLED
#include "emscripten.h"
#include "emws_client.h"