diff options
Diffstat (limited to 'modules')
44 files changed, 755 insertions, 575 deletions
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index b3dfc2eecf..873c9c31b7 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -49,7 +49,9 @@ CollisionObjectBullet::ShapeWrapper::~ShapeWrapper() {} void CollisionObjectBullet::ShapeWrapper::set_transform(const Transform &p_transform) { + G_TO_B(p_transform.get_basis().get_scale(), scale); G_TO_B(p_transform, transform); + UNSCALE_BT_BASIS(transform); } void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_transform) { transform = p_transform; @@ -235,7 +237,7 @@ void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transfor ERR_FAIL_INDEX(p_index, get_shape_count()); shapes[p_index].set_transform(p_transform); - on_shapes_changed(); + on_shape_changed(shapes[p_index].shape); } void RigidCollisionObjectBullet::remove_shape(ShapeBullet *p_shape) { @@ -320,7 +322,7 @@ void RigidCollisionObjectBullet::on_shapes_changed() { shpWrapper = &shapes[i]; if (shpWrapper->active) { if (!shpWrapper->bt_shape) { - shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape(); + shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape(shpWrapper->scale); } compoundShape->addChildShape(shpWrapper->transform, shpWrapper->bt_shape); } else { diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index a9b8aee019..506976eabf 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -72,6 +72,7 @@ public: ShapeBullet *shape; btCollisionShape *bt_shape; btTransform transform; + btVector3 scale; bool active; ShapeWrapper() : @@ -102,6 +103,7 @@ public: shape = otherShape.shape; bt_shape = otherShape.bt_shape; transform = otherShape.transform; + scale = otherShape.scale; active = otherShape.active; } diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 0e293a38a6..f2115a5d50 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -204,7 +204,7 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { const CollisionObjectBullet::ShapeWrapper *shape_wrapper; - btVector3 owner_body_scale(owner->get_bt_body_scale()); + btVector3 owner_scale(owner->get_bt_body_scale()); for (int i = shapes_count - 1; 0 <= i; --i) { shape_wrapper = &shapes_wrappers[i]; @@ -213,14 +213,14 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { } shapes[i].transform = shape_wrapper->transform; - shapes[i].transform.getOrigin() *= owner_body_scale; + shapes[i].transform.getOrigin() *= owner_scale; switch (shape_wrapper->shape->get_type()) { case PhysicsServer::SHAPE_SPHERE: case PhysicsServer::SHAPE_BOX: case PhysicsServer::SHAPE_CAPSULE: case PhysicsServer::SHAPE_CONVEX_POLYGON: case PhysicsServer::SHAPE_RAY: { - shapes[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_body_scale, safe_margin)); + shapes[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); } break; default: WARN_PRINT("This shape is not supported to be kinematic!"); diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index ee1cc418bc..27eac4e6ee 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -48,11 +48,6 @@ ShapeBullet::ShapeBullet() {} ShapeBullet::~ShapeBullet() {} -btCollisionShape *ShapeBullet::create_bt_shape() { - btVector3 s(1, 1, 1); - return create_bt_shape(s); -} - btCollisionShape *ShapeBullet::create_bt_shape(const Vector3 &p_implicit_scale, real_t p_margin) { btVector3 s; G_TO_B(p_implicit_scale, s); @@ -82,7 +77,7 @@ void ShapeBullet::add_owner(ShapeOwnerBullet *p_owner) { void ShapeBullet::remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFromThisBody) { Map<ShapeOwnerBullet *, int>::Element *E = owners.find(p_owner); - ERR_FAIL_COND(!E); + if (!E) return; E->get()--; if (p_permanentlyFromThisBody || 0 >= E->get()) { owners.erase(E); diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index 12fa9754bd..4a03c0f014 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -62,7 +62,6 @@ public: ShapeBullet(); virtual ~ShapeBullet(); - btCollisionShape *create_bt_shape(); btCollisionShape *create_bt_shape(const Vector3 &p_implicit_scale, real_t p_margin = 0); virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0) = 0; diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 83dd055760..d60d8ba0e2 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -857,31 +857,31 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f btVector3 recover_initial_position(0, 0, 0); { /// Phase one - multi shapes depenetration using margin for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - if (recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, recover_initial_position)) { - - // Add recover position to "From" and "To" transforms - body_safe_position.getOrigin() += recover_initial_position; - } else { + if (!recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, recover_initial_position)) { break; } } + + // Add recover movement in order to make it safe + body_safe_position.getOrigin() += recover_initial_position; } #endif - btVector3 recovered_motion; - G_TO_B(p_motion, recovered_motion); - const int shape_count(p_body->get_shape_count()); + btVector3 motion; + G_TO_B(p_motion, motion); { /// phase two - sweep test, from a secure position without margin + const int shape_count(p_body->get_shape_count()); + #if debug_test_motion -//Vector3 sup_line; -//B_TO_G(body_safe_position.getOrigin(), sup_line); -//motionVec->clear(); -//motionVec->begin(Mesh::PRIMITIVE_LINES, NULL); -//motionVec->add_vertex(sup_line); -//motionVec->add_vertex(sup_line + p_motion * 10); -//motionVec->end(); + Vector3 sup_line; + B_TO_G(body_safe_position.getOrigin(), sup_line); + motionVec->clear(); + motionVec->begin(Mesh::PRIMITIVE_LINES, NULL); + motionVec->add_vertex(sup_line); + motionVec->add_vertex(sup_line + p_motion * 10); + motionVec->end(); #endif for (int shIndex = 0; shIndex < shape_count; ++shIndex) { @@ -898,7 +898,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f btTransform shape_world_from = body_safe_position * p_body->get_kinematic_utilities()->shapes[shIndex].transform; btTransform shape_world_to(shape_world_from); - shape_world_to.getOrigin() += recovered_motion; + shape_world_to.getOrigin() += motion; GodotKinClosestConvexResultCallback btResult(shape_world_from.getOrigin(), shape_world_to.getOrigin(), p_body, IGNORE_AREAS_TRUE); btResult.m_collisionFilterGroup = p_body->get_collision_layer(); @@ -909,27 +909,30 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f if (btResult.hasHit()) { /// Since for each sweep test I fix the motion of new shapes in base the recover result, /// if another shape will hit something it means that has a deepest penetration respect the previous shape - recovered_motion *= btResult.m_closestHitFraction; + motion *= btResult.m_closestHitFraction; } } + + body_safe_position.getOrigin() += motion; } bool has_penetration = false; { /// Phase three - Recover + contact test with margin + btVector3 delta_recover_movement(0, 0, 0); RecoverResult r_recover_result; bool l_has_penetration; real_t l_penetration_distance = 1e20; for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - l_has_penetration = recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, recovered_motion, &r_recover_result); + l_has_penetration = recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, delta_recover_movement, &r_recover_result); if (r_result) { #if PERFORM_INITIAL_UNSTACK - B_TO_G(recovered_motion + recover_initial_position, r_result->motion); + B_TO_G(motion + delta_recover_movement + recover_initial_position, r_result->motion); #else - B_TO_G(recovered_motion, r_result->motion); + B_TO_G(motion + delta_recover_movement, r_result->motion); #endif if (l_has_penetration) { has_penetration = true; @@ -942,7 +945,8 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object); CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer()); - r_result->remainder = p_motion - r_result->motion; // is the remaining movements + B_TO_G(motion, r_result->remainder); // is the remaining movements + r_result->remainder = p_motion - r_result->remainder; B_TO_G(r_recover_result.pointWorld, r_result->collision_point); B_TO_G(r_recover_result.normal, r_result->collision_normal); B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot @@ -961,17 +965,14 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f //} #if debug_test_motion -//Vector3 sup_line2; -//B_TO_G(recovered_motion, sup_line2); -////Vector3 sup_pos; -////B_TO_G( pt.getPositionWorldOnB(), sup_pos); -//normalLine->clear(); -//normalLine->begin(Mesh::PRIMITIVE_LINES, NULL); -//normalLine->add_vertex(r_result->collision_point); -//normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10); -//normalLine->end(); + Vector3 sup_line2; + B_TO_G(motion, sup_line2); + normalLine->clear(); + normalLine->begin(Mesh::PRIMITIVE_LINES, NULL); + normalLine->add_vertex(r_result->collision_point); + normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10); + normalLine->end(); #endif - } else { r_result->remainder = Vector3(); } @@ -1019,7 +1020,7 @@ public: } }; -bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result) { +bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) { RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), p_body->get_collision_mask()); @@ -1043,7 +1044,7 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran body_shape_position = p_body_position * kin_shape.transform; body_shape_position_recovered = body_shape_position; - body_shape_position_recovered.getOrigin() += r_recover_position; + body_shape_position_recovered.getOrigin() += r_delta_recover_movement; kin_shape.shape->getAabb(body_shape_position_recovered, minAabb, maxAabb); dynamicsWorld->getBroadphase()->aabbTest(minAabb, maxAabb, recover_broad_result); @@ -1060,24 +1061,24 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran for (int x = cs->getNumChildShapes() - 1; 0 <= x; --x) { if (cs->getChildShape(x)->isConvex()) { - if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), otherObject, x, body_shape_position_recovered, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_recover_position, r_recover_result)) { + if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), otherObject, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { penetration = true; } } else { - if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(x), p_body->get_bt_collision_object(), otherObject, kinIndex, x, body_shape_position_recovered, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_recover_position, r_recover_result)) { + if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(x), p_body->get_bt_collision_object(), otherObject, kinIndex, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { penetration = true; } } } } else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape - if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, 0, body_shape_position_recovered, otherObject->getWorldTransform(), p_recover_movement_scale, r_recover_position, r_recover_result)) { + if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, 0, body_shape_position, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { penetration = true; } } else { - if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, body_shape_position_recovered, otherObject->getWorldTransform(), p_recover_movement_scale, r_recover_position, r_recover_result)) { + if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, body_shape_position, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) { penetration = true; } @@ -1085,26 +1086,15 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran } } -#if debug_test_motion - Vector3 pos; - B_TO_G(p_body_position.getOrigin(), pos); - Vector3 sup_line; - B_TO_G(sum_recover_normals, sup_line); - motionVec->clear(); - motionVec->begin(Mesh::PRIMITIVE_LINES, NULL); - motionVec->add_vertex(pos); - motionVec->add_vertex(pos + (sup_line * 10)); - motionVec->end(); -#endif - return penetration; } -bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result) { +bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) { // Initialize GJK input btGjkPairDetector::ClosestPointInput gjk_input; gjk_input.m_transformA = p_transformA; + gjk_input.m_transformA.getOrigin() += r_delta_recover_movement; gjk_input.m_transformB = p_transformB; // Perform GJK test @@ -1113,7 +1103,7 @@ bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const bt gjk_pair_detector.getClosestPoints(gjk_input, result, 0); if (0 > result.m_distance) { // Has penetration - r_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1 * p_recover_movement_scale); + r_delta_recover_movement += result.m_normalOnBInWorld * (result.m_distance * -1 * p_recover_movement_scale); if (r_recover_result) { if (result.m_distance < r_recover_result->penetration_distance) { @@ -1130,11 +1120,14 @@ bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const bt return false; } -bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result) { +bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) { /// Contact test - btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, p_transformA, -1, p_shapeId_A); + btTransform tA(p_transformA); + tA.getOrigin() += r_delta_recover_movement; + + btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, tA, -1, p_shapeId_A); btCollisionObjectWrapper obB(NULL, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B); btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CLOSEST_POINT_ALGORITHMS); @@ -1147,7 +1140,7 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC dispatcher->freeCollisionAlgorithm(algorithm); if (contactPointResult.hasHit()) { - r_recover_position += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1 * p_recover_movement_scale); + r_delta_recover_movement += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1 * p_recover_movement_scale); if (r_recover_result) { if (contactPointResult.m_penetration_distance < r_recover_result->penetration_distance) { diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 8d31ab765b..0aeb407dcc 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -191,15 +191,20 @@ private: RecoverResult() : hasPenetration(false), - penetration_distance(1e20) {} + normal(0, 0, 0), + pointWorld(0, 0, 0), + penetration_distance(1e20), + other_compound_shape_index(0), + other_collision_object(NULL), + local_shape_most_recovered(0) {} }; - bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btScalar p_recover_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL); + bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL); /// This is an API that recover a kinematic object from penetration /// This allow only Convex Convex test and it always use GJK algorithm, With this API we don't benefit of Bullet special accelerated functions - bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL); + bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL); /// This is an API that recover a kinematic object from penetration /// Using this we leave Bullet to select the best algorithm, For example GJK in case we have Convex Convex, or a Bullet accelerated algorithm - bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_movement_scale, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL); + bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL); }; #endif diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index 25d17542ea..00162d6e60 100644 --- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -47,12 +47,6 @@ Create server that listens to connections via [code]port[/code]. </description> </method> - <method name="get_compression_mode" qualifiers="const"> - <return type="int" enum="NetworkedMultiplayerENet.CompressionMode"> - </return> - <description> - </description> - </method> <method name="set_bind_ip"> <return type="void"> </return> @@ -61,15 +55,11 @@ <description> </description> </method> - <method name="set_compression_mode"> - <return type="void"> - </return> - <argument index="0" name="mode" type="int" enum="NetworkedMultiplayerENet.CompressionMode"> - </argument> - <description> - </description> - </method> </methods> + <members> + <member name="compression_mode" type="int" setter="set_compression_mode" getter="get_compression_mode" enum="NetworkedMultiplayerENet.CompressionMode"> + </member> + </members> <constants> <constant name="COMPRESS_NONE" value="0" enum="CompressionMode"> </constant> diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index 3ad80d3978..f3f4acd768 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -36,6 +36,10 @@ void NetworkedMultiplayerENet::set_transfer_mode(TransferMode p_mode) { transfer_mode = p_mode; } +NetworkedMultiplayerPeer::TransferMode NetworkedMultiplayerENet::get_transfer_mode() const { + + return transfer_mode; +} void NetworkedMultiplayerENet::set_target_peer(int p_peer) { @@ -659,6 +663,8 @@ void NetworkedMultiplayerENet::_bind_methods() { ClassDB::bind_method(D_METHOD("get_compression_mode"), &NetworkedMultiplayerENet::get_compression_mode); ClassDB::bind_method(D_METHOD("set_bind_ip", "ip"), &NetworkedMultiplayerENet::set_bind_ip); + ADD_PROPERTY(PropertyInfo(Variant::INT, "compression_mode", PROPERTY_HINT_ENUM, "None,Range Coder,FastLZ,ZLib,ZStd"), "set_compression_mode", "get_compression_mode"); + BIND_ENUM_CONSTANT(COMPRESS_NONE); BIND_ENUM_CONSTANT(COMPRESS_RANGE_CODER); BIND_ENUM_CONSTANT(COMPRESS_FASTLZ); diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h index 93758de94b..440e9b5400 100644 --- a/modules/enet/networked_multiplayer_enet.h +++ b/modules/enet/networked_multiplayer_enet.h @@ -110,6 +110,7 @@ protected: public: virtual void set_transfer_mode(TransferMode p_mode); + virtual TransferMode get_transfer_mode() const; virtual void set_target_peer(int p_peer); virtual int get_packet_peer() const; diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp index e56ec774dd..8a674bc8c1 100644 --- a/modules/etc/image_etc.cpp +++ b/modules/etc/image_etc.cpp @@ -118,7 +118,6 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f } uint32_t imgw = p_img->get_width(), imgh = p_img->get_height(); - ERR_FAIL_COND(next_power_of_2(imgw) != imgw || next_power_of_2(imgh) != imgh); Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels); @@ -127,6 +126,25 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f if (img->get_format() != Image::FORMAT_RGBA8) img->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert + if (img->has_mipmaps()) { + if (next_power_of_2(imgw) != imgw || next_power_of_2(imgh) != imgh) { + img->resize_to_po2(); + imgw = img->get_width(); + imgh = img->get_height(); + } + } else { + if (imgw % 4 != 0 || imgh % 4 != 0) { + if (imgw % 4) { + imgw += 4 - imgw % 4; + } + if (imgh % 4) { + imgh += 4 - imgh % 4; + } + + img->resize(imgw, imgh); + } + } + PoolVector<uint8_t>::Read r = img->get_data().read(); int target_size = Image::get_image_data_size(imgw, imgh, etc_format, p_img->has_mipmaps() ? -1 : 0); diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 350dc540f7..7f5dbc12be 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -40,6 +40,24 @@ extern "C" { #endif +godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs) { + const CharString *cs = (const CharString *)p_cs; + + return cs->length(); +} + +const char GDAPI *godot_char_string_get_data(const godot_char_string *p_cs) { + const CharString *cs = (const CharString *)p_cs; + + return cs->get_data(); +} + +void GDAPI godot_char_string_destroy(godot_char_string *p_cs) { + CharString *cs = (CharString *)p_cs; + + cs->~CharString(); +} + void GDAPI godot_string_new(godot_string *r_dest) { String *dest = (String *)r_dest; memnew_placement(dest, String); @@ -51,35 +69,11 @@ void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src memnew_placement(dest, String(*src)); } -void GDAPI godot_string_new_data(godot_string *r_dest, const char *p_contents, const int p_size) { - String *dest = (String *)r_dest; - memnew_placement(dest, String(String::utf8(p_contents, p_size))); -} - -void GDAPI godot_string_new_unicode_data(godot_string *r_dest, const wchar_t *p_contents, const int p_size) { +void GDAPI godot_string_new_with_wide_string(godot_string *r_dest, const wchar_t *p_contents, const int p_size) { String *dest = (String *)r_dest; memnew_placement(dest, String(p_contents, p_size)); } -void GDAPI godot_string_get_data(const godot_string *p_self, char *p_dest, int *p_size) { - String *self = (String *)p_self; - - if (p_size) { - // we have a length pointer, that means we either want to know - // the length or want to write *p_size bytes into a buffer - - CharString utf8_string = self->utf8(); - - int len = utf8_string.length(); - - if (p_dest) { - memcpy(p_dest, utf8_string.get_data(), *p_size); - } else { - *p_size = len; - } - } -} - wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx) { String *self = (String *)p_self; return &(self->operator[](p_idx)); @@ -90,7 +84,7 @@ wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, cons return self->operator[](p_idx); } -const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_self) { +const wchar_t GDAPI *godot_string_wide_str(const godot_string *p_self) { const String *self = (const String *)p_self; return self->c_str(); } @@ -130,6 +124,26 @@ godot_int GDAPI godot_string_length(const godot_string *p_self) { /* Helpers */ +signed char GDAPI godot_string_casecmp_to(const godot_string *p_self, const godot_string *p_str) { + const String *self = (const String *)p_self; + const String *str = (const String *)p_str; + + return self->casecmp_to(*str); +} + +signed char GDAPI godot_string_nocasecmp_to(const godot_string *p_self, const godot_string *p_str) { + const String *self = (const String *)p_self; + const String *str = (const String *)p_str; + + return self->nocasecmp_to(*str); +} +signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, const godot_string *p_str) { + const String *self = (const String *)p_self; + const String *str = (const String *)p_str; + + return self->naturalnocasecmp_to(*str); +} + godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string) { const String *self = (const String *)p_self; const String *string = (const String *)p_string; @@ -534,7 +548,7 @@ godot_string GDAPI godot_string_capitalize(const godot_string *p_self) { memnew_placement(&result, String(self->capitalize())); return result; -}; +} godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -542,7 +556,7 @@ godot_string GDAPI godot_string_camelcase_to_underscore(const godot_string *p_se memnew_placement(&result, String(self->camelcase_to_underscore(false))); return result; -}; +} godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -550,45 +564,45 @@ godot_string GDAPI godot_string_camelcase_to_underscore_lowercased(const godot_s memnew_placement(&result, String(self->camelcase_to_underscore())); return result; -}; +} double GDAPI godot_string_char_to_double(const char *p_what) { return String::to_double(p_what); -}; +} godot_int GDAPI godot_string_char_to_int(const char *p_what) { return String::to_int(p_what); -}; +} int64_t GDAPI godot_string_wchar_to_int(const wchar_t *p_str) { return String::to_int(p_str); -}; +} godot_int GDAPI godot_string_char_to_int_with_len(const char *p_what, godot_int p_len) { return String::to_int(p_what, p_len); -}; +} int64_t GDAPI godot_string_char_to_int64_with_len(const wchar_t *p_str, int p_len) { return String::to_int(p_str, p_len); -}; +} int64_t GDAPI godot_string_hex_to_int64(const godot_string *p_self) { const String *self = (const String *)p_self; return self->hex_to_int64(false); -}; +} int64_t GDAPI godot_string_hex_to_int64_with_prefix(const godot_string *p_self) { const String *self = (const String *)p_self; return self->hex_to_int64(); -}; +} int64_t GDAPI godot_string_to_int64(const godot_string *p_self) { const String *self = (const String *)p_self; return self->to_int64(); -}; +} double GDAPI godot_string_unicode_char_to_double(const wchar_t *p_str, const wchar_t **r_end) { return String::to_double(p_str, r_end); @@ -601,7 +615,7 @@ godot_string GDAPI godot_string_get_slice(const godot_string *p_self, godot_stri memnew_placement(&result, String(self->get_slice(*splitter, p_slice))); return result; -}; +} godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, wchar_t p_splitter, godot_int p_slice) { const String *self = (const String *)p_self; @@ -609,7 +623,7 @@ godot_string GDAPI godot_string_get_slicec(const godot_string *p_self, wchar_t p memnew_placement(&result, String(self->get_slicec(p_splitter, p_slice))); return result; -}; +} godot_array GDAPI godot_string_split(const godot_string *p_self, const godot_string *p_splitter) { const String *self = (const String *)p_self; @@ -625,7 +639,7 @@ godot_array GDAPI godot_string_split(const godot_string *p_self, const godot_str } return result; -}; +} godot_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, const godot_string *p_splitter) { const String *self = (const String *)p_self; @@ -641,7 +655,7 @@ godot_array GDAPI godot_string_split_allow_empty(const godot_string *p_self, con } return result; -}; +} godot_array GDAPI godot_string_split_floats(const godot_string *p_self, const godot_string *p_splitter) { const String *self = (const String *)p_self; @@ -657,7 +671,7 @@ godot_array GDAPI godot_string_split_floats(const godot_string *p_self, const go } return result; -}; +} godot_array GDAPI godot_string_split_floats_allows_empty(const godot_string *p_self, const godot_string *p_splitter) { const String *self = (const String *)p_self; @@ -673,7 +687,7 @@ godot_array GDAPI godot_string_split_floats_allows_empty(const godot_string *p_s } return result; -}; +} godot_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const godot_array *p_splitters) { const String *self = (const String *)p_self; @@ -696,7 +710,7 @@ godot_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const } return result; -}; +} godot_array GDAPI godot_string_split_floats_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters) { const String *self = (const String *)p_self; @@ -719,7 +733,7 @@ godot_array GDAPI godot_string_split_floats_mk_allows_empty(const godot_string * } return result; -}; +} godot_array GDAPI godot_string_split_ints(const godot_string *p_self, const godot_string *p_splitter) { const String *self = (const String *)p_self; @@ -735,7 +749,7 @@ godot_array GDAPI godot_string_split_ints(const godot_string *p_self, const godo } return result; -}; +} godot_array GDAPI godot_string_split_ints_allows_empty(const godot_string *p_self, const godot_string *p_splitter) { const String *self = (const String *)p_self; @@ -751,7 +765,7 @@ godot_array GDAPI godot_string_split_ints_allows_empty(const godot_string *p_sel } return result; -}; +} godot_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const godot_array *p_splitters) { const String *self = (const String *)p_self; @@ -774,7 +788,7 @@ godot_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const g } return result; -}; +} godot_array GDAPI godot_string_split_ints_mk_allows_empty(const godot_string *p_self, const godot_array *p_splitters) { const String *self = (const String *)p_self; @@ -797,7 +811,7 @@ godot_array GDAPI godot_string_split_ints_mk_allows_empty(const godot_string *p_ } return result; -}; +} godot_array GDAPI godot_string_split_spaces(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -812,22 +826,22 @@ godot_array GDAPI godot_string_split_spaces(const godot_string *p_self) { } return result; -}; +} godot_int GDAPI godot_string_get_slice_count(const godot_string *p_self, godot_string p_splitter) { const String *self = (const String *)p_self; String *splitter = (String *)&p_splitter; return self->get_slice_count(*splitter); -}; +} wchar_t GDAPI godot_string_char_lowercase(wchar_t p_char) { return String::char_lowercase(p_char); -}; +} wchar_t GDAPI godot_string_char_uppercase(wchar_t p_char) { return String::char_uppercase(p_char); -}; +} godot_string GDAPI godot_string_to_lower(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -835,7 +849,7 @@ godot_string GDAPI godot_string_to_lower(const godot_string *p_self) { memnew_placement(&result, String(self->to_lower())); return result; -}; +} godot_string GDAPI godot_string_to_upper(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -843,7 +857,7 @@ godot_string GDAPI godot_string_to_upper(const godot_string *p_self) { memnew_placement(&result, String(self->to_upper())); return result; -}; +} godot_string GDAPI godot_string_get_basename(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -851,7 +865,7 @@ godot_string GDAPI godot_string_get_basename(const godot_string *p_self) { memnew_placement(&result, String(self->get_basename())); return result; -}; +} godot_string GDAPI godot_string_get_extension(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -859,7 +873,7 @@ godot_string GDAPI godot_string_get_extension(const godot_string *p_self) { memnew_placement(&result, String(self->get_extension())); return result; -}; +} godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos) { const String *self = (const String *)p_self; @@ -867,13 +881,13 @@ godot_string GDAPI godot_string_left(const godot_string *p_self, godot_int p_pos memnew_placement(&result, String(self->left(p_pos))); return result; -}; +} wchar_t GDAPI godot_string_ord_at(const godot_string *p_self, godot_int p_idx) { const String *self = (const String *)p_self; return self->ord_at(p_idx); -}; +} godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godot_string *p_file) { const String *self = (const String *)p_self; @@ -882,7 +896,7 @@ godot_string GDAPI godot_string_plus_file(const godot_string *p_self, const godo memnew_placement(&result, String(self->plus_file(*file))); return result; -}; +} godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_pos) { const String *self = (const String *)p_self; @@ -890,7 +904,7 @@ godot_string GDAPI godot_string_right(const godot_string *p_self, godot_int p_po memnew_placement(&result, String(self->right(p_pos))); return result; -}; +} godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bool p_left, godot_bool p_right) { const String *self = (const String *)p_self; @@ -898,7 +912,7 @@ godot_string GDAPI godot_string_strip_edges(const godot_string *p_self, godot_bo memnew_placement(&result, String(self->strip_edges(p_left, p_right))); return result; -}; +} godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -906,94 +920,96 @@ godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self) { memnew_placement(&result, String(self->strip_escapes())); return result; -}; +} void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars) { String *self = (String *)p_self; return self->erase(p_pos, p_chars); -}; +} -void GDAPI godot_string_ascii(godot_string *p_self, char *result) { - String *self = (String *)p_self; - Vector<char> return_value = self->ascii(); +godot_char_string GDAPI godot_string_ascii(const godot_string *p_self) { + const String *self = (const String *)p_self; + godot_char_string result; - for (int i = 0; i < return_value.size(); i++) { - result[i] = return_value[i]; - } + memnew_placement(&result, CharString(self->ascii())); + + return result; } -void GDAPI godot_string_ascii_extended(godot_string *p_self, char *result) { - String *self = (String *)p_self; - Vector<char> return_value = self->ascii(true); +godot_char_string GDAPI godot_string_ascii_extended(const godot_string *p_self) { + const String *self = (const String *)p_self; - for (int i = 0; i < return_value.size(); i++) { - result[i] = return_value[i]; - } + godot_char_string result; + + memnew_placement(&result, CharString(self->ascii(true))); + + return result; } -void GDAPI godot_string_utf8(godot_string *p_self, char *result) { - String *self = (String *)p_self; - Vector<char> return_value = self->utf8(); +godot_char_string GDAPI godot_string_utf8(const godot_string *p_self) { + const String *self = (const String *)p_self; - for (int i = 0; i < return_value.size(); i++) { - result[i] = return_value[i]; - } + godot_char_string result; + + memnew_placement(&result, CharString(self->utf8())); + + return result; } godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8) { String *self = (String *)p_self; return self->parse_utf8(p_utf8); -}; +} godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len) { String *self = (String *)p_self; return self->parse_utf8(p_utf8, p_len); -}; +} godot_string GDAPI godot_string_chars_to_utf8(const char *p_utf8) { godot_string result; memnew_placement(&result, String(String::utf8(p_utf8))); return result; -}; +} godot_string GDAPI godot_string_chars_to_utf8_with_len(const char *p_utf8, godot_int p_len) { godot_string result; memnew_placement(&result, String(String::utf8(p_utf8, p_len))); return result; -}; +} uint32_t GDAPI godot_string_hash(const godot_string *p_self) { const String *self = (const String *)p_self; return self->hash(); -}; +} uint64_t GDAPI godot_string_hash64(const godot_string *p_self) { const String *self = (const String *)p_self; return self->hash64(); -}; +} uint32_t GDAPI godot_string_hash_chars(const char *p_cstr) { return String::hash(p_cstr); -}; +} uint32_t GDAPI godot_string_hash_chars_with_len(const char *p_cstr, godot_int p_len) { return String::hash(p_cstr, p_len); -}; +} uint32_t GDAPI godot_string_hash_utf8_chars(const wchar_t *p_str) { return String::hash(p_str); -}; +} uint32_t GDAPI godot_string_hash_utf8_chars_with_len(const wchar_t *p_str, godot_int p_len) { return String::hash(p_str, p_len); -}; +} godot_pool_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1010,7 +1026,7 @@ godot_pool_byte_array GDAPI godot_string_md5_buffer(const godot_string *p_self) } return result; -}; +} godot_string GDAPI godot_string_md5_text(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1018,7 +1034,7 @@ godot_string GDAPI godot_string_md5_text(const godot_string *p_self) { memnew_placement(&result, String(self->md5_text())); return result; -}; +} godot_pool_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1035,7 +1051,7 @@ godot_pool_byte_array GDAPI godot_string_sha256_buffer(const godot_string *p_sel } return result; -}; +} godot_string GDAPI godot_string_sha256_text(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1043,13 +1059,13 @@ godot_string GDAPI godot_string_sha256_text(const godot_string *p_self) { memnew_placement(&result, String(self->sha256_text())); return result; -}; +} godot_bool godot_string_empty(const godot_string *p_self) { const String *self = (const String *)p_self; return self->empty(); -}; +} // path functions godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self) { @@ -1059,7 +1075,7 @@ godot_string GDAPI godot_string_get_base_dir(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_get_file(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1068,7 +1084,7 @@ godot_string GDAPI godot_string_get_file(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_humanize_size(size_t p_size) { godot_string result; @@ -1076,25 +1092,25 @@ godot_string GDAPI godot_string_humanize_size(size_t p_size) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_bool GDAPI godot_string_is_abs_path(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_abs_path(); -}; +} godot_bool GDAPI godot_string_is_rel_path(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_rel_path(); -}; +} godot_bool GDAPI godot_string_is_resource_file(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_resource_file(); -}; +} godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_string *p_path) { const String *self = (const String *)p_self; @@ -1104,7 +1120,7 @@ godot_string GDAPI godot_string_path_to(const godot_string *p_self, const godot_ memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const godot_string *p_path) { const String *self = (const String *)p_self; @@ -1114,7 +1130,7 @@ godot_string GDAPI godot_string_path_to_file(const godot_string *p_self, const g memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_simplify_path(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1123,7 +1139,7 @@ godot_string GDAPI godot_string_simplify_path(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_c_escape(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1132,7 +1148,7 @@ godot_string GDAPI godot_string_c_escape(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1141,7 +1157,7 @@ godot_string GDAPI godot_string_c_escape_multiline(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_c_unescape(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1150,7 +1166,7 @@ godot_string GDAPI godot_string_c_unescape(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_http_escape(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1159,7 +1175,7 @@ godot_string GDAPI godot_string_http_escape(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_http_unescape(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1168,7 +1184,7 @@ godot_string GDAPI godot_string_http_unescape(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_json_escape(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1177,7 +1193,7 @@ godot_string GDAPI godot_string_json_escape(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_word_wrap(const godot_string *p_self, godot_int p_chars_per_line) { const String *self = (const String *)p_self; @@ -1186,7 +1202,7 @@ godot_string GDAPI godot_string_word_wrap(const godot_string *p_self, godot_int memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_xml_escape(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1195,7 +1211,7 @@ godot_string GDAPI godot_string_xml_escape(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1204,7 +1220,7 @@ godot_string GDAPI godot_string_xml_escape_with_quotes(const godot_string *p_sel memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1213,7 +1229,7 @@ godot_string GDAPI godot_string_xml_unescape(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_percent_decode(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1222,7 +1238,7 @@ godot_string GDAPI godot_string_percent_decode(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_string GDAPI godot_string_percent_encode(const godot_string *p_self) { const String *self = (const String *)p_self; @@ -1231,43 +1247,43 @@ godot_string GDAPI godot_string_percent_encode(const godot_string *p_self) { memnew_placement(&result, String(return_value)); return result; -}; +} godot_bool GDAPI godot_string_is_valid_float(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_valid_float(); -}; +} godot_bool GDAPI godot_string_is_valid_hex_number(const godot_string *p_self, godot_bool p_with_prefix) { const String *self = (const String *)p_self; return self->is_valid_hex_number(p_with_prefix); -}; +} godot_bool GDAPI godot_string_is_valid_html_color(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_valid_html_color(); -}; +} godot_bool GDAPI godot_string_is_valid_identifier(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_valid_identifier(); -}; +} godot_bool GDAPI godot_string_is_valid_integer(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_valid_integer(); -}; +} godot_bool GDAPI godot_string_is_valid_ip_address(const godot_string *p_self) { const String *self = (const String *)p_self; return self->is_valid_ip_address(); -}; +} #ifdef __cplusplus } diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp index 9bd8c99612..715f2e3c08 100644 --- a/modules/gdnative/gdnative/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -63,7 +63,7 @@ godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self) { return dest; } -void GDAPI godot_transform_set_basis(godot_transform *p_self, godot_basis *p_v) { +void GDAPI godot_transform_set_basis(godot_transform *p_self, const godot_basis *p_v) { Transform *self = (Transform *)p_self; const Basis *v = (const Basis *)p_v; self->basis = *v; @@ -76,7 +76,7 @@ godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self) { return dest; } -void GDAPI godot_transform_set_origin(godot_transform *p_self, godot_vector3 *p_v) { +void GDAPI godot_transform_set_origin(godot_transform *p_self, const godot_vector3 *p_v) { Transform *self = (Transform *)p_self; const Vector3 *v = (const Vector3 *)p_v; self->origin = *v; diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 06c6e9f410..6e3cf16758 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -3516,7 +3516,7 @@ "return_type": "void", "arguments": [ ["godot_transform *", "p_self"], - ["godot_basis *", "p_v"] + ["const godot_basis *", "p_v"] ] }, { @@ -3531,7 +3531,7 @@ "return_type": "void", "arguments": [ ["godot_transform *", "p_self"], - ["godot_vector3 *", "p_v"] + ["const godot_vector3 *", "p_v"] ] }, { @@ -4324,45 +4324,48 @@ ] }, { - "name": "godot_string_new", - "return_type": "void", + "name": "godot_char_string_length", + "return_type": "godot_int", "arguments": [ - ["godot_string *", "r_dest"] + ["const godot_char_string *", "p_cs"] ] }, { - "name": "godot_string_new_copy", + "name": "godot_char_string_get_data", + "return_type": "const char *", + "arguments": [ + ["const godot_char_string *", "p_cs"] + ] + }, + { + "name": "godot_char_string_destroy", "return_type": "void", "arguments": [ - ["godot_string *", "r_dest"], - ["const godot_string *", "p_src"] + ["godot_char_string *", "p_cs"] ] }, { - "name": "godot_string_new_data", + "name": "godot_string_new", "return_type": "void", "arguments": [ - ["godot_string *", "r_dest"], - ["const char *", "p_contents"], - ["const int", "p_size"] + ["godot_string *", "r_dest"] ] }, { - "name": "godot_string_new_unicode_data", + "name": "godot_string_new_copy", "return_type": "void", "arguments": [ ["godot_string *", "r_dest"], - ["const wchar_t *", "p_contents"], - ["const int", "p_size"] + ["const godot_string *", "p_src"] ] }, { - "name": "godot_string_get_data", + "name": "godot_string_new_with_wide_string", "return_type": "void", "arguments": [ - ["const godot_string *", "p_self"], - ["char *", "p_dest"], - ["int *", "p_size"] + ["godot_string *", "r_dest"], + ["const wchar_t *", "p_contents"], + ["const int", "p_size"] ] }, { @@ -4382,7 +4385,7 @@ ] }, { - "name": "godot_string_unicode_str", + "name": "godot_string_wide_str", "return_type": "const wchar_t *", "arguments": [ ["const godot_string *", "p_self"] @@ -4420,6 +4423,30 @@ ] }, { + "name": "godot_string_casecmp_to", + "return_type": "signed char", + "arguments": [ + ["const godot_string *", "p_self"], + ["const godot_string *", "p_str"] + ] + }, + { + "name": "godot_string_nocasecmp_to", + "return_type": "signed char", + "arguments": [ + ["const godot_string *", "p_self"], + ["const godot_string *", "p_str"] + ] + }, + { + "name": "godot_string_naturalnocasecmp_to", + "return_type": "signed char", + "arguments": [ + ["const godot_string *", "p_self"], + ["const godot_string *", "p_str"] + ] + }, + { "name": "godot_string_begins_with", "return_type": "godot_bool", "arguments": [ @@ -5125,26 +5152,23 @@ }, { "name": "godot_string_ascii", - "return_type": "void", + "return_type": "godot_char_string", "arguments": [ - ["godot_string *", "p_self"], - ["char *", "result"] + ["const godot_string *", "p_self"] ] }, { "name": "godot_string_ascii_extended", - "return_type": "void", + "return_type": "godot_char_string", "arguments": [ - ["godot_string *", "p_self"], - ["char *", "result"] + ["const godot_string *", "p_self"] ] }, { "name": "godot_string_utf8", - "return_type": "void", + "return_type": "godot_char_string", "arguments": [ - ["godot_string *", "p_self"], - ["char *", "result"] + ["const godot_string *", "p_self"] ] }, { diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h index 080c0aa171..73245160c1 100644 --- a/modules/gdnative/include/gdnative/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -38,13 +38,24 @@ extern "C" { #include <stdint.h> #include <wchar.h> +typedef wchar_t godot_char_type; + #define GODOT_STRING_SIZE sizeof(void *) +#define GODOT_CHAR_STRING_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED #define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED typedef struct { uint8_t _dont_touch_that[GODOT_STRING_SIZE]; } godot_string; + +#endif + +#ifndef GODOT_CORE_API_GODOT_CHAR_STRING_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_CHAR_STRING_TYPE_DEFINED +typedef struct { + uint8_t _dont_touch_that[GODOT_CHAR_STRING_SIZE]; +} godot_char_string; #endif // reduce extern "C" nesting for VS2013 @@ -60,16 +71,17 @@ typedef struct { extern "C" { #endif +godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs); +const char GDAPI *godot_char_string_get_data(const godot_char_string *p_cs); +void GDAPI godot_char_string_destroy(godot_char_string *p_cs); + void GDAPI godot_string_new(godot_string *r_dest); void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src); -void GDAPI godot_string_new_data(godot_string *r_dest, const char *p_contents, const int p_size); -void GDAPI godot_string_new_unicode_data(godot_string *r_dest, const wchar_t *p_contents, const int p_size); - -void GDAPI godot_string_get_data(const godot_string *p_self, char *p_dest, int *p_size); +void GDAPI godot_string_new_with_wide_string(godot_string *r_dest, const wchar_t *p_contents, const int p_size); wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx); wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx); -const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_self); +const wchar_t GDAPI *godot_string_wide_str(const godot_string *p_self); godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b); godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b); @@ -81,6 +93,10 @@ godot_int GDAPI godot_string_length(const godot_string *p_self); /* Helpers */ +signed char GDAPI godot_string_casecmp_to(const godot_string *p_self, const godot_string *p_str); +signed char GDAPI godot_string_nocasecmp_to(const godot_string *p_self, const godot_string *p_str); +signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, const godot_string *p_str); + godot_bool GDAPI godot_string_begins_with(const godot_string *p_self, const godot_string *p_string); godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self, const char *p_char_array); godot_array GDAPI godot_string_bigrams(const godot_string *p_self); @@ -177,9 +193,9 @@ godot_string GDAPI godot_string_strip_escapes(const godot_string *p_self); void GDAPI godot_string_erase(godot_string *p_self, godot_int p_pos, godot_int p_chars); -void GDAPI godot_string_ascii(godot_string *p_self, char *result); -void GDAPI godot_string_ascii_extended(godot_string *p_self, char *result); -void GDAPI godot_string_utf8(godot_string *p_self, char *result); +godot_char_string GDAPI godot_string_ascii(const godot_string *p_self); +godot_char_string GDAPI godot_string_ascii_extended(const godot_string *p_self); +godot_char_string GDAPI godot_string_utf8(const godot_string *p_self); godot_bool GDAPI godot_string_parse_utf8(godot_string *p_self, const char *p_utf8); godot_bool GDAPI godot_string_parse_utf8_with_len(godot_string *p_self, const char *p_utf8, godot_int p_len); godot_string GDAPI godot_string_chars_to_utf8(const char *p_utf8); diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform.h index 10a242b205..a646da146a 100644 --- a/modules/gdnative/include/gdnative/transform.h +++ b/modules/gdnative/include/gdnative/transform.h @@ -64,10 +64,10 @@ void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const g void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin); godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self); -void GDAPI godot_transform_set_basis(godot_transform *p_self, godot_basis *p_v); +void GDAPI godot_transform_set_basis(godot_transform *p_self, const godot_basis *p_v); godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self); -void GDAPI godot_transform_set_origin(godot_transform *p_self, godot_vector3 *p_v); +void GDAPI godot_transform_set_origin(godot_transform *p_self, const godot_vector3 *p_v); godot_string GDAPI godot_transform_as_string(const godot_transform *p_self); diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 2405afc677..8101ebc6f3 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -45,7 +45,11 @@ void PluginScriptLanguage::init() { } String PluginScriptLanguage::get_type() const { - return String(_desc.type); + // We should use _desc.type here, however the returned type is used to + // query ClassDB which would complain given the type is not registered + // from his point of view... + // To solve this we just use a more generic (but present in ClassDB) type. + return String("PluginScript"); } String PluginScriptLanguage::get_extension() const { @@ -168,7 +172,7 @@ Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_ for (int i = 0; i < options.size(); i++) { r_options->push_back(String(options[i])); } - Error err = *(Error *)tmp; + Error err = *(Error *)&tmp; return err; } return ERR_UNAVAILABLE; diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 228c7dc56f..4e3ee4d22c 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -705,7 +705,7 @@ bool GDScript::_set(const StringName &p_name, const Variant &p_value) { void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const { - p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } void GDScript::_bind_methods() { diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index b5bbaa6dc9..9566e3b32e 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -349,7 +349,9 @@ public: csi.resize(_debug_call_stack_pos); for (int i = 0; i < _debug_call_stack_pos; i++) { csi[_debug_call_stack_pos - i - 1].line = _call_stack[i].line ? *_call_stack[i].line : 0; - csi[_debug_call_stack_pos - i - 1].script = Ref<GDScript>(_call_stack[i].function->get_script()); + if (_call_stack[i].function) + csi[_debug_call_stack_pos - i - 1].func = _call_stack[i].function->get_name(); + csi[_debug_call_stack_pos - i - 1].file = _call_stack[i].function->get_script()->get_path(); } return csi; } diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index c30c6d77b9..f814304180 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -67,34 +67,6 @@ The orientation of the cell at the grid-based X, Y and Z coordinates. -1 is retuned if the cell is empty. </description> </method> - <method name="get_cell_size" qualifiers="const"> - <return type="Vector3"> - </return> - <description> - The dimensions of the grid's cells. - </description> - </method> - <method name="get_center_x" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns whether or not grid items are centered on the X axis. - </description> - </method> - <method name="get_center_y" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns whether or not grid items are centered on the Y axis. - </description> - </method> - <method name="get_center_z" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns whether or not grid items are centered on the Z axis. - </description> - </method> <method name="get_collision_layer_bit" qualifiers="const"> <return type="bool"> </return> @@ -118,20 +90,6 @@ Array of [Transform] and [Mesh] references corresponding to the non empty cells in the grid. The transforms are specified in world space. </description> </method> - <method name="get_octant_size" qualifiers="const"> - <return type="int"> - </return> - <description> - The size of each octant measured in number of cells. This applies to all three axis. - </description> - </method> - <method name="get_theme" qualifiers="const"> - <return type="MeshLibrary"> - </return> - <description> - The assigned [MeshLibrary]. - </description> - </method> <method name="get_used_cells" qualifiers="const"> <return type="Array"> </return> @@ -188,42 +146,6 @@ Optionally, the item's orientation can be passed. </description> </method> - <method name="set_cell_size"> - <return type="void"> - </return> - <argument index="0" name="size" type="Vector3"> - </argument> - <description> - Sets the height, width and depth of the grid's cells. - </description> - </method> - <method name="set_center_x"> - <return type="void"> - </return> - <argument index="0" name="enable" type="bool"> - </argument> - <description> - Set grid items to be centered on the X axis. By default it is enabled. - </description> - </method> - <method name="set_center_y"> - <return type="void"> - </return> - <argument index="0" name="enable" type="bool"> - </argument> - <description> - Set grid items to be centered on the Y axis. By default it is enabled. - </description> - </method> - <method name="set_center_z"> - <return type="void"> - </return> - <argument index="0" name="enable" type="bool"> - </argument> - <description> - Set grid items to be centered on the Z axis. By default it is enabled. - </description> - </method> <method name="set_clip"> <return type="void"> </return> @@ -258,24 +180,6 @@ <description> </description> </method> - <method name="set_octant_size"> - <return type="void"> - </return> - <argument index="0" name="size" type="int"> - </argument> - <description> - Sets the size for each octant measured in number of cells. This applies to all three axis. - </description> - </method> - <method name="set_theme"> - <return type="void"> - </return> - <argument index="0" name="theme" type="MeshLibrary"> - </argument> - <description> - Sets the collection of meshes for the map. - </description> - </method> <method name="world_to_map" qualifiers="const"> <return type="Vector3"> </return> @@ -286,10 +190,30 @@ </method> </methods> <members> + <member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x"> + If [code]true[/code] grid items are centered on the X axis. + </member> + <member name="cell_center_y" type="bool" setter="set_center_y" getter="get_center_y"> + If [code]true[/code] grid items are centered on the Y axis. + </member> + <member name="cell_center_z" type="bool" setter="set_center_z" getter="get_center_z"> + If [code]true[/code] grid items are centered on the Z axis. + </member> + <member name="cell_octant_size" type="int" setter="set_octant_size" getter="get_octant_size"> + The size of each octant measured in number of cells. This applies to all three axis. + </member> + <member name="cell_scale" type="float" setter="set_cell_scale" getter="get_cell_scale"> + </member> + <member name="cell_size" type="Vector3" setter="set_cell_size" getter="get_cell_size"> + The dimensions of the grid's cells. + </member> <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer"> </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"> + The assigned [MeshLibrary]. + </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 e8e9419af8..234a59e516 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -43,28 +43,7 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; - if (name == "theme") { - - set_theme(p_value); - } else if (name == "cell_size") { - if (p_value.get_type() == Variant::INT || p_value.get_type() == Variant::REAL) { - //compatibility - float cs = p_value; - set_cell_size(Vector3(cs, cs, cs)); - } else { - set_cell_size(p_value); - } - } else if (name == "cell_octant_size") { - set_octant_size(p_value); - } else if (name == "cell_center_x") { - set_center_x(p_value); - } else if (name == "cell_center_y") { - set_center_y(p_value); - } else if (name == "cell_center_z") { - set_center_z(p_value); - } else if (name == "cell_scale") { - set_cell_scale(p_value); - /* } else if (name=="cells") { + /* } else if (name=="cells") { PoolVector<int> cells = p_value; int amount=cells.size(); PoolVector<int>::Read r = cells.read(); @@ -81,7 +60,7 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) { } _recreate_octant_data();*/ - } else if (name == "data") { + if (name == "data") { Dictionary d = p_value; @@ -134,21 +113,7 @@ bool GridMap::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; - if (name == "theme") { - r_ret = get_theme(); - } else if (name == "cell_size") { - r_ret = get_cell_size(); - } else if (name == "cell_octant_size") { - r_ret = get_octant_size(); - } else if (name == "cell_center_x") { - r_ret = get_center_x(); - } else if (name == "cell_center_y") { - r_ret = get_center_y(); - } else if (name == "cell_center_z") { - r_ret = get_center_z(); - } else if (name == "cell_scale") { - r_ret = cell_scale; - } else if (name == "data") { + if (name == "data") { Dictionary d; @@ -184,14 +149,6 @@ bool GridMap::_get(const StringName &p_name, Variant &r_ret) const { void GridMap::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary")); - p_list->push_back(PropertyInfo(Variant::NIL, "Cell", PROPERTY_HINT_NONE, "cell_", PROPERTY_USAGE_GROUP)); - p_list->push_back(PropertyInfo(Variant::VECTOR3, "cell_size")); - p_list->push_back(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1")); - p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_x")); - p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_y")); - p_list->push_back(PropertyInfo(Variant::BOOL, "cell_center_z")); - p_list->push_back(PropertyInfo(Variant::REAL, "cell_scale")); if (baked_meshes.size()) { p_list->push_back(PropertyInfo(Variant::ARRAY, "baked_meshes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE)); } @@ -895,6 +852,9 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_cell_size", "size"), &GridMap::set_cell_size); ClassDB::bind_method(D_METHOD("get_cell_size"), &GridMap::get_cell_size); + ClassDB::bind_method(D_METHOD("set_cell_scale", "scale"), &GridMap::set_cell_scale); + ClassDB::bind_method(D_METHOD("get_cell_scale"), &GridMap::get_cell_scale); + ClassDB::bind_method(D_METHOD("set_octant_size", "size"), &GridMap::set_octant_size); ClassDB::bind_method(D_METHOD("get_octant_size"), &GridMap::get_octant_size); @@ -929,6 +889,14 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_baked_meshes"), &GridMap::clear_baked_meshes); ClassDB::bind_method(D_METHOD("make_baked_meshes", "gen_lightmap_uv", "lightmap_uv_texel_size"), &GridMap::make_baked_meshes, DEFVAL(false), DEFVAL(0.1)); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"), "set_theme", "get_theme"); + ADD_GROUP("Cell", "cell_"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cell_size"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_octant_size", "get_octant_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_x"), "set_center_x", "get_center_x"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_y"), "set_center_y", "get_center_y"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_z"), "set_center_z", "get_center_z"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_scale"), "set_cell_scale", "get_cell_scale"); ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 949c636050..7df2043a62 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -445,6 +445,76 @@ String CSharpLanguage::_get_indentation() const { return "\t"; } +Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() { + + // Printing an error here will result in endless recursion, so we must be careful + + if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_api_assembly() || !GDMonoUtils::mono_cache.corlib_cache_updated) + return Vector<StackInfo>(); + + MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr()); + + MonoBoolean need_file_info = true; + void *ctor_args[1] = { &need_file_info }; + + CACHED_METHOD(System_Diagnostics_StackTrace, ctor_bool)->invoke_raw(stack_trace, ctor_args); + + Vector<StackInfo> si; + si = stack_trace_get_info(stack_trace); + + return si; +} + +Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) { + + // Printing an error here could result in endless recursion, so we must be careful + + MonoObject *exc = NULL; + + GDMonoUtils::StackTrace_GetFrames st_get_frames = CACHED_METHOD_THUNK(System_Diagnostics_StackTrace, GetFrames); + MonoArray *frames = st_get_frames(p_stack_trace, &exc); + + if (exc) { + GDMonoUtils::print_unhandled_exception(exc, true /* fail silently to avoid endless recursion */); + return Vector<StackInfo>(); + } + + int frame_count = mono_array_length(frames); + + if (frame_count <= 0) + return Vector<StackInfo>(); + + GDMonoUtils::DebugUtils_StackFrameInfo get_sf_info = CACHED_METHOD_THUNK(DebuggingUtils, GetStackFrameInfo); + + Vector<StackInfo> si; + si.resize(frame_count); + + for (int i = 0; i < frame_count; i++) { + StackInfo &sif = si[i]; + MonoObject *frame = mono_array_get(frames, MonoObject *, i); + + MonoString *file_name; + int file_line_num; + MonoString *method_decl; + get_sf_info(frame, &file_name, &file_line_num, &method_decl, &exc); + + if (exc) { + GDMonoUtils::print_unhandled_exception(exc, true /* fail silently to avoid endless recursion */); + return Vector<StackInfo>(); + } + + // TODO + // what if the StackFrame method is null (method_decl is empty). should we skip this frame? + // can reproduce with a MissingMethodException on internal calls + + sif.file = GDMonoMarshal::mono_string_to_godot(file_name); + sif.line = file_line_num; + sif.func = GDMonoMarshal::mono_string_to_godot(method_decl); + } + + return si; +} + void CSharpLanguage::frame() { const Ref<MonoGCHandle> &task_scheduler_handle = GDMonoUtils::mono_cache.task_scheduler_handle; @@ -1049,7 +1119,7 @@ bool CSharpInstance::has_method(const StringName &p_method) const { GDMonoClass *top = script->script_class; while (top && top != script->native) { - if (top->has_method(p_method)) { + if (top->has_fetched_method_unknown_params(p_method)) { return true; } @@ -1227,7 +1297,7 @@ ScriptInstance::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) GDMonoClass *top = script->script_class; while (top && top != script->native) { - GDMonoMethod *method = top->get_method(p_method); + GDMonoMethod *method = top->get_fetched_method_unknown_params(p_method); if (method && !method->is_static()) return _member_get_rpc_mode(method); @@ -1610,7 +1680,7 @@ bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) { void CSharpScript::_get_property_list(List<PropertyInfo> *p_properties) const { - p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } void CSharpScript::_bind_methods() { @@ -1848,7 +1918,7 @@ void CSharpScript::set_source_code(const String &p_code) { bool CSharpScript::has_method(const StringName &p_method) const { - return script_class->has_method(p_method); + return script_class->has_fetched_method_unknown_params(p_method); } Error CSharpScript::reload(bool p_keep_state) { diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 171601f3d8..3ce8a9b64e 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -303,7 +303,7 @@ public: /* TODO */ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} /* TODO */ virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} /* TODO */ virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { return ""; } - /* TODO */ virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); } + virtual Vector<StackInfo> debug_get_current_stack_info(); /* PROFILING FUNCTIONS */ /* TODO */ virtual void profiling_start() {} @@ -335,6 +335,8 @@ public: virtual void *alloc_instance_binding_data(Object *p_object); virtual void free_instance_binding_data(void *p_data); + Vector<StackInfo> stack_trace_get_info(MonoObject *p_stack_trace); + CSharpLanguage(); ~CSharpLanguage(); }; diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 2205ac4e98..800e3b723b 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -448,14 +448,14 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo compile_items.push_back(output_file); } - for (Map<StringName, TypeInterface>::Element *E = obj_types.front(); E; E = E->next()) { - const TypeInterface &itype = E->get(); + for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { + const TypeInterface &itype = E.get(); if (itype.api_type == ClassDB::API_EDITOR) continue; - String output_file = path_join(obj_type_dir, E->get().proxy_name + ".cs"); - Error err = _generate_cs_type(E->get(), output_file); + String output_file = path_join(obj_type_dir, itype.proxy_name + ".cs"); + Error err = _generate_cs_type(itype, output_file); if (err == ERR_SKIP) continue; @@ -580,14 +580,14 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir, if (!solution.set_path(p_output_dir)) return ERR_FILE_NOT_FOUND; - for (Map<StringName, TypeInterface>::Element *E = obj_types.front(); E; E = E->next()) { - const TypeInterface &itype = E->get(); + for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { + const TypeInterface &itype = E.get(); if (itype.api_type != ClassDB::API_EDITOR) continue; - String output_file = path_join(obj_type_dir, E->get().proxy_name + ".cs"); - Error err = _generate_cs_type(E->get(), output_file); + String output_file = path_join(obj_type_dir, itype.proxy_name + ".cs"); + Error err = _generate_cs_type(itype, output_file); if (err == ERR_SKIP) continue; @@ -945,7 +945,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str return ERR_BUG; } - Map<StringName, TypeInterface>::Element *object_itype = obj_types.find("Object"); + OrderedHashMap<StringName, TypeInterface>::Element object_itype = obj_types.find("Object"); if (!object_itype) { ERR_PRINT("BUG: Object type interface not found!"); @@ -953,7 +953,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } output.push_back(MEMBER_BEGIN "public " CS_CLASS_SIGNALAWAITER " ToSignal("); - output.push_back(object_itype->get().cs_type); + 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); } @@ -999,9 +999,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte // Search it in base types too const TypeInterface *current_type = &p_itype; while (!setter && current_type->base_name != StringName()) { - Map<StringName, TypeInterface>::Element *base_match = obj_types.find(current_type->base_name); - ERR_FAIL_NULL_V(base_match, ERR_BUG); - current_type = &base_match->get(); + OrderedHashMap<StringName, TypeInterface>::Element base_match = obj_types.find(current_type->base_name); + ERR_FAIL_COND_V(!base_match, ERR_BUG); + current_type = &base_match.get(); setter = current_type->find_method_by_name(p_iprop.setter); } @@ -1010,9 +1010,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte // Search it in base types too current_type = &p_itype; while (!getter && current_type->base_name != StringName()) { - Map<StringName, TypeInterface>::Element *base_match = obj_types.find(current_type->base_name); - ERR_FAIL_NULL_V(base_match, ERR_BUG); - current_type = &base_match->get(); + OrderedHashMap<StringName, TypeInterface>::Element base_match = obj_types.find(current_type->base_name); + ERR_FAIL_COND_V(!base_match, ERR_BUG); + current_type = &base_match.get(); getter = current_type->find_method_by_name(p_iprop.getter); } @@ -1324,8 +1324,8 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { generated_icall_funcs.clear(); - for (Map<StringName, TypeInterface>::Element *type_elem = obj_types.front(); type_elem; type_elem = type_elem->next()) { - const TypeInterface &itype = type_elem->get(); + for (OrderedHashMap<StringName, TypeInterface>::Element type_elem = obj_types.front(); type_elem; type_elem = type_elem.next()) { + const TypeInterface &itype = type_elem.get(); List<InternalCall> &custom_icalls = itype.api_type == ClassDB::API_EDITOR ? editor_custom_icalls : core_custom_icalls; @@ -1631,20 +1631,20 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_null(const StringName &p_cname) { - const Map<StringName, TypeInterface>::Element *match = builtin_types.find(p_cname); + const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_cname); - if (match) - return &match->get(); + if (builtin_type_match) + return &builtin_type_match->get(); - match = obj_types.find(p_cname); + const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_cname); - if (match) - return &match->get(); + if (obj_type_match) + return &obj_type_match.get(); - match = enum_types.find(p_cname); + const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_cname); - if (match) - return &match->get(); + if (enum_match) + return &enum_match->get(); return NULL; } @@ -2484,8 +2484,8 @@ void BindingsGenerator::initialize() { _generate_header_icalls(); - for (Map<StringName, TypeInterface>::Element *E = obj_types.front(); E; E = E->next()) - _generate_method_icalls(E->get()); + 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"]); diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 717a6b7a6b..8929b45cce 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -429,10 +429,11 @@ class BindingsGenerator { static bool verbose_output; + OrderedHashMap<StringName, TypeInterface> obj_types; + Map<StringName, TypeInterface> placeholder_types; Map<StringName, TypeInterface> builtin_types; Map<StringName, TypeInterface> enum_types; - Map<StringName, TypeInterface> obj_types; List<EnumInterface> global_enums; List<ConstantInterface> global_constants; diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index da0a7b4fbd..9e48da68c1 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -151,7 +151,7 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int if (p_line >= 0) { args.push_back("-g"); - args.push_back(script_path + ":" + itos(p_line) + ":" + itos(p_col)); + args.push_back(script_path + ":" + itos(p_line + 1) + ":" + itos(p_col)); } else { args.push_back(script_path); } @@ -170,6 +170,11 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int monodevel_instance = memnew(MonoDevelopInstance(GodotSharpDirs::get_project_sln_path())); String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path()); + + if (p_line >= 0) { + script_path += ";" + itos(p_line + 1) + ";" + itos(p_col); + } + monodevel_instance->execute(script_path); } break; default: diff --git a/modules/mono/editor/monodevelop_instance.cpp b/modules/mono/editor/monodevelop_instance.cpp index 0b0b36e1e3..48a285561d 100644 --- a/modules/mono/editor/monodevelop_instance.cpp +++ b/modules/mono/editor/monodevelop_instance.cpp @@ -35,6 +35,8 @@ void MonoDevelopInstance::execute(const Vector<String> &p_files) { + _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) + ERR_FAIL_NULL(execute_method); ERR_FAIL_COND(gc_handle.is_null()); diff --git a/modules/mono/glue/cs_files/Color.cs b/modules/mono/glue/cs_files/Color.cs index db0e1fb744..f9e31e9703 100644 --- a/modules/mono/glue/cs_files/Color.cs +++ b/modules/mono/glue/cs_files/Color.cs @@ -336,7 +336,7 @@ namespace Godot this.r = (rgba & 0xFF) / 255.0f; } - private static float _parse_col(string str, int ofs) + private static int _parse_col(string str, int ofs) { int ig = 0; @@ -415,17 +415,17 @@ namespace Godot if (alpha) { - if ((int)_parse_col(color, 0) < 0) + if (_parse_col(color, 0) < 0) return false; } int from = alpha ? 2 : 0; - if ((int)_parse_col(color, from + 0) < 0) + if (_parse_col(color, from + 0) < 0) return false; - if ((int)_parse_col(color, from + 2) < 0) + if (_parse_col(color, from + 2) < 0) return false; - if ((int)_parse_col(color, from + 4) < 0) + if (_parse_col(color, from + 4) < 0) return false; return true; @@ -467,10 +467,10 @@ namespace Godot if (alpha) { - a = _parse_col(rgba, 0); + a = _parse_col(rgba, 0) / 255f; if (a < 0) - throw new ArgumentOutOfRangeException("Invalid color code. Alpha is " + a + " but zero or greater is expected: " + rgba); + throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba); } else { @@ -479,20 +479,20 @@ namespace Godot int from = alpha ? 2 : 0; - r = _parse_col(rgba, from + 0); + r = _parse_col(rgba, from + 0) / 255f; if (r < 0) - throw new ArgumentOutOfRangeException("Invalid color code. Red is " + r + " but zero or greater is expected: " + rgba); + throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba); - g = _parse_col(rgba, from + 2); + g = _parse_col(rgba, from + 2) / 255f; if (g < 0) - throw new ArgumentOutOfRangeException("Invalid color code. Green is " + g + " but zero or greater is expected: " + rgba); + throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba); - b = _parse_col(rgba, from + 4); + b = _parse_col(rgba, from + 4) / 255f; if (b < 0) - throw new ArgumentOutOfRangeException("Invalid color code. Blue is " + b + " but zero or greater is expected: " + rgba); + throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba); } public static bool operator ==(Color left, Color right) diff --git a/modules/mono/glue/cs_files/DebuggingUtils.cs b/modules/mono/glue/cs_files/DebuggingUtils.cs new file mode 100644 index 0000000000..42ca57fbf9 --- /dev/null +++ b/modules/mono/glue/cs_files/DebuggingUtils.cs @@ -0,0 +1,83 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Text; + +namespace Godot +{ + internal static class DebuggingUtils + { + internal static void AppendTypeName(this StringBuilder sb, Type type) + { + if (type.IsPrimitive) + sb.Append(type.Name); + else if (type == typeof(void)) + sb.Append("void"); + else + sb.Append(type.ToString()); + + sb.Append(" "); + } + + public static void GetStackFrameInfo(StackFrame frame, out string fileName, out int fileLineNumber, out string methodDecl) + { + fileName = frame.GetFileName(); + fileLineNumber = frame.GetFileLineNumber(); + + MethodBase methodBase = frame.GetMethod(); + + if (methodBase == null) + { + methodDecl = string.Empty; + return; + } + + StringBuilder sb = new StringBuilder(); + + if (methodBase is MethodInfo methodInfo) + sb.AppendTypeName(methodInfo.ReturnType); + + sb.Append(methodBase.DeclaringType.FullName); + sb.Append("."); + sb.Append(methodBase.Name); + + if (methodBase.IsGenericMethod) + { + Type[] genericParams = methodBase.GetGenericArguments(); + + sb.Append("<"); + + for (int j = 0; j < genericParams.Length; j++) + { + if (j > 0) + sb.Append(", "); + + sb.AppendTypeName(genericParams[j]); + } + + sb.Append(">"); + } + + sb.Append("("); + + bool varArgs = (methodBase.CallingConvention & CallingConventions.VarArgs) != 0; + + ParameterInfo[] parameter = methodBase.GetParameters(); + + for (int i = 0; i < parameter.Length; i++) + { + if (i > 0) + sb.Append(", "); + + if (i == parameter.Length - 1 && varArgs) + sb.Append("params "); + + sb.AppendTypeName(parameter[i].ParameterType); + } + + sb.Append(")"); + + methodDecl = sb.ToString(); + } + } +} diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index d4df7e0cb2..6c07c90f79 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -226,7 +226,7 @@ void GDMono::initialize() { mono_install_unhandled_exception_hook(gdmono_unhandled_exception_hook, NULL); - OS::get_singleton()->print("Mono: ALL IS GOOD\n"); + OS::get_singleton()->print("Mono: INITIALIZED\n"); } #ifndef MONO_GLUE_DISABLED diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index d3315568cb..b826352f02 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -89,11 +89,6 @@ Vector<MonoClassField *> GDMonoClass::get_enum_fields() { } #endif -bool GDMonoClass::has_method(const StringName &p_name) { - - return get_method(p_name) != NULL; -} - bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) { #ifdef DEBUG_ENABLED @@ -225,7 +220,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base methods_fetched = true; } -GDMonoMethod *GDMonoClass::get_method(const StringName &p_name) { +GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p_name) { ERR_FAIL_COND_V(!methods_fetched, NULL); @@ -239,6 +234,11 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name) { return NULL; } +bool GDMonoClass::has_fetched_method_unknown_params(const StringName &p_name) { + + return get_fetched_method_unknown_params(p_name) != NULL; +} + GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) { MethodKey key = MethodKey(p_name, p_params_count); @@ -303,6 +303,8 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class); mono_method_desc_free(desc); + ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, NULL); + return get_method(method); } diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index b6052ac0ed..f5895be144 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -112,7 +112,8 @@ public: Vector<MonoClassField *> get_enum_fields(); #endif - bool has_method(const StringName &p_name); + GDMonoMethod *get_fetched_method_unknown_params(const StringName &p_name); + bool has_fetched_method_unknown_params(const StringName &p_name); bool has_attribute(GDMonoClass *p_attr_class); MonoObject *get_attribute(GDMonoClass *p_attr_class); @@ -120,8 +121,7 @@ public: void fetch_attributes(); void fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base); - GDMonoMethod *get_method(const StringName &p_name); - GDMonoMethod *get_method(const StringName &p_name, int p_params_count); + GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0); GDMonoMethod *get_method(MonoMethod *p_raw_method); GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name); GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count); diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index ff999b36f2..835a4614c1 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -31,6 +31,7 @@ #include "gd_mono_utils.h" #include "os/dir_access.h" +#include "os/os.h" #include "project_settings.h" #include "reference.h" @@ -43,16 +44,20 @@ namespace GDMonoUtils { MonoCache mono_cache; -#define CACHE_AND_CHECK(m_var, m_val) \ - { \ - m_var = m_val; \ - if (!m_var) ERR_PRINT("Mono Cache: Member " #m_var " is null. This is really bad!"); \ +#define CACHE_AND_CHECK(m_var, m_val) \ + { \ + m_var = m_val; \ + if (!m_var) { \ + ERR_EXPLAIN("Mono Cache: Member " #m_var " is null"); \ + ERR_FAIL(); \ + } \ } #define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_class, m_val) #define CACHE_NS_CLASS_AND_CHECK(m_ns, m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_ns##_##m_class, m_val) #define CACHE_RAW_MONO_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.rawclass_##m_class, m_val) #define CACHE_FIELD_AND_CHECK(m_class, m_field, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.field_##m_class##_##m_field, m_val) +#define CACHE_METHOD_AND_CHECK(m_class, m_method, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.method_##m_class##_##m_method, m_val) #define CACHE_METHOD_THUNK_AND_CHECK(m_class, m_method, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.methodthunk_##m_class##_##m_method, m_val) void MonoCache::clear_members() { @@ -72,6 +77,13 @@ void MonoCache::clear_members() { class_String = NULL; class_IntPtr = NULL; +#ifdef DEBUG_ENABLED + class_System_Diagnostics_StackTrace = NULL; + methodthunk_System_Diagnostics_StackTrace_GetFrames = NULL; + method_System_Diagnostics_StackTrace_ctor_bool = NULL; + method_System_Diagnostics_StackTrace_ctor_Exception_bool = NULL; +#endif + rawclass_Dictionary = NULL; class_Vector2 = NULL; @@ -94,6 +106,11 @@ void MonoCache::clear_members() { class_WeakRef = NULL; class_MarshalUtils = NULL; +#ifdef DEBUG_ENABLED + class_DebuggingUtils = NULL; + methodthunk_DebuggingUtils_GetStackFrameInfo = NULL; +#endif + class_ExportAttribute = NULL; field_ExportAttribute_hint = NULL; field_ExportAttribute_hintString = NULL; @@ -119,6 +136,12 @@ void MonoCache::clear_members() { task_scheduler_handle = Ref<MonoGCHandle>(); } +void MonoCache::cleanup() { + + corlib_cache_updated = false; + godot_api_cache_updated = false; +} + #define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class)) void update_corlib_cache() { @@ -137,6 +160,15 @@ void update_corlib_cache() { CACHE_CLASS_AND_CHECK(double, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_double_class())); CACHE_CLASS_AND_CHECK(String, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_string_class())); CACHE_CLASS_AND_CHECK(IntPtr, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_intptr_class())); + +#ifdef DEBUG_ENABLED + CACHE_CLASS_AND_CHECK(System_Diagnostics_StackTrace, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Diagnostics", "StackTrace")); + CACHE_METHOD_THUNK_AND_CHECK(System_Diagnostics_StackTrace, GetFrames, (StackTrace_GetFrames)CACHED_CLASS(System_Diagnostics_StackTrace)->get_method("GetFrames")->get_thunk()); + CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(bool)", true)); + CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true)); +#endif + + mono_cache.corlib_cache_updated = true; } void update_godot_api_cache() { @@ -161,6 +193,10 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(WeakRef, GODOT_API_CLASS(WeakRef)); CACHE_CLASS_AND_CHECK(MarshalUtils, GODOT_API_CLASS(MarshalUtils)); +#ifdef DEBUG_ENABLED + CACHE_CLASS_AND_CHECK(DebuggingUtils, GODOT_API_CLASS(DebuggingUtils)); +#endif + // Attributes CACHE_CLASS_AND_CHECK(ExportAttribute, GODOT_API_CLASS(ExportAttribute)); CACHE_FIELD_AND_CHECK(ExportAttribute, hint, CACHED_CLASS(ExportAttribute)->get_field("hint")); @@ -183,6 +219,10 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, (SignalAwaiter_FailureCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("FailureCallback", 0)->get_thunk()); CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, (GodotTaskScheduler_Activate)GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0)->get_thunk()); +#ifdef DEBUG_ENABLED + CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, (DebugUtils_StackFrameInfo)GODOT_API_CLASS(DebuggingUtils)->get_method("GetStackFrameInfo", 4)->get_thunk()); +#endif + { /* * TODO Right now we only support Dictionary<object, object>. @@ -202,6 +242,8 @@ void update_godot_api_cache() { MonoObject *task_scheduler = mono_object_new(SCRIPTS_DOMAIN, GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); mono_runtime_object_init(task_scheduler); mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler); + + mono_cache.corlib_cache_updated = true; } void clear_cache() { @@ -366,9 +408,50 @@ String get_exception_name_and_message(MonoObject *p_ex) { return res; } -void print_unhandled_exception(MonoObject *p_ex) { - ERR_PRINT(GDMonoUtils::get_exception_name_and_message(p_ex).utf8()); - mono_print_unhandled_exception(p_ex); +void print_unhandled_exception(MonoObject *p_exc) { + print_unhandled_exception(p_exc, false); +} + +void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) { + mono_print_unhandled_exception(p_exc); +#ifdef DEBUG_ENABLED + if (!ScriptDebugger::get_singleton()) + return; + + GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace); + MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr()); + + MonoBoolean need_file_info = true; + void *ctor_args[2] = { p_exc, &need_file_info }; + + MonoObject *unexpected_exc = NULL; + CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc); + + if (unexpected_exc != NULL) { + mono_print_unhandled_exception(unexpected_exc); + + if (p_recursion_caution) { + // Called from CSharpLanguage::get_current_stack_info, + // so printing an error here could result in endless recursion + OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed"); + return; + } else { + ERR_FAIL(); + } + } + + Vector<ScriptLanguage::StackInfo> si; + if (stack_trace != NULL && !p_recursion_caution) + si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); + + String file = si.size() ? si[0].file : __FILE__; + String func = si.size() ? si[0].func : FUNCTION_STR; + int line = si.size() ? si[0].line : __LINE__; + String error_msg = "Unhandled exception"; + String exc_msg = GDMonoUtils::get_exception_name_and_message(p_exc); + + ScriptDebugger::get_singleton()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si); +#endif } } // namespace GDMonoUtils diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 284585856e..2666433170 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -46,13 +46,10 @@ typedef MonoObject *(*MarshalUtils_ArraysToDict)(MonoArray *, MonoArray *, MonoO typedef MonoObject *(*SignalAwaiter_SignalCallback)(MonoObject *, MonoArray **, MonoObject **); typedef MonoObject *(*SignalAwaiter_FailureCallback)(MonoObject *, MonoObject **); typedef MonoObject *(*GodotTaskScheduler_Activate)(MonoObject *, MonoObject **); +typedef MonoArray *(*StackTrace_GetFrames)(MonoObject *, MonoObject **); +typedef void (*DebugUtils_StackFrameInfo)(MonoObject *, MonoString **, int *, MonoString **, MonoObject **); struct MonoCache { - // Format for cached classes in the Godot namespace: class_<Class> - // Macro: CACHED_CLASS(<Class>) - - // Format for cached classes in a different namespace: class_<Namespace>_<Class> - // Macro: CACHED_NS_CLASS(<Namespace>, <Class>) // ----------------------------------------------- // corlib classes @@ -73,6 +70,13 @@ struct MonoCache { GDMonoClass *class_String; GDMonoClass *class_IntPtr; +#ifdef DEBUG_ENABLED + GDMonoClass *class_System_Diagnostics_StackTrace; + StackTrace_GetFrames methodthunk_System_Diagnostics_StackTrace_GetFrames; + GDMonoMethod *method_System_Diagnostics_StackTrace_ctor_bool; + GDMonoMethod *method_System_Diagnostics_StackTrace_ctor_Exception_bool; +#endif + MonoClass *rawclass_Dictionary; // ----------------------------------------------- @@ -96,6 +100,11 @@ struct MonoCache { GDMonoClass *class_WeakRef; GDMonoClass *class_MarshalUtils; +#ifdef DEBUG_ENABLED + GDMonoClass *class_DebuggingUtils; + DebugUtils_StackFrameInfo methodthunk_DebuggingUtils_GetStackFrameInfo; +#endif + GDMonoClass *class_ExportAttribute; GDMonoField *field_ExportAttribute_hint; GDMonoField *field_ExportAttribute_hintString; @@ -120,10 +129,16 @@ struct MonoCache { Ref<MonoGCHandle> task_scheduler_handle; + bool corlib_cache_updated; + bool godot_api_cache_updated; + void clear_members(); - void cleanup() {} + void cleanup(); MonoCache() { + corlib_cache_updated = false; + godot_api_cache_updated = false; + clear_members(); } }; @@ -167,7 +182,8 @@ MonoDomain *create_domain(const String &p_friendly_name); String get_exception_name_and_message(MonoObject *p_ex); -void print_unhandled_exception(MonoObject *p_ex); +void print_unhandled_exception(MonoObject *p_exc); +void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution); } // namespace GDMonoUtils @@ -175,9 +191,9 @@ void print_unhandled_exception(MonoObject *p_ex); #define CACHED_CLASS(m_class) (GDMonoUtils::mono_cache.class_##m_class) #define CACHED_CLASS_RAW(m_class) (GDMonoUtils::mono_cache.class_##m_class->get_mono_ptr()) -#define CACHED_NS_CLASS(m_ns, m_class) (GDMonoUtils::mono_cache.class_##m_ns##_##m_class) #define CACHED_RAW_MONO_CLASS(m_class) (GDMonoUtils::mono_cache.rawclass_##m_class) #define CACHED_FIELD(m_class, m_field) (GDMonoUtils::mono_cache.field_##m_class##_##m_field) +#define CACHED_METHOD(m_class, m_method) (GDMonoUtils::mono_cache.method_##m_class##_##m_method) #define CACHED_METHOD_THUNK(m_class, m_method) (GDMonoUtils::mono_cache.methodthunk_##m_class##_##m_method) #ifdef REAL_T_IS_DOUBLE diff --git a/modules/regex/doc_classes/RegExMatch.xml b/modules/regex/doc_classes/RegExMatch.xml index 0217099ce6..b84a98ff6d 100644 --- a/modules/regex/doc_classes/RegExMatch.xml +++ b/modules/regex/doc_classes/RegExMatch.xml @@ -28,13 +28,6 @@ Returns the number of capturing groups. </description> </method> - <method name="get_names" qualifiers="const"> - <return type="Dictionary"> - </return> - <description> - Returns a dictionary of named groups and its corresponding group number. Only groups with that were matched are included. If multiple groups have the same name, that name would refer to the first matching one. - </description> - </method> <method name="get_start" qualifiers="const"> <return type="int"> </return> @@ -55,21 +48,18 @@ Returns an empty string if the group did not match or doesn't exist. </description> </method> - <method name="get_strings" qualifiers="const"> - <return type="Array"> - </return> - <description> - Returns an [Array] of the match and its capturing groups. - </description> - </method> - <method name="get_subject" qualifiers="const"> - <return type="String"> - </return> - <description> - Returns the source string used with the search pattern to find this matching result. - </description> - </method> </methods> + <members> + <member name="names" type="Dictionary" setter="" getter="get_names"> + A dictionary of named groups and its corresponding group number. Only groups with that were matched are included. If multiple groups have the same name, that name would refer to the first matching one. + </member> + <member name="strings" type="Array" setter="" getter="get_strings"> + An [Array] of the match and its capturing groups. + </member> + <member name="subject" type="String" setter="" getter="get_subject"> + The source string used with the search pattern to find this matching result. + </member> + </members> <constants> </constants> </class> diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index 9bcbc4c4ea..6f2bb46fc8 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -156,6 +156,10 @@ void RegExMatch::_bind_methods() { ClassDB::bind_method(D_METHOD("get_string", "name"), &RegExMatch::get_string, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_start", "name"), &RegExMatch::get_start, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_end", "name"), &RegExMatch::get_end, DEFVAL(0)); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "subject"), "", "get_subject"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "names"), "", "get_names"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "strings"), "", "get_strings"); } void RegEx::_pattern_info(uint32_t what, void *where) const { @@ -343,15 +347,20 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a ERR_FAIL_COND_V(!is_valid(), String()); - String output; - output.resize(p_subject.length()); + // safety_zone is the number of chars we allocate in addition to the number of chars expected in order to + // guard against the PCRE API writing one additional \0 at the end. PCRE's API docs are unclear on whether + // PCRE understands outlength in pcre2_substitute() as counting an implicit additional terminating char or + // not. always allocating one char more than telling PCRE has us on the safe side. + const int safety_zone = 1; + + PCRE2_SIZE olength = p_subject.length() + 1; // space for output string and one terminating \0 character + Vector<CharType> output; + output.resize(olength + safety_zone); uint32_t flags = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH; if (p_all) flags |= PCRE2_SUBSTITUTE_GLOBAL; - PCRE2_SIZE olength = output.length(); - PCRE2_SIZE length = p_subject.length(); if (p_end >= 0 && (uint32_t)p_end < length) length = p_end; @@ -363,15 +372,15 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx); PCRE2_SPTR16 s = (PCRE2_SPTR16)p_subject.c_str(); PCRE2_SPTR16 r = (PCRE2_SPTR16)p_replacement.c_str(); - PCRE2_UCHAR16 *o = (PCRE2_UCHAR16 *)output.c_str(); + PCRE2_UCHAR16 *o = (PCRE2_UCHAR16 *)output.ptrw(); pcre2_match_data_16 *match = pcre2_match_data_create_from_pattern_16(c, gctx); int res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); if (res == PCRE2_ERROR_NOMEMORY) { - output.resize(olength); - o = (PCRE2_UCHAR16 *)output.c_str(); + output.resize(olength + safety_zone); + o = (PCRE2_UCHAR16 *)output.ptrw(); res = pcre2_substitute_16(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); } @@ -388,15 +397,15 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx); PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.c_str(); PCRE2_SPTR32 r = (PCRE2_SPTR32)p_replacement.c_str(); - PCRE2_UCHAR32 *o = (PCRE2_UCHAR32 *)output.c_str(); + PCRE2_UCHAR32 *o = (PCRE2_UCHAR32 *)output.ptrw(); pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx); int res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); if (res == PCRE2_ERROR_NOMEMORY) { - output.resize(olength); - o = (PCRE2_UCHAR32 *)output.c_str(); + output.resize(olength + safety_zone); + o = (PCRE2_UCHAR32 *)output.ptrw(); res = pcre2_substitute_32(c, s, length, p_offset, flags, match, mctx, r, p_replacement.length(), o, &olength); } @@ -407,7 +416,7 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a return String(); } - return output; + return String(output.ptr(), olength); } bool RegEx::is_valid() const { diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index d06bd79460..6a6ee390cc 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -263,8 +263,8 @@ float AudioStreamOGGVorbis::get_loop_offset() const { void AudioStreamOGGVorbis::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamOGGVorbis::set_data); - ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamOGGVorbis::get_data); + ClassDB::bind_method(D_METHOD("_set_data", "data"), &AudioStreamOGGVorbis::set_data); + ClassDB::bind_method(D_METHOD("_get_data"), &AudioStreamOGGVorbis::get_data); ClassDB::bind_method(D_METHOD("set_loop", "enable"), &AudioStreamOGGVorbis::set_loop); ClassDB::bind_method(D_METHOD("has_loop"), &AudioStreamOGGVorbis::has_loop); @@ -272,7 +272,7 @@ void AudioStreamOGGVorbis::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamOGGVorbis::set_loop_offset); ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOGGVorbis::get_loop_offset); - ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data"); + ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "loop_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop_offset", "get_loop_offset"); } diff --git a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml index 4533d59cae..57fcc75887 100644 --- a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml +++ b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml @@ -11,49 +11,13 @@ <demos> </demos> <methods> - <method name="get_data" qualifiers="const"> - <return type="PoolByteArray"> - </return> - <description> - </description> - </method> - <method name="get_loop_offset" qualifiers="const"> - <return type="float"> - </return> - <description> - </description> - </method> - <method name="has_loop" qualifiers="const"> - <return type="bool"> - </return> - <description> - </description> - </method> - <method name="set_data"> - <return type="void"> - </return> - <argument index="0" name="data" type="PoolByteArray"> - </argument> - <description> - </description> - </method> - <method name="set_loop"> - <return type="void"> - </return> - <argument index="0" name="enable" type="bool"> - </argument> - <description> - </description> - </method> - <method name="set_loop_offset"> - <return type="void"> - </return> - <argument index="0" name="seconds" type="float"> - </argument> - <description> - </description> - </method> </methods> + <members> + <member name="loop" type="bool" setter="set_loop" getter="has_loop"> + </member> + <member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset"> + </member> + </members> <constants> </constants> </class> diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index ac1e81859a..58c6d73ab2 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -724,5 +724,5 @@ void VideoStreamTheora::_bind_methods() { ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamTheora::set_file); ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamTheora::get_file); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_file", "get_file"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file"); } diff --git a/modules/visual_script/doc_classes/VisualScriptYield.xml b/modules/visual_script/doc_classes/VisualScriptYield.xml index 72ef586c1f..b42fc027cf 100644 --- a/modules/visual_script/doc_classes/VisualScriptYield.xml +++ b/modules/visual_script/doc_classes/VisualScriptYield.xml @@ -9,22 +9,10 @@ <demos> </demos> <methods> - <method name="get_yield_mode"> - <return type="int" enum="VisualScriptYield.YieldMode"> - </return> - <description> - </description> - </method> - <method name="set_yield_mode"> - <return type="void"> - </return> - <argument index="0" name="mode" type="int" enum="VisualScriptYield.YieldMode"> - </argument> - <description> - </description> - </method> </methods> <members> + <member name="mode" type="int" setter="set_yield_mode" getter="get_yield_mode" enum="VisualScriptYield.YieldMode"> + </member> <member name="wait_time" type="float" setter="set_wait_time" getter="get_wait_time"> </member> </members> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index fd493978e6..5987fdf5da 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -130,7 +130,7 @@ void VisualScriptNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_default_input_values", "values"), &VisualScriptNode::_set_default_input_values); ClassDB::bind_method(D_METHOD("_get_default_input_values"), &VisualScriptNode::_get_default_input_values); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_default_input_values", "_get_default_input_values"); ADD_SIGNAL(MethodInfo("ports_changed")); } @@ -1319,7 +1319,7 @@ void VisualScript::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_data", "data"), &VisualScript::_set_data); ClassDB::bind_method(D_METHOD("_get_data"), &VisualScript::_get_data); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::INT, "id"))); } diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index 130b243715..187c9b0b9e 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -425,7 +425,7 @@ void VisualScriptFunctionCall::_update_method_cache() { #ifdef DEBUG_METHODS_ENABLED - method_cache.return_val = mb->get_argument_info(-1); + method_cache.return_val = mb->get_return_info(); #endif if (mb->is_vararg()) { @@ -546,7 +546,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const if (property.name == "base_type") { if (call_mode != CALL_MODE_INSTANCE) { - property.usage = PROPERTY_USAGE_NOEDITOR; + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } } @@ -739,7 +739,7 @@ void VisualScriptFunctionCall::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "singleton"), "set_singleton", "get_singleton"); ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "argument_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_argument_cache", "_get_argument_cache"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "argument_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_argument_cache", "_get_argument_cache"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "function"), "set_function", "get_function"); //when set, if loaded properly, will override argument count. ADD_PROPERTY(PropertyInfo(Variant::INT, "use_default_args"), "set_use_default_args", "get_use_default_args"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "validate"), "set_validate", "get_validate"); @@ -1350,7 +1350,7 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { if (property.name == "base_type") { if (call_mode != CALL_MODE_INSTANCE) { - property.usage = PROPERTY_USAGE_NOEDITOR; + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } } @@ -1493,7 +1493,7 @@ void VisualScriptPropertySet::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_type_cache", "_get_type_cache"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property"); @@ -2078,7 +2078,7 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { if (property.name == "base_type") { if (call_mode != CALL_MODE_INSTANCE) { - property.usage = PROPERTY_USAGE_NOEDITOR; + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } } @@ -2217,7 +2217,7 @@ void VisualScriptPropertyGet::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_type_cache", "_get_type_cache"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property"); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 1988eb0f5b..e0b4fde237 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -3107,8 +3107,8 @@ void VisualScriptConstructor::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constructor", "constructor"), &VisualScriptConstructor::set_constructor); ClassDB::bind_method(D_METHOD("get_constructor"), &VisualScriptConstructor::get_constructor); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_constructor_type", "get_constructor_type"); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "constructor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_constructor", "get_constructor"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor_type", "get_constructor_type"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "constructor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor", "get_constructor"); } VisualScriptConstructor::VisualScriptConstructor() { @@ -3722,7 +3722,7 @@ void VisualScriptDeconstruct::_bind_methods() { } ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_deconstruct_type", "get_deconstruct_type"); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_elem_cache", "_get_elem_cache"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_elem_cache", "_get_elem_cache"); } VisualScriptDeconstruct::VisualScriptDeconstruct() { diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index e6952d14d7..fac47225bc 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -436,7 +436,7 @@ void VideoStreamWebm::_bind_methods() { ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamWebm::set_file); ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamWebm::get_file); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_file", "get_file"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_file", "get_file"); } void VideoStreamWebm::set_audio_track(int p_track) { |