diff options
Diffstat (limited to 'modules')
58 files changed, 859 insertions, 594 deletions
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index bfb452d109..b004641838 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -80,7 +80,7 @@ void AreaBullet::dispatch_callbacks() { // Reverse order because I've to remove EXIT objects for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - OverlappingObjectData &otherObj = overlappingObjects[i]; + OverlappingObjectData &otherObj = overlappingObjects.write[i]; switch (otherObj.state) { case OVERLAP_STATE_ENTER: @@ -199,13 +199,13 @@ void AreaBullet::add_overlap(CollisionObjectBullet *p_otherObject) { void AreaBullet::put_overlap_as_exit(int p_index) { scratch(); - overlappingObjects[p_index].state = OVERLAP_STATE_EXIT; + overlappingObjects.write[p_index].state = OVERLAP_STATE_EXIT; } void AreaBullet::put_overlap_as_inside(int p_index) { // This check is required to be sure this body was inside if (OVERLAP_STATE_DIRTY == overlappingObjects[p_index].state) { - overlappingObjects[p_index].state = OVERLAP_STATE_INSIDE; + overlappingObjects.write[p_index].state = OVERLAP_STATE_INSIDE; } } diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 1d63318fd7..271cdb0223 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -223,7 +223,7 @@ void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform } void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) { - ShapeWrapper &shp = shapes[p_index]; + ShapeWrapper &shp = shapes.write[p_index]; shp.shape->remove_owner(this); p_shape->add_owner(this); shp.shape = p_shape; @@ -233,8 +233,8 @@ void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) { void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) { ERR_FAIL_INDEX(p_index, get_shape_count()); - shapes[p_index].set_transform(p_transform); - on_shape_changed(shapes[p_index].shape); + shapes.write[p_index].set_transform(p_transform); + on_shape_changed(shapes.write[p_index].shape); } void RigidCollisionObjectBullet::remove_shape(ShapeBullet *p_shape) { @@ -287,7 +287,7 @@ void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_sha const int size = shapes.size(); for (int i = 0; i < size; ++i) { if (shapes[i].shape == p_shape) { - bulletdelete(shapes[i].bt_shape); + bulletdelete(shapes.write[i].bt_shape); } } on_shapes_changed(); @@ -307,7 +307,7 @@ void RigidCollisionObjectBullet::on_shapes_changed() { // Reset shape if required if (force_shape_reset) { for (i = 0; i < shapes_size; ++i) { - shpWrapper = &shapes[i]; + shpWrapper = &shapes.write[i]; bulletdelete(shpWrapper->bt_shape); } force_shape_reset = false; @@ -316,7 +316,7 @@ void RigidCollisionObjectBullet::on_shapes_changed() { // Insert all shapes btVector3 body_scale(get_bt_body_scale()); for (i = 0; i < shapes_size; ++i) { - shpWrapper = &shapes[i]; + shpWrapper = &shapes.write[i]; if (shpWrapper->active) { if (!shpWrapper->bt_shape) { shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape(shpWrapper->scale * body_scale); @@ -334,7 +334,7 @@ void RigidCollisionObjectBullet::on_shapes_changed() { } void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) { - shapes[p_index].active = !p_disabled; + shapes.write[p_index].active = !p_disabled; on_shapes_changed(); } @@ -348,7 +348,7 @@ void RigidCollisionObjectBullet::on_body_scale_changed() { } void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) { - ShapeWrapper &shp = shapes[p_index]; + ShapeWrapper &shp = shapes.write[p_index]; shp.shape->remove_owner(this, p_permanentlyFromThisBody); bulletdelete(shp.bt_shape); } diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 18f8f5f677..81a62edba6 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -158,6 +158,10 @@ Vector3 BulletPhysicsDirectBodyState::get_contact_local_normal(int p_contact_idx return body->collisions[p_contact_idx].hitNormal; } +float BulletPhysicsDirectBodyState::get_contact_impulse(int p_contact_idx) const { + return body->collisions[p_contact_idx].appliedImpulse; +} + int BulletPhysicsDirectBodyState::get_contact_local_shape(int p_contact_idx) const { return body->collisions[p_contact_idx].local_shape; } @@ -179,7 +183,7 @@ int BulletPhysicsDirectBodyState::get_contact_collider_shape(int p_contact_idx) } Vector3 BulletPhysicsDirectBodyState::get_contact_collider_velocity_at_position(int p_contact_idx) const { - RigidBodyBullet::CollisionData &colDat = body->collisions[p_contact_idx]; + RigidBodyBullet::CollisionData &colDat = body->collisions.write[p_contact_idx]; btVector3 hitLocation; G_TO_B(colDat.hitLocalLocation, hitLocation); @@ -224,8 +228,8 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { continue; } - shapes[i].transform = shape_wrapper->transform; - shapes[i].transform.getOrigin() *= owner_scale; + shapes.write[i].transform = shape_wrapper->transform; + shapes.write[i].transform.getOrigin() *= owner_scale; switch (shape_wrapper->shape->get_type()) { case PhysicsServer::SHAPE_SPHERE: case PhysicsServer::SHAPE_BOX: @@ -233,11 +237,11 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { case PhysicsServer::SHAPE_CYLINDER: case PhysicsServer::SHAPE_CONVEX_POLYGON: case PhysicsServer::SHAPE_RAY: { - shapes[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); + shapes.write[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); } break; default: WARN_PRINT("This shape is not supported to be kinematic!"); - shapes[i].shape = NULL; + shapes.write[i].shape = NULL; } } } @@ -245,7 +249,7 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) { for (int i = shapes.size() - 1; 0 <= i; --i) { if (shapes[i].shape) { - bulletdelete(shapes[i].shape); + bulletdelete(shapes.write[i].shape); } } shapes.resize(new_size); @@ -287,7 +291,7 @@ RigidBodyBullet::RigidBodyBullet() : areasWhereIam.resize(maxAreasWhereIam); for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { - areasWhereIam[i] = NULL; + areasWhereIam.write[i] = NULL; } btBody->setSleepingThresholds(0.2, 0.2); } @@ -407,17 +411,18 @@ void RigidBodyBullet::on_collision_checker_start() { collisionsCount = 0; } -bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, int p_other_shape_index, int p_local_shape_index) { +bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) { if (collisionsCount >= maxCollisionsDetection) { return false; } - CollisionData &cd = collisions[collisionsCount]; + CollisionData &cd = collisions.write[collisionsCount]; cd.hitLocalLocation = p_hitLocalLocation; cd.otherObject = p_otherObject; cd.hitWorldLocation = p_hitWorldLocation; cd.hitNormal = p_hitNormal; + cd.appliedImpulse = p_appliedImpulse; cd.other_object_shape = p_other_shape_index; cd.local_shape = p_local_shape_index; @@ -817,15 +822,15 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) { if (NULL == areasWhereIam[i]) { // This area has the highest priority - areasWhereIam[i] = p_area; + areasWhereIam.write[i] = p_area; break; } else { if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) { // The position was found, just shift all elements for (int j = i; j < areaWhereIamCount; ++j) { - areasWhereIam[j + 1] = areasWhereIam[j]; + areasWhereIam.write[j + 1] = areasWhereIam[j]; } - areasWhereIam[i] = p_area; + areasWhereIam.write[i] = p_area; break; } } @@ -849,7 +854,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { if (p_area == areasWhereIam[i]) { // The area was fount, just shift down all elements for (int j = i; j < areaWhereIamCount; ++j) { - areasWhereIam[j] = areasWhereIam[j + 1]; + areasWhereIam.write[j] = areasWhereIam[j + 1]; } wasTheAreaFound = true; break; @@ -862,7 +867,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { } --areaWhereIamCount; - areasWhereIam[areaWhereIamCount] = NULL; // Even if this is not required, I clear the last element to be safe + areasWhereIam.write[areaWhereIamCount] = NULL; // Even if this is not required, I clear the last element to be safe if (PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) { scratch_space_override_modificator(); } diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index 7dbb5cf870..35af3b90d8 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -124,6 +124,7 @@ public: virtual Vector3 get_contact_local_position(int p_contact_idx) const; virtual Vector3 get_contact_local_normal(int p_contact_idx) const; + virtual float get_contact_impulse(int p_contact_idx) const; virtual int get_contact_local_shape(int p_contact_idx) const; virtual RID get_contact_collider(int p_contact_idx) const; @@ -150,6 +151,7 @@ public: Vector3 hitLocalLocation; Vector3 hitWorldLocation; Vector3 hitNormal; + float appliedImpulse; }; struct ForceIntegrationCallback { @@ -252,7 +254,7 @@ public: } bool can_add_collision() { return collisionsCount < maxCollisionsDetection; } - bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, int p_other_shape_index, int p_local_shape_index); + bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index); void assert_no_constraints(); diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 92e7c2df98..e4c1a5f9b5 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -304,7 +304,7 @@ void ConvexPolygonShapeBullet::get_vertices(Vector<Vector3> &out_vertices) { const int n_of_vertices = vertices.size(); out_vertices.resize(n_of_vertices); for (int i = n_of_vertices - 1; 0 <= i; --i) { - B_TO_G(vertices[i], out_vertices[i]); + B_TO_G(vertices[i], out_vertices.write[i]); } } diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index b3680d58db..1686a6e87e 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -90,7 +90,7 @@ void SoftBodyBullet::update_visual_server(SoftBodyVisualServerHandler *p_visual_ const btSoftBody::tNodeArray &nodes(bt_soft_body->m_nodes); const int nodes_count = nodes.size(); - Vector<int> *vs_indices; + const Vector<int> *vs_indices; const void *vertex_position; const void *vertex_normal; @@ -359,7 +359,7 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVecto indices_table.push_back(Vector<int>()); } - indices_table[vertex_id].push_back(vs_vertex_index); + indices_table.write[vertex_id].push_back(vs_vertex_index); vs_indices_to_physics_table.push_back(vertex_id); } } @@ -374,9 +374,9 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVecto PoolVector<Vector3>::Read p_vertices_read = p_vertices.read(); for (int i = 0; i < indices_map_size; ++i) { - bt_vertices[3 * i + 0] = p_vertices_read[indices_table[i][0]].x; - bt_vertices[3 * i + 1] = p_vertices_read[indices_table[i][0]].y; - bt_vertices[3 * i + 2] = p_vertices_read[indices_table[i][0]].z; + bt_vertices.write[3 * i + 0] = p_vertices_read[indices_table[i][0]].x; + bt_vertices.write[3 * i + 1] = p_vertices_read[indices_table[i][0]].y; + bt_vertices.write[3 * i + 2] = p_vertices_read[indices_table[i][0]].z; } } @@ -390,9 +390,9 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVecto PoolVector<int>::Read p_indices_read = p_indices.read(); for (int i = 0; i < triangles_size; ++i) { - bt_triangles[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]]; - bt_triangles[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]]; - bt_triangles[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]]; + bt_triangles.write[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]]; + bt_triangles.write[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]]; + bt_triangles.write[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]]; } } diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 132c3739d6..8454bea4eb 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -686,7 +686,7 @@ void SpaceBullet::check_ghost_overlaps() { /// 1. Reset all states for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) { - AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects[i]; + AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects.write[i]; // This check prevent the overwrite of ENTER state // if this function is called more times before dispatchCallbacks if (otherObj.state != AreaBullet::OVERLAP_STATE_ENTER) { @@ -795,19 +795,20 @@ void SpaceBullet::check_body_collision() { Vector3 collisionWorldPosition; Vector3 collisionLocalPosition; Vector3 normalOnB; + float appliedImpulse = pt.m_appliedImpulse; B_TO_G(pt.m_normalWorldOnB, normalOnB); if (bodyA->can_add_collision()) { B_TO_G(pt.getPositionWorldOnB(), collisionWorldPosition); /// pt.m_localPointB Doesn't report the exact point in local space B_TO_G(pt.getPositionWorldOnB() - contactManifold->getBody1()->getWorldTransform().getOrigin(), collisionLocalPosition); - bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, pt.m_index1, pt.m_index0); + bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, appliedImpulse, pt.m_index1, pt.m_index0); } if (bodyB->can_add_collision()) { B_TO_G(pt.getPositionWorldOnA(), collisionWorldPosition); /// pt.m_localPointA Doesn't report the exact point in local space B_TO_G(pt.getPositionWorldOnA() - contactManifold->getBody0()->getWorldTransform().getOrigin(), collisionLocalPosition); - bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, pt.m_index0, pt.m_index1); + bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, appliedImpulse * -1, pt.m_index0, pt.m_index1); } #ifdef DEBUG_ENABLED diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 006c6462cf..6b86fc2f03 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -164,7 +164,7 @@ public: contactDebugCount = 0; } _FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) { - if (contactDebugCount < contactDebug.size()) contactDebug[contactDebugCount++] = p_contact; + if (contactDebugCount < contactDebug.size()) contactDebug.write[contactDebugCount++] = p_contact; } _FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contactDebug; } _FORCE_INLINE_ int get_debug_contact_count() { return contactDebugCount; } diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 4e6e701bfd..87c2caec0d 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -62,7 +62,7 @@ void CSGBrush::build_from_faces(const PoolVector<Vector3> &p_vertices, const Poo faces.resize(p_vertices.size() / 3); for (int i = 0; i < faces.size(); i++) { - Face &f = faces[i]; + Face &f = faces.write[i]; f.vertices[0] = rv[i * 3 + 0]; f.vertices[1] = rv[i * 3 + 1]; f.vertices[2] = rv[i * 3 + 2]; @@ -101,7 +101,7 @@ void CSGBrush::build_from_faces(const PoolVector<Vector3> &p_vertices, const Poo materials.resize(material_map.size()); for (Map<Ref<Material>, int>::Element *E = material_map.front(); E; E = E->next()) { - materials[E->get()] = E->key(); + materials.write[E->get()] = E->key(); } _regen_face_aabbs(); @@ -111,10 +111,10 @@ void CSGBrush::_regen_face_aabbs() { for (int i = 0; i < faces.size(); i++) { - faces[i].aabb.position = faces[i].vertices[0]; - faces[i].aabb.expand_to(faces[i].vertices[1]); - faces[i].aabb.expand_to(faces[i].vertices[2]); - faces[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision erros + faces.write[i].aabb.position = faces[i].vertices[0]; + faces.write[i].aabb.expand_to(faces[i].vertices[1]); + faces.write[i].aabb.expand_to(faces[i].vertices[2]); + faces.write[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision erros } } @@ -125,7 +125,7 @@ void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform &p_xform) { for (int i = 0; i < faces.size(); i++) { for (int j = 0; j < 3; j++) { - faces[i].vertices[j] = p_xform.xform(p_brush.faces[i].vertices[j]); + faces.write[i].vertices[j] = p_xform.xform(p_brush.faces[i].vertices[j]); } } @@ -341,7 +341,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_ new_edge.points[0] = edges[i].points[0]; new_edge.points[1] = point_idx; new_edge.outer = edges[i].outer; - edges[i].points[0] = point_idx; + edges.write[i].points[0] = point_idx; edges.insert(i, new_edge); i++; //skip newly inserted edge base_edges++; //will need an extra one in the base triangle @@ -637,7 +637,7 @@ void CSGBrushOperation::_add_poly_points(const BuildPoly &p_poly, int p_edge, in int to_point = e.edge_point; int current_edge = e.edge; - edge_process[e.edge] = true; //mark as processed + edge_process.write[e.edge] = true; //mark as processed int limit = p_poly.points.size() * 4; //avoid infinite recursion @@ -708,7 +708,7 @@ void CSGBrushOperation::_add_poly_points(const BuildPoly &p_poly, int p_edge, in prev_point = to_point; to_point = next_point; - edge_process[next_edge] = true; //mark this edge as processed + edge_process.write[next_edge] = true; //mark this edge as processed current_edge = next_edge; limit--; @@ -792,13 +792,13 @@ void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const Build //none processed by default for (int i = 0; i < edge_process.size(); i++) { - edge_process[i] = false; + edge_process.write[i] = false; } //put edges in points, so points can go through them for (int i = 0; i < p_poly.edges.size(); i++) { - vertex_process[p_poly.edges[i].points[0]].push_back(i); - vertex_process[p_poly.edges[i].points[1]].push_back(i); + vertex_process.write[p_poly.edges[i].points[0]].push_back(i); + vertex_process.write[p_poly.edges[i].points[1]].push_back(i); } Vector<PolyPoints> polys; @@ -854,7 +854,7 @@ void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const Build _add_poly_outline(p_poly, p_poly.edges[i].points[0], p_poly.edges[i].points[1], vertex_process, outline); if (outline.size() > 1) { - polys[intersect_poly].holes.push_back(outline); + polys.write[intersect_poly].holes.push_back(outline); } } _add_poly_points(p_poly, i, p_poly.edges[i].points[0], p_poly.edges[i].points[1], vertex_process, edge_process, polys); @@ -953,18 +953,18 @@ void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const Build //duplicate point int insert_at = with_outline_vertex; - polys[i].points.insert(insert_at, polys[i].points[insert_at]); + polys.write[i].points.insert(insert_at, polys[i].points[insert_at]); insert_at++; //insert all others, outline should be backwards (must check) int holesize = polys[i].holes[j].size(); for (int k = 0; k <= holesize; k++) { int idx = (from_hole_vertex + k) % holesize; - polys[i].points.insert(insert_at, polys[i].holes[j][idx]); + polys.write[i].points.insert(insert_at, polys[i].holes[j][idx]); insert_at++; } added_hole = true; - polys[i].holes.remove(j); + polys.write[i].holes.remove(j); break; //got rid of hole, break and continue } } @@ -980,7 +980,7 @@ void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const Build Vector<Vector2> vertices; vertices.resize(polys[i].points.size()); for (int j = 0; j < vertices.size(); j++) { - vertices[j] = p_poly.points[polys[i].points[j]].point; + vertices.write[j] = p_poly.points[polys[i].points[j]].point; } Vector<int> indices = Geometry::triangulate_polygon(vertices); @@ -1267,7 +1267,7 @@ void CSGBrushOperation::MeshMerge::mark_inside_faces() { int intersections = _bvh_count_intersections(bvh, max_depth, max_alloc - 1, center, target, i); if (intersections & 1) { - faces[i].inside = true; + faces.write[i].inside = true; } } } @@ -1419,13 +1419,13 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_A if (mesh_merge.faces[i].inside) continue; for (int j = 0; j < 3; j++) { - result.faces[outside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]]; - result.faces[outside_count].uvs[j] = mesh_merge.faces[i].uvs[j]; + result.faces.write[outside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]]; + result.faces.write[outside_count].uvs[j] = mesh_merge.faces[i].uvs[j]; } - result.faces[outside_count].smooth = mesh_merge.faces[i].smooth; - result.faces[outside_count].invert = mesh_merge.faces[i].invert; - result.faces[outside_count].material = mesh_merge.faces[i].material_idx; + result.faces.write[outside_count].smooth = mesh_merge.faces[i].smooth; + result.faces.write[outside_count].invert = mesh_merge.faces[i].invert; + result.faces.write[outside_count].material = mesh_merge.faces[i].material_idx; outside_count++; } @@ -1451,13 +1451,13 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_A if (!mesh_merge.faces[i].inside) continue; for (int j = 0; j < 3; j++) { - result.faces[inside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]]; - result.faces[inside_count].uvs[j] = mesh_merge.faces[i].uvs[j]; + result.faces.write[inside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]]; + result.faces.write[inside_count].uvs[j] = mesh_merge.faces[i].uvs[j]; } - result.faces[inside_count].smooth = mesh_merge.faces[i].smooth; - result.faces[inside_count].invert = mesh_merge.faces[i].invert; - result.faces[inside_count].material = mesh_merge.faces[i].material_idx; + result.faces.write[inside_count].smooth = mesh_merge.faces[i].smooth; + result.faces.write[inside_count].invert = mesh_merge.faces[i].invert; + result.faces.write[inside_count].material = mesh_merge.faces[i].material_idx; inside_count++; } @@ -1489,19 +1489,19 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_A continue; for (int j = 0; j < 3; j++) { - result.faces[face_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]]; - result.faces[face_count].uvs[j] = mesh_merge.faces[i].uvs[j]; + result.faces.write[face_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]]; + result.faces.write[face_count].uvs[j] = mesh_merge.faces[i].uvs[j]; } if (mesh_merge.faces[i].from_b) { //invert facing of insides of B - SWAP(result.faces[face_count].vertices[1], result.faces[face_count].vertices[2]); - SWAP(result.faces[face_count].uvs[1], result.faces[face_count].uvs[2]); + SWAP(result.faces.write[face_count].vertices[1], result.faces.write[face_count].vertices[2]); + SWAP(result.faces.write[face_count].uvs[1], result.faces.write[face_count].uvs[2]); } - result.faces[face_count].smooth = mesh_merge.faces[i].smooth; - result.faces[face_count].invert = mesh_merge.faces[i].invert; - result.faces[face_count].material = mesh_merge.faces[i].material_idx; + result.faces.write[face_count].smooth = mesh_merge.faces[i].smooth; + result.faces.write[face_count].invert = mesh_merge.faces[i].invert; + result.faces.write[face_count].material = mesh_merge.faces[i].material_idx; face_count++; } @@ -1513,6 +1513,6 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_A //updatelist of materials result.materials.resize(mesh_merge.materials.size()); for (const Map<Ref<Material>, int>::Element *E = mesh_merge.materials.front(); E; E = E->next()) { - result.materials[E->get()] = E->key(); + result.materials.write[E->get()] = E->key(); } } diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index 2150320c4a..3b1ddfe4c0 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -278,8 +278,8 @@ void CSGShapeSpatialGizmo::redraw() { int f = i / 6; for (int j = 0; j < 3; j++) { int j_n = (j + 1) % 3; - lines[i + j * 2 + 0] = r[f * 3 + j]; - lines[i + j * 2 + 1] = r[f * 3 + j_n]; + lines.write[i + j * 2 + 0] = r[f * 3 + j]; + lines.write[i + j * 2 + 1] = r[f * 3 + j_n]; } } } diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 67cc7e1ba2..9f2171a82a 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -177,7 +177,7 @@ void CSGShape::_update_shape() { Vector<int> face_count; face_count.resize(n->materials.size() + 1); for (int i = 0; i < face_count.size(); i++) { - face_count[i] = 0; + face_count.write[i] = 0; } for (int i = 0; i < n->faces.size(); i++) { @@ -200,7 +200,7 @@ void CSGShape::_update_shape() { } } - face_count[idx]++; + face_count.write[idx]++; } Vector<ShapeUpdateSurface> surfaces; @@ -210,18 +210,18 @@ void CSGShape::_update_shape() { //create arrays for (int i = 0; i < surfaces.size(); i++) { - surfaces[i].vertices.resize(face_count[i] * 3); - surfaces[i].normals.resize(face_count[i] * 3); - surfaces[i].uvs.resize(face_count[i] * 3); - surfaces[i].last_added = 0; + surfaces.write[i].vertices.resize(face_count[i] * 3); + surfaces.write[i].normals.resize(face_count[i] * 3); + surfaces.write[i].uvs.resize(face_count[i] * 3); + surfaces.write[i].last_added = 0; if (i != surfaces.size() - 1) { - surfaces[i].material = n->materials[i]; + surfaces.write[i].material = n->materials[i]; } - surfaces[i].verticesw = surfaces[i].vertices.write(); - surfaces[i].normalsw = surfaces[i].normals.write(); - surfaces[i].uvsw = surfaces[i].uvs.write(); + surfaces.write[i].verticesw = surfaces.write[i].vertices.write(); + surfaces.write[i].normalsw = surfaces.write[i].normals.write(); + surfaces.write[i].uvsw = surfaces.write[i].uvs.write(); } //fill arrays @@ -281,7 +281,7 @@ void CSGShape::_update_shape() { surfaces[idx].normalsw[last + order[j]] = normal; } - surfaces[idx].last_added += 3; + surfaces.write[idx].last_added += 3; } } @@ -290,9 +290,9 @@ void CSGShape::_update_shape() { for (int i = 0; i < surfaces.size(); i++) { - surfaces[i].verticesw = PoolVector<Vector3>::Write(); - surfaces[i].normalsw = PoolVector<Vector3>::Write(); - surfaces[i].uvsw = PoolVector<Vector2>::Write(); + surfaces.write[i].verticesw = PoolVector<Vector3>::Write(); + surfaces.write[i].normalsw = PoolVector<Vector3>::Write(); + surfaces.write[i].uvsw = PoolVector<Vector2>::Write(); if (surfaces[i].last_added == 0) continue; diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index 88768829d7..25b7f2472d 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -666,7 +666,7 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer * while (total) { for (size_t i = 0; i < inBufferCount; i++) { int to_copy = MIN(total, int(inBuffers[i].dataLength)); - copymem(&enet->src_compressor_mem[ofs], inBuffers[i].data, to_copy); + copymem(&enet->src_compressor_mem.write[ofs], inBuffers[i].data, to_copy); ofs += to_copy; total -= to_copy; } diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index 116a86b27b..46b2a832f1 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -17,268 +17,19 @@ SConscript("net/SCsub") SConscript("arvr/SCsub") SConscript("pluginscript/SCsub") -def _spaced(e): - return e if e[-1] == '*' else e + ' ' +from platform_methods import run_in_subprocess +import gdnative_builders -def _build_gdnative_api_struct_header(api): - gdnative_api_init_macro = [ - '\textern const godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct;' - ] - - for ext in api['extensions']: - name = ext['name'] - gdnative_api_init_macro.append( - '\textern const godot_gdnative_ext_{0}_api_struct *_gdnative_wrapper_{0}_api_struct;'.format(name)) - - gdnative_api_init_macro.append('\t_gdnative_wrapper_api_struct = options->api_struct;') - gdnative_api_init_macro.append('\tfor (unsigned int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { ') - gdnative_api_init_macro.append('\t\tswitch (_gdnative_wrapper_api_struct->extensions[i]->type) {') - - for ext in api['extensions']: - name = ext['name'] - gdnative_api_init_macro.append( - '\t\t\tcase GDNATIVE_EXT_%s:' % ext['type']) - gdnative_api_init_macro.append( - '\t\t\t\t_gdnative_wrapper_{0}_api_struct = (godot_gdnative_ext_{0}_api_struct *)' - ' _gdnative_wrapper_api_struct->extensions[i];'.format(name)) - gdnative_api_init_macro.append('\t\t\t\tbreak;') - gdnative_api_init_macro.append('\t\t}') - gdnative_api_init_macro.append('\t}') - - out = [ - '/* THIS FILE IS GENERATED DO NOT EDIT */', - '#ifndef GODOT_GDNATIVE_API_STRUCT_H', - '#define GODOT_GDNATIVE_API_STRUCT_H', - '', - '#include <gdnative/gdnative.h>', - '#include <android/godot_android.h>', - '#include <arvr/godot_arvr.h>', - '#include <nativescript/godot_nativescript.h>', - '#include <pluginscript/godot_pluginscript.h>', - '', - '#define GDNATIVE_API_INIT(options) do { \\\n' + ' \\\n'.join(gdnative_api_init_macro) + ' \\\n } while (0)', - '', - '#ifdef __cplusplus', - 'extern "C" {', - '#endif', - '', - 'enum GDNATIVE_API_TYPES {', - '\tGDNATIVE_' + api['core']['type'] + ',' - ] - - for ext in api['extensions']: - out += ['\tGDNATIVE_EXT_' + ext['type'] + ','] - - out += ['};', ''] - - - def generate_extension_struct(name, ext, include_version=True): - ret_val = [] - if ext['next']: - ret_val += generate_extension_struct(name, ext['next']) - - ret_val += [ - 'typedef struct godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct {', - '\tunsigned int type;', - '\tgodot_gdnative_api_version version;', - '\tconst godot_gdnative_api_struct *next;' - ] - - for funcdef in ext['api']: - args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) - ret_val.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args)) - - ret_val += ['} godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct;', ''] - - return ret_val - - - for ext in api['extensions']: - name = ext['name'] - out += generate_extension_struct(name, ext, False) - - out += [ - 'typedef struct godot_gdnative_core_api_struct {', - '\tunsigned int type;', - '\tgodot_gdnative_api_version version;', - '\tconst godot_gdnative_api_struct *next;', - '\tunsigned int num_extensions;', - '\tconst godot_gdnative_api_struct **extensions;', - ] - - for funcdef in api['core']['api']: - args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) - out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args)) - - out += [ - '} godot_gdnative_core_api_struct;', - '', - '#ifdef __cplusplus', - '}', - '#endif', - '', - '#endif // GODOT_GDNATIVE_API_STRUCT_H', - '' - ] - return '\n'.join(out) - -def _build_gdnative_api_struct_source(api): - out = [ - '/* THIS FILE IS GENERATED DO NOT EDIT */', - '', - '#include <gdnative_api_struct.gen.h>', - '' - ] - - def get_extension_struct_name(name, ext, include_version=True): - return 'godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct' - - def get_extension_struct_instance_name(name, ext, include_version=True): - return 'api_extension_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_struct' - - def get_extension_struct_definition(name, ext, include_version=True): - - ret_val = [] - - if ext['next']: - ret_val += get_extension_struct_definition(name, ext['next']) - - ret_val += [ - 'extern const ' + get_extension_struct_name(name, ext, include_version) + ' ' + get_extension_struct_instance_name(name, ext, include_version) + ' = {', - '\tGDNATIVE_EXT_' + ext['type'] + ',', - '\t{' + str(ext['version']['major']) + ', ' + str(ext['version']['minor']) + '},', - '\t' + ('NULL' if not ext['next'] else ('(const godot_gdnative_api_struct *)&' + get_extension_struct_instance_name(name, ext['next']))) + ',' - ] - - for funcdef in ext['api']: - ret_val.append('\t%s,' % funcdef['name']) - - ret_val += ['};\n'] - - return ret_val - - for ext in api['extensions']: - name = ext['name'] - out += get_extension_struct_definition(name, ext, False) - - out += ['', 'const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {'] - - for ext in api['extensions']: - name = ext['name'] - out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,'] - - out += ['};\n'] - - out += [ - 'extern const godot_gdnative_core_api_struct api_struct = {', - '\tGDNATIVE_' + api['core']['type'] + ',', - '\t{' + str(api['core']['version']['major']) + ', ' + str(api['core']['version']['minor']) + '},', - '\tNULL,', - '\t' + str(len(api['extensions'])) + ',', - '\tgdnative_extensions_pointers,', - ] - - for funcdef in api['core']['api']: - out.append('\t%s,' % funcdef['name']) - out.append('};\n') - - return '\n'.join(out) - -def build_gdnative_api_struct(target, source, env): - import json - from collections import OrderedDict - - with open(source[0].path, 'r') as fd: - api = json.load(fd) - - header, source = target - with open(header.path, 'w') as fd: - fd.write(_build_gdnative_api_struct_header(api)) - with open(source.path, 'w') as fd: - fd.write(_build_gdnative_api_struct_source(api)) _, gensource = gdn_env.CommandNoCache(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'], - 'gdnative_api.json', build_gdnative_api_struct) + 'gdnative_api.json', run_in_subprocess(gdnative_builders.build_gdnative_api_struct)) gdn_env.add_source_files(env.modules_sources, [gensource]) env.use_ptrcall = True -def _build_gdnative_wrapper_code(api): - out = [ - '/* THIS FILE IS GENERATED DO NOT EDIT */', - '', - '#include <gdnative/gdnative.h>', - '#include <nativescript/godot_nativescript.h>', - '#include <pluginscript/godot_pluginscript.h>', - '#include <arvr/godot_arvr.h>', - '', - '#include <gdnative_api_struct.gen.h>', - '', - '#ifdef __cplusplus', - 'extern "C" {', - '#endif', - '', - 'godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;', - ] - - for ext in api['extensions']: - name = ext['name'] - out.append('godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct = 0;') - - out += [''] - - for funcdef in api['core']['api']: - args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) - out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args)) - - args = ', '.join(['%s' % n for t, n in funcdef['arguments']]) - - return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t' - return_line += '_gdnative_wrapper_api_struct->' + funcdef['name'] + '(' + args + ');' - - out.append(return_line) - out.append('}') - out.append('') - - for ext in api['extensions']: - name = ext['name'] - for funcdef in ext['api']: - args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) - out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args)) - - args = ', '.join(['%s' % n for t, n in funcdef['arguments']]) - - return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t' - return_line += '_gdnative_wrapper_' + name + '_api_struct->' + funcdef['name'] + '(' + args + ');' - - out.append(return_line) - out.append('}') - out.append('') - - out += [ - '#ifdef __cplusplus', - '}', - '#endif' - ] - - return '\n'.join(out) - - -def build_gdnative_wrapper_code(target, source, env): - import json - with open(source[0].path, 'r') as fd: - api = json.load(fd) - - wrapper_file = target[0] - with open(wrapper_file.path, 'w') as fd: - fd.write(_build_gdnative_wrapper_code(api)) - - - if ARGUMENTS.get('gdnative_wrapper', False): -#build wrapper code - gensource, = gdn_env.CommandNoCache('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', build_gdnative_wrapper_code) + gensource, = gdn_env.CommandNoCache('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', run_in_subprocess(gdnative_builders.build_gdnative_wrapper_code)) gd_wrapper_env = env.Clone() gd_wrapper_env.Append(CPPPATH=['#modules/gdnative/include/']) diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp index 385c020a78..b525725107 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp @@ -125,7 +125,7 @@ bool ARVRInterfaceGDNative::is_stereo() { return stereo; } -bool ARVRInterfaceGDNative::is_initialized() { +bool ARVRInterfaceGDNative::is_initialized() const { bool initialized; ERR_FAIL_COND_V(interface == NULL, false); diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.h b/modules/gdnative/arvr/arvr_interface_gdnative.h index e50be6e196..26d0cdf9f4 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.h +++ b/modules/gdnative/arvr/arvr_interface_gdnative.h @@ -59,7 +59,7 @@ public: virtual StringName get_name() const; virtual int get_capabilities() const; - virtual bool is_initialized(); + virtual bool is_initialized() const; virtual bool initialize(); virtual void uninitialize(); diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py index c5b37d35b4..701a13d32f 100644 --- a/modules/gdnative/config.py +++ b/modules/gdnative/config.py @@ -9,9 +9,11 @@ def get_doc_classes(): "ARVRInterfaceGDNative", "GDNative", "GDNativeLibrary", + "MultiplayerPeerGDNative", "NativeScript", "PacketPeerGDNative", "PluginScript", + "StreamPeerGDNative", ] def get_doc_path(): diff --git a/modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml b/modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml new file mode 100644 index 0000000000..4433179726 --- /dev/null +++ b/modules/gdnative/doc_classes/MultiplayerPeerGDNative.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MultiplayerPeerGDNative" inherits="NetworkedMultiplayerPeer" category="Core" version="3.1"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/gdnative/doc_classes/PacketPeerGDNative.xml b/modules/gdnative/doc_classes/PacketPeerGDNative.xml new file mode 100644 index 0000000000..0ae54bc9c7 --- /dev/null +++ b/modules/gdnative/doc_classes/PacketPeerGDNative.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="PacketPeerGDNative" inherits="PacketPeer" category="Core" version="3.1"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/gdnative/doc_classes/StreamPeerGDNative.xml b/modules/gdnative/doc_classes/StreamPeerGDNative.xml new file mode 100644 index 0000000000..d86cd2c25a --- /dev/null +++ b/modules/gdnative/doc_classes/StreamPeerGDNative.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="StreamPeerGDNative" inherits="StreamPeer" category="Core" version="3.1"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index e7ebcc73af..0acd6c27d8 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -277,7 +277,7 @@ void GDNative::set_library(Ref<GDNativeLibrary> p_library) { library = p_library; } -Ref<GDNativeLibrary> GDNative::get_library() { +Ref<GDNativeLibrary> GDNative::get_library() const { return library; } @@ -373,7 +373,7 @@ bool GDNative::initialize() { if (library->should_load_once() && !GDNativeLibrary::loaded_libraries->has(lib_path)) { Vector<Ref<GDNative> > gdnatives; gdnatives.resize(1); - gdnatives[0] = Ref<GDNative>(this); + gdnatives.write[0] = Ref<GDNative>(this); GDNativeLibrary::loaded_libraries->insert(lib_path, gdnatives); } @@ -428,7 +428,7 @@ bool GDNative::terminate() { return true; } -bool GDNative::is_initialized() { +bool GDNative::is_initialized() const { return initialized; } @@ -442,7 +442,7 @@ Vector<StringName> GDNativeCallRegistry::get_native_call_types() { size_t idx = 0; for (Map<StringName, native_call_cb>::Element *E = native_calls.front(); E; E = E->next(), idx++) { - call_types[idx] = E->key(); + call_types.write[idx] = E->key(); } return call_types; @@ -474,7 +474,7 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced return res; } -Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional) { +Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional) const { if (!initialized) { ERR_PRINT("No valid library handle, can't get symbol from GDNative object"); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index b17bb94f1c..148f85723e 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -148,16 +148,16 @@ public: static void _bind_methods(); void set_library(Ref<GDNativeLibrary> p_library); - Ref<GDNativeLibrary> get_library(); + Ref<GDNativeLibrary> get_library() const; - bool is_initialized(); + bool is_initialized() const; bool initialize(); bool terminate(); Variant call_native(StringName p_native_call_type, StringName p_procedure_name, Array p_arguments = Array()); - Error get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional = true); + Error get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional = true) const; }; class GDNativeLibraryResourceLoader : public ResourceFormatLoader { diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 7f5dbc12be..8ca57392a3 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -207,7 +207,7 @@ godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_arra Array *keys_proxy = (Array *)p_keys; keys.resize(keys_proxy->size()); for (int i = 0; i < keys_proxy->size(); i++) { - keys[i] = (*keys_proxy)[i]; + keys.write[i] = (*keys_proxy)[i]; } return self->findmk(keys); @@ -220,7 +220,7 @@ godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot Array *keys_proxy = (Array *)p_keys; keys.resize(keys_proxy->size()); for (int i = 0; i < keys_proxy->size(); i++) { - keys[i] = (*keys_proxy)[i]; + keys.write[i] = (*keys_proxy)[i]; } return self->findmk(keys, p_from); @@ -233,7 +233,7 @@ godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, co Array *keys_proxy = (Array *)p_keys; keys.resize(keys_proxy->size()); for (int i = 0; i < keys_proxy->size(); i++) { - keys[i] = (*keys_proxy)[i]; + keys.write[i] = (*keys_proxy)[i]; } return self->findmk(keys, p_from, r_key); @@ -696,7 +696,7 @@ godot_array GDAPI godot_string_split_floats_mk(const godot_string *p_self, const Array *splitter_proxy = (Array *)p_splitters; splitters.resize(splitter_proxy->size()); for (int i = 0; i < splitter_proxy->size(); i++) { - splitters[i] = (*splitter_proxy)[i]; + splitters.write[i] = (*splitter_proxy)[i]; } godot_array result; @@ -719,7 +719,7 @@ godot_array GDAPI godot_string_split_floats_mk_allows_empty(const godot_string * Array *splitter_proxy = (Array *)p_splitters; splitters.resize(splitter_proxy->size()); for (int i = 0; i < splitter_proxy->size(); i++) { - splitters[i] = (*splitter_proxy)[i]; + splitters.write[i] = (*splitter_proxy)[i]; } godot_array result; @@ -774,7 +774,7 @@ godot_array GDAPI godot_string_split_ints_mk(const godot_string *p_self, const g Array *splitter_proxy = (Array *)p_splitters; splitters.resize(splitter_proxy->size()); for (int i = 0; i < splitter_proxy->size(); i++) { - splitters[i] = (*splitter_proxy)[i]; + splitters.write[i] = (*splitter_proxy)[i]; } godot_array result; @@ -797,7 +797,7 @@ godot_array GDAPI godot_string_split_ints_mk_allows_empty(const godot_string *p_ Array *splitter_proxy = (Array *)p_splitters; splitters.resize(splitter_proxy->size()); for (int i = 0; i < splitter_proxy->size(); i++) { - splitters[i] = (*splitter_proxy)[i]; + splitters.write[i] = (*splitter_proxy)[i]; } godot_array result; diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py new file mode 100644 index 0000000000..8a1cd049af --- /dev/null +++ b/modules/gdnative/gdnative_builders.py @@ -0,0 +1,261 @@ +"""Functions used to generate source files during build time + +All such functions are invoked in a subprocess on Windows to prevent build flakiness. + +""" +import json +from platform_methods import subprocess_main + + +def _spaced(e): + return e if e[-1] == '*' else e + ' ' + + +def _build_gdnative_api_struct_header(api): + gdnative_api_init_macro = [ + '\textern const godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct;' + ] + + for ext in api['extensions']: + name = ext['name'] + gdnative_api_init_macro.append( + '\textern const godot_gdnative_ext_{0}_api_struct *_gdnative_wrapper_{0}_api_struct;'.format(name)) + + gdnative_api_init_macro.append('\t_gdnative_wrapper_api_struct = options->api_struct;') + gdnative_api_init_macro.append('\tfor (unsigned int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { ') + gdnative_api_init_macro.append('\t\tswitch (_gdnative_wrapper_api_struct->extensions[i]->type) {') + + for ext in api['extensions']: + name = ext['name'] + gdnative_api_init_macro.append( + '\t\t\tcase GDNATIVE_EXT_%s:' % ext['type']) + gdnative_api_init_macro.append( + '\t\t\t\t_gdnative_wrapper_{0}_api_struct = (godot_gdnative_ext_{0}_api_struct *)' + ' _gdnative_wrapper_api_struct->extensions[i];'.format(name)) + gdnative_api_init_macro.append('\t\t\t\tbreak;') + gdnative_api_init_macro.append('\t\t}') + gdnative_api_init_macro.append('\t}') + + out = [ + '/* THIS FILE IS GENERATED DO NOT EDIT */', + '#ifndef GODOT_GDNATIVE_API_STRUCT_H', + '#define GODOT_GDNATIVE_API_STRUCT_H', + '', + '#include <gdnative/gdnative.h>', + '#include <android/godot_android.h>', + '#include <arvr/godot_arvr.h>', + '#include <nativescript/godot_nativescript.h>', + '#include <pluginscript/godot_pluginscript.h>', + '', + '#define GDNATIVE_API_INIT(options) do { \\\n' + ' \\\n'.join(gdnative_api_init_macro) + ' \\\n } while (0)', + '', + '#ifdef __cplusplus', + 'extern "C" {', + '#endif', + '', + 'enum GDNATIVE_API_TYPES {', + '\tGDNATIVE_' + api['core']['type'] + ',' + ] + + for ext in api['extensions']: + out += ['\tGDNATIVE_EXT_' + ext['type'] + ','] + + out += ['};', ''] + + def generate_extension_struct(name, ext, include_version=True): + ret_val = [] + if ext['next']: + ret_val += generate_extension_struct(name, ext['next']) + + ret_val += [ + 'typedef struct godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct {', + '\tunsigned int type;', + '\tgodot_gdnative_api_version version;', + '\tconst godot_gdnative_api_struct *next;' + ] + + for funcdef in ext['api']: + args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) + ret_val.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args)) + + ret_val += ['} godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct;', ''] + + return ret_val + + for ext in api['extensions']: + name = ext['name'] + out += generate_extension_struct(name, ext, False) + + out += [ + 'typedef struct godot_gdnative_core_api_struct {', + '\tunsigned int type;', + '\tgodot_gdnative_api_version version;', + '\tconst godot_gdnative_api_struct *next;', + '\tunsigned int num_extensions;', + '\tconst godot_gdnative_api_struct **extensions;', + ] + + for funcdef in api['core']['api']: + args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) + out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args)) + + out += [ + '} godot_gdnative_core_api_struct;', + '', + '#ifdef __cplusplus', + '}', + '#endif', + '', + '#endif // GODOT_GDNATIVE_API_STRUCT_H', + '' + ] + return '\n'.join(out) + + +def _build_gdnative_api_struct_source(api): + out = [ + '/* THIS FILE IS GENERATED DO NOT EDIT */', + '', + '#include <gdnative_api_struct.gen.h>', + '' + ] + + def get_extension_struct_name(name, ext, include_version=True): + return 'godot_gdnative_ext_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_api_struct' + + def get_extension_struct_instance_name(name, ext, include_version=True): + return 'api_extension_' + name + ('' if not include_version else ('_{0}_{1}'.format(ext['version']['major'], ext['version']['minor']))) + '_struct' + + def get_extension_struct_definition(name, ext, include_version=True): + + ret_val = [] + + if ext['next']: + ret_val += get_extension_struct_definition(name, ext['next']) + + ret_val += [ + 'extern const ' + get_extension_struct_name(name, ext, include_version) + ' ' + get_extension_struct_instance_name(name, ext, include_version) + ' = {', + '\tGDNATIVE_EXT_' + ext['type'] + ',', + '\t{' + str(ext['version']['major']) + ', ' + str(ext['version']['minor']) + '},', + '\t' + ('NULL' if not ext['next'] else ('(const godot_gdnative_api_struct *)&' + get_extension_struct_instance_name(name, ext['next']))) + ',' + ] + + for funcdef in ext['api']: + ret_val.append('\t%s,' % funcdef['name']) + + ret_val += ['};\n'] + + return ret_val + + for ext in api['extensions']: + name = ext['name'] + out += get_extension_struct_definition(name, ext, False) + + out += ['', 'const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {'] + + for ext in api['extensions']: + name = ext['name'] + out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,'] + + out += ['};\n'] + + out += [ + 'extern const godot_gdnative_core_api_struct api_struct = {', + '\tGDNATIVE_' + api['core']['type'] + ',', + '\t{' + str(api['core']['version']['major']) + ', ' + str(api['core']['version']['minor']) + '},', + '\tNULL,', + '\t' + str(len(api['extensions'])) + ',', + '\tgdnative_extensions_pointers,', + ] + + for funcdef in api['core']['api']: + out.append('\t%s,' % funcdef['name']) + out.append('};\n') + + return '\n'.join(out) + + +def build_gdnative_api_struct(target, source, env): + + with open(source[0], 'r') as fd: + api = json.load(fd) + + header, source = target + with open(header, 'w') as fd: + fd.write(_build_gdnative_api_struct_header(api)) + with open(source, 'w') as fd: + fd.write(_build_gdnative_api_struct_source(api)) + + +def _build_gdnative_wrapper_code(api): + out = [ + '/* THIS FILE IS GENERATED DO NOT EDIT */', + '', + '#include <gdnative/gdnative.h>', + '#include <nativescript/godot_nativescript.h>', + '#include <pluginscript/godot_pluginscript.h>', + '#include <arvr/godot_arvr.h>', + '', + '#include <gdnative_api_struct.gen.h>', + '', + '#ifdef __cplusplus', + 'extern "C" {', + '#endif', + '', + 'godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;', + ] + + for ext in api['extensions']: + name = ext['name'] + out.append('godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct = 0;') + + out += [''] + + for funcdef in api['core']['api']: + args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) + out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args)) + + args = ', '.join(['%s' % n for t, n in funcdef['arguments']]) + + return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t' + return_line += '_gdnative_wrapper_api_struct->' + funcdef['name'] + '(' + args + ');' + + out.append(return_line) + out.append('}') + out.append('') + + for ext in api['extensions']: + name = ext['name'] + for funcdef in ext['api']: + args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']]) + out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args)) + + args = ', '.join(['%s' % n for t, n in funcdef['arguments']]) + + return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t' + return_line += '_gdnative_wrapper_' + name + '_api_struct->' + funcdef['name'] + '(' + args + ');' + + out.append(return_line) + out.append('}') + out.append('') + + out += [ + '#ifdef __cplusplus', + '}', + '#endif' + ] + + return '\n'.join(out) + + +def build_gdnative_wrapper_code(target, source, env): + with open(source[0], 'r') as fd: + api = json.load(fd) + + wrapper_file = target[0] + with open(wrapper_file, 'w') as fd: + fd.write(_build_gdnative_wrapper_code(api)) + + +if __name__ == '__main__': + subprocess_main(globals()) diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index eb52bede24..23747af86b 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -556,12 +556,17 @@ bool NativeScriptInstance::set(const StringName &p_name, const Variant &p_value) Variant name = p_name; const Variant *args[2] = { &name, &p_value }; - E->get().method.method((godot_object *)owner, + godot_variant result; + result = E->get().method.method((godot_object *)owner, E->get().method.method_data, userdata, 2, (godot_variant **)args); - return true; + bool handled = *(Variant *)&result; + godot_variant_destroy(&result); + if (handled) { + return true; + } } script_data = script_data->base_data; @@ -596,10 +601,9 @@ bool NativeScriptInstance::get(const StringName &p_name, Variant &r_ret) const { (godot_variant **)args); r_ret = *(Variant *)&result; godot_variant_destroy(&result); - if (r_ret.get_type() == Variant::NIL) { - return false; + if (r_ret.get_type() != Variant::NIL) { + return true; } - return true; } script_data = script_data->base_data; @@ -1157,8 +1161,8 @@ int NativeScriptLanguage::register_binding_functions(godot_instance_binding_func } // set the functions - binding_functions[idx].first = true; - binding_functions[idx].second = p_binding_functions; + binding_functions.write[idx].first = true; + binding_functions.write[idx].second = p_binding_functions; return idx; } @@ -1173,7 +1177,7 @@ void NativeScriptLanguage::unregister_binding_functions(int p_idx) { binding_functions[p_idx].second.free_instance_binding_data(binding_functions[p_idx].second.data, binding_data[p_idx]); } - binding_functions[p_idx].first = false; + binding_functions.write[p_idx].first = false; if (binding_functions[p_idx].second.free_func) binding_functions[p_idx].second.free_func(binding_functions[p_idx].second.data); @@ -1199,7 +1203,7 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec binding_data->resize(p_idx + 1); for (int i = old_size; i <= p_idx; i++) { - (*binding_data)[i] = NULL; + (*binding_data).write[i] = NULL; } } @@ -1208,7 +1212,7 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec const void *global_type_tag = global_type_tags[p_idx].get(p_object->get_class_name()); // no binding data yet, soooooo alloc new one \o/ - (*binding_data)[p_idx] = binding_functions[p_idx].second.alloc_instance_binding_data(binding_functions[p_idx].second.data, global_type_tag, (godot_object *)p_object); + (*binding_data).write[p_idx] = binding_functions[p_idx].second.alloc_instance_binding_data(binding_functions[p_idx].second.data, global_type_tag, (godot_object *)p_object); } return (*binding_data)[p_idx]; @@ -1221,7 +1225,7 @@ void *NativeScriptLanguage::alloc_instance_binding_data(Object *p_object) { binding_data->resize(binding_functions.size()); for (int i = 0; i < binding_functions.size(); i++) { - (*binding_data)[i] = NULL; + (*binding_data).write[i] = NULL; } binding_instances.insert(binding_data); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index d18297f2f8..ae1a218392 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -341,10 +341,10 @@ void register_gdnative_types() { Ref<GDNativeLibrary> lib = ResourceLoader::load(path); - singleton_gdnatives[i].instance(); - singleton_gdnatives[i]->set_library(lib); + singleton_gdnatives.write[i].instance(); + singleton_gdnatives.write[i]->set_library(lib); - if (!singleton_gdnatives[i]->initialize()) { + if (!singleton_gdnatives.write[i]->initialize()) { // Can't initialize. Don't make a native_call then continue; } @@ -374,7 +374,7 @@ void unregister_gdnative_types() { continue; } - singleton_gdnatives[i]->terminate(); + singleton_gdnatives.write[i]->terminate(); } singleton_gdnatives.clear(); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 8bd29ffc55..cff3be76ae 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -730,7 +730,7 @@ Error GDScript::load_byte_code(const String &p_path) { Vector<uint8_t> key; key.resize(32); for (int i = 0; i < key.size(); i++) { - key[i] = script_encryption_key[i]; + key.write[i] = script_encryption_key[i]; } Error err = fae->open_and_parse(fa, key, FileAccessEncrypted::MODE_READ); ERR_FAIL_COND_V(err, err); @@ -941,7 +941,7 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { if (!E->get().data_type.is_type(p_value)) { return false; // Type mismatch } - members[E->get().index] = p_value; + members.write[E->get().index] = p_value; } return true; } @@ -1270,7 +1270,7 @@ void GDScriptInstance::reload_members() { if (member_indices_cache.has(E->key())) { Variant value = members[member_indices_cache[E->key()]]; - new_members[E->get().index] = value; + new_members.write[E->get().index] = value; } } @@ -1320,7 +1320,7 @@ void GDScriptLanguage::_add_global(const StringName &p_name, const Variant &p_va if (globals.has(p_name)) { //overwrite existing - global_array[globals[p_name]] = p_value; + global_array.write[globals[p_name]] = p_value; return; } globals[p_name] = global_array.size(); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index d5fe7a000b..79ac9ed413 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -355,10 +355,10 @@ public: Vector<StackInfo> csi; 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.write[_debug_call_stack_pos - i - 1].line = _call_stack[i].line ? *_call_stack[i].line : 0; 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(); + csi.write[_debug_call_stack_pos - i - 1].func = _call_stack[i].function->get_name(); + csi.write[_debug_call_stack_pos - i - 1].file = _call_stack[i].function->get_script()->get_path(); } return csi; } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index a428ccd306..fe393957db 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -140,7 +140,7 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D } break; case GDScriptParser::DataType::CLASS: { result.kind = GDScriptDataType::GDSCRIPT; - if (p_datatype.class_type->name == StringName()) { + if (!p_datatype.class_type->owner) { result.script_type = Ref<GDScript>(main_script); } else { result.script_type = class_map[p_datatype.class_type->name]; @@ -482,7 +482,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: Variant script; int idx = -1; - if (cn->cast_type.class_type->name == StringName()) { + if (!cn->cast_type.class_type->owner) { script = codegen.script; } else { StringName name = cn->cast_type.class_type->name; @@ -785,8 +785,8 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(codegen.opcodes.size() + 3); - codegen.opcodes[jump_fail_pos] = codegen.opcodes.size(); - codegen.opcodes[jump_fail_pos2] = codegen.opcodes.size(); + codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size(); + codegen.opcodes.write[jump_fail_pos2] = codegen.opcodes.size(); codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_FALSE); codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS; @@ -818,8 +818,8 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(codegen.opcodes.size() + 3); - codegen.opcodes[jump_success_pos] = codegen.opcodes.size(); - codegen.opcodes[jump_success_pos2] = codegen.opcodes.size(); + codegen.opcodes.write[jump_success_pos] = codegen.opcodes.size(); + codegen.opcodes.write[jump_success_pos2] = codegen.opcodes.size(); codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TRUE); codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS; @@ -850,7 +850,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: int jump_past_pos = codegen.opcodes.size(); codegen.opcodes.push_back(0); - codegen.opcodes[jump_fail_pos] = codegen.opcodes.size(); + codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size(); res = _parse_expression(codegen, on->arguments[2], p_stack_level); if (res < 0) return res; @@ -859,7 +859,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS); codegen.opcodes.push_back(res); - codegen.opcodes[jump_past_pos] = codegen.opcodes.size(); + codegen.opcodes.write[jump_past_pos] = codegen.opcodes.size(); return p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS; @@ -1181,7 +1181,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: Variant script; int idx = -1; - if (assign_type.class_type->name == StringName()) { + if (!assign_type.class_type->owner) { script = codegen.script; } else { StringName name = assign_type.class_type->name; @@ -1361,10 +1361,10 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(break_addr); - codegen.opcodes[continue_addr + 1] = codegen.opcodes.size(); + codegen.opcodes.write[continue_addr + 1] = codegen.opcodes.size(); } - codegen.opcodes[break_addr + 1] = codegen.opcodes.size(); + codegen.opcodes.write[break_addr + 1] = codegen.opcodes.size(); } break; @@ -1393,16 +1393,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); int end_addr = codegen.opcodes.size(); codegen.opcodes.push_back(0); - codegen.opcodes[else_addr] = codegen.opcodes.size(); + codegen.opcodes.write[else_addr] = codegen.opcodes.size(); Error err = _parse_block(codegen, cf->body_else, p_stack_level, p_break_addr, p_continue_addr); if (err) return err; - codegen.opcodes[end_addr] = codegen.opcodes.size(); + codegen.opcodes.write[end_addr] = codegen.opcodes.size(); } else { //end without else - codegen.opcodes[else_addr] = codegen.opcodes.size(); + codegen.opcodes.write[else_addr] = codegen.opcodes.size(); } } break; @@ -1453,7 +1453,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(continue_pos); - codegen.opcodes[break_pos + 1] = codegen.opcodes.size(); + codegen.opcodes.write[break_pos + 1] = codegen.opcodes.size(); codegen.pop_stack_identifiers(); @@ -1479,7 +1479,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP); codegen.opcodes.push_back(continue_addr); - codegen.opcodes[break_addr + 1] = codegen.opcodes.size(); + codegen.opcodes.write[break_addr + 1] = codegen.opcodes.size(); } break; case GDScriptParser::ControlFlowNode::CF_SWITCH: { @@ -1689,7 +1689,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser gdfunc->rpc_mode = p_func->rpc_mode; gdfunc->argument_types.resize(p_func->argument_types.size()); for (int i = 0; i < p_func->argument_types.size(); i++) { - gdfunc->argument_types[i] = _gdtype_from_datatype(p_func->argument_types[i]); + gdfunc->argument_types.write[i] = _gdtype_from_datatype(p_func->argument_types[i]); } gdfunc->return_type = _gdtype_from_datatype(p_func->return_type); } else { @@ -1708,11 +1708,11 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser if (codegen.constant_map.size()) { gdfunc->_constant_count = codegen.constant_map.size(); gdfunc->constants.resize(codegen.constant_map.size()); - gdfunc->_constants_ptr = &gdfunc->constants[0]; + gdfunc->_constants_ptr = gdfunc->constants.ptrw(); const Variant *K = NULL; while ((K = codegen.constant_map.next(K))) { int idx = codegen.constant_map[*K]; - gdfunc->constants[idx] = *K; + gdfunc->constants.write[idx] = *K; } } else { @@ -1726,7 +1726,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser gdfunc->_global_names_ptr = &gdfunc->global_names[0]; for (Map<StringName, int>::Element *E = codegen.name_map.front(); E; E = E->next()) { - gdfunc->global_names[E->get()] = E->key(); + gdfunc->global_names.write[E->get()] = E->key(); } gdfunc->_global_names_count = gdfunc->global_names.size(); @@ -1741,7 +1741,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser gdfunc->named_globals.resize(codegen.named_globals.size()); gdfunc->_named_globals_ptr = gdfunc->named_globals.ptr(); for (int i = 0; i < codegen.named_globals.size(); i++) { - gdfunc->named_globals[i] = codegen.named_globals[i]; + gdfunc->named_globals.write[i] = codegen.named_globals[i]; } gdfunc->_named_globals_count = gdfunc->named_globals.size(); } @@ -1994,7 +1994,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, GDScript *p_owner p_script->_signals[name] = p_class->_signals[i].arguments; } - if (p_class->name != StringName()) { + if (!p_class->owner) { parsed_classes.insert(p_class->name); } diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 2e4a4c40dd..2a42524ba7 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2918,7 +2918,7 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t } //print_line(itos(indent_stack.size())+","+itos(tc)+": "+l); - lines[i] = l; + lines.write[i] = l; } p_code = ""; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 6a08d86904..bae3f48923 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -62,7 +62,7 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta } #endif //member indexing is O(1) - return &p_instance->members[address]; + return &p_instance->members.write[address]; } break; case ADDR_TYPE_CLASS_CONSTANT: { @@ -742,13 +742,22 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX); +#ifdef DEBUG_ENABLED if (src->get_type() != var_type) { - err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + - "' to a variable of type '" + Variant::get_type_name(var_type) + "'."; - OPCODE_BREAK; + if (Variant::can_convert_strict(src->get_type(), var_type)) { + Variant::CallError ce; + *dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce); + } else { + err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + + "' to a variable of type '" + Variant::get_type_name(var_type) + "'."; + OPCODE_BREAK; + } + } else { +#endif // DEBUG_ENABLED + *dst = *src; +#ifdef DEBUG_ENABLED } - - *dst = *src; +#endif // DEBUG_ENABLED ip += 4; } @@ -761,17 +770,22 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_VARIANT_PTR(dst, 2); GET_VARIANT_PTR(src, 3); +#ifdef DEBUG_ENABLED GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *()); GD_ERR_BREAK(!nc); + if (!src->get_type() != Variant::OBJECT && !src->get_type() != Variant::NIL) { + err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + + "' to a variable of type '" + nc->get_name() + "'."; + OPCODE_BREAK; + } Object *src_obj = src->operator Object *(); - GD_ERR_BREAK(!src_obj); - if (!ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) { + if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) { err_text = "Trying to assign value of type '" + src_obj->get_class_name() + "' to a variable of type '" + nc->get_name() + "'."; OPCODE_BREAK; } - +#endif // DEBUG_ENABLED *dst = *src; ip += 4; @@ -785,6 +799,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_VARIANT_PTR(dst, 2); GET_VARIANT_PTR(src, 3); +#ifdef DEBUG_ENABLED Script *base_type = Object::cast_to<Script>(type->operator Object *()); GD_ERR_BREAK(!base_type); @@ -820,6 +835,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } } +#endif // DEBUG_ENABLED *dst = *src; @@ -1218,7 +1234,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a gdfs->state.stack.resize(alloca_size); //copy variant stack for (int i = 0; i < _stack_size; i++) { - memnew_placement(&gdfs->state.stack[sizeof(Variant) * i], Variant(stack[i])); + memnew_placement(&gdfs->state.stack.write[sizeof(Variant) * i], Variant(stack[i])); } gdfs->state.stack_size = _stack_size; gdfs->state.self = self; @@ -1579,7 +1595,7 @@ StringName GDScriptFunction::get_global_name(int p_idx) const { int GDScriptFunction::get_default_argument_count() const { - return default_arguments.size(); + return _default_arg_count; } int GDScriptFunction::get_default_argument_addr(int p_idx) const { diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 7e98b6ced9..f2e52d48dd 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -1098,7 +1098,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ for (Map<StringName, GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) { if (d.has(E->key())) { - ins->members[E->get().index] = d[E->key()]; + ins->members.write[E->get().index] = d[E->key()]; } } @@ -1412,7 +1412,7 @@ bool GDScriptFunctions::is_deterministic(Function p_func) { MethodInfo GDScriptFunctions::get_info(Function p_func) { -#ifdef TOOLS_ENABLED +#ifdef DEBUG_ENABLED //using a switch, so the compiler generates a jumptable switch (p_func) { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index ac53f33e9e..852d465206 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1411,8 +1411,8 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s op->op = expression[i].op; op->arguments.push_back(expression[i + 1].node); op->line = op_line; //line might have been changed from a \n - expression[i].is_op = false; - expression[i].node = op; + expression.write[i].is_op = false; + expression.write[i].node = op; expression.remove(i + 1); } @@ -1466,7 +1466,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s op->arguments.push_back(expression[next_op + 3].node); //expression after next goes as when-false //replace all 3 nodes by this operator and make it an expression - expression[next_op - 1].node = op; + expression.write[next_op - 1].node = op; expression.remove(next_op); expression.remove(next_op); expression.remove(next_op); @@ -1502,7 +1502,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s op->arguments.push_back(expression[next_op + 1].node); //next expression goes as right //replace all 3 nodes by this operator and make it an expression - expression[next_op - 1].node = op; + expression.write[next_op - 1].node = op; expression.remove(next_op); expression.remove(next_op); } @@ -1526,7 +1526,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to for (int i = 0; i < an->elements.size(); i++) { - an->elements[i] = _reduce_expression(an->elements[i], p_to_const); + an->elements.write[i] = _reduce_expression(an->elements[i], p_to_const); if (an->elements[i]->type != Node::TYPE_CONSTANT) all_constants = false; } @@ -1556,10 +1556,10 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to for (int i = 0; i < dn->elements.size(); i++) { - dn->elements[i].key = _reduce_expression(dn->elements[i].key, p_to_const); + dn->elements.write[i].key = _reduce_expression(dn->elements[i].key, p_to_const); if (dn->elements[i].key->type != Node::TYPE_CONSTANT) all_constants = false; - dn->elements[i].value = _reduce_expression(dn->elements[i].value, p_to_const); + dn->elements.write[i].value = _reduce_expression(dn->elements[i].value, p_to_const); if (dn->elements[i].value->type != Node::TYPE_CONSTANT) all_constants = false; } @@ -1592,7 +1592,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to for (int i = 0; i < op->arguments.size(); i++) { - op->arguments[i] = _reduce_expression(op->arguments[i], p_to_const); + op->arguments.write[i] = _reduce_expression(op->arguments[i], p_to_const); if (op->arguments[i]->type != Node::TYPE_CONSTANT) { all_constants = false; last_not_constant = i; @@ -1620,7 +1620,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to for (int i = 0; i < ptrs.size(); i++) { ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i + 1]); - ptrs[i] = &cn->value; + ptrs.write[i] = &cn->value; } vptr = (const Variant **)&ptrs[0]; @@ -3332,6 +3332,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { switch (token) { + case GDScriptTokenizer::TK_CURSOR: { + tokenizer->advance(); + } break; case GDScriptTokenizer::TK_EOF: p_class->end_line = tokenizer->get_token_line(); case GDScriptTokenizer::TK_ERROR: { @@ -3552,7 +3555,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { DataType argtype; if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) { - if (!_parse_type(argtype)) { + if (tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) { + argtype.infer_type = true; + tokenizer->advance(); + } else if (!_parse_type(argtype)) { _set_error("Expected type for argument."); return; } @@ -4187,6 +4193,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; current_export.hint_string = native_class->get_name(); + current_export.class_name = native_class->get_name(); } else { current_export = PropertyInfo(); @@ -4546,6 +4553,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { member._export.type = Variant::OBJECT; member._export.hint = PROPERTY_HINT_RESOURCE_TYPE; member._export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; + member._export.hint_string = member.data_type.native_type; member._export.class_name = member.data_type.native_type; } else { _set_error("Invalid export type. Only built-in and native resource types can be exported.", member.line); @@ -5433,6 +5441,9 @@ GDScriptParser::DataType GDScriptParser::_get_operation_type(const Variant::Oper if (b_type == Variant::INT || b_type == Variant::REAL) { Variant::evaluate(Variant::OP_ADD, b, 1, b, r_valid); } + if (a_type == Variant::STRING && b_type != Variant::ARRAY) { + a = "%s"; // Work around for formatting operator (%) + } Variant ret; Variant::evaluate(p_op, a, b, ret, r_valid); @@ -5956,7 +5967,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { id->name = cn->value.operator StringName(); op->op = OperatorNode::OP_INDEX_NAMED; - op->arguments[1] = id; + op->arguments.write[1] = id; return _reduce_node_type(op); } @@ -6323,7 +6334,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat Vector<DataType> par_types; par_types.resize(p_call->arguments.size() - 1); for (int i = 1; i < p_call->arguments.size(); i++) { - par_types[i - 1] = _reduce_node_type(p_call->arguments[i]); + par_types.write[i - 1] = _reduce_node_type(p_call->arguments[i]); } if (error_set) return DataType(); @@ -6770,7 +6781,26 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType // Check classes in current file ClassNode *base = NULL; if (!p_base_type) { - // Possibly this is a global, check first + base = current_class; + base_type.has_type = true; + base_type.is_constant = true; + base_type.kind = DataType::CLASS; + base_type.class_type = base; + } else { + base_type = DataType(*p_base_type); + if (base_type.kind == DataType::CLASS) { + base = base_type.class_type; + } + } + + DataType member_type; + + if (_get_member_type(base_type, p_identifier, member_type)) { + return member_type; + } + + if (!p_base_type) { + // Possibly this is a global, check before failing if (ClassDB::class_exists(p_identifier) || ClassDB::class_exists("_" + p_identifier.operator String())) { DataType result; @@ -6796,6 +6826,9 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType result.class_type = outer_class; return result; } + if (outer_class->constant_expressions.has(p_identifier)) { + return outer_class->constant_expressions[p_identifier].type; + } for (int i = 0; i < outer_class->subclasses.size(); i++) { if (outer_class->subclasses[i] == current_class) { continue; @@ -6885,27 +6918,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType } } - // Nothing found, keep looking in local scope - - base = current_class; - base_type.has_type = true; - base_type.is_constant = true; - base_type.kind = DataType::CLASS; - base_type.class_type = base; - } else { - base_type = *p_base_type; - if (base_type.kind == DataType::CLASS) { - base = base_type.class_type; - } - } - - DataType member_type; - - if (_get_member_type(base_type, p_identifier, member_type)) { - return member_type; - } - - if (!p_base_type) { // This means looking in the current class, which type is always known _set_error("Identifier '" + p_identifier.operator String() + "' is not declared in the current scope.", p_line); } @@ -6949,7 +6961,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) { // Class variables for (int i = 0; i < p_class->variables.size(); i++) { - ClassNode::Member &v = p_class->variables[i]; + ClassNode::Member &v = p_class->variables.write[i]; DataType tmp; if (_get_member_type(p_class->base_type, v.identifier, tmp)) { @@ -6993,7 +7005,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) { convert_call->arguments.push_back(tgt_type); v.expression = convert_call; - v.initial_assignment->arguments[1] = convert_call; + v.initial_assignment->arguments.write[1] = convert_call; } } @@ -7131,11 +7143,9 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) { // Arguments int defaults_ofs = p_function->arguments.size() - p_function->default_values.size(); for (int i = 0; i < p_function->arguments.size(); i++) { - - // Resolve types - p_function->argument_types[i] = _resolve_type(p_function->argument_types[i], p_function->line); - - if (i >= defaults_ofs) { + if (i < defaults_ofs) { + p_function->argument_types.write[i] = _resolve_type(p_function->argument_types[i], p_function->line); + } else { if (p_function->default_values[i - defaults_ofs]->type != Node::TYPE_OPERATOR) { _set_error("Parser bug: invalid argument default value.", p_function->line, p_function->column); return; @@ -7150,17 +7160,25 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) { DataType def_type = _reduce_node_type(op->arguments[1]); - if (!_is_type_compatible(p_function->argument_types[i], def_type, true)) { - String arg_name = p_function->arguments[i]; - _set_error("Value type (" + def_type.to_string() + ") doesn't match the type of argument '" + - arg_name + "' (" + p_function->arguments[i] + ")", - p_function->line); + if (p_function->argument_types[i].infer_type) { + def_type.is_constant = false; + p_function->argument_types.write[i] = def_type; + } else { + p_function->return_type = _resolve_type(p_function->return_type, p_function->line); + + if (!_is_type_compatible(p_function->argument_types[i], def_type, true)) { + String arg_name = p_function->arguments[i]; + _set_error("Value type (" + def_type.to_string() + ") doesn't match the type of argument '" + + arg_name + "' (" + p_function->arguments[i] + ")", + p_function->line); + } } } } if (!(p_function->name == "_init")) { // Signature for the initializer may vary +#ifdef DEBUG_ENABLED DataType return_type; List<DataType> arg_types; int default_arg_count = 0; @@ -7171,18 +7189,44 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) { if (_get_function_signature(base_type, p_function->name, return_type, arg_types, default_arg_count, _static, vararg)) { bool valid = _static == p_function->_static; valid = valid && return_type == p_function->return_type; - valid = valid && p_function->default_values.size() >= default_arg_count; - valid = valid && arg_types.size() == p_function->arguments.size(); + int argsize_diff = p_function->arguments.size() - arg_types.size(); + valid = valid && argsize_diff >= 0; + valid = valid && p_function->default_values.size() >= default_arg_count + argsize_diff; int i = 0; for (List<DataType>::Element *E = arg_types.front(); valid && E; E = E->next()) { valid = valid && E->get() == p_function->argument_types[i++]; } if (!valid) { - _set_error("Function signature doesn't match the parent.", p_function->line); + String parent_signature = return_type.has_type ? return_type.to_string() : "Variant"; + if (parent_signature == "null") { + parent_signature = "void"; + } + parent_signature += " " + p_function->name + "("; + if (arg_types.size()) { + int i = 0; + for (List<DataType>::Element *E = arg_types.front(); E; E = E->next()) { + if (E != arg_types.front()) { + parent_signature += ", "; + } + String arg = E->get().to_string(); + if (arg == "null" || arg == "var") { + arg = "Variant"; + } + parent_signature += arg; + if (i == arg_types.size() - default_arg_count) { + parent_signature += "=default"; + } + + i++; + } + } + parent_signature += ")"; + _set_error("Function signature doesn't match the parent. Parent signature is: '" + parent_signature + "'.", p_function->line); return; } } +#endif // DEBUG_ENABLED } else { if (p_function->return_type.has_type && (p_function->return_type.kind != DataType::BUILTIN || p_function->return_type.builtin_type != Variant::NIL)) { _set_error("Constructor cannot return a value.", p_function->line); @@ -7284,7 +7328,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { convert_call->arguments.push_back(tgt_type); lv->assign = convert_call; - lv->assign_op->arguments[1] = convert_call; + lv->assign_op->arguments.write[1] = convert_call; } } if (lv->datatype.infer_type) { @@ -7402,7 +7446,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { convert_call->arguments.push_back(op->arguments[1]); convert_call->arguments.push_back(tgt_type); - op->arguments[1] = convert_call; + op->arguments.write[1] = convert_call; } } if (!rh_type.has_type && (op->op != OperatorNode::OP_ASSIGN || lh_type.has_type || op->arguments[0]->type == Node::TYPE_OPERATOR)) { diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 940bdcbc8d..7ae7c72ed3 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -1172,15 +1172,15 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) Vector<uint8_t> cs; cs.resize(len); for (int j = 0; j < len; j++) { - cs[j] = b[j] ^ 0xb6; + cs.write[j] = b[j] ^ 0xb6; } - cs[cs.size() - 1] = 0; + cs.write[cs.size() - 1] = 0; String s; s.parse_utf8((const char *)cs.ptr()); b += len; total_len -= len + 4; - identifiers[i] = s; + identifiers.write[i] = s; } constants.resize(constant_count); @@ -1193,7 +1193,7 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) return err; b += len; total_len -= len; - constants[i] = v; + constants.write[i] = v; } ERR_FAIL_COND_V(line_count * 8 > total_len, ERR_INVALID_DATA); @@ -1218,10 +1218,10 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) if ((*b) & TOKEN_BYTE_MASK) { //little endian always ERR_FAIL_COND_V(total_len < 4, ERR_INVALID_DATA); - tokens[i] = decode_uint32(b) & ~TOKEN_BYTE_MASK; + tokens.write[i] = decode_uint32(b) & ~TOKEN_BYTE_MASK; b += 4; } else { - tokens[i] = *b; + tokens.write[i] = *b; b += 1; total_len--; } @@ -1320,15 +1320,15 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) //save header buf.resize(24); - buf[0] = 'G'; - buf[1] = 'D'; - buf[2] = 'S'; - buf[3] = 'C'; - encode_uint32(BYTECODE_VERSION, &buf[4]); - encode_uint32(identifier_map.size(), &buf[8]); - encode_uint32(constant_map.size(), &buf[12]); - encode_uint32(line_map.size(), &buf[16]); - encode_uint32(token_array.size(), &buf[20]); + buf.write[0] = 'G'; + buf.write[1] = 'D'; + buf.write[2] = 'S'; + buf.write[3] = 'C'; + encode_uint32(BYTECODE_VERSION, &buf.write[4]); + encode_uint32(identifier_map.size(), &buf.write[8]); + encode_uint32(constant_map.size(), &buf.write[12]); + encode_uint32(line_map.size(), &buf.write[16]); + encode_uint32(token_array.size(), &buf.write[20]); //save identifiers @@ -1360,7 +1360,7 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) ERR_FAIL_COND_V(err != OK, Vector<uint8_t>()); int pos = buf.size(); buf.resize(pos + len); - encode_variant(E->get(), &buf[pos], len); + encode_variant(E->get(), &buf.write[pos], len); } for (Map<int, uint32_t>::Element *E = rev_line_map.front(); E; E = E->next()) { diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 234a59e516..0c5df57d49 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -508,7 +508,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { continue; PhysicsServer::get_singleton()->body_add_shape(g.static_body, shapes[i].shape->get_rid(), xform * shapes[i].local_transform); if (g.collision_debug.is_valid()) { - shapes[i].shape->add_vertices_to_array(col_debug, xform * shapes[i].local_transform); + shapes.write[i].shape->add_vertices_to_array(col_debug, xform * shapes[i].local_transform); } //print_line("PHIS x: "+xform); @@ -758,7 +758,7 @@ void GridMap::_update_visibility() { for (Map<OctantKey, Octant *>::Element *e = octant_map.front(); e; e = e->next()) { Octant *octant = e->value(); for (int i = 0; i < octant->multimesh_instances.size(); i++) { - Octant::MultimeshInstance &mi = octant->multimesh_instances[i]; + const Octant::MultimeshInstance &mi = octant->multimesh_instances[i]; VS::get_singleton()->instance_set_visible(mi.instance, is_visible()); } } diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index 40540a857f..d11d7a7ec7 100755 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub @@ -20,6 +20,8 @@ if env['builtin_mbedtls']: "camellia.c", "ccm.c", "certs.c", + "chacha20.c", + "chachapoly.c", "cipher.c", "cipher_wrap.c", "cmac.c", @@ -37,6 +39,7 @@ if env['builtin_mbedtls']: "error.c", "gcm.c", "havege.c", + "hkdf.c", "hmac_drbg.c", "md2.c", "md4.c", @@ -45,6 +48,7 @@ if env['builtin_mbedtls']: "md_wrap.c", "memory_buffer_alloc.c", "net_sockets.c", + "nist_kw.c", "oid.c", "padlock.c", "pem.c", @@ -57,6 +61,7 @@ if env['builtin_mbedtls']: "pkwrite.c", "platform.c", "platform_util.c", + "poly1305.c", "ripemd160.c", "rsa.c", "rsa_internal.c", diff --git a/modules/mobile_vr/config.py b/modules/mobile_vr/config.py index 4912457e2b..e85fa631dd 100644 --- a/modules/mobile_vr/config.py +++ b/modules/mobile_vr/config.py @@ -1,6 +1,5 @@ def can_build(env, platform): - # should probably change this to only be true on iOS and Android - return False + return True def configure(env): pass diff --git a/modules/mobile_vr/mobile_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 6b1c7eb279..2ec00aa72d 100644 --- a/modules/mobile_vr/mobile_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "mobile_interface.h" +#include "mobile_vr_interface.h" #include "core/os/input.h" #include "core/os/os.h" #include "servers/visual/visual_server_global.h" @@ -279,7 +279,7 @@ bool MobileVRInterface::is_stereo() { return true; }; -bool MobileVRInterface::is_initialized() { +bool MobileVRInterface::is_initialized() const { return (initialized); }; diff --git a/modules/mobile_vr/mobile_interface.h b/modules/mobile_vr/mobile_vr_interface.h index bb84281b46..7b2344f1fe 100644 --- a/modules/mobile_vr/mobile_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -134,7 +134,7 @@ public: virtual StringName get_name() const; virtual int get_capabilities() const; - virtual bool is_initialized(); + virtual bool is_initialized() const; virtual bool initialize(); virtual void uninitialize(); @@ -150,4 +150,4 @@ public: ~MobileVRInterface(); }; -#endif // MOBILE_VR_INTERFACE_H +#endif // !MOBILE_VR_INTERFACE_H diff --git a/modules/mobile_vr/register_types.cpp b/modules/mobile_vr/register_types.cpp index 0655727a4a..edddaa87e1 100644 --- a/modules/mobile_vr/register_types.cpp +++ b/modules/mobile_vr/register_types.cpp @@ -30,7 +30,7 @@ #include "register_types.h" -#include "mobile_interface.h" +#include "mobile_vr_interface.h" void register_mobile_vr_types() { ClassDB::register_class<MobileVRInterface>(); diff --git a/modules/mono/SCsub b/modules/mono/SCsub index c69a3c9ba6..a2df83925c 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -61,6 +61,7 @@ env_mono.add_source_files(env.modules_sources, 'utils/*.cpp') if env['tools']: env_mono.add_source_files(env.modules_sources, 'editor/*.cpp') + # NOTE: It is safe to generate this file here, since this is still execute serially make_cs_files_header('glue/cs_files', 'glue/cs_compressed.gen.h') vars = Variables() diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 8471083f49..7d7028a7a6 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -523,7 +523,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec si.resize(frame_count); for (int i = 0; i < frame_count; i++) { - StackInfo &sif = si[i]; + StackInfo &sif = si.write[i]; MonoObject *frame = mono_array_get(frames, MonoObject *, i); MonoString *file_name; diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 6819c0abe8..76907451e7 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -1650,7 +1650,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte "\t\tvarargs.set(i, GDMonoMarshal::mono_object_to_variant(elem));\n" "\t\t" C_LOCAL_PTRCALL_ARGS ".set("); p_output.push_back(real_argc_str); - p_output.push_back(" + i, &varargs[i]);\n\t" CLOSE_BLOCK); + p_output.push_back(" + i, &varargs.write[i]);\n\t" CLOSE_BLOCK); } else { p_output.push_back(c_in_statements); p_output.push_back("\tconst void* " C_LOCAL_PTRCALL_ARGS "["); diff --git a/modules/mono/glue/cs_files/Color.cs b/modules/mono/glue/cs_files/Color.cs index e0d6d27840..1195071bd3 100644 --- a/modules/mono/glue/cs_files/Color.cs +++ b/modules/mono/glue/cs_files/Color.cs @@ -293,28 +293,80 @@ namespace Godot return res; } - public int ToRgba32() + public int ToAbgr32() { - int c = (byte)(r * 255); + int c = (byte)Math.Round(a * 255); c <<= 8; - c |= (byte)(g * 255); + c |= (byte)Math.Round(b * 255); c <<= 8; - c |= (byte)(b * 255); + c |= (byte)Math.Round(g * 255); c <<= 8; - c |= (byte)(a * 255); + c |= (byte)Math.Round(r * 255); + + return c; + } + + public long ToAbgr64() + { + long c = (ushort)Math.Round(a * 65535); + c <<= 16; + c |= (ushort)Math.Round(b * 65535); + c <<= 16; + c |= (ushort)Math.Round(g * 65535); + c <<= 16; + c |= (ushort)Math.Round(r * 65535); return c; } public int ToArgb32() { - int c = (byte)(a * 255); + int c = (byte)Math.Round(a * 255); + c <<= 8; + c |= (byte)Math.Round(r * 255); + c <<= 8; + c |= (byte)Math.Round(g * 255); + c <<= 8; + c |= (byte)Math.Round(b * 255); + + return c; + } + + public long ToArgb64() + { + long c = (ushort)Math.Round(a * 65535); + c <<= 16; + c |= (ushort)Math.Round(r * 65535); + c <<= 16; + c |= (ushort)Math.Round(g * 65535); + c <<= 16; + c |= (ushort)Math.Round(b * 65535); + + return c; + } + + public int ToRgba32() + { + int c = (byte)Math.Round(r * 255); c <<= 8; - c |= (byte)(r * 255); + c |= (byte)Math.Round(g * 255); c <<= 8; - c |= (byte)(g * 255); + c |= (byte)Math.Round(b * 255); c <<= 8; - c |= (byte)(b * 255); + c |= (byte)Math.Round(a * 255); + + return c; + } + + public long ToRgba64() + { + long c = (ushort)Math.Round(r * 65535); + c <<= 16; + c |= (ushort)Math.Round(g * 65535); + c <<= 16; + c |= (ushort)Math.Round(b * 65535); + c <<= 16; + c |= (ushort)Math.Round(a * 65535); return c; } @@ -353,6 +405,17 @@ namespace Godot r = (rgba & 0xFF) / 255.0f; } + public Color(long rgba) + { + a = (rgba & 0xFFFF) / 65535.0f; + rgba >>= 16; + b = (rgba & 0xFFFF) / 65535.0f; + rgba >>= 16; + g = (rgba & 0xFFFF) / 65535.0f; + rgba >>= 16; + r = (rgba & 0xFFFF) / 65535.0f; + } + private static int _parse_col(string str, int ofs) { int ig = 0; @@ -392,7 +455,7 @@ namespace Godot private String _to_hex(float val) { - var v = (int) Mathf.Clamp(val * 255.0f, 0, 255); + int v = Mathf.RoundToInt(Mathf.Clamp(val * 255, 0, 255)); var ret = string.Empty; diff --git a/modules/mono/glue/cs_files/NodeExtensions.cs b/modules/mono/glue/cs_files/NodeExtensions.cs index a099b0e400..71534d7782 100644 --- a/modules/mono/glue/cs_files/NodeExtensions.cs +++ b/modules/mono/glue/cs_files/NodeExtensions.cs @@ -6,5 +6,40 @@ namespace Godot { return (T)GetNode(path); } + + public T GetNodeOrNull<T>(NodePath path) where T : Godot.Node + { + return GetNode(path) as T; + } + + public T GetChild<T>(int idx) where T : Godot.Node + { + return (T)GetChild(idx); + } + + public T GetChildOrNull<T>(int idx) where T : Godot.Node + { + return GetChild(idx) as T; + } + + public T GetOwner<T>() where T : Godot.Node + { + return (T)GetOwner(); + } + + public T GetOwnerOrNull<T>() where T : Godot.Node + { + return GetOwner() as T; + } + + public T GetParent<T>() where T : Godot.Node + { + return (T)GetParent(); + } + + public T GetParentOrNull<T>() where T : Godot.Node + { + return GetParent() as T; + } } } diff --git a/modules/mono/glue/cs_files/VERSION.txt b/modules/mono/glue/cs_files/VERSION.txt index 7ed6ff82de..7f8f011eb7 100755 --- a/modules/mono/glue/cs_files/VERSION.txt +++ b/modules/mono/glue/cs_files/VERSION.txt @@ -1 +1 @@ -5 +7 diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 0f4e211be5..f564b93f8f 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -77,12 +77,12 @@ void setup_runtime_main_args() { Vector<char *> main_args; main_args.resize(cmdline_args.size() + 1); - main_args[0] = execpath.ptrw(); + main_args.write[0] = execpath.ptrw(); int i = 1; for (List<String>::Element *E = cmdline_args.front(); E; E = E->next()) { CharString &stored = cmdline_args_utf8.push_back(E->get().utf8())->get(); - main_args[i] = stored.ptrw(); + main_args.write[i] = stored.ptrw(); i++; } diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 53d6b7074c..ad74f73d74 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -503,7 +503,7 @@ GDMonoClass::~GDMonoClass() { } } - deleted_methods[offset] = method; + deleted_methods.write[offset] = method; ++offset; memdelete(method); diff --git a/modules/recast/navigation_mesh_generator.cpp b/modules/recast/navigation_mesh_generator.cpp index 64c4b85269..c1ce2592a4 100644 --- a/modules/recast/navigation_mesh_generator.cpp +++ b/modules/recast/navigation_mesh_generator.cpp @@ -126,9 +126,9 @@ void NavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(con for (unsigned int j = 0; j < ntris; j++) { Vector<int> nav_indices; nav_indices.resize(3); - nav_indices[0] = ((int)(bverts + tris[j * 4 + 0])); - nav_indices[1] = ((int)(bverts + tris[j * 4 + 1])); - nav_indices[2] = ((int)(bverts + tris[j * 4 + 2])); + nav_indices.write[0] = ((int)(bverts + tris[j * 4 + 0])); + nav_indices.write[1] = ((int)(bverts + tris[j * 4 + 1])); + nav_indices.write[2] = ((int)(bverts + tris[j * 4 + 2])); p_nav_mesh->add_polygon(nav_indices); } } diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index 6f2bb46fc8..733f32277b 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -265,8 +265,8 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) for (uint32_t i = 0; i < size; i++) { - result->data[i].start = ovector[i * 2]; - result->data[i].end = ovector[i * 2 + 1]; + result->data.write[i].start = ovector[i * 2]; + result->data.write[i].end = ovector[i * 2 + 1]; } pcre2_match_data_free_16(match); @@ -295,8 +295,8 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) for (uint32_t i = 0; i < size; i++) { - result->data[i].start = ovector[i * 2]; - result->data[i].end = ovector[i * 2 + 1]; + result->data.write[i].start = ovector[i * 2]; + result->data.write[i].end = ovector[i * 2 + 1]; } pcre2_match_data_free_32(match); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 9dea7a9c9e..de9b3d5a91 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -771,7 +771,7 @@ void VisualScript::custom_signal_set_argument_type(const StringName &p_func, int ERR_FAIL_COND(instances.size()); ERR_FAIL_COND(!custom_signals.has(p_func)); ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); - custom_signals[p_func][p_argidx].type = p_type; + custom_signals[p_func].write[p_argidx].type = p_type; } Variant::Type VisualScript::custom_signal_get_argument_type(const StringName &p_func, int p_argidx) const { @@ -783,7 +783,7 @@ void VisualScript::custom_signal_set_argument_name(const StringName &p_func, int ERR_FAIL_COND(instances.size()); ERR_FAIL_COND(!custom_signals.has(p_func)); ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); - custom_signals[p_func][p_argidx].name = p_name; + custom_signals[p_func].write[p_argidx].name = p_name; } String VisualScript::custom_signal_get_argument_name(const StringName &p_func, int p_argidx) const { @@ -811,7 +811,7 @@ void VisualScript::custom_signal_swap_argument(const StringName &p_func, int p_a ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); ERR_FAIL_INDEX(p_with_argidx, custom_signals[p_func].size()); - SWAP(custom_signals[p_func][p_argidx], custom_signals[p_func][p_with_argidx]); + SWAP(custom_signals[p_func].write[p_argidx], custom_signals[p_func].write[p_with_argidx]); } void VisualScript::remove_custom_signal(const StringName &p_name) { diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index d29104ed45..ef40af686c 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1295,7 +1295,7 @@ void VisualScriptEditor::_on_nodes_duplicate() { Ref<VisualScriptNode> node = script->get_node(edited_func, F->get()); - Ref<VisualScriptNode> dupe = node->duplicate(); + Ref<VisualScriptNode> dupe = node->duplicate(true); int new_id = idc++; to_select.insert(new_id); @@ -1330,7 +1330,7 @@ void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) { } void VisualScriptEditor::_generic_search() { - new_connect_node_select->select_from_visual_script(String("")); + new_connect_node_select->select_from_visual_script(String(""), false); } void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) { @@ -2610,7 +2610,7 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua undo_redo->commit_action(); } -void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category) { +void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting) { Vector2 ofs = graph->get_scroll_ofs() + port_action_pos; if (graph->is_using_snap()) { int snap = graph->get_snap(); @@ -2625,12 +2625,12 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri Ref<VisualScriptNode> vnode_old = script->get_node(edited_func, port_action_node); int new_id = script->get_available_id(); - if (Object::cast_to<VisualScriptOperator>(vnode_new.ptr())) { + if (Object::cast_to<VisualScriptOperator>(vnode_new.ptr()) && script->get_node(edited_func, port_action_node).is_valid()) { Variant::Type type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).type; Object::cast_to<VisualScriptOperator>(vnode_new.ptr())->set_typed(type); } - if (Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr())) { + if (Object::cast_to<VisualScriptTypeCast>(vnode_new.ptr()) && script->get_node(edited_func, port_action_node).is_valid()) { Variant::Type type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).type; String hint_name = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; @@ -2644,8 +2644,11 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri } undo_redo->create_action(TTR("Add Node")); undo_redo->add_do_method(script.ptr(), "add_node", edited_func, new_id, vnode_new, ofs); - connect_seq(vnode_old, vnode_new, new_id); - connect_data(vnode_old, vnode_new, new_id); + if (vnode_old.is_valid() && p_connecting == true) { + connect_seq(vnode_old, vnode_new, new_id); + connect_data(vnode_old, vnode_new, new_id); + } + undo_redo->add_undo_method(script.ptr(), "remove_node", edited_func, new_id); undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); @@ -2728,11 +2731,11 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); if (tg.type == Variant::OBJECT) { vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE); - + vsfc->set_base_type(String("")); if (tg.gdclass != StringName()) { vsfc->set_base_type(tg.gdclass); - } else { + } else if (script->get_node(edited_func, port_action_node).is_valid()) { PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint; String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; @@ -2740,7 +2743,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri vsfc->set_base_type(base_type); } if (p_text == "call" || p_text == "call_deferred") { - vsfc->set_function(""); + vsfc->set_function(String("")); } } if (tg.script.is_valid()) { @@ -2748,7 +2751,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri } } else if (tg.type == Variant::NIL) { vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE); - vsfc->set_base_type(script->get_instance_base_type()); + vsfc->set_base_type(String("")); } else { vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE); vsfc->set_basic_type(tg.type); @@ -2762,11 +2765,11 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); if (tg.type == Variant::OBJECT) { vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE); - + vsp->set_base_type(String("")); if (tg.gdclass != StringName()) { vsp->set_base_type(tg.gdclass); - } else { + } else if (script->get_node(edited_func, port_action_node).is_valid()) { PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint; String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; @@ -2779,7 +2782,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri } } else if (tg.type == Variant::NIL) { vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE); - vsp->set_base_type(script->get_instance_base_type()); + vsp->set_base_type(String("")); } else { vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_BASIC_TYPE); vsp->set_basic_type(tg.type); @@ -2792,14 +2795,13 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); if (tg.type == Variant::OBJECT) { vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE); - + vsp->set_base_type(String("")); if (tg.gdclass != StringName()) { vsp->set_base_type(tg.gdclass); - } else { + } else if (script->get_node(edited_func, port_action_node).is_valid()) { PropertyHint hint = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint; String base_type = script->get_node(edited_func, port_action_node)->get_output_value_port_info(port_action_output).hint_string; - if (base_type != String() && hint == PROPERTY_HINT_TYPE_STRING) { vsp->set_base_type(base_type); } @@ -2809,16 +2811,17 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri } } else if (tg.type == Variant::NIL) { vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE); - vsp->set_base_type(script->get_instance_base_type()); + vsp->set_base_type(String("")); } else { vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE); vsp->set_basic_type(tg.type); } } Ref<VisualScriptNode> vnode_old = script->get_node(edited_func, port_action_node); - connect_seq(vnode_old, vnode, port_action_new_node); - connect_data(vnode_old, vnode, port_action_new_node); - + if (vnode_old.is_valid() && p_connecting == true) { + connect_seq(vnode_old, vnode, port_action_new_node); + connect_data(vnode_old, vnode, port_action_new_node); + } _update_graph(port_action_new_node); _update_graph_connections(); } @@ -2869,7 +2872,7 @@ void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<Visual undo_redo->commit_action(); } -void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, const String &p_category) { +void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting) { String name = p_text; if (script->has_function(name)) { @@ -2902,7 +2905,7 @@ void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, cons undo_redo->add_do_method(script.ptr(), "add_function", name); for (int i = 0; i < minfo.arguments.size(); i++) { - func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name); + func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name, -1, minfo.arguments[i].hint, minfo.arguments[i].hint_string); } undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node); @@ -3170,7 +3173,7 @@ void VisualScriptEditor::_menu_option(int p_what) { return; } if (node.is_valid()) { - clipboard->nodes[id] = node->duplicate(); + clipboard->nodes[id] = node->duplicate(true); clipboard->nodes_positions[id] = script->get_node_position(edited_func, id); } } diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index e0f8a0aaa7..8bfd147519 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -172,12 +172,12 @@ class VisualScriptEditor : public ScriptEditorBase { void connect_data(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode, int new_id); - void _selected_connect_node(const String &p_text, const String &p_category); + void _selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting = true); void connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id); void _cancel_connect_node(); void _create_new_node(const String &p_text, const String &p_category, const Vector2 &p_point); - void _selected_new_virtual_method(const String &p_text, const String &p_category); + void _selected_new_virtual_method(const String &p_text = String(""), const String &p_category = String(""), const bool p_connecting = true); int error_line; diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index d5f9d21348..868d22b541 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -56,11 +56,11 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val int from = inputs.size(); inputs.resize(int(p_value)); for (int i = from; i < inputs.size(); i++) { - inputs[i].name = String::chr('a' + i); + inputs.write[i].name = String::chr('a' + i); if (from == 0) { - inputs[i].type = output_type; + inputs.write[i].type = output_type; } else { - inputs[i].type = inputs[from - 1].type; + inputs.write[i].type = inputs[from - 1].type; } } expression_dirty = true; @@ -78,10 +78,10 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val if (what == "type") { - inputs[idx].type = Variant::Type(int(p_value)); + inputs.write[idx].type = Variant::Type(int(p_value)); } else if (what == "name") { - inputs[idx].name = p_value; + inputs.write[idx].name = p_value; } else { return false; } @@ -1153,8 +1153,8 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { op->op = expression[i].op; op->nodes[0] = expression[i + 1].node; op->nodes[1] = NULL; - expression[i].is_op = false; - expression[i].node = op; + expression.write[i].is_op = false; + expression.write[i].node = op; expression.remove(i + 1); } @@ -1188,7 +1188,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { op->nodes[1] = expression[next_op + 1].node; //next expression goes as right //replace all 3 nodes by this operator and make it an expression - expression[next_op - 1].node = op; + expression.write[next_op - 1].node = op; expression.remove(next_op); expression.remove(next_op); } @@ -1370,8 +1370,8 @@ public: bool ret = _execute(p_inputs, constructor->arguments[i], value, r_error_str, ce); if (ret) return true; - arr[i] = value; - argp[i] = &arr[i]; + arr.write[i] = value; + argp.write[i] = &arr[i]; } r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce); @@ -1397,8 +1397,8 @@ public: bool ret = _execute(p_inputs, bifunc->arguments[i], value, r_error_str, ce); if (ret) return true; - arr[i] = value; - argp[i] = &arr[i]; + arr.write[i] = value; + argp.write[i] = &arr[i]; } VisualScriptBuiltinFunc::exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str); @@ -1429,8 +1429,8 @@ public: bool ret = _execute(p_inputs, call->arguments[i], value, r_error_str, ce); if (ret) return true; - arr[i] = value; - argp[i] = &arr[i]; + arr.write[i] = value; + argp.write[i] = &arr[i]; } r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce); diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp index 0f58a20c00..7535f37ffc 100644 --- a/modules/visual_script/visual_script_flow_control.cpp +++ b/modules/visual_script/visual_script_flow_control.cpp @@ -684,7 +684,7 @@ bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) int idx = String(p_name).get_slice("/", 1).to_int(); ERR_FAIL_INDEX_V(idx, case_values.size(), false); - case_values[idx].type = Variant::Type(int(p_value)); + case_values.write[idx].type = Variant::Type(int(p_value)); _change_notify(); ports_changed_notify(); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index f174300a4c..a6ec36d364 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -54,8 +54,8 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value arguments.resize(new_argc); for (int i = argc; i < new_argc; i++) { - arguments[i].name = "arg" + itos(i + 1); - arguments[i].type = Variant::NIL; + arguments.write[i].name = "arg" + itos(i + 1); + arguments.write[i].type = Variant::NIL; } ports_changed_notify(); _change_notify(); @@ -68,7 +68,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value if (what == "type") { Variant::Type new_type = Variant::Type(int(p_value)); - arguments[idx].type = new_type; + arguments.write[idx].type = new_type; ports_changed_notify(); return true; @@ -76,7 +76,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value if (what == "name") { - arguments[idx].name = p_value; + arguments.write[idx].name = p_value; ports_changed_notify(); return true; } @@ -205,6 +205,8 @@ PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const { PropertyInfo out; out.type = arguments[p_idx].type; out.name = arguments[p_idx].name; + out.hint = arguments[p_idx].hint; + out.hint_string = arguments[p_idx].hint_string; return out; } @@ -218,11 +220,13 @@ String VisualScriptFunction::get_text() const { return get_name(); //use name as function name I guess } -void VisualScriptFunction::add_argument(Variant::Type p_type, const String &p_name, int p_index) { +void VisualScriptFunction::add_argument(Variant::Type p_type, const String &p_name, int p_index, const PropertyHint p_hint, const String &p_hint_string) { Argument arg; arg.name = p_name; arg.type = p_type; + arg.hint = p_hint; + arg.hint_string = p_hint_string; if (p_index >= 0) arguments.insert(p_index, arg); else @@ -234,7 +238,7 @@ void VisualScriptFunction::set_argument_type(int p_argidx, Variant::Type p_type) ERR_FAIL_INDEX(p_argidx, arguments.size()); - arguments[p_argidx].type = p_type; + arguments.write[p_argidx].type = p_type; ports_changed_notify(); } Variant::Type VisualScriptFunction::get_argument_type(int p_argidx) const { @@ -246,7 +250,7 @@ void VisualScriptFunction::set_argument_name(int p_argidx, const String &p_name) ERR_FAIL_INDEX(p_argidx, arguments.size()); - arguments[p_argidx].name = p_name; + arguments.write[p_argidx].name = p_name; ports_changed_notify(); } String VisualScriptFunction::get_argument_name(int p_argidx) const { @@ -3560,8 +3564,8 @@ void VisualScriptDeconstruct::_set_elem_cache(const Array &p_elements) { ERR_FAIL_COND(p_elements.size() % 2 == 1); elements.resize(p_elements.size() / 2); for (int i = 0; i < elements.size(); i++) { - elements[i].name = p_elements[i * 2 + 0]; - elements[i].type = Variant::Type(int(p_elements[i * 2 + 1])); + elements.write[i].name = p_elements[i * 2 + 0]; + elements.write[i].type = Variant::Type(int(p_elements[i * 2 + 1])); } } @@ -3606,7 +3610,7 @@ VisualScriptNodeInstance *VisualScriptDeconstruct::instance(VisualScriptInstance instance->instance = p_instance; instance->outputs.resize(elements.size()); for (int i = 0; i < elements.size(); i++) { - instance->outputs[i] = elements[i].name; + instance->outputs.write[i] = elements[i].name; } return instance; diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index 9bfbd46e47..f7ac995816 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -40,6 +40,8 @@ class VisualScriptFunction : public VisualScriptNode { struct Argument { String name; Variant::Type type; + PropertyHint hint; + String hint_string; }; Vector<Argument> arguments; @@ -70,7 +72,7 @@ public: virtual String get_text() const; virtual String get_category() const { return "flow_control"; } - void add_argument(Variant::Type p_type, const String &p_name, int p_index = -1); + void add_argument(Variant::Type p_type, const String &p_name, int p_index = -1, const PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = String("")); void set_argument_type(int p_argidx, Variant::Type p_type); Variant::Type get_argument_type(int p_argidx) const; void set_argument_name(int p_argidx, const String &p_name); diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 123d697081..e4dfc5fe45 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -206,8 +206,10 @@ void VisualScriptPropertySelector::_update_search() { item->set_icon(0, type_icons[E->get().type]); item->set_metadata(1, "get"); item->set_collapsed(1); - item->set_selectable(1, false); item->set_selectable(0, true); + item->set_selectable(1, false); + item->set_selectable(2, false); + item->set_metadata(2, connecting); } if (input == String() || @@ -218,8 +220,10 @@ void VisualScriptPropertySelector::_update_search() { item->set_metadata(0, E->get().name); item->set_icon(0, type_icons[E->get().type]); item->set_metadata(1, "set"); - item->set_selectable(1, false); item->set_selectable(0, true); + item->set_selectable(1, false); + item->set_selectable(2, false); + item->set_metadata(2, connecting); } } @@ -341,6 +345,9 @@ void VisualScriptPropertySelector::_update_search() { item->set_collapsed(1); item->set_selectable(1, false); + item->set_selectable(2, false); + item->set_metadata(2, connecting); + if (category && category->get_children() == NULL) { memdelete(category); //old category was unused } @@ -369,6 +376,8 @@ void VisualScriptPropertySelector::create_visualscript_item(const String &name, item->set_selectable(0, true); item->set_collapsed(1); item->set_selectable(1, false); + item->set_selectable(2, false); + item->set_metadata(2, connecting); } } @@ -423,6 +432,8 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt item->set_selectable(0, true); item->set_metadata(1, "visualscript"); item->set_selectable(1, false); + item->set_selectable(2, false); + item->set_metadata(2, connecting); } } @@ -431,7 +442,7 @@ void VisualScriptPropertySelector::_confirmed() { TreeItem *ti = search_options->get_selected(); if (!ti) return; - emit_signal("selected", ti->get_metadata(0), ti->get_metadata(1)); + emit_signal("selected", ti->get_metadata(0), ti->get_metadata(1), ti->get_metadata(2)); hide(); } @@ -542,7 +553,7 @@ void VisualScriptPropertySelector::_notification(int p_what) { } } -void VisualScriptPropertySelector::select_method_from_base_type(const String &p_base, const String &p_current, bool p_virtuals_only) { +void VisualScriptPropertySelector::select_method_from_base_type(const String &p_base, const String &p_current, const bool p_virtuals_only, const bool p_connecting) { base_type = p_base; selected = p_current; @@ -555,6 +566,8 @@ void VisualScriptPropertySelector::select_method_from_base_type(const String &p_ show_window(.5f); search_box->set_text(""); search_box->grab_focus(); + connecting = p_connecting; + _update_search(); } @@ -562,7 +575,7 @@ void VisualScriptPropertySelector::set_type_filter(const Vector<Variant::Type> & type_filter = p_type_filter; } -void VisualScriptPropertySelector::select_from_base_type(const String &p_base, const String &p_current /*= ""*/, bool p_virtuals_only /*= false*/, bool p_seq_connect /*= false*/) { +void VisualScriptPropertySelector::select_from_base_type(const String &p_base, const String &p_current, bool p_virtuals_only, bool p_seq_connect, const bool p_connecting) { base_type = p_base; selected = p_current; @@ -576,11 +589,12 @@ void VisualScriptPropertySelector::select_from_base_type(const String &p_base, c search_box->set_text(""); search_box->grab_focus(); seq_connect = p_seq_connect; + connecting = p_connecting; _update_search(); } -void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_script, const String &p_current /*= ""*/) { +void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_script, const String &p_current, const bool p_connecting) { ERR_FAIL_COND(p_script.is_null()); base_type = p_script->get_instance_base_type(); @@ -595,11 +609,12 @@ void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_scrip search_box->set_text(""); search_box->grab_focus(); seq_connect = false; + connecting = p_connecting; _update_search(); } -void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type, const String &p_current /*= ""*/) { +void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type, const String &p_current, const bool p_connecting) { ERR_FAIL_COND(p_type == Variant::NIL); base_type = ""; selected = p_current; @@ -613,11 +628,12 @@ void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type, search_box->set_text(""); search_box->grab_focus(); seq_connect = false; + connecting = p_connecting; _update_search(); } -void VisualScriptPropertySelector::select_from_action(const String &p_type, const String &p_current /*= ""*/) { +void VisualScriptPropertySelector::select_from_action(const String &p_type, const String &p_current, const bool p_connecting) { base_type = p_type; selected = p_current; type = Variant::NIL; @@ -630,10 +646,12 @@ void VisualScriptPropertySelector::select_from_action(const String &p_type, cons search_box->set_text(""); search_box->grab_focus(); seq_connect = true; + connecting = p_connecting; + _update_search(); } -void VisualScriptPropertySelector::select_from_instance(Object *p_instance, const String &p_current /*= ""*/) { +void VisualScriptPropertySelector::select_from_instance(Object *p_instance, const String &p_current, const bool p_connecting) { base_type = ""; selected = p_current; type = Variant::NIL; @@ -646,11 +664,12 @@ void VisualScriptPropertySelector::select_from_instance(Object *p_instance, cons search_box->set_text(""); search_box->grab_focus(); seq_connect = false; + connecting = p_connecting; _update_search(); } -void VisualScriptPropertySelector::select_from_visual_script(const String &p_base) { +void VisualScriptPropertySelector::select_from_visual_script(const String &p_base, const bool p_connecting) { base_type = p_base; selected = ""; type = Variant::NIL; @@ -662,6 +681,7 @@ void VisualScriptPropertySelector::select_from_visual_script(const String &p_bas show_window(.5f); search_box->set_text(""); search_box->grab_focus(); + connecting = p_connecting; _update_search(); } @@ -682,7 +702,7 @@ void VisualScriptPropertySelector::_bind_methods() { ClassDB::bind_method(D_METHOD("_sbox_input"), &VisualScriptPropertySelector::_sbox_input); ClassDB::bind_method(D_METHOD("_item_selected"), &VisualScriptPropertySelector::_item_selected); - ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "category"), PropertyInfo(Variant::BOOL, "connecting"))); } VisualScriptPropertySelector::VisualScriptPropertySelector() { @@ -708,6 +728,7 @@ VisualScriptPropertySelector::VisualScriptPropertySelector() { help_bit = memnew(EditorHelpBit); vbc->add_margin_child(TTR("Description:"), help_bit); help_bit->connect("request_hide", this, "_closed"); - search_options->set_columns(2); + search_options->set_columns(3); search_options->set_column_expand(1, false); + search_options->set_column_expand(2, false); } diff --git a/modules/visual_script/visual_script_property_selector.h b/modules/visual_script/visual_script_property_selector.h index ec536f86a8..917ef9ae6d 100644 --- a/modules/visual_script/visual_script_property_selector.h +++ b/modules/visual_script/visual_script_property_selector.h @@ -56,6 +56,7 @@ class VisualScriptPropertySelector : public ConfirmationDialog { bool properties; bool visual_script_generic; + bool connecting; String selected; Variant::Type type; String base_type; @@ -74,13 +75,13 @@ protected: static void _bind_methods(); public: - void select_method_from_base_type(const String &p_base, const String &p_current = "", bool p_virtuals_only = false); - void select_from_base_type(const String &p_base, const String &p_current = "", bool p_virtuals_only = false, bool p_seq_connect = false); - void select_from_script(const Ref<Script> &p_script, const String &p_current /*= ""*/); - void select_from_basic_type(Variant::Type p_type, const String &p_current = ""); - void select_from_action(const String &p_type, const String &p_current = ""); - void select_from_instance(Object *p_instance, const String &p_current = ""); - void select_from_visual_script(const String &p_base); + void select_method_from_base_type(const String &p_base, const String &p_current = "", const bool p_virtuals_only = false, const bool p_connecting = true); + void select_from_base_type(const String &p_base, const String &p_current = "", bool p_virtuals_only = false, bool p_seq_connect = false, const bool p_connecting = true); + void select_from_script(const Ref<Script> &p_script, const String &p_current = "", const bool p_connecting = true); + void select_from_basic_type(Variant::Type p_type, const String &p_current = "", const bool p_connecting = true); + void select_from_action(const String &p_type, const String &p_current = "", const bool p_connecting = true); + void select_from_instance(Object *p_instance, const String &p_current = "", const bool p_connecting = true); + void select_from_visual_script(const String &p_base, const bool p_connecting = true); void show_window(float p_screen_ratio); |