diff options
Diffstat (limited to 'scene')
139 files changed, 1737 insertions, 1527 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index 37e9d1f8c1..6d380aed3c 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -31,7 +31,6 @@ #include "animated_sprite_2d.h" #include "scene/main/viewport.h" -#include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED Dictionary AnimatedSprite2D::_edit_get_state() const { @@ -202,7 +201,7 @@ void AnimatedSprite2D::_notification(int p_what) { } else { frame = last_frame; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -211,7 +210,7 @@ void AnimatedSprite2D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 0.0; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN((1.0 - frame_progress) / abs_speed, remaining); frame_progress += to_process * abs_speed; @@ -226,7 +225,7 @@ void AnimatedSprite2D::_notification(int p_what) { } else { frame = 0; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -235,7 +234,7 @@ void AnimatedSprite2D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 1.0; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN(frame_progress / abs_speed, remaining); frame_progress -= to_process * abs_speed; @@ -291,12 +290,12 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { } if (frames.is_valid()) { - frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed)); + frames->disconnect(CoreStringName(changed), callable_mp(this, &AnimatedSprite2D::_res_changed)); } stop(); frames = p_frames; if (frames.is_valid()) { - frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed)); + frames->connect(CoreStringName(changed), callable_mp(this, &AnimatedSprite2D::_res_changed)); List<StringName> al; frames->get_animation_list(&al); @@ -363,7 +362,7 @@ void AnimatedSprite2D::set_frame_and_progress(int p_frame, real_t p_progress) { return; // No change, don't redraw. } queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } void AnimatedSprite2D::set_speed_scale(float p_speed_scale) { @@ -482,7 +481,7 @@ void AnimatedSprite2D::play(const StringName &p_name, float p_custom_scale, bool } else { set_frame_and_progress(0, 0.0); } - emit_signal("animation_changed"); + emit_signal(SceneStringName(animation_changed)); } else { bool is_backward = signbit(speed_scale * custom_speed_scale); if (p_from_end && is_backward && frame == 0 && frame_progress <= 0.0) { @@ -537,7 +536,7 @@ void AnimatedSprite2D::set_animation(const StringName &p_name) { animation = p_name; - emit_signal("animation_changed"); + emit_signal(SceneStringName(animation_changed)); if (frames == nullptr) { animation = StringName(); diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 4fc0fe0268..f88db0e3f4 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -37,7 +37,6 @@ #include "scene/audio/audio_stream_player_internal.h" #include "scene/main/viewport.h" #include "scene/resources/world_2d.h" -#include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" #include "servers/audio_server.h" @@ -81,10 +80,10 @@ StringName AudioStreamPlayer2D::_get_actual_bus() { //check if any area is diverting sound into a bus Ref<World2D> world_2d = get_world_2d(); - ERR_FAIL_COND_V(world_2d.is_null(), SceneStringNames::get_singleton()->Master); + ERR_FAIL_COND_V(world_2d.is_null(), SceneStringName(Master)); PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space()); - ERR_FAIL_NULL_V(space_state, SceneStringNames::get_singleton()->Master); + ERR_FAIL_NULL_V(space_state, SceneStringName(Master)); PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS]; PhysicsDirectSpaceState2D::PointParameters point_params; diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 822f1b58fd..18ef2d8505 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -54,16 +54,18 @@ void Camera2D::_update_scroll() { if (is_current()) { ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id)); + Size2 screen_size = _get_camera_screen_size(); + Transform2D xform; if (is_physics_interpolated_and_enabled()) { xform = _interpolation_data.xform_prev.interpolate_with(_interpolation_data.xform_curr, Engine::get_singleton()->get_physics_interpolation_fraction()); + camera_screen_center = xform.affine_inverse().xform(0.5 * screen_size); } else { xform = get_camera_transform(); } viewport->set_canvas_transform(xform); - Size2 screen_size = _get_camera_screen_size(); Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5) : Point2()); Point2 adj_screen_pos = camera_screen_center - (screen_size * 0.5); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 2cd59776ec..9c9ba93b41 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -35,7 +35,6 @@ #include "scene/resources/curve_texture.h" #include "scene/resources/gradient_texture.h" #include "scene/resources/particle_process_material.h" -#include "scene/scene_string_names.h" void CPUParticles2D::set_emitting(bool p_emitting) { if (emitting == p_emitting) { @@ -997,7 +996,7 @@ void CPUParticles2D::_particles_process(double p_delta) { } if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) { active = false; - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } } diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index bc39513c03..1d3f1ceada 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -35,7 +35,6 @@ #include "scene/resources/curve_texture.h" #include "scene/resources/gradient_texture.h" #include "scene/resources/particle_process_material.h" -#include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED #include "core/config/engine.h" @@ -731,7 +730,7 @@ void GPUParticles2D::_notification(int p_what) { } if (time > active_time) { if (active && !signal_canceled) { - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } active = false; if (!emitting) { diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 4fc375ff8d..ae45d431fe 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -30,8 +30,6 @@ #include "mesh_instance_2d.h" -#include "scene/scene_string_names.h" - void MeshInstance2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { @@ -70,7 +68,7 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { } texture = p_texture; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> MeshInstance2D::get_texture() const { diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 9631b2cc4e..417e628517 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -30,8 +30,6 @@ #include "multimesh_instance_2d.h" -#include "scene/scene_string_names.h" - void MultiMeshInstance2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { @@ -79,7 +77,7 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { } texture = p_texture; queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> MultiMeshInstance2D::get_texture() const { diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 5d14358120..9e3e6ea583 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -796,7 +796,7 @@ void NavigationAgent2D::_trigger_waypoint_reached() { Dictionary details; const Vector2 waypoint = navigation_path[navigation_path_index]; - details[SNAME("position")] = waypoint; + details[CoreStringName(position)] = waypoint; int waypoint_type = -1; if (path_metadata_flags.has_flag(NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) { diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index ab44e57d05..bad9de5daa 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -162,8 +162,19 @@ void NavigationRegion2D::_notification(int p_what) { set_physics_process_internal(true); } break; + case NOTIFICATION_VISIBILITY_CHANGED: { +#ifdef DEBUG_ENABLED + if (debug_instance_rid.is_valid()) { + RS::get_singleton()->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree()); + } +#endif // DEBUG_ENABLED + } break; + case NOTIFICATION_EXIT_TREE: { _region_exit_navigation_map(); +#ifdef DEBUG_ENABLED + _free_debug(); +#endif // DEBUG_ENABLED } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -189,6 +200,9 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_ } navigation_polygon = p_navigation_polygon; +#ifdef DEBUG_ENABLED + debug_mesh_dirty = true; +#endif // DEBUG_ENABLED NavigationServer2D::get_singleton()->region_set_navigation_polygon(region, p_navigation_polygon); if (navigation_polygon.is_valid()) { @@ -420,12 +434,42 @@ void NavigationRegion2D::_region_update_transform() { #ifdef DEBUG_ENABLED void NavigationRegion2D::_update_debug_mesh() { - Vector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices(); - if (navigation_polygon_vertices.size() < 3) { + if (!is_inside_tree()) { + _free_debug(); return; } const NavigationServer2D *ns2d = NavigationServer2D::get_singleton(); + RenderingServer *rs = RenderingServer::get_singleton(); + + if (!debug_instance_rid.is_valid()) { + debug_instance_rid = rs->canvas_item_create(); + } + if (!debug_mesh_rid.is_valid()) { + debug_mesh_rid = rs->mesh_create(); + } + + const Transform2D region_gt = get_global_transform(); + + rs->canvas_item_set_parent(debug_instance_rid, get_world_2d()->get_canvas()); + rs->canvas_item_set_transform(debug_instance_rid, region_gt); + + if (!debug_mesh_dirty) { + return; + } + + rs->mesh_clear(debug_mesh_rid); + debug_mesh_dirty = false; + + const Vector<Vector2> &vertices = navigation_polygon->get_vertices(); + if (vertices.size() < 3) { + return; + } + + int polygon_count = navigation_polygon->get_polygon_count(); + if (polygon_count == 0) { + return; + } bool enabled_geometry_face_random_color = ns2d->get_debug_navigation_enable_geometry_face_random_color(); bool enabled_edge_lines = ns2d->get_debug_navigation_enable_edge_lines(); @@ -438,39 +482,109 @@ void NavigationRegion2D::_update_debug_mesh() { debug_edge_color = ns2d->get_debug_navigation_geometry_edge_disabled_color(); } + int vertex_count = 0; + int line_count = 0; + + for (int i = 0; i < polygon_count; i++) { + const Vector<int> &polygon = navigation_polygon->get_polygon(i); + int polygon_size = polygon.size(); + if (polygon_size < 3) { + continue; + } + line_count += polygon_size * 2; + vertex_count += (polygon_size - 2) * 3; + } + + Vector<Vector2> face_vertex_array; + face_vertex_array.resize(vertex_count); + + Vector<Color> face_color_array; + if (enabled_geometry_face_random_color) { + face_color_array.resize(vertex_count); + } + + Vector<Vector2> line_vertex_array; + if (enabled_edge_lines) { + line_vertex_array.resize(line_count); + } + RandomPCG rand; + Color polygon_color = debug_face_color; - for (int i = 0; i < navigation_polygon->get_polygon_count(); i++) { - // An array of vertices for this polygon. - Vector<int> polygon = navigation_polygon->get_polygon(i); - Vector<Vector2> debug_polygon_vertices; - debug_polygon_vertices.resize(polygon.size()); - for (int j = 0; j < polygon.size(); j++) { - ERR_FAIL_INDEX(polygon[j], navigation_polygon_vertices.size()); - debug_polygon_vertices.write[j] = navigation_polygon_vertices[polygon[j]]; + int face_vertex_index = 0; + int line_vertex_index = 0; + + Vector2 *face_vertex_array_ptrw = face_vertex_array.ptrw(); + Color *face_color_array_ptrw = face_color_array.ptrw(); + Vector2 *line_vertex_array_ptrw = line_vertex_array.ptrw(); + + for (int polygon_index = 0; polygon_index < polygon_count; polygon_index++) { + const Vector<int> &polygon_indices = navigation_polygon->get_polygon(polygon_index); + int polygon_indices_size = polygon_indices.size(); + if (polygon_indices_size < 3) { + continue; } - // Generate the polygon color, slightly randomly modified from the settings one. - Color random_variation_color = debug_face_color; if (enabled_geometry_face_random_color) { - random_variation_color.set_hsv( - debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1, - debug_face_color.get_s(), - debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2); + // Generate the polygon color, slightly randomly modified from the settings one. + polygon_color.set_hsv(debug_face_color.get_h() + rand.random(-1.0, 1.0) * 0.1, debug_face_color.get_s(), debug_face_color.get_v() + rand.random(-1.0, 1.0) * 0.2); + polygon_color.a = debug_face_color.a; } - random_variation_color.a = debug_face_color.a; - Vector<Color> debug_face_colors; - debug_face_colors.push_back(random_variation_color); - RS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), debug_polygon_vertices, debug_face_colors); + for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size - 2; polygon_indices_index++) { + face_vertex_array_ptrw[face_vertex_index] = vertices[polygon_indices[0]]; + face_vertex_array_ptrw[face_vertex_index + 1] = vertices[polygon_indices[polygon_indices_index + 1]]; + face_vertex_array_ptrw[face_vertex_index + 2] = vertices[polygon_indices[polygon_indices_index + 2]]; + if (enabled_geometry_face_random_color) { + face_color_array_ptrw[face_vertex_index] = polygon_color; + face_color_array_ptrw[face_vertex_index + 1] = polygon_color; + face_color_array_ptrw[face_vertex_index + 2] = polygon_color; + } + face_vertex_index += 3; + } if (enabled_edge_lines) { - Vector<Color> debug_edge_colors; - debug_edge_colors.push_back(debug_edge_color); - debug_polygon_vertices.push_back(debug_polygon_vertices[0]); // Add first again for closing polyline. - RS::get_singleton()->canvas_item_add_polyline(get_canvas_item(), debug_polygon_vertices, debug_edge_colors); + for (int polygon_indices_index = 0; polygon_indices_index < polygon_indices_size; polygon_indices_index++) { + line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index]]; + line_vertex_index += 1; + if (polygon_indices_index + 1 == polygon_indices_size) { + line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[0]]; + line_vertex_index += 1; + } else { + line_vertex_array_ptrw[line_vertex_index] = vertices[polygon_indices[polygon_indices_index + 1]]; + line_vertex_index += 1; + } + } } } + + if (!enabled_geometry_face_random_color) { + face_color_array.resize(face_vertex_array.size()); + face_color_array.fill(debug_face_color); + } + + Array face_mesh_array; + face_mesh_array.resize(Mesh::ARRAY_MAX); + face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array; + face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array; + + rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_TRIANGLES, face_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); + + if (enabled_edge_lines) { + Vector<Color> line_color_array; + line_color_array.resize(line_vertex_array.size()); + line_color_array.fill(debug_edge_color); + + Array line_mesh_array; + line_mesh_array.resize(Mesh::ARRAY_MAX); + line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array; + line_mesh_array[Mesh::ARRAY_COLOR] = line_color_array; + + rs->mesh_add_surface_from_arrays(debug_mesh_rid, RS::PRIMITIVE_LINES, line_mesh_array, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); + } + + rs->canvas_item_add_mesh(debug_instance_rid, debug_mesh_rid, Transform2D()); + rs->canvas_item_set_visible(debug_instance_rid, is_visible_in_tree()); } #endif // DEBUG_ENABLED @@ -512,3 +626,19 @@ void NavigationRegion2D::_update_debug_baking_rect() { } } #endif // DEBUG_ENABLED + +#ifdef DEBUG_ENABLED +void NavigationRegion2D::_free_debug() { + RenderingServer *rs = RenderingServer::get_singleton(); + ERR_FAIL_NULL(rs); + if (debug_instance_rid.is_valid()) { + rs->canvas_item_clear(debug_instance_rid); + rs->free(debug_instance_rid); + debug_instance_rid = RID(); + } + if (debug_mesh_rid.is_valid()) { + rs->free(debug_mesh_rid); + debug_mesh_rid = RID(); + } +} +#endif // DEBUG_ENABLED diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 5a86dd607d..52101cb93e 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -52,6 +52,12 @@ class NavigationRegion2D : public Node2D { #ifdef DEBUG_ENABLED private: + RID debug_mesh_rid; + RID debug_instance_rid; + + bool debug_mesh_dirty = true; + + void _free_debug(); void _update_debug_mesh(); void _update_debug_edge_connections_mesh(); void _update_debug_baking_rect(); diff --git a/scene/2d/physics/area_2d.cpp b/scene/2d/physics/area_2d.cpp index b1ff94dda4..305ac8248e 100644 --- a/scene/2d/physics/area_2d.cpp +++ b/scene/2d/physics/area_2d.cpp @@ -30,7 +30,6 @@ #include "area_2d.h" -#include "scene/scene_string_names.h" #include "servers/audio_server.h" void Area2D::set_gravity_space_override_mode(SpaceOverride p_mode) { @@ -142,9 +141,9 @@ void Area2D::_body_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -156,9 +155,9 @@ void Area2D::_body_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -172,9 +171,9 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i lock_callback(); locked = true; if (body_in) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } else { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } locked = false; unlock_callback(); @@ -200,10 +199,10 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } } @@ -213,7 +212,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_area_shape); } } else { @@ -227,15 +226,15 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i if (E->value.rc == 0) { body_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + emit_signal(SceneStringName(body_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_area_shape); } } @@ -253,9 +252,9 @@ void Area2D::_area_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_entered), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -267,9 +266,9 @@ void Area2D::_area_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->area_exited, node); + emit_signal(SceneStringName(area_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -283,9 +282,9 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i lock_callback(); locked = true; if (area_in) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } else { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } locked = false; unlock_callback(); @@ -311,10 +310,10 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); } } } @@ -324,7 +323,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, node, p_area_shape, p_self_shape); } } else { @@ -338,15 +337,15 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i if (E->value.rc == 0) { area_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, obj, p_area_shape, p_self_shape); } } @@ -370,18 +369,18 @@ void Area2D::_clear_monitoring() { continue; } - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_body_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); } - emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + emit_signal(SceneStringName(body_exited), obj); } } @@ -398,18 +397,18 @@ void Area2D::_clear_monitoring() { continue; } - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area2D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area2D::_area_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); } - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } @@ -538,7 +537,7 @@ StringName Area2D::get_audio_bus_name() const { return audio_bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void Area2D::_validate_property(PropertyInfo &p_property) const { diff --git a/scene/2d/physics/collision_object_2d.cpp b/scene/2d/physics/collision_object_2d.cpp index 4e5852984b..00b6085f0c 100644 --- a/scene/2d/physics/collision_object_2d.cpp +++ b/scene/2d/physics/collision_object_2d.cpp @@ -31,7 +31,6 @@ #include "collision_object_2d.h" #include "scene/resources/world_2d.h" -#include "scene/scene_string_names.h" void CollisionObject2D::_notification(int p_what) { switch (p_what) { @@ -519,27 +518,27 @@ bool CollisionObject2D::is_pickable() const { void CollisionObject2D::_input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) { GDVIRTUAL_CALL(_input_event, p_viewport, p_input_event, p_shape); - emit_signal(SceneStringNames::get_singleton()->input_event, p_viewport, p_input_event, p_shape); + emit_signal(SceneStringName(input_event), p_viewport, p_input_event, p_shape); } void CollisionObject2D::_mouse_enter() { GDVIRTUAL_CALL(_mouse_enter); - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } void CollisionObject2D::_mouse_exit() { GDVIRTUAL_CALL(_mouse_exit); - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } void CollisionObject2D::_mouse_shape_enter(int p_shape) { GDVIRTUAL_CALL(_mouse_shape_enter, p_shape); - emit_signal(SceneStringNames::get_singleton()->mouse_shape_entered, p_shape); + emit_signal(SceneStringName(mouse_shape_entered), p_shape); } void CollisionObject2D::_mouse_shape_exit(int p_shape) { GDVIRTUAL_CALL(_mouse_shape_exit, p_shape); - emit_signal(SceneStringNames::get_singleton()->mouse_shape_exited, p_shape); + emit_signal(SceneStringName(mouse_shape_exited), p_shape); } void CollisionObject2D::set_only_update_transform_changes(bool p_enable) { diff --git a/scene/2d/physics/joints/joint_2d.cpp b/scene/2d/physics/joints/joint_2d.cpp index 1afac7c150..a32bcbae78 100644 --- a/scene/2d/physics/joints/joint_2d.cpp +++ b/scene/2d/physics/joints/joint_2d.cpp @@ -31,19 +31,18 @@ #include "joint_2d.h" #include "scene/2d/physics/physics_body_2d.h" -#include "scene/scene_string_names.h" void Joint2D::_disconnect_signals() { Node *node_a = get_node_or_null(a); PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a); if (body_a) { - body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); + body_a->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); } Node *node_b = get_node_or_null(b); PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b); if (body_b) { - body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); + body_b->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); } } @@ -117,8 +116,12 @@ void Joint2D::_update_joint(bool p_only_free) { ba = body_a->get_rid(); bb = body_b->get_rid(); - body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); - body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint2D::_body_exit_tree)); + if (!body_a->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree))) { + body_a->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); + } + if (!body_b->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree))) { + body_b->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint2D::_body_exit_tree)); + } PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision); } diff --git a/scene/2d/physics/rigid_body_2d.cpp b/scene/2d/physics/rigid_body_2d.cpp index 5e05c563a4..402e5c8b95 100644 --- a/scene/2d/physics/rigid_body_2d.cpp +++ b/scene/2d/physics/rigid_body_2d.cpp @@ -30,8 +30,6 @@ #include "rigid_body_2d.h" -#include "scene/scene_string_names.h" - void RigidBody2D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); @@ -44,10 +42,10 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) { contact_monitor->locked = true; E->value.in_scene = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -65,10 +63,10 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) { contact_monitor->locked = true; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -93,10 +91,10 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan //E->value.rc=0; E->value.in_scene = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree).bind(objid)); if (E->value.in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } @@ -108,7 +106,7 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan } if (E->value.in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_local_shape); } } else { @@ -122,17 +120,17 @@ void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan if (E->value.shapes.is_empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree)); if (in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); } } contact_monitor->body_map.remove(E); } if (node && in_scene) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, node, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, node, p_body_shape, p_local_shape); } } } @@ -158,7 +156,7 @@ void RigidBody2D::_sync_body_state(PhysicsDirectBodyState2D *p_state) { if (sleeping != p_state->is_sleeping()) { sleeping = p_state->is_sleeping(); - emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + emit_signal(SceneStringName(sleeping_state_changed)); } } @@ -605,8 +603,8 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody2D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody2D::_body_exit_tree)); } } diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index 5745a59297..efb5029ac4 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -31,7 +31,6 @@ #include "sprite_2d.h" #include "scene/main/window.h" -#include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED Dictionary Sprite2D::_edit_get_state() const { @@ -146,7 +145,7 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) { } queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); item_rect_changed(); } @@ -260,7 +259,7 @@ void Sprite2D::set_frame(int p_frame) { frame = p_frame; item_rect_changed(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } int Sprite2D::get_frame() const { diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 165d4d5a67..f7d672620d 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -31,7 +31,6 @@ #include "tile_map.h" #include "tile_map.compat.inc" -#include "core/core_string_names.h" #include "core/io/marshalls.h" #include "scene/gui/control.h" @@ -54,7 +53,7 @@ void TileMap::_tile_set_changed() { } void TileMap::_emit_changed() { - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMap::_set_tile_map_data_using_compatibility_format(int p_layer, TileMapDataFormat p_format, const Vector<int> &p_data) { @@ -226,91 +225,6 @@ int TileMap::get_rendering_quadrant_size() const { return rendering_quadrant_size; } -void TileMap::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) { - ERR_FAIL_COND(!p_tile_set.is_valid()); - ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id)); - ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords)); - ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile)); - TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id); - TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); - if (atlas_source) { - // Check for the frame. - if (p_frame >= 0) { - ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords)); - } - - // Get the texture. - Ref<Texture2D> tex = atlas_source->get_runtime_texture(); - if (!tex.is_valid()) { - return; - } - - // Check if we are in the texture, return otherwise. - Vector2i grid_size = atlas_source->get_atlas_grid_size(); - if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) { - return; - } - - // Get tile data. - const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile); - - // Get the tile modulation. - Color modulate = tile_data->get_modulate() * p_modulation; - - // Compute the offset. - Vector2 tile_offset = tile_data->get_texture_origin(); - - // Get destination rect. - Rect2 dest_rect; - dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size; - dest_rect.size.x += FP_ADJUST; - dest_rect.size.y += FP_ADJUST; - - bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE); - if (transpose) { - dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset); - } else { - dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset); - } - - if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) { - dest_rect.size.x = -dest_rect.size.x; - } - - if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) { - dest_rect.size.y = -dest_rect.size.y; - } - - // Draw the tile. - if (p_frame >= 0) { - Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame); - tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping()); - } else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) { - Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0); - tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping()); - } else { - real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords); - real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed; - real_t animation_offset = p_normalized_animation_offset * animation_duration; - // Accumulate durations unaffected by the speed to avoid accumulating floating point division errors. - // Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`. - real_t time_unscaled = 0.0; - for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) { - real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame); - real_t slice_start = time_unscaled / speed; - real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed; - RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset); - - Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame); - tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping()); - - time_unscaled += frame_duration_unscaled; - } - RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0); - } - } -} - void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { if (p_tileset == tile_set) { return; @@ -360,7 +274,7 @@ void TileMap::add_layer(int p_to_pos) { for (uint32_t i = 0; i < layers.size(); i++) { layers[i]->set_as_tile_map_internal_node(i); } - new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); + new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed)); notify_property_list_changed(); @@ -768,7 +682,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) { new_layer->set_as_tile_map_internal_node(index); new_layer->set_name(vformat("Layer%d", index)); new_layer->set_tile_set(tile_set); - new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); + new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); } @@ -1051,7 +965,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY_DEFAULT("format", TileMapDataFormat::TILE_MAP_DATA_FORMAT_1); - ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed)); + ADD_SIGNAL(MethodInfo(CoreStringName(changed))); BIND_ENUM_CONSTANT(VISIBILITY_MODE_DEFAULT); BIND_ENUM_CONSTANT(VISIBILITY_MODE_FORCE_HIDE); @@ -1064,7 +978,7 @@ TileMap::TileMap() { new_layer->set_as_tile_map_internal_node(0); new_layer->set_name("Layer0"); new_layer->set_tile_set(tile_set); - new_layer->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TileMap::_emit_changed)); + new_layer->connect(CoreStringName(changed), callable_mp(this, &TileMap::_emit_changed)); layers.push_back(new_layer); if (!base_property_helper.is_initialized()) { @@ -1073,6 +987,7 @@ TileMap::TileMap() { TileMapLayer *defaults = memnew(TileMapLayer); base_property_helper.set_prefix("layer_"); + base_property_helper.set_array_length_getter(&TileMap::get_layers_count); base_property_helper.register_property(PropertyInfo(Variant::STRING, "name"), defaults->get_name(), &TileMap::set_layer_name, &TileMap::get_layer_name); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "enabled"), defaults->is_enabled(), &TileMap::set_layer_enabled, &TileMap::is_layer_enabled); base_property_helper.register_property(PropertyInfo(Variant::COLOR, "modulate"), defaults->get_modulate(), &TileMap::set_layer_modulate, &TileMap::get_layer_modulate); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 45604bfb8a..690102f730 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -63,8 +63,6 @@ private: // A compatibility enum to specify how is the data if formatted. mutable TileMapDataFormat format = TileMapDataFormat::TILE_MAP_DATA_FORMAT_3; - static constexpr float FP_ADJUST = 0.00001; - // Properties. Ref<TileSet> tile_set; int rendering_quadrant_size = 16; @@ -123,8 +121,6 @@ public: void set_rendering_quadrant_size(int p_size); int get_rendering_quadrant_size() const; - static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0); - // Accessors. void set_tileset(const Ref<TileSet> &p_tileset); Ref<TileSet> get_tileset() const; diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index fd1a638b58..0ac236eaa7 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -30,7 +30,6 @@ #include "tile_map_layer.h" -#include "core/core_string_names.h" #include "core/io/marshalls.h" #include "scene/2d/tile_map.h" #include "scene/gui/control.h" @@ -341,7 +340,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { } // Drawing the tile in the canvas item. - TileMap::draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset); + draw_tile(ci, local_tile_pos - rendering_quadrant->canvas_items_position, tile_set, cell_data.cell.source_id, cell_data.cell.get_atlas_coords(), cell_data.cell.alternative_tile, -1, get_self_modulate(), tile_data, random_animation_offset); } // Reset physics interpolation for any recreated canvas items. @@ -604,6 +603,7 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) { rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder(occlusion_layer_index, flip_h, flip_v, transpose)->get_rid()); rs->canvas_light_occluder_attach_to_canvas(occluder, get_canvas()); rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index)); + rs->canvas_light_occluder_set_as_sdf_collision(occluder, tile_set->get_occlusion_layer_sdf_collision(occlusion_layer_index)); } else { // Clear occluder. if (occluder.is_valid()) { @@ -1598,11 +1598,11 @@ RBSet<TerrainConstraint> TileMapLayer::_get_terrain_constraints_from_painted_cel void TileMapLayer::_tile_set_changed() { dirty.flags[DIRTY_FLAGS_TILE_SET] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::_renamed() { - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::_update_notify_local_transform() { @@ -1696,18 +1696,18 @@ void TileMapLayer::_notification(int p_what) { _internal_update(true); } break; - case TileMap::NOTIFICATION_ENTER_CANVAS: { + case NOTIFICATION_ENTER_CANVAS: { dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true; _queue_internal_update(); } break; - case TileMap::NOTIFICATION_EXIT_CANVAS: { + case NOTIFICATION_EXIT_CANVAS: { dirty.flags[DIRTY_FLAGS_LAYER_IN_CANVAS] = true; // Update immediately on exiting, and force cleanup. _internal_update(true); } break; - case TileMap::NOTIFICATION_VISIBILITY_CHANGED: { + case NOTIFICATION_VISIBILITY_CHANGED: { dirty.flags[DIRTY_FLAGS_LAYER_VISIBILITY] = true; _queue_internal_update(); } break; @@ -1805,7 +1805,7 @@ void TileMapLayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "navigation_enabled"), "set_navigation_enabled", "is_navigation_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode"); - ADD_SIGNAL(MethodInfo(CoreStringNames::get_singleton()->changed)); + ADD_SIGNAL(MethodInfo(CoreStringName(changed))); ADD_PROPERTY_DEFAULT("tile_map_data_format", TileMapDataFormat::TILE_MAP_DATA_FORMAT_1); @@ -1819,7 +1819,7 @@ void TileMapLayer::_update_self_texture_filter(RS::CanvasItemTextureFilter p_tex CanvasItem::_update_self_texture_filter(p_texture_filter); dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_FILTER] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::_update_self_texture_repeat(RS::CanvasItemTextureRepeat p_texture_repeat) { @@ -1827,7 +1827,7 @@ void TileMapLayer::_update_self_texture_repeat(RS::CanvasItemTextureRepeat p_tex CanvasItem::_update_self_texture_repeat(p_texture_repeat); dirty.flags[DIRTY_FLAGS_LAYER_TEXTURE_REPEAT] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_as_tile_map_internal_node(int p_index) { @@ -2162,6 +2162,91 @@ TileMapCell TileMapLayer::get_cell(const Vector2i &p_coords) const { } } +void TileMapLayer::draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override, real_t p_normalized_animation_offset) { + ERR_FAIL_COND(p_tile_set.is_null()); + ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id)); + ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords)); + ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_alternative_tile(p_atlas_coords, p_alternative_tile)); + TileSetSource *source = *p_tile_set->get_source(p_atlas_source_id); + TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); + if (atlas_source) { + // Check for the frame. + if (p_frame >= 0) { + ERR_FAIL_INDEX(p_frame, atlas_source->get_tile_animation_frames_count(p_atlas_coords)); + } + + // Get the texture. + Ref<Texture2D> tex = atlas_source->get_runtime_texture(); + if (tex.is_null()) { + return; + } + + // Check if we are in the texture, return otherwise. + Vector2i grid_size = atlas_source->get_atlas_grid_size(); + if (p_atlas_coords.x >= grid_size.x || p_atlas_coords.y >= grid_size.y) { + return; + } + + // Get tile data. + const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile); + + // Get the tile modulation. + Color modulate = tile_data->get_modulate() * p_modulation; + + // Compute the offset. + Vector2 tile_offset = tile_data->get_texture_origin(); + + // Get destination rect. + Rect2 dest_rect; + dest_rect.size = atlas_source->get_runtime_tile_texture_region(p_atlas_coords).size; + dest_rect.size.x += FP_ADJUST; + dest_rect.size.y += FP_ADJUST; + + bool transpose = tile_data->get_transpose() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE); + if (transpose) { + dest_rect.position = (p_position - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset); + } else { + dest_rect.position = (p_position - dest_rect.size / 2 - tile_offset); + } + + if (tile_data->get_flip_h() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H)) { + dest_rect.size.x = -dest_rect.size.x; + } + + if (tile_data->get_flip_v() ^ bool(p_alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V)) { + dest_rect.size.y = -dest_rect.size.y; + } + + // Draw the tile. + if (p_frame >= 0) { + Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, p_frame); + tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping()); + } else if (atlas_source->get_tile_animation_frames_count(p_atlas_coords) == 1) { + Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, 0); + tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping()); + } else { + real_t speed = atlas_source->get_tile_animation_speed(p_atlas_coords); + real_t animation_duration = atlas_source->get_tile_animation_total_duration(p_atlas_coords) / speed; + real_t animation_offset = p_normalized_animation_offset * animation_duration; + // Accumulate durations unaffected by the speed to avoid accumulating floating point division errors. + // Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`. + real_t time_unscaled = 0.0; + for (int frame = 0; frame < atlas_source->get_tile_animation_frames_count(p_atlas_coords); frame++) { + real_t frame_duration_unscaled = atlas_source->get_tile_animation_frame_duration(p_atlas_coords, frame); + real_t slice_start = time_unscaled / speed; + real_t slice_end = (time_unscaled + frame_duration_unscaled) / speed; + RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, animation_duration, slice_start, slice_end, animation_offset); + + Rect2i source_rect = atlas_source->get_runtime_tile_texture_region(p_atlas_coords, frame); + tex->draw_rect_region(p_canvas_item, dest_rect, source_rect, modulate, transpose, p_tile_set->is_uv_clipping()); + + time_unscaled += frame_duration_unscaled; + } + RenderingServer::get_singleton()->canvas_item_add_animation_slice(p_canvas_item, 1.0, 0.0, 1.0, 0.0); + } + } +} + void TileMapLayer::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile) { // Set the current cell tile (using integer position). Vector2i pk(p_coords); @@ -2212,7 +2297,7 @@ void TileMapLayer::erase_cell(const Vector2i &p_coords) { } void TileMapLayer::fix_invalid_tiles() { - ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMap without a valid TileSet."); + ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot call fix_invalid_tiles() on a TileMapLayer without a valid TileSet."); RBSet<Vector2i> coords; for (const KeyValue<Vector2i, CellData> &E : tile_map_layer_data) { @@ -2502,7 +2587,7 @@ void TileMapLayer::update_internals() { void TileMapLayer::notify_runtime_tile_data_update() { dirty.flags[TileMapLayer::DIRTY_FLAGS_LAYER_RUNTIME_UPDATE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } Vector2i TileMapLayer::map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern) { @@ -2537,7 +2622,7 @@ void TileMapLayer::set_enabled(bool p_enabled) { enabled = p_enabled; dirty.flags[DIRTY_FLAGS_LAYER_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_enabled() const { @@ -2563,7 +2648,7 @@ void TileMapLayer::set_tile_set(const Ref<TileSet> &p_tile_set) { tile_set->connect_changed(callable_mp(this, &TileMapLayer::_tile_set_changed)); } - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); // Trigger updates for TileSet's read-only status. notify_property_list_changed(); @@ -2675,7 +2760,7 @@ void TileMapLayer::set_self_modulate(const Color &p_self_modulate) { CanvasItem::set_self_modulate(p_self_modulate); dirty.flags[DIRTY_FLAGS_LAYER_SELF_MODULATE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) { @@ -2685,7 +2770,7 @@ void TileMapLayer::set_y_sort_enabled(bool p_y_sort_enabled) { CanvasItem::set_y_sort_enabled(p_y_sort_enabled); dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); _update_notify_local_transform(); } @@ -2697,7 +2782,7 @@ void TileMapLayer::set_y_sort_origin(int p_y_sort_origin) { y_sort_origin = p_y_sort_origin; dirty.flags[DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } int TileMapLayer::get_y_sort_origin() const { @@ -2711,7 +2796,7 @@ void TileMapLayer::set_z_index(int p_z_index) { CanvasItem::set_z_index(p_z_index); dirty.flags[DIRTY_FLAGS_LAYER_Z_INDEX] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_light_mask(int p_light_mask) { @@ -2721,7 +2806,7 @@ void TileMapLayer::set_light_mask(int p_light_mask) { CanvasItem::set_light_mask(p_light_mask); dirty.flags[DIRTY_FLAGS_LAYER_LIGHT_MASK] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } void TileMapLayer::set_rendering_quadrant_size(int p_size) { @@ -2733,7 +2818,7 @@ void TileMapLayer::set_rendering_quadrant_size(int p_size) { rendering_quadrant_size = p_size; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } int TileMapLayer::get_rendering_quadrant_size() const { @@ -2747,7 +2832,7 @@ void TileMapLayer::set_collision_enabled(bool p_enabled) { collision_enabled = p_enabled; dirty.flags[DIRTY_FLAGS_LAYER_COLLISION_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_collision_enabled() const { @@ -2758,7 +2843,7 @@ void TileMapLayer::set_use_kinematic_bodies(bool p_use_kinematic_bodies) { use_kinematic_bodies = p_use_kinematic_bodies; dirty.flags[DIRTY_FLAGS_LAYER_USE_KINEMATIC_BODIES] = p_use_kinematic_bodies; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_using_kinematic_bodies() const { @@ -2772,7 +2857,7 @@ void TileMapLayer::set_collision_visibility_mode(TileMapLayer::DebugVisibilityMo collision_visibility_mode = p_show_collision; dirty.flags[DIRTY_FLAGS_LAYER_COLLISION_VISIBILITY_MODE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } TileMapLayer::DebugVisibilityMode TileMapLayer::get_collision_visibility_mode() const { @@ -2786,7 +2871,7 @@ void TileMapLayer::set_navigation_enabled(bool p_enabled) { navigation_enabled = p_enabled; dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_ENABLED] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } bool TileMapLayer::is_navigation_enabled() const { @@ -2800,7 +2885,7 @@ void TileMapLayer::set_navigation_map(RID p_map) { navigation_map_override = p_map; dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_MAP] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } RID TileMapLayer::get_navigation_map() const { @@ -2819,7 +2904,7 @@ void TileMapLayer::set_navigation_visibility_mode(TileMapLayer::DebugVisibilityM navigation_visibility_mode = p_show_navigation; dirty.flags[DIRTY_FLAGS_LAYER_NAVIGATION_VISIBILITY_MODE] = true; _queue_internal_update(); - emit_signal(CoreStringNames::get_singleton()->changed); + emit_signal(CoreStringName(changed)); } TileMapLayer::DebugVisibilityMode TileMapLayer::get_navigation_visibility_mode() const { diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h index 5861433c8a..57c83d7c4c 100644 --- a/scene/2d/tile_map_layer.h +++ b/scene/2d/tile_map_layer.h @@ -269,6 +269,8 @@ public: }; private: + static constexpr float FP_ADJUST = 0.00001; + // Properties. HashMap<Vector2i, CellData> tile_map_layer_data; @@ -407,6 +409,8 @@ public: // Not exposed to users. TileMapCell get_cell(const Vector2i &p_coords) const; + static void draw_tile(RID p_canvas_item, const Vector2 &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr, real_t p_normalized_animation_offset = 0.0); + ////////////// Exposed functions ////////////// // --- Cells manipulation --- diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 5ed7fadb2a..ff409272c5 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -31,18 +31,17 @@ #include "touch_screen_button.h" #include "scene/main/window.h" -#include "scene/scene_string_names.h" void TouchScreenButton::set_texture_normal(const Ref<Texture2D> &p_texture) { if (texture_normal == p_texture) { return; } if (texture_normal.is_valid()) { - texture_normal->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); + texture_normal->disconnect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); } texture_normal = p_texture; if (texture_normal.is_valid()) { - texture_normal->connect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); + texture_normal->connect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); } queue_redraw(); } @@ -56,11 +55,11 @@ void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pres return; } if (texture_pressed.is_valid()) { - texture_pressed->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); + texture_pressed->disconnect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); } texture_pressed = p_texture_pressed; if (texture_pressed.is_valid()) { - texture_pressed->connect(SceneStringNames::get_singleton()->changed, callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); + texture_pressed->connect(CoreStringName(changed), callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw), CONNECT_REFERENCE_COUNTED); } queue_redraw(); } @@ -306,7 +305,7 @@ void TouchScreenButton::_press(int p_finger_pressed) { get_viewport()->push_input(iea, true); } - emit_signal(SNAME("pressed")); + emit_signal(SceneStringName(pressed)); queue_redraw(); } @@ -371,10 +370,10 @@ bool TouchScreenButton::is_passby_press_enabled() const { #ifndef DISABLE_DEPRECATED bool TouchScreenButton::_set(const StringName &p_name, const Variant &p_value) { - if (p_name == SNAME("normal")) { // Compatibility with Godot 3.x. + if (p_name == CoreStringName(normal)) { // Compatibility with Godot 3.x. set_texture_normal(p_value); return true; - } else if (p_name == SNAME("pressed")) { // Compatibility with Godot 3.x. + } else if (p_name == SceneStringName(pressed)) { // Compatibility with Godot 3.x. set_texture_pressed(p_value); return true; } diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp index 89b2c20b20..c64507fe32 100644 --- a/scene/2d/visible_on_screen_notifier_2d.cpp +++ b/scene/2d/visible_on_screen_notifier_2d.cpp @@ -30,8 +30,6 @@ #include "visible_on_screen_notifier_2d.h" -#include "scene/scene_string_names.h" - #ifdef TOOLS_ENABLED Rect2 VisibleOnScreenNotifier2D::_edit_get_rect() const { return rect; @@ -48,7 +46,7 @@ void VisibleOnScreenNotifier2D::_visibility_enter() { } on_screen = true; - emit_signal(SceneStringNames::get_singleton()->screen_entered); + emit_signal(SceneStringName(screen_entered)); _screen_enter(); } void VisibleOnScreenNotifier2D::_visibility_exit() { @@ -57,7 +55,7 @@ void VisibleOnScreenNotifier2D::_visibility_exit() { } on_screen = false; - emit_signal(SceneStringNames::get_singleton()->screen_exited); + emit_signal(SceneStringName(screen_exited)); _screen_exit(); } diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index 6afbc68e42..2716738684 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -149,7 +149,7 @@ void BoneAttachment3D::_check_bind() { bone_idx = sk->find_bone(bone_name); } if (bone_idx != -1) { - sk->connect(SNAME("skeleton_updated"), callable_mp(this, &BoneAttachment3D::on_skeleton_update)); + sk->connect(SceneStringName(skeleton_updated), callable_mp(this, &BoneAttachment3D::on_skeleton_update)); bound = true; callable_mp(this, &BoneAttachment3D::on_skeleton_update); } @@ -177,7 +177,7 @@ void BoneAttachment3D::_check_unbind() { Skeleton3D *sk = _get_skeleton3d(); if (sk) { - sk->disconnect(SNAME("skeleton_updated"), callable_mp(this, &BoneAttachment3D::on_skeleton_update)); + sk->disconnect(SceneStringName(skeleton_updated), callable_mp(this, &BoneAttachment3D::on_skeleton_update)); } bound = false; } diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 5aa50a4a21..03fe5e1fad 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -37,7 +37,6 @@ #include "scene/resources/gradient_texture.h" #include "scene/resources/image_texture.h" #include "scene/resources/particle_process_material.h" -#include "scene/scene_string_names.h" AABB CPUParticles3D::get_aabb() const { return AABB(); @@ -880,7 +879,7 @@ void CPUParticles3D::_particles_process(double p_delta) { } break; case EMISSION_SHAPE_RING: { real_t ring_random_angle = Math::randf() * Math_TAU; - real_t ring_random_radius = Math::sqrt(Math::randf() * (emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius); + real_t ring_random_radius = Math::sqrt(Math::randf() * (emission_ring_radius * emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius); Vector3 axis = emission_ring_axis == Vector3(0.0, 0.0, 0.0) ? Vector3(0.0, 0.0, 1.0) : emission_ring_axis.normalized(); Vector3 ortho_axis; if (axis.abs() == Vector3(1.0, 0.0, 0.0)) { @@ -1156,7 +1155,7 @@ void CPUParticles3D::_particles_process(double p_delta) { } if (!Math::is_equal_approx(time, 0.0) && active && !should_be_active) { active = false; - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } } diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 16813b9017..3771b385e5 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -34,7 +34,6 @@ #include "scene/resources/curve_texture.h" #include "scene/resources/gradient_texture.h" #include "scene/resources/particle_process_material.h" -#include "scene/scene_string_names.h" AABB GPUParticles3D::get_aabb() const { return AABB(); @@ -478,7 +477,7 @@ void GPUParticles3D::_notification(int p_what) { } if (time > active_time) { if (active && !signal_canceled) { - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } active = false; if (!emitting) { diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index 54370f42da..0f2ce829eb 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -32,7 +32,6 @@ #include "scene/main/viewport.h" #include "scene/resources/theme.h" -#include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" void Label3D::_bind_methods() { diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index cc923b6676..ef492a6994 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -1102,7 +1102,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa } } - Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, denoiser_strength, bounces, bounce_indirect_energy, bias, max_texture_size, directional, use_texture_for_bounces, Lightmapper::GenerateProbes(gen_probes), environment_image, environment_transform, _lightmap_bake_step_function, &bsud, exposure_normalization); + Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, denoiser_strength, denoiser_range, bounces, bounce_indirect_energy, bias, max_texture_size, directional, use_texture_for_bounces, Lightmapper::GenerateProbes(gen_probes), environment_image, environment_transform, _lightmap_bake_step_function, &bsud, exposure_normalization); if (bake_err == Lightmapper::BAKE_ERROR_LIGHTMAP_TOO_SMALL) { return BAKE_ERROR_TEXTURE_SIZE_TOO_SMALL; @@ -1450,6 +1450,14 @@ float LightmapGI::get_denoiser_strength() const { return denoiser_strength; } +void LightmapGI::set_denoiser_range(int p_denoiser_range) { + denoiser_range = p_denoiser_range; +} + +int LightmapGI::get_denoiser_range() const { + return denoiser_range; +} + void LightmapGI::set_directional(bool p_enable) { directional = p_enable; } @@ -1593,6 +1601,9 @@ void LightmapGI::_validate_property(PropertyInfo &p_property) const { if (p_property.name == "denoiser_strength" && !use_denoiser) { p_property.usage = PROPERTY_USAGE_NONE; } + if (p_property.name == "denoiser_range" && !use_denoiser) { + p_property.usage = PROPERTY_USAGE_NONE; + } } void LightmapGI::_bind_methods() { @@ -1638,6 +1649,9 @@ void LightmapGI::_bind_methods() { ClassDB::bind_method(D_METHOD("set_denoiser_strength", "denoiser_strength"), &LightmapGI::set_denoiser_strength); ClassDB::bind_method(D_METHOD("get_denoiser_strength"), &LightmapGI::get_denoiser_strength); + ClassDB::bind_method(D_METHOD("set_denoiser_range", "denoiser_range"), &LightmapGI::set_denoiser_range); + ClassDB::bind_method(D_METHOD("get_denoiser_range"), &LightmapGI::get_denoiser_range); + ClassDB::bind_method(D_METHOD("set_interior", "enable"), &LightmapGI::set_interior); ClassDB::bind_method(D_METHOD("is_interior"), &LightmapGI::is_interior); @@ -1661,6 +1675,7 @@ void LightmapGI::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_denoiser"), "set_use_denoiser", "is_using_denoiser"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "denoiser_strength", PROPERTY_HINT_RANGE, "0.001,0.2,0.001,or_greater"), "set_denoiser_strength", "get_denoiser_strength"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "denoiser_range", PROPERTY_HINT_RANGE, "1,20"), "set_denoiser_range", "get_denoiser_range"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0.00001,0.1,0.00001,or_greater"), "set_bias", "get_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texel_scale", PROPERTY_HINT_RANGE, "0.01,100.0,0.01"), "set_texel_scale", "get_texel_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_texture_size", PROPERTY_HINT_RANGE, "2048,16384,1"), "set_max_texture_size", "get_max_texture_size"); diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h index 765e4a731d..527667177b 100644 --- a/scene/3d/lightmap_gi.h +++ b/scene/3d/lightmap_gi.h @@ -156,6 +156,7 @@ private: BakeQuality bake_quality = BAKE_QUALITY_MEDIUM; bool use_denoiser = true; float denoiser_strength = 0.1f; + int denoiser_range = 10; int bounces = 3; float bounce_indirect_energy = 1.0; float bias = 0.0005; @@ -256,6 +257,9 @@ public: void set_denoiser_strength(float p_denoiser_strength); float get_denoiser_strength() const; + void set_denoiser_range(int p_denoiser_range); + int get_denoiser_range() const; + void set_directional(bool p_enable); bool is_directional() const; diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h index 521013d600..39181ad9a2 100644 --- a/scene/3d/lightmapper.h +++ b/scene/3d/lightmapper.h @@ -180,7 +180,7 @@ public: virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) = 0; virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) = 0; virtual void add_probe(const Vector3 &p_position) = 0; - virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_bounces, float p_bounce_indirect_energy, float p_bias, int p_max_texture_size, bool p_bake_sh, bool p_texture_for_bounces, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, float p_exposure_normalization = 1.0) = 0; + virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_denoiser_range, int p_bounces, float p_bounce_indirect_energy, float p_bias, int p_max_texture_size, bool p_bake_sh, bool p_texture_for_bounces, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr, float p_exposure_normalization = 1.0) = 0; virtual int get_bake_texture_count() const = 0; virtual Ref<Image> get_bake_texture(int p_index) const = 0; diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 43c41c1b5b..dff413f5d2 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -865,7 +865,7 @@ void NavigationAgent3D::_trigger_waypoint_reached() { Dictionary details; const Vector3 waypoint = navigation_path[navigation_path_index]; - details[SNAME("position")] = waypoint; + details[CoreStringName(position)] = waypoint; int waypoint_type = -1; if (path_metadata_flags.has_flag(NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) { diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 856c52b5d5..40e04f0fb4 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -474,7 +474,7 @@ void NavigationRegion3D::_update_debug_mesh() { return; } - if (!NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { + if (!NavigationServer3D::get_singleton()->get_debug_enabled() || !NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { if (debug_instance.is_valid()) { RS::get_singleton()->instance_set_visible(debug_instance, false); } @@ -640,7 +640,7 @@ void NavigationRegion3D::_update_debug_mesh() { #ifdef DEBUG_ENABLED void NavigationRegion3D::_update_debug_edge_connections_mesh() { - if (!NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { + if (!NavigationServer3D::get_singleton()->get_debug_enabled() || !NavigationServer3D::get_singleton()->get_debug_navigation_enabled()) { if (debug_edge_connections_instance.is_valid()) { RS::get_singleton()->instance_set_visible(debug_edge_connections_instance, false); } diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 98a5134283..2e08afb30d 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -33,7 +33,6 @@ #include "scene/3d/visual_instance_3d.h" #include "scene/main/viewport.h" #include "scene/property_utils.h" -#include "scene/scene_string_names.h" /* @@ -193,12 +192,12 @@ void Node3D::_notification(int p_what) { ERR_FAIL_NULL(data.viewport); if (get_script_instance()) { - get_script_instance()->call(SceneStringNames::get_singleton()->_enter_world); + get_script_instance()->call(SNAME("_enter_world")); } #ifdef TOOLS_ENABLED if (is_part_of_edited_scene()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SNAME("_request_gizmo_for_id"), get_instance_id()); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_request_gizmo_for_id"), get_instance_id()); } #endif } break; @@ -211,7 +210,7 @@ void Node3D::_notification(int p_what) { #endif if (get_script_instance()) { - get_script_instance()->call(SceneStringNames::get_singleton()->_exit_world); + get_script_instance()->call(SNAME("_exit_world")); } data.viewport = nullptr; @@ -564,7 +563,7 @@ void Node3D::update_gizmos() { } if (data.gizmos.is_empty()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SNAME("_request_gizmo_for_id"), get_instance_id()); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_request_gizmo_for_id"), get_instance_id()); return; } if (data.gizmos_dirty) { @@ -583,7 +582,7 @@ void Node3D::set_subgizmo_selection(Ref<Node3DGizmo> p_gizmo, int p_id, Transfor } if (is_part_of_edited_scene()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_set_subgizmo_selection, this, p_gizmo, p_id, p_transform); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_set_subgizmo_selection"), this, p_gizmo, p_id, p_transform); } #endif } @@ -600,7 +599,7 @@ void Node3D::clear_subgizmo_selection() { } if (is_part_of_edited_scene()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_clear_subgizmo_selection, this); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(_spatial_editor_group), SNAME("_clear_subgizmo_selection"), this); } #endif } @@ -777,7 +776,7 @@ Ref<World3D> Node3D::get_world_3d() const { void Node3D::_propagate_visibility_changed() { notification(NOTIFICATION_VISIBILITY_CHANGED); - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); #ifdef TOOLS_ENABLED if (!data.gizmos.is_empty()) { diff --git a/scene/3d/physical_bone_simulator_3d.cpp b/scene/3d/physical_bone_simulator_3d.cpp index aba052165c..ef3c51b032 100644 --- a/scene/3d/physical_bone_simulator_3d.cpp +++ b/scene/3d/physical_bone_simulator_3d.cpp @@ -35,16 +35,16 @@ void PhysicalBoneSimulator3D::_skeleton_changed(Skeleton3D *p_old, Skeleton3D *p if (p_old->is_connected(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed))) { p_old->disconnect(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed)); } - if (p_old->is_connected(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) { - p_old->disconnect(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated)); + if (p_old->is_connected(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) { + p_old->disconnect(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated)); } } if (p_new) { if (!p_new->is_connected(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed))) { p_new->connect(SNAME("bone_list_changed"), callable_mp(this, &PhysicalBoneSimulator3D::_bone_list_changed)); } - if (!p_new->is_connected(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) { - p_new->connect(SNAME("pose_updated"), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated)); + if (!p_new->is_connected(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated))) { + p_new->connect(SceneStringName(pose_updated), callable_mp(this, &PhysicalBoneSimulator3D::_pose_updated)); } } _bone_list_changed(); diff --git a/scene/3d/physics/area_3d.cpp b/scene/3d/physics/area_3d.cpp index 014c33cad0..be95512bea 100644 --- a/scene/3d/physics/area_3d.cpp +++ b/scene/3d/physics/area_3d.cpp @@ -30,7 +30,6 @@ #include "area_3d.h" -#include "scene/scene_string_names.h" #include "servers/audio_server.h" void Area3D::set_gravity_space_override_mode(SpaceOverride p_mode) { @@ -199,9 +198,9 @@ void Area3D::_body_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -213,9 +212,9 @@ void Area3D::_body_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].area_shape); } } @@ -229,9 +228,9 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i locked = true; // Emit the appropriate signals. if (body_in) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } else { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, (Node *)nullptr, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, (Node *)nullptr, p_body_shape, p_area_shape); } locked = false; unlock_callback(); @@ -257,10 +256,10 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } } @@ -270,7 +269,7 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_area_shape); } } else { @@ -284,15 +283,15 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i if (E->value.rc == 0) { body_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_exited, obj); + emit_signal(SceneStringName(body_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_area_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_area_shape); } } @@ -317,18 +316,18 @@ void Area3D::_clear_monitoring() { } //ERR_CONTINUE(!node); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_body_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); + emit_signal(SceneStringName(body_shape_exited), E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); } - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); } } @@ -346,18 +345,18 @@ void Area3D::_clear_monitoring() { } //ERR_CONTINUE(!node); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree)); if (!E.value.in_tree) { continue; } for (int i = 0; i < E.value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); } - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } @@ -405,9 +404,9 @@ void Area3D::_area_enter_tree(ObjectID p_id) { ERR_FAIL_COND(E->value.in_tree); E->value.in_tree = true; - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_entered), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -419,9 +418,9 @@ void Area3D::_area_exit_tree(ObjectID p_id) { ERR_FAIL_COND(!E); ERR_FAIL_COND(!E->value.in_tree); E->value.in_tree = false; - emit_signal(SceneStringNames::get_singleton()->area_exited, node); + emit_signal(SceneStringName(area_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); + emit_signal(SceneStringName(area_shape_exited), E->value.rid, node, E->value.shapes[i].area_shape, E->value.shapes[i].self_shape); } } @@ -435,9 +434,9 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i locked = true; // Emit the appropriate signals. if (area_in) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } else { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, (Node *)nullptr, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, (Node *)nullptr, p_area_shape, p_self_shape); } locked = false; unlock_callback(); @@ -463,10 +462,10 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i E->value.rc = 0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_entered, node); + emit_signal(SceneStringName(area_entered), node); } } } @@ -476,7 +475,7 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i } if (!node || E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_area, node, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_entered), p_area, node, p_area_shape, p_self_shape); } } else { @@ -490,15 +489,15 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i if (E->value.rc == 0) { area_map.remove(E); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &Area3D::_area_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Area3D::_area_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_exited, obj); + emit_signal(SceneStringName(area_exited), obj); } } } if (!node || in_tree) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_area, obj, p_area_shape, p_self_shape); + emit_signal(SceneStringName(area_shape_exited), p_area, obj, p_area_shape, p_self_shape); } } @@ -605,7 +604,7 @@ StringName Area3D::get_audio_bus_name() const { return audio_bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void Area3D::set_use_reverb_bus(bool p_enable) { @@ -626,7 +625,7 @@ StringName Area3D::get_reverb_bus_name() const { return reverb_bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void Area3D::set_reverb_amount(float p_amount) { @@ -812,6 +811,8 @@ void Area3D::_bind_methods() { Area3D::Area3D() : CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) { + audio_bus = SceneStringName(Master); + reverb_bus = SceneStringName(Master); set_gravity(9.8); set_gravity_direction(Vector3(0, -1, 0)); set_monitoring(true); diff --git a/scene/3d/physics/area_3d.h b/scene/3d/physics/area_3d.h index 41382b6128..8848f9c23a 100644 --- a/scene/3d/physics/area_3d.h +++ b/scene/3d/physics/area_3d.h @@ -33,7 +33,6 @@ #include "core/templates/vset.h" #include "scene/3d/physics/collision_object_3d.h" -#include "scene/scene_string_names.h" class Area3D : public CollisionObject3D { GDCLASS(Area3D, CollisionObject3D); @@ -135,10 +134,10 @@ private: void _clear_monitoring(); bool audio_bus_override = false; - StringName audio_bus = SceneStringNames::get_singleton()->Master; + StringName audio_bus; bool use_reverb_bus = false; - StringName reverb_bus = SceneStringNames::get_singleton()->Master; + StringName reverb_bus; float reverb_amount = 0.0; float reverb_uniformity = 0.0; diff --git a/scene/3d/physics/collision_object_3d.cpp b/scene/3d/physics/collision_object_3d.cpp index 54752b1281..dddaf7eb4a 100644 --- a/scene/3d/physics/collision_object_3d.cpp +++ b/scene/3d/physics/collision_object_3d.cpp @@ -31,7 +31,6 @@ #include "collision_object_3d.h" #include "scene/resources/3d/shape_3d.h" -#include "scene/scene_string_names.h" void CollisionObject3D::_notification(int p_what) { switch (p_what) { @@ -291,17 +290,17 @@ void CollisionObject3D::_apply_enabled() { void CollisionObject3D::_input_event_call(Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) { GDVIRTUAL_CALL(_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape); - emit_signal(SceneStringNames::get_singleton()->input_event, p_camera, p_input_event, p_pos, p_normal, p_shape); + emit_signal(SceneStringName(input_event), p_camera, p_input_event, p_pos, p_normal, p_shape); } void CollisionObject3D::_mouse_enter() { GDVIRTUAL_CALL(_mouse_enter); - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } void CollisionObject3D::_mouse_exit() { GDVIRTUAL_CALL(_mouse_exit); - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } void CollisionObject3D::set_body_mode(PhysicsServer3D::BodyMode p_mode) { diff --git a/scene/3d/physics/joints/cone_twist_joint_3d.cpp b/scene/3d/physics/joints/cone_twist_joint_3d.cpp index 404c074911..3da0cbee71 100644 --- a/scene/3d/physics/joints/cone_twist_joint_3d.cpp +++ b/scene/3d/physics/joints/cone_twist_joint_3d.cpp @@ -30,8 +30,6 @@ #include "cone_twist_joint_3d.h" -#include "scene/scene_string_names.h" - void ConeTwistJoint3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &ConeTwistJoint3D::set_param); ClassDB::bind_method(D_METHOD("get_param", "param"), &ConeTwistJoint3D::get_param); diff --git a/scene/3d/physics/joints/joint_3d.cpp b/scene/3d/physics/joints/joint_3d.cpp index a9c2526bd0..47c89f37e2 100644 --- a/scene/3d/physics/joints/joint_3d.cpp +++ b/scene/3d/physics/joints/joint_3d.cpp @@ -30,19 +30,17 @@ #include "joint_3d.h" -#include "scene/scene_string_names.h" - void Joint3D::_disconnect_signals() { Node *node_a = get_node_or_null(a); PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a); if (body_a) { - body_a->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + body_a->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); } Node *node_b = get_node_or_null(b); PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b); if (body_b) { - body_b->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + body_b->disconnect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); } } @@ -108,12 +106,16 @@ void Joint3D::_update_joint(bool p_only_free) { if (body_a) { ba = body_a->get_rid(); - body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + if (!body_a->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree))) { + body_a->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); + } } if (body_b) { bb = body_b->get_rid(); - body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); + if (!body_b->is_connected(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree))) { + body_b->connect(SceneStringName(tree_exiting), callable_mp(this, &Joint3D::_body_exit_tree)); + } } PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision); diff --git a/scene/3d/physics/joints/slider_joint_3d.cpp b/scene/3d/physics/joints/slider_joint_3d.cpp index 2e87ae1e83..df6b1cc045 100644 --- a/scene/3d/physics/joints/slider_joint_3d.cpp +++ b/scene/3d/physics/joints/slider_joint_3d.cpp @@ -30,8 +30,6 @@ #include "slider_joint_3d.h" -#include "scene/scene_string_names.h" - void SliderJoint3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &SliderJoint3D::set_param); ClassDB::bind_method(D_METHOD("get_param", "param"), &SliderJoint3D::get_param); diff --git a/scene/3d/physics/rigid_body_3d.cpp b/scene/3d/physics/rigid_body_3d.cpp index 6cd621c1c7..5ea413f2c4 100644 --- a/scene/3d/physics/rigid_body_3d.cpp +++ b/scene/3d/physics/rigid_body_3d.cpp @@ -30,8 +30,6 @@ #include "rigid_body_3d.h" -#include "scene/scene_string_names.h" - void RigidBody3D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); @@ -45,10 +43,10 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) { contact_monitor->locked = true; - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_entered), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -66,10 +64,10 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) { contact_monitor->locked = true; - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); for (int i = 0; i < E->value.shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); + emit_signal(SceneStringName(body_shape_exited), E->value.rid, node, E->value.shapes[i].body_shape, E->value.shapes[i].local_shape); } contact_monitor->locked = false; @@ -94,10 +92,10 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan //E->value.rc=0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree).bind(objid)); + node->connect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree).bind(objid)); + node->connect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_entered, node); + emit_signal(SceneStringName(body_entered), node); } } } @@ -107,7 +105,7 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan } if (E->value.in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_body, node, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_entered), p_body, node, p_body_shape, p_local_shape); } } else { @@ -121,17 +119,17 @@ void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instan if (E->value.shapes.is_empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree)); if (in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_exited, node); + emit_signal(SceneStringName(body_exited), node); } } contact_monitor->body_map.remove(E); } if (node && in_tree) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_body, obj, p_body_shape, p_local_shape); + emit_signal(SceneStringName(body_shape_exited), p_body, obj, p_body_shape, p_local_shape); } } } @@ -157,7 +155,7 @@ void RigidBody3D::_sync_body_state(PhysicsDirectBodyState3D *p_state) { if (sleeping != p_state->is_sleeping()) { sleeping = p_state->is_sleeping(); - emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + emit_signal(SceneStringName(sleeping_state_changed)); } } @@ -613,8 +611,8 @@ void RigidBody3D::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree)); + node->disconnect(SceneStringName(tree_entered), callable_mp(this, &RigidBody3D::_body_enter_tree)); + node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &RigidBody3D::_body_exit_tree)); } } diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 72b5b53b19..a4804e928a 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -34,7 +34,6 @@ #include "core/variant/type_info.h" #include "scene/3d/skeleton_modifier_3d.h" #include "scene/resources/surface_tool.h" -#include "scene/scene_string_names.h" #ifndef DISABLE_DEPRECATED #include "scene/3d/physical_bone_simulator_3d.h" #endif // _DISABLE_DEPRECATED @@ -314,7 +313,7 @@ void Skeleton3D::_notification(int p_what) { _process_modifiers(); } - emit_signal(SceneStringNames::get_singleton()->skeleton_updated); + emit_signal(SceneStringName(skeleton_updated)); // Update skins. RenderingServer *rs = RenderingServer::get_singleton(); @@ -605,7 +604,7 @@ void Skeleton3D::set_bone_enabled(int p_bone, bool p_enabled) { ERR_FAIL_INDEX(p_bone, bone_size); bones.write[p_bone].enabled = p_enabled; - emit_signal(SceneStringNames::get_singleton()->bone_enabled_changed, p_bone); + emit_signal(SceneStringName(bone_enabled_changed), p_bone); _make_dirty(); } @@ -617,7 +616,7 @@ bool Skeleton3D::is_bone_enabled(int p_bone) const { void Skeleton3D::set_show_rest_only(bool p_enabled) { show_rest_only = p_enabled; - emit_signal(SceneStringNames::get_singleton()->show_rest_only_changed); + emit_signal(SceneStringName(show_rest_only_changed)); _make_dirty(); } @@ -840,7 +839,7 @@ void Skeleton3D::force_update_all_bone_transforms() { if (updating) { return; } - emit_signal(SceneStringNames::get_singleton()->pose_updated); + emit_signal(SceneStringName(pose_updated)); } void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) { @@ -848,12 +847,13 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) { ERR_FAIL_INDEX(p_bone_idx, bone_size); Bone *bonesptr = bones.ptrw(); - List<int> bones_to_process = List<int>(); + thread_local LocalVector<int> bones_to_process; + bones_to_process.clear(); bones_to_process.push_back(p_bone_idx); - while (bones_to_process.size() > 0) { - int current_bone_idx = bones_to_process.front()->get(); - bones_to_process.erase(current_bone_idx); + uint32_t index = 0; + while (index < bones_to_process.size()) { + int current_bone_idx = bones_to_process[index]; Bone &b = bonesptr[current_bone_idx]; bool bone_enabled = b.enabled && !show_rest_only; @@ -906,6 +906,8 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) { for (int i = 0; i < child_bone_size; i++) { bones_to_process.push_back(b.child_bones[i]); } + + index++; } } diff --git a/scene/3d/skeleton_modifier_3d.cpp b/scene/3d/skeleton_modifier_3d.cpp index 96e3e33841..8d806ef5fc 100644 --- a/scene/3d/skeleton_modifier_3d.cpp +++ b/scene/3d/skeleton_modifier_3d.cpp @@ -110,7 +110,7 @@ void SkeletonModifier3D::process_modification() { } void SkeletonModifier3D::_process_modification() { - // + GDVIRTUAL_CALL(_process_modification); } void SkeletonModifier3D::_notification(int p_what) { @@ -133,6 +133,7 @@ void SkeletonModifier3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "influence", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_influence", "get_influence"); ADD_SIGNAL(MethodInfo("modification_processed")); + GDVIRTUAL_BIND(_process_modification); } SkeletonModifier3D::SkeletonModifier3D() { diff --git a/scene/3d/skeleton_modifier_3d.h b/scene/3d/skeleton_modifier_3d.h index 25c09f3b93..d00a1e94a9 100644 --- a/scene/3d/skeleton_modifier_3d.h +++ b/scene/3d/skeleton_modifier_3d.h @@ -60,6 +60,7 @@ protected: virtual void _set_active(bool p_active); virtual void _process_modification(); + GDVIRTUAL0(_process_modification); public: virtual PackedStringArray get_configuration_warnings() const override; diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 7d2a821d16..ba3b32a031 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -31,7 +31,6 @@ #include "sprite_3d.h" #include "scene/resources/atlas_texture.h" -#include "scene/scene_string_names.h" Color SpriteBase3D::_get_color_accum() { if (!color_dirty) { @@ -796,15 +795,15 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) { return; } if (texture.is_valid()) { - texture->disconnect(SceneStringNames::get_singleton()->changed, callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); + texture->disconnect(CoreStringName(changed), callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); } texture = p_texture; if (texture.is_valid()) { - texture->connect(SceneStringNames::get_singleton()->changed, callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); + texture->connect(CoreStringName(changed), callable_mp((SpriteBase3D *)this, &Sprite3D::_queue_redraw)); } _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> Sprite3D::get_texture() const { @@ -849,7 +848,7 @@ void Sprite3D::set_frame(int p_frame) { frame = p_frame; _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } int Sprite3D::get_frame() const { @@ -1122,7 +1121,7 @@ void AnimatedSprite3D::_notification(int p_what) { } else { frame = last_frame; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -1131,7 +1130,7 @@ void AnimatedSprite3D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 0.0; _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN((1.0 - frame_progress) / abs_speed, remaining); frame_progress += to_process * abs_speed; @@ -1146,7 +1145,7 @@ void AnimatedSprite3D::_notification(int p_what) { } else { frame = 0; pause(); - emit_signal(SceneStringNames::get_singleton()->animation_finished); + emit_signal(SceneStringName(animation_finished)); return; } } else { @@ -1155,7 +1154,7 @@ void AnimatedSprite3D::_notification(int p_what) { _calc_frame_speed_scale(); frame_progress = 1.0; _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } double to_process = MIN(frame_progress / abs_speed, remaining); frame_progress -= to_process * abs_speed; @@ -1177,12 +1176,12 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { } if (frames.is_valid()) { - frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed)); + frames->disconnect(CoreStringName(changed), callable_mp(this, &AnimatedSprite3D::_res_changed)); } stop(); frames = p_frames; if (frames.is_valid()) { - frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite3D::_res_changed)); + frames->connect(CoreStringName(changed), callable_mp(this, &AnimatedSprite3D::_res_changed)); List<StringName> al; frames->get_animation_list(&al); @@ -1249,7 +1248,7 @@ void AnimatedSprite3D::set_frame_and_progress(int p_frame, real_t p_progress) { return; // No change, don't redraw. } _queue_redraw(); - emit_signal(SceneStringNames::get_singleton()->frame_changed); + emit_signal(SceneStringName(frame_changed)); } void AnimatedSprite3D::set_speed_scale(float p_speed_scale) { @@ -1343,7 +1342,7 @@ void AnimatedSprite3D::play(const StringName &p_name, float p_custom_scale, bool } else { set_frame_and_progress(0, 0.0); } - emit_signal("animation_changed"); + emit_signal(SceneStringName(animation_changed)); } else { bool is_backward = signbit(speed_scale * custom_speed_scale); if (p_from_end && is_backward && frame == 0 && frame_progress <= 0.0) { @@ -1398,7 +1397,7 @@ void AnimatedSprite3D::set_animation(const StringName &p_name) { animation = p_name; - emit_signal("animation_changed"); + emit_signal(SceneStringName(animation_changed)); if (frames == nullptr) { animation = StringName(); diff --git a/scene/3d/visible_on_screen_notifier_3d.cpp b/scene/3d/visible_on_screen_notifier_3d.cpp index 272852e8fa..a510540e4e 100644 --- a/scene/3d/visible_on_screen_notifier_3d.cpp +++ b/scene/3d/visible_on_screen_notifier_3d.cpp @@ -30,15 +30,13 @@ #include "visible_on_screen_notifier_3d.h" -#include "scene/scene_string_names.h" - void VisibleOnScreenNotifier3D::_visibility_enter() { if (!is_inside_tree() || Engine::get_singleton()->is_editor_hint()) { return; } on_screen = true; - emit_signal(SceneStringNames::get_singleton()->screen_entered); + emit_signal(SceneStringName(screen_entered)); _screen_enter(); } void VisibleOnScreenNotifier3D::_visibility_exit() { @@ -47,7 +45,7 @@ void VisibleOnScreenNotifier3D::_visibility_exit() { } on_screen = false; - emit_signal(SceneStringNames::get_singleton()->screen_exited); + emit_signal(SceneStringName(screen_exited)); _screen_exit(); } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index e0dc300a6b..f14ae3a285 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -30,9 +30,6 @@ #include "visual_instance_3d.h" -#include "core/core_string_names.h" -#include "scene/scene_string_names.h" - AABB VisualInstance3D::get_aabb() const { AABB ret; GDVIRTUAL_CALL(_get_aabb, ret); @@ -169,11 +166,11 @@ VisualInstance3D::~VisualInstance3D() { void GeometryInstance3D::set_material_override(const Ref<Material> &p_material) { if (material_override.is_valid()) { - material_override->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + material_override->disconnect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } material_override = p_material; if (material_override.is_valid()) { - material_override->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed)); + material_override->connect(CoreStringName(property_list_changed), callable_mp((Object *)this, &Object::notify_property_list_changed)); } RS::get_singleton()->instance_geometry_set_material_override(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID()); } @@ -279,12 +276,12 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) return true; } #ifndef DISABLE_DEPRECATED - if (p_name == SceneStringNames::get_singleton()->use_in_baked_light && bool(p_value)) { + if (p_name == SNAME("use_in_baked_light") && bool(p_value)) { set_gi_mode(GI_MODE_STATIC); return true; } - if (p_name == SceneStringNames::get_singleton()->use_dynamic_gi && bool(p_value)) { + if (p_name == SNAME("use_dynamic_gi") && bool(p_value)) { set_gi_mode(GI_MODE_DYNAMIC); return true; } diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp index fbdda67526..ffca856fba 100644 --- a/scene/3d/voxel_gi.cpp +++ b/scene/3d/voxel_gi.cpp @@ -31,7 +31,6 @@ #include "voxel_gi.h" #include "core/config/project_settings.h" -#include "core/core_string_names.h" #include "mesh_instance_3d.h" #include "multimesh_instance_3d.h" #include "scene/resources/camera_attributes.h" diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index f3385b4cdc..6e33a1b27c 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -31,7 +31,6 @@ #include "animation_blend_tree.h" #include "scene/resources/animation.h" -#include "scene/scene_string_names.h" void AnimationNodeAnimation::set_animation(const StringName &p_name) { animation = p_name; @@ -194,8 +193,8 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe nti.is_just_looped = is_just_looped; // 3. Progress for Animation. - double prev_playback_time = prev_time - start_offset; - double cur_playback_time = cur_time - start_offset; + double prev_playback_time = prev_time + start_offset; + double cur_playback_time = cur_time + start_offset; if (stretch_time_scale) { double mlt = anim_size / cur_len; cur_playback_time *= mlt; @@ -238,11 +237,11 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe if (process_state->tree && !p_test_only) { // AnimationTree uses seek to 0 "internally" to process the first key of the animation, which is used as the start detection. if (p_seek && !p_is_external_seeking && cur_playback_time == 0) { - process_state->tree->call_deferred(SNAME("emit_signal"), "animation_started", animation); + process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_started), animation); } // Finished. - if (prev_time - start_offset < anim_size && cur_playback_time >= anim_size) { - process_state->tree->call_deferred(SNAME("emit_signal"), "animation_finished", animation); + if (prev_time + start_offset < anim_size && cur_playback_time >= anim_size) { + process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_finished), animation); } } } @@ -1421,7 +1420,7 @@ AnimationNodeOutput::AnimationNodeOutput() { void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) { ERR_FAIL_COND(nodes.has(p_name)); ERR_FAIL_COND(p_node.is_null()); - ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); + ERR_FAIL_COND(p_name == SceneStringName(output)); ERR_FAIL_COND(String(p_name).contains("/")); Node n; @@ -1491,7 +1490,7 @@ Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const Strin void AnimationNodeBlendTree::remove_node(const StringName &p_name) { ERR_FAIL_COND(!nodes.has(p_name)); - ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); //can't delete output + ERR_FAIL_COND(p_name == SceneStringName(output)); //can't delete output { Ref<AnimationNode> node = nodes[p_name].node; @@ -1520,8 +1519,8 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) { void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringName &p_new_name) { ERR_FAIL_COND(!nodes.has(p_name)); ERR_FAIL_COND(nodes.has(p_new_name)); - ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); - ERR_FAIL_COND(p_new_name == SceneStringNames::get_singleton()->output); + ERR_FAIL_COND(p_name == SceneStringName(output)); + ERR_FAIL_COND(p_new_name == SceneStringName(output)); nodes[p_name].node->disconnect_changed(callable_mp(this, &AnimationNodeBlendTree::_node_changed)); @@ -1546,7 +1545,7 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) { ERR_FAIL_COND(!nodes.has(p_output_node)); ERR_FAIL_COND(!nodes.has(p_input_node)); - ERR_FAIL_COND(p_output_node == SceneStringNames::get_singleton()->output); + ERR_FAIL_COND(p_output_node == SceneStringName(output)); ERR_FAIL_COND(p_input_node == p_output_node); Ref<AnimationNode> input = nodes[p_input_node].node; @@ -1574,7 +1573,7 @@ void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_inp } AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const { - if (!nodes.has(p_output_node) || p_output_node == SceneStringNames::get_singleton()->output) { + if (!nodes.has(p_output_node) || p_output_node == SceneStringName(output)) { return CONNECTION_ERROR_NO_OUTPUT; } @@ -1627,8 +1626,8 @@ String AnimationNodeBlendTree::get_caption() const { } AnimationNode::NodeTimeInfo AnimationNodeBlendTree::_process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only) { - Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node; - node_state.connections = nodes[SceneStringNames::get_singleton()->output].connections; + Ref<AnimationNodeOutput> output = nodes[SceneStringName(output)].node; + node_state.connections = nodes[SceneStringName(output)].connections; ERR_FAIL_COND_V(output.is_null(), NodeTimeInfo()); AnimationMixer::PlaybackInfo pi = p_playback_info; diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index d22b58346f..e600de6b8b 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -35,7 +35,6 @@ #include "core/config/project_settings.h" #include "scene/animation/animation_player.h" #include "scene/resources/animation.h" -#include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" #ifndef _3D_DISABLED @@ -301,7 +300,7 @@ Error AnimationMixer::add_animation_library(const StringName &p_name, const Ref< ald.library->connect(SNAME("animation_added"), callable_mp(this, &AnimationMixer::_animation_added).bind(p_name)); ald.library->connect(SNAME("animation_removed"), callable_mp(this, &AnimationMixer::_animation_removed).bind(p_name)); ald.library->connect(SNAME("animation_renamed"), callable_mp(this, &AnimationMixer::_animation_renamed).bind(p_name)); - ald.library->connect(SNAME("animation_changed"), callable_mp(this, &AnimationMixer::_animation_changed)); + ald.library->connect(SceneStringName(animation_changed), callable_mp(this, &AnimationMixer::_animation_changed)); _animation_set_cache_update(); @@ -325,7 +324,7 @@ void AnimationMixer::remove_animation_library(const StringName &p_name) { animation_libraries[at_pos].library->disconnect(SNAME("animation_added"), callable_mp(this, &AnimationMixer::_animation_added)); animation_libraries[at_pos].library->disconnect(SNAME("animation_removed"), callable_mp(this, &AnimationMixer::_animation_removed)); animation_libraries[at_pos].library->disconnect(SNAME("animation_renamed"), callable_mp(this, &AnimationMixer::_animation_renamed)); - animation_libraries[at_pos].library->disconnect(SNAME("animation_changed"), callable_mp(this, &AnimationMixer::_animation_changed)); + animation_libraries[at_pos].library->disconnect(SceneStringName(animation_changed), callable_mp(this, &AnimationMixer::_animation_changed)); animation_libraries.remove_at(at_pos); _animation_set_cache_update(); @@ -502,6 +501,7 @@ AnimationMixer::AnimationCallbackModeMethod AnimationMixer::get_callback_mode_me void AnimationMixer::set_callback_mode_discrete(AnimationCallbackModeDiscrete p_mode) { callback_mode_discrete = p_mode; + _clear_caches(); emit_signal(SNAME("mixer_updated")); } @@ -628,9 +628,9 @@ bool AnimationMixer::_update_caches() { #endif Ref<Animation> reset_anim; - bool has_reset_anim = has_animation(SceneStringNames::get_singleton()->RESET); + bool has_reset_anim = has_animation(SceneStringName(RESET)); if (has_reset_anim) { - reset_anim = get_animation(SceneStringNames::get_singleton()->RESET); + reset_anim = get_animation(SceneStringName(RESET)); } for (const StringName &E : sname) { Ref<Animation> anim = get_animation(E); @@ -689,7 +689,7 @@ bool AnimationMixer::_update_caches() { track_value->init_value = anim->track_get_key_value(i, 0); track_value->init_value.zero(); - track_value->init_use_continuous = callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS; + track_value->is_init = false; // Can't interpolate them, need to convert. track_value->is_variant_interpolatable = Animation::is_variant_interpolatable(track_value->init_value); @@ -699,7 +699,6 @@ bool AnimationMixer::_update_caches() { int rt = reset_anim->find_track(path, track_src_type); if (rt >= 0) { if (track_src_type == Animation::TYPE_VALUE) { - track_value->init_use_continuous = track_value->init_use_continuous || (reset_anim->value_track_get_update_mode(rt) != Animation::UPDATE_DISCRETE); // Take precedence Force Continuous. if (reset_anim->track_get_key_count(rt) > 0) { track_value->init_value = reset_anim->track_get_key_value(rt, 0); } @@ -1007,7 +1006,7 @@ void AnimationMixer::_blend_init() { TrackCacheValue *t = static_cast<TrackCacheValue *>(track); t->value = Animation::cast_to_blendwise(t->init_value); t->element_size = t->init_value.is_string() ? (real_t)(t->init_value.operator String()).length() : 0; - t->use_continuous = t->init_use_continuous; + t->use_continuous = false; t->use_discrete = false; } break; case Animation::TYPE_AUDIO: { @@ -1463,12 +1462,12 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) { t->value = Animation::blend_variant(t->value, value, blend); } } else { - t->use_discrete = true; if (seeked) { int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT, true); if (idx < 0) { continue; } + t->use_discrete = true; Variant value = a->track_get_key_value(i, idx); value = post_process_key_value(a, i, value, t->object_id); Object *t_obj = ObjectDB::get_instance(t->object_id); @@ -1479,6 +1478,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) { List<int> indices; a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag); for (int &F : indices) { + t->use_discrete = true; Variant value = a->track_get_key_value(i, F); value = post_process_key_value(a, i, value, t->object_id); Object *t_obj = ObjectDB::get_instance(t->object_id); @@ -1683,7 +1683,8 @@ void AnimationMixer::_blend_apply() { // Finally, set the tracks. for (const KeyValue<Animation::TypeHash, TrackCache *> &K : track_cache) { TrackCache *track = K.value; - if (!deterministic && Math::is_zero_approx(track->total_weight)) { + bool is_zero_amount = Math::is_zero_approx(track->total_weight); + if (!deterministic && is_zero_amount) { continue; } switch (track->type) { @@ -1743,10 +1744,24 @@ void AnimationMixer::_blend_apply() { case Animation::TYPE_VALUE: { TrackCacheValue *t = static_cast<TrackCacheValue *>(track); - if (!t->is_variant_interpolatable || !t->use_continuous || (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && t->use_discrete)) { + if (t->use_discrete && !t->use_continuous) { + t->is_init = true; // If only disctere value is applied, no more RESET. + } + + if ((t->is_init && (is_zero_amount || !t->use_continuous)) || + (callback_mode_discrete != ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS && + !is_zero_amount && + callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT && + t->use_discrete)) { break; // Don't overwrite the value set by UPDATE_DISCRETE. } + if (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS) { + t->is_init = false; // Always update in Force Continuous. + } else { + t->is_init = !t->use_continuous; // If there is no Continuous in non-Force Continuous type, it means RESET. + } + // Trim unused elements if init array/string is not blended. if (t->value.is_array()) { int actual_blended_size = (int)Math::round(Math::abs(t->element_size.operator real_t())); @@ -1926,7 +1941,7 @@ bool AnimationMixer::is_reset_on_save_enabled() const { } bool AnimationMixer::can_apply_reset() const { - return has_animation(SceneStringNames::get_singleton()->RESET); + return has_animation(SceneStringName(RESET)); } void AnimationMixer::_build_backup_track_cache() { @@ -2013,7 +2028,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() { Ref<AnimatedValuesBackup> backup; backup.instantiate(); - Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; + Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation; ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>()); _blend_init(); @@ -2022,7 +2037,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() { pi.delta = 0; pi.seeked = true; pi.weight = 1.0; - make_animation_instance(SceneStringNames::get_singleton()->RESET, pi); + make_animation_instance(SceneStringName(RESET), pi); _build_backup_track_cache(); backup->set_data(track_cache); @@ -2034,7 +2049,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::make_backup() { void AnimationMixer::reset() { ERR_FAIL_COND(!can_apply_reset()); - Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; + Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation; ERR_FAIL_COND(reset_anim.is_null()); Node *root_node_object = get_node_or_null(root_node); @@ -2044,11 +2059,11 @@ void AnimationMixer::reset() { root_node_object->add_child(aux_player); Ref<AnimationLibrary> al; al.instantiate(); - al->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim); + al->add_animation(SceneStringName(RESET), reset_anim); aux_player->set_reset_on_save_enabled(false); aux_player->set_root_node(aux_player->get_path_to(root_node_object)); aux_player->add_animation_library("", al); - aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET); + aux_player->set_assigned_animation(SceneStringName(RESET)); aux_player->seek(0.0f, true); aux_player->queue_free(); } @@ -2068,7 +2083,7 @@ Ref<AnimatedValuesBackup> AnimationMixer::apply_reset(bool p_user_initiated) { } ERR_FAIL_COND_V(!can_apply_reset(), Ref<AnimatedValuesBackup>()); - Ref<Animation> reset_anim = animation_set[SceneStringNames::get_singleton()->RESET].animation; + Ref<Animation> reset_anim = animation_set[SceneStringName(RESET)].animation; ERR_FAIL_COND_V(reset_anim.is_null(), Ref<AnimatedValuesBackup>()); Ref<AnimatedValuesBackup> backup_current = make_backup(); @@ -2286,7 +2301,7 @@ void AnimationMixer::_bind_methods() { } AnimationMixer::AnimationMixer() { - root_node = SceneStringNames::get_singleton()->path_pp; + root_node = SceneStringName(path_pp); } AnimationMixer::~AnimationMixer() { diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h index b7898cffc9..089a210193 100644 --- a/scene/animation/animation_mixer.h +++ b/scene/animation/animation_mixer.h @@ -126,7 +126,7 @@ protected: /* ---- General settings for animation ---- */ AnimationCallbackModeProcess callback_mode_process = ANIMATION_CALLBACK_MODE_PROCESS_IDLE; AnimationCallbackModeMethod callback_mode_method = ANIMATION_CALLBACK_MODE_METHOD_DEFERRED; - AnimationCallbackModeDiscrete callback_mode_discrete = ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT; + AnimationCallbackModeDiscrete callback_mode_discrete = ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE; int audio_max_polyphony = 32; NodePath root_node; @@ -224,7 +224,7 @@ protected: Vector<StringName> subpath; // TODO: There are many boolean, can be packed into one integer. - bool init_use_continuous = false; + bool is_init = false; bool use_continuous = false; bool use_discrete = false; bool is_using_angle = false; @@ -237,7 +237,7 @@ protected: init_value(p_other.init_value), value(p_other.value), subpath(p_other.subpath), - init_use_continuous(p_other.init_use_continuous), + is_init(p_other.is_init), use_continuous(p_other.use_continuous), use_discrete(p_other.use_discrete), is_using_angle(p_other.is_using_angle), diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 2213800476..0c24d79ad7 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -32,7 +32,6 @@ #include "animation_player.compat.inc" #include "core/config/engine.h" -#include "scene/scene_string_names.h" bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; @@ -41,7 +40,7 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) { } else if (name.begins_with("next/")) { String which = name.get_slicec('/', 1); animation_set_next(which, p_value); - } else if (p_name == SceneStringNames::get_singleton()->blend_times) { + } else if (p_name == SceneStringName(blend_times)) { Array array = p_value; int len = array.size(); ERR_FAIL_COND_V(len % 3, false); @@ -77,7 +76,7 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const { String which = name.get_slicec('/', 1); r_ret = animation_get_next(which); - } else if (name == "blend_times") { + } else if (p_name == SceneStringName(blend_times)) { Vector<BlendKey> keys; for (const KeyValue<BlendKey, double> &E : blend_times) { keys.ordered_insert(E.key); @@ -326,14 +325,14 @@ void AnimationPlayer::_blend_post_process() { String new_name = playback.assigned; playback_queue.pop_front(); if (end_notify) { - emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); + emit_signal(SceneStringName(animation_changed), old, new_name); } } else { _clear_caches(); playing = false; _set_process(false); if (end_notify) { - emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); + emit_signal(SceneStringName(animation_finished), playback.assigned); if (movie_quit_on_finish && OS::get_singleton()->has_feature("movie")) { print_line(vformat("Movie Maker mode is enabled. Quitting on animation finish as requested by: %s", get_path())); get_tree()->quit(); @@ -448,10 +447,10 @@ void AnimationPlayer::_play(const StringName &p_name, double p_custom_blend, flo } else { if (p_from_end && c.current.pos == 0) { // Animation reset but played backwards, set position to the end. - c.current.pos = c.current.from->animation->get_length(); + seek(c.current.from->animation->get_length(), true, true); } else if (!p_from_end && c.current.pos == c.current.from->animation->get_length()) { // Animation resumed but already ended, set position to the beginning. - c.current.pos = 0; + seek(0, true, true); } else if (playing) { return; } @@ -463,7 +462,7 @@ void AnimationPlayer::_play(const StringName &p_name, double p_custom_blend, flo _set_process(true); // Always process when starting an animation. playing = true; - emit_signal(SceneStringNames::get_singleton()->animation_started, c.assigned); + emit_signal(SceneStringName(animation_started), c.assigned); if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { return; // No next in this case. diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 28a163768f..d4061ab167 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -34,7 +34,6 @@ #include "animation_blend_tree.h" #include "core/config/engine.h" #include "scene/animation/animation_player.h" -#include "scene/scene_string_names.h" void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const { Array parameters; @@ -627,7 +626,7 @@ bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const for (int i = 0; i < p_track_count; i++) { src_blendsw[i] = 1.0; // By default all go to 1 for the root input. } - root_animation_node->node_state.base_path = SceneStringNames::get_singleton()->parameters_base_path; + root_animation_node->node_state.base_path = SceneStringName(parameters_base_path); root_animation_node->node_state.parent = nullptr; } @@ -788,7 +787,7 @@ void AnimationTree::_update_properties() { input_activity_map_get.clear(); if (root_animation_node.is_valid()) { - _update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root_animation_node); + _update_properties_for_node(SceneStringName(parameters_base_path), root_animation_node); } properties_dirty = false; @@ -810,7 +809,7 @@ void AnimationTree::_notification(int p_what) { void AnimationTree::set_animation_player(const NodePath &p_path) { animation_player = p_path; if (p_path.is_empty()) { - set_root_node(SceneStringNames::get_singleton()->path_pp); + set_root_node(SceneStringName(path_pp)); while (animation_libraries.size()) { remove_animation_library(animation_libraries[0].name); } diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 56c582e2d7..6a61e8693d 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -351,7 +351,7 @@ bool Tween::step(double p_delta) { if (loops_done == loops) { running = false; dead = true; - emit_signal(SNAME("finished")); + emit_signal(SceneStringName(finished)); break; } else { emit_signal(SNAME("loop_finished"), loops_done); @@ -614,7 +614,7 @@ bool PropertyTweener::step(double &r_delta) { target_instance->set_indexed(property, final_val); finished = true; r_delta = elapsed_time - delay - duration; - emit_signal(SNAME("finished")); + emit_signal(SceneStringName(finished)); return false; } } @@ -674,7 +674,7 @@ bool IntervalTweener::step(double &r_delta) { } else { finished = true; r_delta = elapsed_time - duration; - emit_signal(SNAME("finished")); + emit_signal(SceneStringName(finished)); return false; } } @@ -717,7 +717,7 @@ bool CallbackTweener::step(double &r_delta) { finished = true; r_delta = elapsed_time - delay; - emit_signal(SNAME("finished")); + emit_signal(SceneStringName(finished)); return false; } @@ -803,7 +803,7 @@ bool MethodTweener::step(double &r_delta) { } else { finished = true; r_delta = elapsed_time - delay - duration; - emit_signal(SNAME("finished")); + emit_signal(SceneStringName(finished)); return false; } } diff --git a/scene/audio/audio_stream_player_internal.cpp b/scene/audio/audio_stream_player_internal.cpp index 19b3ec481b..a7b8faaaae 100644 --- a/scene/audio/audio_stream_player_internal.cpp +++ b/scene/audio/audio_stream_player_internal.cpp @@ -31,7 +31,6 @@ #include "audio_stream_player_internal.h" #include "scene/main/node.h" -#include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" void AudioStreamPlayerInternal::_set_process(bool p_enabled) { @@ -78,7 +77,7 @@ void AudioStreamPlayerInternal::process() { _set_process(false); } if (!playbacks_to_remove.is_empty()) { - node->emit_signal(SNAME("finished")); + node->emit_signal(SceneStringName(finished)); } } @@ -307,14 +306,14 @@ StringName AudioStreamPlayerInternal::get_bus() const { return bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } AudioStreamPlayerInternal::AudioStreamPlayerInternal(Node *p_node, const Callable &p_play_callable, bool p_physical) { node = p_node; play_callable = p_play_callable; physical = p_physical; - bus = SceneStringNames::get_singleton()->Master; + bus = SceneStringName(Master); AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp((Object *)node, &Object::notify_property_list_changed)); AudioServer::get_singleton()->connect("bus_renamed", callable_mp((Object *)node, &Object::notify_property_list_changed).unbind(3)); diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 66b14dc967..01e3cce78b 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -33,7 +33,6 @@ #include "core/config/project_settings.h" #include "core/os/keyboard.h" #include "scene/main/window.h" -#include "scene/scene_string_names.h" void BaseButton::_unpress_group() { if (!button_group.is_valid()) { @@ -135,7 +134,7 @@ void BaseButton::_notification(int p_what) { void BaseButton::_pressed() { GDVIRTUAL_CALL(_pressed); pressed(); - emit_signal(SNAME("pressed")); + emit_signal(SceneStringName(pressed)); } void BaseButton::_toggled(bool p_pressed) { @@ -162,7 +161,7 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) { status.pressed = !status.pressed; _unpress_group(); if (button_group.is_valid()) { - button_group->emit_signal(SNAME("pressed"), this); + button_group->emit_signal(SceneStringName(pressed), this); } _toggled(status.pressed); _pressed(); @@ -226,7 +225,7 @@ void BaseButton::set_pressed(bool p_pressed) { if (p_pressed) { _unpress_group(); if (button_group.is_valid()) { - button_group->emit_signal(SNAME("pressed"), this); + button_group->emit_signal(SceneStringName(pressed), this); } } _toggled(status.pressed); @@ -368,7 +367,7 @@ void BaseButton::shortcut_input(const Ref<InputEvent> &p_event) { _unpress_group(); if (button_group.is_valid()) { - button_group->emit_signal(SNAME("pressed"), this); + button_group->emit_signal(SceneStringName(pressed), this); } _toggled(status.pressed); diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index 88f65ca1bc..d8fcbbb883 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -243,8 +243,8 @@ Size2 BoxContainer::get_minimum_size() const { bool first = true; for (int i = 0; i < get_child_count(); i++) { - Control *c = as_sortable_control(get_child(i)); - if (!c) { + Control *c = Object::cast_to<Control>(get_child(i)); + if (!c || !c->is_visible() || c->is_set_as_top_level()) { continue; } diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index ad3f607661..3bf9d79c7f 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -50,6 +50,83 @@ void Button::_set_internal_margin(Side p_side, float p_value) { void Button::_queue_update_size_cache() { } +void Button::_update_theme_item_cache() { + Control::_update_theme_item_cache(); + + const bool rtl = is_layout_rtl(); + if (rtl && has_theme_stylebox(SNAME("normal_mirrored"))) { + theme_cache.max_style_size = theme_cache.normal_mirrored->get_minimum_size(); + theme_cache.style_margin_left = theme_cache.normal_mirrored->get_margin(SIDE_LEFT); + theme_cache.style_margin_right = theme_cache.normal_mirrored->get_margin(SIDE_RIGHT); + theme_cache.style_margin_top = theme_cache.normal_mirrored->get_margin(SIDE_TOP); + theme_cache.style_margin_bottom = theme_cache.normal_mirrored->get_margin(SIDE_BOTTOM); + } else { + theme_cache.max_style_size = theme_cache.normal->get_minimum_size(); + theme_cache.style_margin_left = theme_cache.normal->get_margin(SIDE_LEFT); + theme_cache.style_margin_right = theme_cache.normal->get_margin(SIDE_RIGHT); + theme_cache.style_margin_top = theme_cache.normal->get_margin(SIDE_TOP); + theme_cache.style_margin_bottom = theme_cache.normal->get_margin(SIDE_BOTTOM); + } + if (has_theme_stylebox("hover_pressed")) { + if (rtl && has_theme_stylebox(SNAME("hover_pressed_mirrored"))) { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover_pressed_mirrored->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover_pressed_mirrored->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover_pressed_mirrored->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover_pressed_mirrored->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover_pressed_mirrored->get_margin(SIDE_BOTTOM)); + } else { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover_pressed->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover_pressed->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover_pressed->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover_pressed->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover_pressed->get_margin(SIDE_BOTTOM)); + } + } + if (rtl && has_theme_stylebox(SNAME("pressed_mirrored"))) { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.pressed_mirrored->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.pressed_mirrored->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.pressed_mirrored->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.pressed_mirrored->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.pressed_mirrored->get_margin(SIDE_BOTTOM)); + } else { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.pressed->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.pressed->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.pressed->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.pressed->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.pressed->get_margin(SIDE_BOTTOM)); + } + if (rtl && has_theme_stylebox(SNAME("hover_mirrored"))) { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover_mirrored->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover_mirrored->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover_mirrored->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover_mirrored->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover_mirrored->get_margin(SIDE_BOTTOM)); + } else { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.hover->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.hover->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.hover->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.hover->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.hover->get_margin(SIDE_BOTTOM)); + } + if (rtl && has_theme_stylebox(SNAME("disabled_mirrored"))) { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.disabled_mirrored->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.disabled_mirrored->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.disabled_mirrored->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.disabled_mirrored->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.disabled_mirrored->get_margin(SIDE_BOTTOM)); + } else { + theme_cache.max_style_size = theme_cache.max_style_size.max(theme_cache.disabled->get_minimum_size()); + theme_cache.style_margin_left = MAX(theme_cache.style_margin_left, theme_cache.disabled->get_margin(SIDE_LEFT)); + theme_cache.style_margin_right = MAX(theme_cache.style_margin_right, theme_cache.disabled->get_margin(SIDE_RIGHT)); + theme_cache.style_margin_top = MAX(theme_cache.style_margin_top, theme_cache.disabled->get_margin(SIDE_TOP)); + theme_cache.style_margin_bottom = MAX(theme_cache.style_margin_bottom, theme_cache.disabled->get_margin(SIDE_BOTTOM)); + } +} + +Size2 Button::_get_largest_stylebox_size() const { + return theme_cache.max_style_size; +} + Ref<StyleBox> Button::_get_current_stylebox() const { Ref<StyleBox> stylebox = theme_cache.normal; const bool rtl = is_layout_rtl(); @@ -137,16 +214,13 @@ void Button::_notification(int p_what) { const RID ci = get_canvas_item(); const Size2 size = get_size(); - const Ref<StyleBox> style = _get_current_stylebox(); - { // Draws the stylebox in the current state. - if (!flat) { - style->draw(ci, Rect2(Point2(), size)); - } + // Draws the stylebox in the current state. + if (!flat) { + _get_current_stylebox()->draw(ci, Rect2(Point2(), size)); + } - if (has_focus()) { - Ref<StyleBox> style2 = theme_cache.focus; - style2->draw(ci, Rect2(Point2(), size)); - } + if (has_focus()) { + theme_cache.focus->draw(ci, Rect2(Point2(), size)); } Ref<Texture2D> _icon = icon; @@ -158,16 +232,11 @@ void Button::_notification(int p_what) { break; } - const float style_margin_left = style->get_margin(SIDE_LEFT); - const float style_margin_right = style->get_margin(SIDE_RIGHT); - const float style_margin_top = style->get_margin(SIDE_TOP); - const float style_margin_bottom = style->get_margin(SIDE_BOTTOM); - Size2 drawable_size_remained = size; { // The size after the stelybox is stripped. - drawable_size_remained.width -= style_margin_left + style_margin_right; - drawable_size_remained.height -= style_margin_top + style_margin_bottom; + drawable_size_remained.width -= theme_cache.style_margin_left + theme_cache.style_margin_right; + drawable_size_remained.height -= theme_cache.style_margin_top + theme_cache.style_margin_bottom; } const int h_separation = MAX(0, theme_cache.h_separation); @@ -298,6 +367,7 @@ void Button::_notification(int p_what) { icon_size = Size2(icon_width, icon_height); } icon_size = _fit_icon_size(icon_size); + icon_size = icon_size.round(); } if (icon_size.width > 0.0f) { @@ -311,12 +381,12 @@ void Button::_notification(int p_what) { [[fallthrough]]; case HORIZONTAL_ALIGNMENT_FILL: case HORIZONTAL_ALIGNMENT_LEFT: { - icon_ofs.x += style_margin_left; + icon_ofs.x += theme_cache.style_margin_left; icon_ofs.x += left_internal_margin_with_h_separation; } break; case HORIZONTAL_ALIGNMENT_RIGHT: { - icon_ofs.x = size.x - style_margin_right; + icon_ofs.x = size.x - theme_cache.style_margin_right; icon_ofs.x -= right_internal_margin_with_h_separation; icon_ofs.x -= icon_size.width; } break; @@ -329,13 +399,14 @@ void Button::_notification(int p_what) { [[fallthrough]]; case VERTICAL_ALIGNMENT_FILL: case VERTICAL_ALIGNMENT_TOP: { - icon_ofs.y += style_margin_top; + icon_ofs.y += theme_cache.style_margin_top; } break; case VERTICAL_ALIGNMENT_BOTTOM: { - icon_ofs.y = size.y - style_margin_bottom - icon_size.height; + icon_ofs.y = size.y - theme_cache.style_margin_bottom - icon_size.height; } break; } + icon_ofs = icon_ofs.floor(); Rect2 icon_region = Rect2(icon_ofs, icon_size); draw_texture_rect(_icon, icon_region, false, icon_modulate_color); @@ -371,7 +442,7 @@ void Button::_notification(int p_what) { case HORIZONTAL_ALIGNMENT_FILL: case HORIZONTAL_ALIGNMENT_LEFT: case HORIZONTAL_ALIGNMENT_RIGHT: { - text_ofs.x += style_margin_left; + text_ofs.x += theme_cache.style_margin_left; text_ofs.x += left_internal_margin_with_h_separation; if (icon_align_rtl_checked == HORIZONTAL_ALIGNMENT_LEFT) { // Offset by the space's width that occupied by icon and h_separation together. @@ -380,7 +451,7 @@ void Button::_notification(int p_what) { } break; } - text_ofs.y = (drawable_size_remained.height - text_buf->get_size().height) / 2.0f + style_margin_top; + text_ofs.y = (drawable_size_remained.height - text_buf->get_size().height) / 2.0f + theme_cache.style_margin_top; if (vertical_icon_alignment == VERTICAL_ALIGNMENT_TOP) { text_ofs.y += custom_element_size.height - drawable_size_remained.height; // Offset by the icon's height. } @@ -450,7 +521,7 @@ Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Textu } } - return _get_current_stylebox()->get_minimum_size() + minsize; + return _get_largest_stylebox_size() + minsize; } void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) { diff --git a/scene/gui/button.h b/scene/gui/button.h index 86fdbd35d5..eefb690913 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -69,6 +69,12 @@ private: Ref<StyleBox> disabled_mirrored; Ref<StyleBox> focus; + Size2 max_style_size; + float style_margin_left = 0; + float style_margin_right = 0; + float style_margin_top = 0; + float style_margin_bottom = 0; + Color font_color; Color font_focus_color; Color font_pressed_color; @@ -94,16 +100,18 @@ private: int icon_max_width = 0; } theme_cache; - Size2 _fit_icon_size(const Size2 &p_size) const; - void _shape(Ref<TextParagraph> p_paragraph = Ref<TextParagraph>(), String p_text = ""); void _texture_changed(); protected: + virtual void _update_theme_item_cache() override; + void _set_internal_margin(Side p_side, float p_value); virtual void _queue_update_size_cache(); + Size2 _fit_icon_size(const Size2 &p_size) const; Ref<StyleBox> _get_current_stylebox() const; + Size2 _get_largest_stylebox_size() const; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index af6696834e..99937aaf41 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -59,14 +59,14 @@ Size2 CheckBox::get_icon_size() const { if (!theme_cache.radio_unchecked_disabled.is_null()) { tex_size = tex_size.max(theme_cache.radio_unchecked_disabled->get_size()); } - return tex_size; + return _fit_icon_size(tex_size); } Size2 CheckBox::get_minimum_size() const { Size2 minsize = Button::get_minimum_size(); const Size2 tex_size = get_icon_size(); if (tex_size.width > 0 || tex_size.height > 0) { - const Size2 padding = _get_current_stylebox()->get_minimum_size(); + const Size2 padding = _get_largest_stylebox_size(); Size2 content_size = minsize - padding; if (content_size.width > 0 && tex_size.width > 0) { content_size.width += MAX(0, theme_cache.h_separation); @@ -127,9 +127,9 @@ void CheckBox::_notification(int p_what) { ofs.y = int((get_size().height - get_icon_size().height) / 2) + theme_cache.check_v_offset; if (is_pressed()) { - on_tex->draw(ci, ofs); + on_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(on_tex->get_size()))); } else { - off_tex->draw(ci, ofs); + off_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(off_tex->get_size()))); } } break; } diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index ab3b74a3c3..29b9504776 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -63,14 +63,14 @@ Size2 CheckButton::get_icon_size() const { tex_size = tex_size.max(off_tex->get_size()); } - return tex_size; + return _fit_icon_size(tex_size); } Size2 CheckButton::get_minimum_size() const { Size2 minsize = Button::get_minimum_size(); const Size2 tex_size = get_icon_size(); if (tex_size.width > 0 || tex_size.height > 0) { - const Size2 padding = _get_current_stylebox()->get_minimum_size(); + const Size2 padding = _get_largest_stylebox_size(); Size2 content_size = minsize - padding; if (content_size.width > 0 && tex_size.width > 0) { content_size.width += MAX(0, theme_cache.h_separation); @@ -134,9 +134,9 @@ void CheckButton::_notification(int p_what) { ofs.y = (get_size().height - tex_size.height) / 2 + theme_cache.check_v_offset; if (is_pressed()) { - on_tex->draw(ci, ofs); + on_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(on_tex->get_size()))); } else { - off_tex->draw(ci, ofs); + off_tex->draw_rect(ci, Rect2(ofs, _fit_icon_size(off_tex->get_size()))); } } break; } diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 8131fe7aaa..c843bb8c44 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -3050,7 +3050,7 @@ void CodeEdit::_update_delimiter_cache(int p_from_line, int p_to_line) { } int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) const { - if (delimiters.size() == 0) { + if (delimiters.size() == 0 || p_line >= delimiter_cache.size()) { return -1; } ERR_FAIL_INDEX_V(p_line, get_line_count(), 0); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index aeaaac1efc..245a086dda 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -95,8 +95,8 @@ void ColorPicker::_notification(int p_what) { for (int i = 0; i < MODE_BUTTON_COUNT; i++) { mode_btns[i]->begin_bulk_theme_override(); - mode_btns[i]->add_theme_style_override(SNAME("pressed"), theme_cache.mode_button_pressed); - mode_btns[i]->add_theme_style_override(SNAME("normal"), theme_cache.mode_button_normal); + mode_btns[i]->add_theme_style_override(SceneStringName(pressed), theme_cache.mode_button_pressed); + mode_btns[i]->add_theme_style_override(CoreStringName(normal), theme_cache.mode_button_normal); mode_btns[i]->add_theme_style_override(SNAME("hover"), theme_cache.mode_button_hover); mode_btns[i]->end_bulk_theme_override(); } @@ -420,18 +420,18 @@ void ColorPicker::create_slider(GridContainer *gc, int idx) { LineEdit *vle = val->get_line_edit(); vle->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed)); - vle->connect("gui_input", callable_mp(this, &ColorPicker::_line_edit_input)); + vle->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_line_edit_input)); vle->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - val->connect("gui_input", callable_mp(this, &ColorPicker::_slider_or_spin_input)); + val->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_slider_or_spin_input)); slider->set_h_size_flags(SIZE_EXPAND_FILL); slider->connect("drag_started", callable_mp(this, &ColorPicker::_slider_drag_started)); slider->connect("value_changed", callable_mp(this, &ColorPicker::_slider_value_changed).unbind(1)); slider->connect("drag_ended", callable_mp(this, &ColorPicker::_slider_drag_ended).unbind(1)); - slider->connect("draw", callable_mp(this, &ColorPicker::_slider_draw).bind(idx)); - slider->connect("gui_input", callable_mp(this, &ColorPicker::_slider_or_spin_input)); + slider->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_slider_draw).bind(idx)); + slider->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_slider_or_spin_input)); if (idx < SLIDER_COUNT) { sliders[idx] = slider; @@ -761,7 +761,7 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) { btn_preset_new->set_button_group(preset_group); preset_container->add_child(btn_preset_new); btn_preset_new->set_pressed(true); - btn_preset_new->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input).bind(p_color)); + btn_preset_new->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_preset_input).bind(p_color)); } void ColorPicker::_add_recent_preset_button(int p_size, const Color &p_color) { @@ -1510,7 +1510,7 @@ void ColorPicker::_pick_button_pressed() { if (!picker_window) { picker_window = memnew(Popup); picker_window->set_size(Vector2i(1, 1)); - picker_window->connect("visibility_changed", callable_mp(this, &ColorPicker::_pick_finished)); + picker_window->connect(SceneStringName(visibility_changed), callable_mp(this, &ColorPicker::_pick_finished)); add_child(picker_window, false, INTERNAL_MODE_FRONT); } picker_window->popup(); @@ -1546,7 +1546,7 @@ void ColorPicker::_pick_button_pressed_legacy() { picker_texture_rect->set_anchors_preset(Control::PRESET_FULL_RECT); picker_window->add_child(picker_texture_rect); picker_texture_rect->set_default_cursor_shape(CURSOR_POINTING_HAND); - picker_texture_rect->connect("gui_input", callable_mp(this, &ColorPicker::_picker_texture_input)); + picker_texture_rect->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_picker_texture_input)); picker_preview = memnew(Panel); picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP); @@ -1823,11 +1823,11 @@ ColorPicker::ColorPicker() { uv_edit = memnew(Control); hb_edit->add_child(uv_edit); - uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input).bind(uv_edit)); + uv_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(uv_edit)); uv_edit->set_mouse_filter(MOUSE_FILTER_PASS); uv_edit->set_h_size_flags(SIZE_EXPAND_FILL); uv_edit->set_v_size_flags(SIZE_EXPAND_FILL); - uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(0, uv_edit)); + uv_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, uv_edit)); sample_hbc = memnew(HBoxContainer); real_vbox->add_child(sample_hbc); @@ -1836,18 +1836,18 @@ ColorPicker::ColorPicker() { sample_hbc->add_child(btn_pick); if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SCREEN_CAPTURE)) { btn_pick->set_tooltip_text(ETR("Pick a color from the screen.")); - btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed)); + btn_pick->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_pick_button_pressed)); } else { // On unsupported platforms, use a legacy method for color picking. btn_pick->set_tooltip_text(ETR("Pick a color from the application window.")); - btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy)); + btn_pick->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_pick_button_pressed_legacy)); } sample = memnew(TextureRect); sample_hbc->add_child(sample); sample->set_h_size_flags(SIZE_EXPAND_FILL); - sample->connect("gui_input", callable_mp(this, &ColorPicker::_sample_input)); - sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw)); + sample->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_sample_input)); + sample->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_sample_draw)); btn_shape = memnew(MenuButton); btn_shape->set_flat(false); @@ -1883,7 +1883,7 @@ ColorPicker::ColorPicker() { mode_btns[i]->set_toggle_mode(true); mode_btns[i]->set_text(modes[i]->get_name()); mode_btns[i]->set_button_group(mode_group); - mode_btns[i]->connect("pressed", callable_mp(this, &ColorPicker::set_color_mode).bind((ColorModeType)i)); + mode_btns[i]->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::set_color_mode).bind((ColorModeType)i)); } mode_btns[0]->set_pressed(true); @@ -1936,7 +1936,7 @@ ColorPicker::ColorPicker() { text_type->set_text("#"); text_type->set_tooltip_text(RTR("Switch between hexadecimal and code values.")); if (Engine::get_singleton()->is_editor_hint()) { - text_type->connect("pressed", callable_mp(this, &ColorPicker::_text_type_toggled)); + text_type->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_text_type_toggled)); } else { text_type->set_flat(true); text_type->set_mouse_filter(MOUSE_FILTER_IGNORE); @@ -1950,7 +1950,7 @@ ColorPicker::ColorPicker() { c_text->set_placeholder(ETR("Hex code or named color")); c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted)); c_text->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed)); - c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit)); + c_text->connect(SceneStringName(focus_exited), callable_mp(this, &ColorPicker::_html_focus_exit)); wheel_edit = memnew(AspectRatioContainer); wheel_edit->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1969,19 +1969,19 @@ ColorPicker::ColorPicker() { wheel = memnew(Control); wheel_margin->add_child(wheel); wheel->set_mouse_filter(MOUSE_FILTER_PASS); - wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(2, wheel)); + wheel->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(2, wheel)); wheel_uv = memnew(Control); wheel_margin->add_child(wheel_uv); - wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input).bind(wheel_uv)); - wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(0, wheel_uv)); + wheel_uv->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_uv_input).bind(wheel_uv)); + wheel_uv->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(0, wheel_uv)); w_edit = memnew(Control); hb_edit->add_child(w_edit); w_edit->set_h_size_flags(SIZE_FILL); w_edit->set_v_size_flags(SIZE_EXPAND_FILL); - w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input)); - w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw).bind(1, w_edit)); + w_edit->connect(SceneStringName(gui_input), callable_mp(this, &ColorPicker::_w_input)); + w_edit->connect(SceneStringName(draw), callable_mp(this, &ColorPicker::_hsv_draw).bind(1, w_edit)); _update_controls(); updating = false; @@ -2026,7 +2026,7 @@ ColorPicker::ColorPicker() { btn_add_preset = memnew(Button); btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER); btn_add_preset->set_tooltip_text(ETR("Add current color as a preset.")); - btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed)); + btn_add_preset->connect(SceneStringName(pressed), callable_mp(this, &ColorPicker::_add_preset_pressed)); preset_container->add_child(btn_add_preset); } @@ -2171,7 +2171,7 @@ void ColorPickerButton::_update_picker() { picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed)); popup->connect("about_to_popup", callable_mp(this, &ColorPickerButton::_about_to_popup)); popup->connect("popup_hide", callable_mp(this, &ColorPickerButton::_modal_closed)); - picker->connect("minimum_size_changed", callable_mp((Window *)popup, &Window::reset_size)); + picker->connect(SceneStringName(minimum_size_changed), callable_mp((Window *)popup, &Window::reset_size)); picker->set_pick_color(color); picker->set_edit_alpha(edit_alpha); picker->set_display_old_color(true); diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 5db8d69eef..f1faf3e899 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -30,8 +30,6 @@ #include "container.h" -#include "scene/scene_string_names.h" - void Container::_child_minsize_changed() { update_minimum_size(); queue_sort(); @@ -45,9 +43,9 @@ void Container::add_child_notify(Node *p_child) { return; } - control->connect(SNAME("size_flags_changed"), callable_mp(this, &Container::queue_sort)); - control->connect(SNAME("minimum_size_changed"), callable_mp(this, &Container::_child_minsize_changed)); - control->connect(SNAME("visibility_changed"), callable_mp(this, &Container::_child_minsize_changed)); + control->connect(SceneStringName(size_flags_changed), callable_mp(this, &Container::queue_sort)); + control->connect(SceneStringName(minimum_size_changed), callable_mp(this, &Container::_child_minsize_changed)); + control->connect(SceneStringName(visibility_changed), callable_mp(this, &Container::_child_minsize_changed)); update_minimum_size(); queue_sort(); @@ -72,9 +70,9 @@ void Container::remove_child_notify(Node *p_child) { return; } - control->disconnect("size_flags_changed", callable_mp(this, &Container::queue_sort)); - control->disconnect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed)); - control->disconnect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed)); + control->disconnect(SceneStringName(size_flags_changed), callable_mp(this, &Container::queue_sort)); + control->disconnect(SceneStringName(minimum_size_changed), callable_mp(this, &Container::_child_minsize_changed)); + control->disconnect(SceneStringName(visibility_changed), callable_mp(this, &Container::_child_minsize_changed)); update_minimum_size(); queue_sort(); @@ -86,10 +84,10 @@ void Container::_sort_children() { } notification(NOTIFICATION_PRE_SORT_CHILDREN); - emit_signal(SceneStringNames::get_singleton()->pre_sort_children); + emit_signal(SceneStringName(pre_sort_children)); notification(NOTIFICATION_SORT_CHILDREN); - emit_signal(SceneStringNames::get_singleton()->sort_children); + emit_signal(SceneStringName(sort_children)); pending_sort = false; } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 2dd12b92f3..0d5c69b207 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -42,7 +42,6 @@ #include "scene/gui/panel.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" -#include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" #include "scene/theme/theme_owner.h" #include "servers/rendering_server.h" @@ -212,17 +211,17 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List const String pf = p_function; Theme::DataType type = Theme::DATA_TYPE_MAX; - if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") { + if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color" || pf == "remove_theme_color_override") { type = Theme::DATA_TYPE_COLOR; - } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") { + } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant" || pf == "remove_theme_constant_override") { type = Theme::DATA_TYPE_CONSTANT; - } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") { + } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font" || pf == "remove_theme_font_override") { type = Theme::DATA_TYPE_FONT; - } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") { + } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size" || pf == "remove_theme_font_size_override") { type = Theme::DATA_TYPE_FONT_SIZE; - } else if (pf == "add_theme_icon_override" || pf == "has_theme_icon" || pf == "has_theme_icon_override" || pf == "get_theme_icon") { + } else if (pf == "add_theme_icon_override" || pf == "has_theme_icon" || pf == "has_theme_icon_override" || pf == "get_theme_icon" || pf == "remove_theme_icon_override") { type = Theme::DATA_TYPE_ICON; - } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") { + } else if (pf == "add_theme_stylebox_override" || pf == "has_theme_stylebox" || pf == "has_theme_stylebox_override" || pf == "get_theme_stylebox" || pf == "remove_theme_stylebox_override") { type = Theme::DATA_TYPE_STYLEBOX; } @@ -1606,7 +1605,7 @@ void Control::_update_minimum_size() { if (minsize != data.last_minimum_size) { data.last_minimum_size = minsize; _size_changed(); - emit_signal(SceneStringNames::get_singleton()->minimum_size_changed); + emit_signal(SceneStringName(minimum_size_changed)); } } @@ -1770,7 +1769,7 @@ void Control::set_h_size_flags(BitField<SizeFlags> p_flags) { return; } data.h_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + emit_signal(SceneStringName(size_flags_changed)); } BitField<Control::SizeFlags> Control::get_h_size_flags() const { @@ -1784,7 +1783,7 @@ void Control::set_v_size_flags(BitField<SizeFlags> p_flags) { return; } data.v_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + emit_signal(SceneStringName(size_flags_changed)); } BitField<Control::SizeFlags> Control::get_v_size_flags() const { @@ -1799,7 +1798,7 @@ void Control::set_stretch_ratio(real_t p_ratio) { } data.expand = p_ratio; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + emit_signal(SceneStringName(size_flags_changed)); } real_t Control::get_stretch_ratio() const { @@ -1811,7 +1810,7 @@ real_t Control::get_stretch_ratio() const { void Control::_call_gui_input(const Ref<InputEvent> &p_event) { if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) { - emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); // Signal should be first, so it's possible to override an event (and then accept it). + emit_signal(SceneStringName(gui_input), p_event); // Signal should be first, so it's possible to override an event (and then accept it). } if (!is_inside_tree() || get_viewport()->is_input_handled()) { return; // Input was handled, abort. @@ -3223,7 +3222,7 @@ void Control::_notification(int p_notification) { case NOTIFICATION_READY: { #ifdef DEBUG_ENABLED - connect("ready", callable_mp(this, &Control::_clear_size_warning), CONNECT_DEFERRED | CONNECT_ONE_SHOT); + connect(SceneStringName(ready), callable_mp(this, &Control::_clear_size_warning), CONNECT_DEFERRED | CONNECT_ONE_SHOT); #endif } break; @@ -3262,7 +3261,7 @@ void Control::_notification(int p_notification) { data.parent_canvas_item = get_parent_item(); if (data.parent_canvas_item) { - data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed)); + data.parent_canvas_item->connect(SceneStringName(item_rect_changed), callable_mp(this, &Control::_size_changed)); } else { // Connect viewport. Viewport *viewport = get_viewport(); @@ -3273,7 +3272,7 @@ void Control::_notification(int p_notification) { case NOTIFICATION_EXIT_CANVAS: { if (data.parent_canvas_item) { - data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed)); + data.parent_canvas_item->disconnect(SceneStringName(item_rect_changed), callable_mp(this, &Control::_size_changed)); data.parent_canvas_item = nullptr; } else { // Disconnect viewport. @@ -3299,7 +3298,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_RESIZED: { - emit_signal(SceneStringNames::get_singleton()->resized); + emit_signal(SceneStringName(resized)); } break; case NOTIFICATION_DRAW: { @@ -3309,25 +3308,25 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_MOUSE_ENTER: { - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } break; case NOTIFICATION_MOUSE_EXIT: { - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } break; case NOTIFICATION_FOCUS_ENTER: { - emit_signal(SceneStringNames::get_singleton()->focus_entered); + emit_signal(SceneStringName(focus_entered)); queue_redraw(); } break; case NOTIFICATION_FOCUS_EXIT: { - emit_signal(SceneStringNames::get_singleton()->focus_exited); + emit_signal(SceneStringName(focus_exited)); queue_redraw(); } break; case NOTIFICATION_THEME_CHANGED: { - emit_signal(SceneStringNames::get_singleton()->theme_changed); + emit_signal(SceneStringName(theme_changed)); _invalidate_theme_cache(); _update_theme_item_cache(); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 4d2080dda2..3d8be38fbd 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -47,7 +47,7 @@ void AcceptDialog::_input_from_window(const Ref<InputEvent> &p_event) { } void AcceptDialog::_parent_focused() { - if (!is_exclusive() && get_flag(FLAG_POPUP)) { + if (popped_up && !is_exclusive() && get_flag(FLAG_POPUP)) { _cancel_pressed(); } } @@ -68,16 +68,25 @@ void AcceptDialog::_notification(int p_what) { parent_visible = get_parent_visible_window(); if (parent_visible) { - parent_visible->connect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused)); + parent_visible->connect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused)); } } else { + popped_up = false; if (parent_visible) { - parent_visible->disconnect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused)); + parent_visible->disconnect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused)); parent_visible = nullptr; } } } break; + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { + if (!is_in_edited_scene_root()) { + if (has_focus()) { + popped_up = true; + } + } + } break; + case NOTIFICATION_THEME_CHANGED: { bg_panel->add_theme_style_override("panel", theme_cache.panel_style); @@ -89,7 +98,7 @@ void AcceptDialog::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { if (parent_visible) { - parent_visible->disconnect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused)); + parent_visible->disconnect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused)); parent_visible = nullptr; } } break; @@ -114,8 +123,14 @@ void AcceptDialog::_text_submitted(const String &p_text) { _ok_pressed(); } +void AcceptDialog::_post_popup() { + Window::_post_popup(); + popped_up = true; +} + void AcceptDialog::_ok_pressed() { if (hide_on_ok) { + popped_up = false; set_visible(false); } ok_pressed(); @@ -124,9 +139,10 @@ void AcceptDialog::_ok_pressed() { } void AcceptDialog::_cancel_pressed() { + popped_up = false; Window *parent_window = parent_visible; if (parent_visible) { - parent_visible->disconnect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused)); + parent_visible->disconnect(SceneStringName(focus_entered), callable_mp(this, &AcceptDialog::_parent_focused)); parent_visible = nullptr; } @@ -308,7 +324,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin } button->set_meta("__right_spacer", right_spacer); - button->connect("visibility_changed", callable_mp(this, &AcceptDialog::_custom_button_visibility_changed).bind(button)); + button->connect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_custom_button_visibility_changed).bind(button)); child_controls_changed(); if (is_visible()) { @@ -316,7 +332,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin } if (!p_action.is_empty()) { - button->connect("pressed", callable_mp(this, &AcceptDialog::_custom_action).bind(p_action)); + button->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action).bind(p_action)); } return button; @@ -330,7 +346,7 @@ Button *AcceptDialog::add_cancel_button(const String &p_cancel) { Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c); - b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed)); + b->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed)); return b; } @@ -345,12 +361,12 @@ void AcceptDialog::remove_button(Button *p_button) { ERR_FAIL_COND_MSG(right_spacer->get_parent() != buttons_hbox, vformat("Cannot remove button %s as its associated spacer does not belong to this dialog.", p_button->get_name())); } - p_button->disconnect("visibility_changed", callable_mp(this, &AcceptDialog::_custom_button_visibility_changed)); - if (p_button->is_connected("pressed", callable_mp(this, &AcceptDialog::_custom_action))) { - p_button->disconnect("pressed", callable_mp(this, &AcceptDialog::_custom_action)); + p_button->disconnect(SceneStringName(visibility_changed), callable_mp(this, &AcceptDialog::_custom_button_visibility_changed)); + if (p_button->is_connected(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action))) { + p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_custom_action)); } - if (p_button->is_connected("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed))) { - p_button->disconnect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed)); + if (p_button->is_connected(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed))) { + p_button->disconnect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_cancel_pressed)); } if (right_spacer) { @@ -433,7 +449,7 @@ AcceptDialog::AcceptDialog() { buttons_hbox->add_child(ok_button); buttons_hbox->add_spacer(); - ok_button->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed)); + ok_button->connect(SceneStringName(pressed), callable_mp(this, &AcceptDialog::_ok_pressed)); set_title(ETR("Alert!")); } diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 12b48c903a..404237bfd8 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -51,6 +51,7 @@ class AcceptDialog : public Window { HBoxContainer *buttons_hbox = nullptr; Button *ok_button = nullptr; + bool popped_up = false; bool hide_on_ok = true; bool close_on_escape = true; @@ -72,6 +73,7 @@ class AcceptDialog : public Window { protected: virtual Size2 _get_contents_minimum_size() const override; virtual void _input_from_window(const Ref<InputEvent> &p_event) override; + virtual void _post_popup() override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 97a2917dc1..0c146ce173 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -1344,6 +1344,7 @@ void FileDialog::_bind_methods() { Option defaults; base_property_helper.set_prefix("option_"); + base_property_helper.set_array_length_getter(&FileDialog::get_option_count); base_property_helper.register_property(PropertyInfo(Variant::STRING, "name"), defaults.name, &FileDialog::set_option_name, &FileDialog::get_option_name); base_property_helper.register_property(PropertyInfo(Variant::PACKED_STRING_ARRAY, "values"), defaults.values, &FileDialog::set_option_values, &FileDialog::get_option_values); base_property_helper.register_property(PropertyInfo(Variant::INT, "default"), defaults.default_idx, &FileDialog::set_option_default, &FileDialog::get_option_default); @@ -1408,9 +1409,9 @@ FileDialog::FileDialog() { hbc->add_child(dir_prev); hbc->add_child(dir_next); hbc->add_child(dir_up); - dir_prev->connect("pressed", callable_mp(this, &FileDialog::_go_back)); - dir_next->connect("pressed", callable_mp(this, &FileDialog::_go_forward)); - dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up)); + dir_prev->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_go_back)); + dir_next->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_go_forward)); + dir_up->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_go_up)); hbc->add_child(memnew(Label(ETR("Path:")))); @@ -1429,7 +1430,7 @@ FileDialog::FileDialog() { refresh = memnew(Button); refresh->set_theme_type_variation("FlatButton"); refresh->set_tooltip_text(ETR("Refresh files.")); - refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list)); + refresh->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::update_file_list)); hbc->add_child(refresh); show_hidden = memnew(Button); @@ -1446,7 +1447,7 @@ FileDialog::FileDialog() { makedir = memnew(Button); makedir->set_theme_type_variation("FlatButton"); makedir->set_tooltip_text(ETR("Create a new folder.")); - makedir->connect("pressed", callable_mp(this, &FileDialog::_make_dir)); + makedir->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_make_dir)); hbc->add_child(makedir); vbox->add_child(hbc); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 646e45b27a..6c2a61d255 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -601,7 +601,7 @@ void GraphEdit::add_child_notify(Node *p_child) { GraphNode *graph_node = Object::cast_to<GraphNode>(graph_element); if (graph_node) { graph_node->connect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated).bind(graph_element)); - graph_node->connect("item_rect_changed", callable_mp(this, &GraphEdit::_graph_node_rect_changed).bind(graph_node)); + graph_node->connect(SceneStringName(item_rect_changed), callable_mp(this, &GraphEdit::_graph_node_rect_changed).bind(graph_node)); _ensure_node_order_from(graph_node); } @@ -618,8 +618,8 @@ void GraphEdit::add_child_notify(Node *p_child) { } graph_element->connect("raise_request", callable_mp(this, &GraphEdit::_ensure_node_order_from).bind(graph_element)); graph_element->connect("resize_request", callable_mp(this, &GraphEdit::_graph_element_resize_request).bind(graph_element)); - graph_element->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw)); - graph_element->connect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw)); + graph_element->connect(SceneStringName(item_rect_changed), callable_mp((CanvasItem *)connections_layer, &CanvasItem::queue_redraw)); + graph_element->connect(SceneStringName(item_rect_changed), callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw)); graph_element->set_scale(Vector2(zoom, zoom)); _graph_element_moved(graph_element); @@ -651,7 +651,7 @@ void GraphEdit::remove_child_notify(Node *p_child) { GraphNode *graph_node = Object::cast_to<GraphNode>(graph_element); if (graph_node) { graph_node->disconnect("slot_updated", callable_mp(this, &GraphEdit::_graph_node_slot_updated)); - graph_node->disconnect("item_rect_changed", callable_mp(this, &GraphEdit::_graph_node_rect_changed)); + graph_node->disconnect(SceneStringName(item_rect_changed), callable_mp(this, &GraphEdit::_graph_node_rect_changed)); // Invalidate all adjacent connections, so that they are removed before the next redraw. for (const Ref<Connection> &conn : connection_map[graph_node->get_name()]) { @@ -692,7 +692,7 @@ void GraphEdit::remove_child_notify(Node *p_child) { // In case of the whole GraphEdit being destroyed these references can already be freed. if (minimap != nullptr && minimap->is_inside_tree()) { - graph_element->disconnect("item_rect_changed", callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw)); + graph_element->disconnect(SceneStringName(item_rect_changed), callable_mp((CanvasItem *)minimap, &GraphEditMinimap::queue_redraw)); } } } @@ -898,6 +898,12 @@ bool GraphEdit::_filter_input(const Point2 &p_point) { return true; } } + + // This prevents interactions with a port hotzone that is behind another node. + Rect2 graph_node_rect = Rect2(graph_node->get_position(), graph_node->get_size() * zoom); + if (graph_node_rect.has_point(click_pos * zoom)) { + break; + } } return false; @@ -1027,6 +1033,12 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) { return; } } + + // This prevents interactions with a port hotzone that is behind another node. + Rect2 graph_node_rect = Rect2(graph_node->get_position(), graph_node->get_size() * zoom); + if (graph_node_rect.has_point(click_pos * zoom)) { + break; + } } } @@ -1059,7 +1071,7 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) { port_size.height = MAX(port_size.height, child ? child->get_size().y : 0); int type = graph_node->get_output_port_type(j); - if ((type == connecting_type || + if ((type == connecting_type || graph_node->is_ignoring_valid_connection_type() || valid_connection_types.has(ConnectionType(type, connecting_type))) && is_in_output_hotzone(graph_node, j, mpos, port_size)) { if (!is_node_hover_valid(graph_node->get_name(), j, connecting_from_node, connecting_from_port_index)) { @@ -1084,7 +1096,7 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) { port_size.height = MAX(port_size.height, child ? child->get_size().y : 0); int type = graph_node->get_input_port_type(j); - if ((type == connecting_type || valid_connection_types.has(ConnectionType(connecting_type, type))) && + if ((type == connecting_type || graph_node->is_ignoring_valid_connection_type() || valid_connection_types.has(ConnectionType(connecting_type, type))) && is_in_input_hotzone(graph_node, j, mpos, port_size)) { if (!is_node_hover_valid(connecting_from_node, connecting_from_port_index, graph_node->get_name(), j)) { continue; @@ -1117,6 +1129,8 @@ void GraphEdit::_top_connection_layer_input(const Ref<InputEvent> &p_ev) { emit_signal(SNAME("connection_from_empty"), connecting_from_node, connecting_from_port_index, mb->get_position()); } } + } else { + set_selected(get_node_or_null(NodePath(connecting_from_node))); } if (connecting) { @@ -1285,18 +1299,26 @@ List<Ref<GraphEdit::Connection>> GraphEdit::get_connections_intersecting_with_re return intersecting_connections; } -void GraphEdit::_draw_minimap_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_from_color, const Color &p_to_color) { - const Vector<Vector2> &points = get_connection_line(p_from, p_to); +void GraphEdit::_draw_minimap_connection_line(const Vector2 &p_from_graph_position, const Vector2 &p_to_graph_position, const Color &p_from_color, const Color &p_to_color) { + Vector<Vector2> points = get_connection_line(p_from_graph_position, p_to_graph_position); + ERR_FAIL_COND_MSG(points.size() < 2, "\"_get_connection_line()\" returned an invalid line."); + // Convert to minimap points. + for (Vector2 &point : points) { + point = minimap->_convert_from_graph_position(point) + minimap->minimap_offset; + } + + // Setup polyline colors. LocalVector<Color> colors; colors.reserve(points.size()); - - float length_inv = 1.0 / (p_from).distance_to(p_to); + const Vector2 &from = points[0]; + const Vector2 &to = points[points.size() - 1]; + float length_inv = 1.0 / (from).distance_to(to); for (const Vector2 &point : points) { - float normalized_curve_position = (p_from).distance_to(point) * length_inv; + float normalized_curve_position = from.distance_to(point) * length_inv; colors.push_back(p_from_color.lerp(p_to_color, normalized_curve_position)); } - p_where->draw_polyline_colors(points, colors, 0.5, lines_antialiased); + minimap->draw_polyline_colors(points, colors, 0.5, lines_antialiased); } void GraphEdit::_update_connections() { @@ -1551,8 +1573,8 @@ void GraphEdit::_minimap_draw() { // Draw node connections. for (const Ref<Connection> &c : connections) { - Vector2 from_position = minimap->_convert_from_graph_position(c->_cache.from_pos * zoom - graph_offset) + minimap_offset; - Vector2 to_position = minimap->_convert_from_graph_position(c->_cache.to_pos * zoom - graph_offset) + minimap_offset; + Vector2 from_graph_position = c->_cache.from_pos * zoom - graph_offset; + Vector2 to_graph_position = c->_cache.to_pos * zoom - graph_offset; Color from_color = c->_cache.from_color; Color to_color = c->_cache.to_color; @@ -1560,7 +1582,8 @@ void GraphEdit::_minimap_draw() { from_color = from_color.lerp(theme_cache.activity_color, c->activity); to_color = to_color.lerp(theme_cache.activity_color, c->activity); } - _draw_minimap_connection_line(minimap, from_position, to_position, from_color, to_color); + + _draw_minimap_connection_line(from_graph_position, to_graph_position, from_color, to_color); } // Draw the "camera" viewport. @@ -1636,12 +1659,12 @@ void GraphEdit::_draw_grid() { void GraphEdit::set_selected(Node *p_child) { for (int i = get_child_count() - 1; i >= 0; i--) { - GraphNode *graph_node = Object::cast_to<GraphNode>(get_child(i)); - if (!graph_node) { + GraphElement *graph_element = Object::cast_to<GraphElement>(get_child(i)); + if (!graph_element) { continue; } - graph_node->set_selected(graph_node == p_child); + graph_element->set_selected(graph_element == p_child); } } @@ -2755,12 +2778,12 @@ GraphEdit::GraphEdit() { add_child(top_layer, false, INTERNAL_MODE_BACK); top_layer->set_mouse_filter(MOUSE_FILTER_IGNORE); top_layer->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - top_layer->connect("draw", callable_mp(this, &GraphEdit::_top_layer_draw)); - top_layer->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); + top_layer->connect(SceneStringName(draw), callable_mp(this, &GraphEdit::_top_layer_draw)); + top_layer->connect(SceneStringName(focus_exited), callable_mp(panner.ptr(), &ViewPanner::release_pan_key)); connections_layer = memnew(Control); add_child(connections_layer, false); - connections_layer->connect("draw", callable_mp(this, &GraphEdit::_update_connections)); + connections_layer->connect(SceneStringName(draw), callable_mp(this, &GraphEdit::_update_connections)); connections_layer->set_name("_connection_layer"); connections_layer->set_disable_visibility_clip(true); // Necessary, so it can draw freely and be offset. connections_layer->set_mouse_filter(MOUSE_FILTER_IGNORE); @@ -2772,7 +2795,7 @@ GraphEdit::GraphEdit() { top_connection_layer->set_mouse_filter(MOUSE_FILTER_PASS); top_connection_layer->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - top_connection_layer->connect("gui_input", callable_mp(this, &GraphEdit::_top_connection_layer_input)); + top_connection_layer->connect(SceneStringName(gui_input), callable_mp(this, &GraphEdit::_top_connection_layer_input)); dragged_connection_line = memnew(Line2D); dragged_connection_line->set_texture_mode(Line2D::LINE_TEXTURE_STRETCH); @@ -2822,7 +2845,7 @@ GraphEdit::GraphEdit() { zoom_minus_button->set_tooltip_text(ETR("Zoom Out")); zoom_minus_button->set_focus_mode(FOCUS_NONE); menu_hbox->add_child(zoom_minus_button); - zoom_minus_button->connect("pressed", callable_mp(this, &GraphEdit::_zoom_minus)); + zoom_minus_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_minus)); zoom_reset_button = memnew(Button); zoom_reset_button->set_theme_type_variation("FlatButton"); @@ -2830,7 +2853,7 @@ GraphEdit::GraphEdit() { zoom_reset_button->set_tooltip_text(ETR("Zoom Reset")); zoom_reset_button->set_focus_mode(FOCUS_NONE); menu_hbox->add_child(zoom_reset_button); - zoom_reset_button->connect("pressed", callable_mp(this, &GraphEdit::_zoom_reset)); + zoom_reset_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_reset)); zoom_plus_button = memnew(Button); zoom_plus_button->set_theme_type_variation("FlatButton"); @@ -2838,7 +2861,7 @@ GraphEdit::GraphEdit() { zoom_plus_button->set_tooltip_text(ETR("Zoom In")); zoom_plus_button->set_focus_mode(FOCUS_NONE); menu_hbox->add_child(zoom_plus_button); - zoom_plus_button->connect("pressed", callable_mp(this, &GraphEdit::_zoom_plus)); + zoom_plus_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_zoom_plus)); // Grid controls. @@ -2850,7 +2873,7 @@ GraphEdit::GraphEdit() { toggle_grid_button->set_tooltip_text(ETR("Toggle the visual grid.")); toggle_grid_button->set_focus_mode(FOCUS_NONE); menu_hbox->add_child(toggle_grid_button); - toggle_grid_button->connect("pressed", callable_mp(this, &GraphEdit::_show_grid_toggled)); + toggle_grid_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_show_grid_toggled)); toggle_snapping_button = memnew(Button); toggle_snapping_button->set_theme_type_variation("FlatButton"); @@ -2860,7 +2883,7 @@ GraphEdit::GraphEdit() { toggle_snapping_button->set_pressed(snapping_enabled); toggle_snapping_button->set_focus_mode(FOCUS_NONE); menu_hbox->add_child(toggle_snapping_button); - toggle_snapping_button->connect("pressed", callable_mp(this, &GraphEdit::_snapping_toggled)); + toggle_snapping_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_snapping_toggled)); snapping_distance_spinbox = memnew(SpinBox); snapping_distance_spinbox->set_visible(show_grid_buttons); @@ -2882,12 +2905,12 @@ GraphEdit::GraphEdit() { minimap_button->set_pressed(show_grid); minimap_button->set_focus_mode(FOCUS_NONE); menu_hbox->add_child(minimap_button); - minimap_button->connect("pressed", callable_mp(this, &GraphEdit::_minimap_toggled)); + minimap_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::_minimap_toggled)); arrange_button = memnew(Button); arrange_button->set_theme_type_variation("FlatButton"); arrange_button->set_visible(show_arrange_button); - arrange_button->connect("pressed", callable_mp(this, &GraphEdit::arrange_nodes)); + arrange_button->connect(SceneStringName(pressed), callable_mp(this, &GraphEdit::arrange_nodes)); arrange_button->set_focus_mode(FOCUS_NONE); menu_hbox->add_child(arrange_button); arrange_button->set_tooltip_text(ETR("Automatically arrange selected nodes.")); @@ -2909,7 +2932,7 @@ GraphEdit::GraphEdit() { minimap->set_offset(Side::SIDE_TOP, -minimap_size.height - MINIMAP_OFFSET); minimap->set_offset(Side::SIDE_RIGHT, -MINIMAP_OFFSET); minimap->set_offset(Side::SIDE_BOTTOM, -MINIMAP_OFFSET); - minimap->connect("draw", callable_mp(this, &GraphEdit::_minimap_draw)); + minimap->connect(SceneStringName(draw), callable_mp(this, &GraphEdit::_minimap_draw)); set_clip_contents(true); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index eeda9ae200..20c98c462c 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -328,7 +328,7 @@ private: void _top_connection_layer_input(const Ref<InputEvent> &p_ev); float _get_shader_line_width(); - void _draw_minimap_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color); + void _draw_minimap_connection_line(const Vector2 &p_from_graph_position, const Vector2 &p_to_graph_position, const Color &p_from_color, const Color &p_to_color); void _invalidate_connection_line_cache(); void _update_top_connection_layer(); void _update_connections(); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 75ac5c5135..d804f83e1c 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -604,6 +604,14 @@ void GraphNode::set_slot_draw_stylebox(int p_slot_index, bool p_enable) { emit_signal(SNAME("slot_updated"), p_slot_index); } +void GraphNode::set_ignore_invalid_connection_type(bool p_ignore) { + ignore_invalid_connection_type = p_ignore; +} + +bool GraphNode::is_ignoring_valid_connection_type() const { + return ignore_invalid_connection_type; +} + Size2 GraphNode::get_minimum_size() const { Ref<StyleBox> sb_panel = theme_cache.panel; Ref<StyleBox> sb_titlebar = theme_cache.titlebar; @@ -859,6 +867,9 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("is_slot_draw_stylebox", "slot_index"), &GraphNode::is_slot_draw_stylebox); ClassDB::bind_method(D_METHOD("set_slot_draw_stylebox", "slot_index", "enable"), &GraphNode::set_slot_draw_stylebox); + ClassDB::bind_method(D_METHOD("set_ignore_invalid_connection_type", "ignore"), &GraphNode::set_ignore_invalid_connection_type); + ClassDB::bind_method(D_METHOD("is_ignoring_valid_connection_type"), &GraphNode::is_ignoring_valid_connection_type); + ClassDB::bind_method(D_METHOD("get_input_port_count"), &GraphNode::get_input_port_count); ClassDB::bind_method(D_METHOD("get_input_port_position", "port_idx"), &GraphNode::get_input_port_position); ClassDB::bind_method(D_METHOD("get_input_port_type", "port_idx"), &GraphNode::get_input_port_type); @@ -874,6 +885,8 @@ void GraphNode::_bind_methods() { GDVIRTUAL_BIND(_draw_port, "slot_index", "position", "left", "color") ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_invalid_connection_type"), "set_ignore_invalid_connection_type", "is_ignoring_valid_connection_type"); + ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "slot_index"))); BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, GraphNode, panel); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 71cc322baa..27af3192c8 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -95,6 +95,8 @@ class GraphNode : public GraphElement { bool port_pos_dirty = true; + bool ignore_invalid_connection_type = false; + void _port_pos_update(); protected: @@ -147,6 +149,9 @@ public: bool is_slot_draw_stylebox(int p_slot_index) const; void set_slot_draw_stylebox(int p_slot_index, bool p_enable); + void set_ignore_invalid_connection_type(bool p_ignore); + bool is_ignoring_valid_connection_type() const; + int get_input_port_count(); Vector2 get_input_port_position(int p_port_idx); int get_input_port_type(int p_port_idx); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 8376ef48b6..cfb46aebc8 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -1882,6 +1882,7 @@ void ItemList::_bind_methods() { Item defaults(true); base_property_helper.set_prefix("item_"); + base_property_helper.set_array_length_getter(&ItemList::get_item_count); base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text, &ItemList::set_item_text, &ItemList::get_item_text); base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &ItemList::set_item_icon, &ItemList::get_item_icon); base_property_helper.register_property(PropertyInfo(Variant::BOOL, "selectable"), defaults.selectable, &ItemList::set_item_selectable, &ItemList::is_item_selectable); @@ -1893,7 +1894,7 @@ ItemList::ItemList() { add_child(scroll_bar, false, INTERNAL_MODE_FRONT); scroll_bar->connect("value_changed", callable_mp(this, &ItemList::_scroll_changed)); - connect("mouse_exited", callable_mp(this, &ItemList::_mouse_exited)); + connect(SceneStringName(mouse_exited), callable_mp(this, &ItemList::_mouse_exited)); set_focus_mode(FOCUS_ALL); set_clip_contents(true); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index c263e14b8a..729e219825 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -2473,8 +2473,8 @@ void LineEdit::_generate_context_menu() { menu_dir->connect("id_pressed", callable_mp(this, &LineEdit::menu_option)); menu_ctl->connect("id_pressed", callable_mp(this, &LineEdit::menu_option)); - menu->connect(SNAME("focus_entered"), callable_mp(this, &LineEdit::_validate_caret_can_draw)); - menu->connect(SNAME("focus_exited"), callable_mp(this, &LineEdit::_validate_caret_can_draw)); + menu->connect(SceneStringName(focus_entered), callable_mp(this, &LineEdit::_validate_caret_can_draw)); + menu->connect(SceneStringName(focus_exited), callable_mp(this, &LineEdit::_validate_caret_can_draw)); } void LineEdit::_update_context_menu() { diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp index 91e6c1f092..06e4a7cc13 100644 --- a/scene/gui/margin_container.cpp +++ b/scene/gui/margin_container.cpp @@ -36,8 +36,8 @@ Size2 MarginContainer::get_minimum_size() const { Size2 max; for (int i = 0; i < get_child_count(); i++) { - Control *c = as_sortable_control(get_child(i)); - if (!c) { + Control *c = Object::cast_to<Control>(get_child(i)); + if (!c || !c->is_visible() || c->is_set_as_top_level()) { continue; } diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index e83d9c7c1b..998f99b2f9 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -190,6 +190,7 @@ void MenuButton::_bind_methods() { PopupMenu::Item defaults(true); base_property_helper.set_prefix("popup/item_"); + base_property_helper.set_array_length_getter(&MenuButton::get_item_count); base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text); base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon); base_property_helper.register_property(PropertyInfo(Variant::INT, "checkable", PROPERTY_HINT_ENUM, "No,As Checkbox,As Radio Button"), defaults.checkable_type); diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index e2ae824e60..f9181d2a2d 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -30,7 +30,6 @@ #include "nine_patch_rect.h" -#include "scene/scene_string_names.h" #include "servers/rendering_server.h" void NinePatchRect::_notification(int p_what) { @@ -111,7 +110,7 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) { queue_redraw(); update_minimum_size(); - emit_signal(SceneStringNames::get_singleton()->texture_changed); + emit_signal(SceneStringName(texture_changed)); } Ref<Texture2D> NinePatchRect::get_texture() const { diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 509c6aca99..68e72ea996 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -60,7 +60,7 @@ Size2 OptionButton::get_minimum_size() const { } if (has_theme_icon(SNAME("arrow"))) { - const Size2 padding = _get_current_stylebox()->get_minimum_size(); + const Size2 padding = _get_largest_stylebox_size(); const Size2 arrow_size = theme_cache.arrow_icon->get_size(); Size2 content_size = minsize - padding; @@ -571,6 +571,7 @@ void OptionButton::_bind_methods() { PopupMenu::Item defaults(true); base_property_helper.set_prefix("popup/item_"); + base_property_helper.set_array_length_getter(&OptionButton::get_item_count); base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text, &OptionButton::_dummy_setter, &OptionButton::get_item_text); base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &OptionButton::_dummy_setter, &OptionButton::get_item_icon); base_property_helper.register_property(PropertyInfo(Variant::INT, "id", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), defaults.id, &OptionButton::_dummy_setter, &OptionButton::get_item_id); diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 97b33c4f74..38204af6d5 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -37,6 +37,7 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) { if (get_flag(FLAG_POPUP) && p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) { + hide_reason = HIDE_REASON_CANCELED; // ESC pressed, mark as canceled unconditionally. _close_pressed(); } Window::_input_from_window(p_event); @@ -51,8 +52,8 @@ void Popup::_initialize_visible_parents() { parent_window = parent_window->get_parent_visible_window(); if (parent_window) { visible_parents.push_back(parent_window); - parent_window->connect("focus_entered", callable_mp(this, &Popup::_parent_focused)); - parent_window->connect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents)); + parent_window->connect(SceneStringName(focus_entered), callable_mp(this, &Popup::_parent_focused)); + parent_window->connect(SceneStringName(tree_exited), callable_mp(this, &Popup::_deinitialize_visible_parents)); } } } @@ -61,8 +62,8 @@ void Popup::_initialize_visible_parents() { void Popup::_deinitialize_visible_parents() { if (is_embedded()) { for (Window *parent_window : visible_parents) { - parent_window->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused)); - parent_window->disconnect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents)); + parent_window->disconnect(SceneStringName(focus_entered), callable_mp(this, &Popup::_parent_focused)); + parent_window->disconnect(SceneStringName(tree_exited), callable_mp(this, &Popup::_deinitialize_visible_parents)); } visible_parents.clear(); @@ -104,13 +105,18 @@ void Popup::_notification(int p_what) { case NOTIFICATION_WM_CLOSE_REQUEST: { if (!is_in_edited_scene_root()) { - hide_reason = HIDE_REASON_UNFOCUSED; + if (hide_reason == HIDE_REASON_NONE) { + hide_reason = HIDE_REASON_UNFOCUSED; + } _close_pressed(); } } break; case NOTIFICATION_APPLICATION_FOCUS_OUT: { if (!is_in_edited_scene_root() && get_flag(FLAG_POPUP)) { + if (hide_reason == HIDE_REASON_NONE) { + hide_reason = HIDE_REASON_UNFOCUSED; + } _close_pressed(); } } break; @@ -119,7 +125,9 @@ void Popup::_notification(int p_what) { void Popup::_parent_focused() { if (popped_up && get_flag(FLAG_POPUP)) { - hide_reason = HIDE_REASON_UNFOCUSED; + if (hide_reason == HIDE_REASON_NONE) { + hide_reason = HIDE_REASON_UNFOCUSED; + } _close_pressed(); } } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 9b991972be..bdd0102b63 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -1014,9 +1014,6 @@ void PopupMenu::_notification(int p_what) { float pm_delay = pm->get_submenu_popup_delay(); set_submenu_popup_delay(pm_delay); } - if (!is_embedded()) { - set_flag(FLAG_NO_FOCUS, true); - } if (system_menu_id != NativeMenu::INVALID_MENU_ID) { bind_global_menu(); } @@ -2808,6 +2805,7 @@ void PopupMenu::_bind_methods() { Item defaults(true); base_property_helper.set_prefix("item_"); + base_property_helper.set_array_length_getter(&PopupMenu::get_item_count); base_property_helper.register_property(PropertyInfo(Variant::STRING, "text"), defaults.text, &PopupMenu::set_item_text, &PopupMenu::get_item_text); base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &PopupMenu::set_item_icon, &PopupMenu::get_item_icon); base_property_helper.register_property(PropertyInfo(Variant::INT, "checkable", PROPERTY_HINT_ENUM, "No,As checkbox,As radio button"), defaults.checkable_type, &PopupMenu::_set_item_checkable_type, &PopupMenu::_get_item_checkable_type); @@ -2828,6 +2826,8 @@ void PopupMenu::popup(const Rect2i &p_bounds) { if (native) { NativeMenu::get_singleton()->popup(global_menu, (p_bounds != Rect2i()) ? p_bounds.position : get_position()); } else { + set_flag(FLAG_NO_FOCUS, !is_embedded()); + moved = Vector2(); popup_time_msec = OS::get_singleton()->get_ticks_msec(); if (!is_embedded()) { @@ -2855,6 +2855,8 @@ void PopupMenu::set_visible(bool p_visible) { NativeMenu::get_singleton()->popup(global_menu, get_position()); } } else { + set_flag(FLAG_NO_FOCUS, !is_embedded()); + Popup::set_visible(p_visible); } } @@ -2873,7 +2875,7 @@ PopupMenu::PopupMenu() { control->set_h_size_flags(Control::SIZE_EXPAND_FILL); control->set_v_size_flags(Control::SIZE_EXPAND_FILL); scroll_container->add_child(control, false, INTERNAL_MODE_FRONT); - control->connect("draw", callable_mp(this, &PopupMenu::_draw_items)); + control->connect(SceneStringName(draw), callable_mp(this, &PopupMenu::_draw_items)); submenu_timer = memnew(Timer); submenu_timer->set_wait_time(0.3); diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index 236dfcc864..00f4a1089a 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -60,7 +60,7 @@ void Range::Shared::emit_value_changed() { } void Range::_changed_notify(const char *p_what) { - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); queue_redraw(); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 19b02f33c6..f6942ca206 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -39,7 +39,6 @@ #include "scene/gui/label.h" #include "scene/gui/rich_text_effect.h" #include "scene/resources/atlas_texture.h" -#include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" #include "servers/display_server.h" @@ -1608,8 +1607,34 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V if (p_meta) { int64_t glyph_idx = TS->shaped_text_hit_test_grapheme(rid, p_click.x - rect.position.x); if (glyph_idx >= 0) { + float baseline_y = rect.position.y + TS->shaped_text_get_ascent(rid); const Glyph *glyphs = TS->shaped_text_get_glyphs(rid); - char_pos = glyphs[glyph_idx].start; + if (glyphs[glyph_idx].flags & TextServer::GRAPHEME_IS_EMBEDDED_OBJECT) { + // Emebedded object. + for (int i = 0; i < objects.size(); i++) { + if (TS->shaped_text_get_object_glyph(rid, objects[i]) == glyph_idx) { + Rect2 obj_rect = TS->shaped_text_get_object_rect(rid, objects[i]); + obj_rect.position.y += baseline_y; + if (p_click.y >= obj_rect.position.y && p_click.y <= obj_rect.position.y + obj_rect.size.y) { + char_pos = glyphs[glyph_idx].start; + } + break; + } + } + } else if (glyphs[glyph_idx].font_rid != RID()) { + // Normal glyph. + float fa = TS->font_get_ascent(glyphs[glyph_idx].font_rid, glyphs[glyph_idx].font_size); + float fd = TS->font_get_descent(glyphs[glyph_idx].font_rid, glyphs[glyph_idx].font_size); + if (p_click.y >= baseline_y - fa && p_click.y <= baseline_y + fd) { + char_pos = glyphs[glyph_idx].start; + } + } else if (!(glyphs[glyph_idx].flags & TextServer::GRAPHEME_IS_VIRTUAL)) { + // Hex code box. + Vector2 gl_size = TS->get_hex_code_box_size(glyphs[glyph_idx].font_size, glyphs[glyph_idx].index); + if (p_click.y >= baseline_y - gl_size.y * 0.9 && p_click.y <= baseline_y + gl_size.y * 0.2) { + char_pos = glyphs[glyph_idx].start; + } + } } } else { char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x); @@ -2993,7 +3018,7 @@ void RichTextLabel::_process_line_caches() { if (fit_content) { update_minimum_size(); } - emit_signal(SNAME("finished")); + emit_signal(SceneStringName(finished)); } void RichTextLabel::_invalidate_current_line(ItemFrame *p_frame) { diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index b35c4e9308..af9f08e389 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -310,15 +310,15 @@ void ScrollBar::_notification(int p_what) { } if (drag_node) { - drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT); + drag_node->connect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->connect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT); } } break; case NOTIFICATION_EXIT_TREE: { if (drag_node) { - drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit)); + drag_node->disconnect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit)); } drag_node = nullptr; @@ -522,7 +522,7 @@ float ScrollBar::get_custom_step() const { void ScrollBar::_drag_node_exit() { if (drag_node) { - drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->disconnect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input)); } drag_node = nullptr; } @@ -591,8 +591,8 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) { void ScrollBar::set_drag_node(const NodePath &p_path) { if (is_inside_tree()) { if (drag_node) { - drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit)); + drag_node->disconnect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->disconnect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit)); } } @@ -606,8 +606,8 @@ void ScrollBar::set_drag_node(const NodePath &p_path) { } if (drag_node) { - drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); - drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT); + drag_node->connect(SceneStringName(gui_input), callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->connect(SceneStringName(tree_exiting), callable_mp(this, &ScrollBar::_drag_node_exit), CONNECT_ONE_SHOT); } } } diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 70acaf7adf..bfea7b0fbe 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -409,9 +409,9 @@ SpinBox::SpinBox() { line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), CONNECT_DEFERRED); - line_edit->connect("focus_entered", callable_mp(this, &SpinBox::_line_edit_focus_enter), CONNECT_DEFERRED); - line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), CONNECT_DEFERRED); - line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input)); + line_edit->connect(SceneStringName(focus_entered), callable_mp(this, &SpinBox::_line_edit_focus_enter), CONNECT_DEFERRED); + line_edit->connect(SceneStringName(focus_exited), callable_mp(this, &SpinBox::_line_edit_focus_exit), CONNECT_DEFERRED); + line_edit->connect(SceneStringName(gui_input), callable_mp(this, &SpinBox::_line_edit_input)); range_click_timer = memnew(Timer); range_click_timer->connect("timeout", callable_mp(this, &SpinBox::_range_click_timeout)); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 98b1db4a96..925600756a 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -39,7 +39,7 @@ void SplitContainerDragger::gui_input(const Ref<InputEvent> &p_event) { SplitContainer *sc = Object::cast_to<SplitContainer>(get_parent()); - if (sc->collapsed || !sc->get_containable_child(0) || !sc->get_containable_child(1) || sc->dragger_visibility != SplitContainer::DRAGGER_VISIBLE) { + if (sc->collapsed || !sc->_get_sortable_child(0) || !sc->_get_sortable_child(1) || sc->dragger_visibility != SplitContainer::DRAGGER_VISIBLE) { return; } @@ -122,12 +122,12 @@ void SplitContainerDragger::_notification(int p_what) { } } -Control *SplitContainer::get_containable_child(int p_idx) const { +Control *SplitContainer::_get_sortable_child(int p_idx) const { int idx = 0; for (int i = 0; i < get_child_count(false); i++) { - Control *c = Object::cast_to<Control>(get_child(i, false)); - if (!c || !c->is_visible() || c->is_set_as_top_level()) { + Control *c = as_sortable_control(get_child(i, false)); + if (!c) { continue; } @@ -154,8 +154,8 @@ Ref<Texture2D> SplitContainer::_get_grabber_icon() const { } void SplitContainer::_compute_middle_sep(bool p_clamp) { - Control *first = get_containable_child(0); - Control *second = get_containable_child(1); + Control *first = _get_sortable_child(0); + Control *second = _get_sortable_child(1); // Determine expanded children. bool first_expanded = (vertical ? first->get_v_size_flags() : first->get_h_size_flags()) & SIZE_EXPAND; @@ -196,8 +196,8 @@ void SplitContainer::_compute_middle_sep(bool p_clamp) { } void SplitContainer::_resort() { - Control *first = get_containable_child(0); - Control *second = get_containable_child(1); + Control *first = _get_sortable_child(0); + Control *second = _get_sortable_child(1); // If we have only one element. if (!first || !second) { @@ -258,7 +258,7 @@ Size2 SplitContainer::get_minimum_size() const { int sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(theme_cache.separation, vertical ? g->get_height() : g->get_width()) : 0; for (int i = 0; i < 2; i++) { - if (!get_containable_child(i)) { + if (!_get_sortable_child(i)) { break; } @@ -270,7 +270,7 @@ Size2 SplitContainer::get_minimum_size() const { } } - Size2 ms = get_containable_child(i)->get_combined_minimum_size(); + Size2 ms = _get_sortable_child(i)->get_combined_minimum_size(); if (vertical) { minimum.height += ms.height; @@ -322,7 +322,7 @@ int SplitContainer::get_split_offset() const { } void SplitContainer::clamp_split_offset() { - if (!get_containable_child(0) || !get_containable_child(1)) { + if (!_get_sortable_child(0) || !_get_sortable_child(1)) { return; } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 0f45ef166d..95f26f5e0b 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -82,12 +82,11 @@ private: Ref<Texture2D> _get_grabber_icon() const; void _compute_middle_sep(bool p_clamp); void _resort(); + Control *_get_sortable_child(int p_idx) const; protected: bool is_fixed = false; - Control *get_containable_child(int p_idx) const; - void _notification(int p_what); void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp index f6cfe6ab18..c715aceb0b 100644 --- a/scene/gui/subviewport_container.cpp +++ b/scene/gui/subviewport_container.cpp @@ -287,7 +287,7 @@ void SubViewportContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stretch_shrink"), &SubViewportContainer::get_stretch_shrink); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stretch"), "set_stretch", "is_stretch_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_shrink"), "set_stretch_shrink", "get_stretch_shrink"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_shrink", PROPERTY_HINT_RANGE, "1,32,1,or_greater"), "set_stretch_shrink", "get_stretch_shrink"); GDVIRTUAL_BIND(_propagate_input_event, "event"); } diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index 0e130d60af..ddc757c452 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -1868,6 +1868,7 @@ void TabBar::_bind_methods() { Tab defaults(true); base_property_helper.set_prefix("tab_"); + base_property_helper.set_array_length_getter(&TabBar::get_tab_count); base_property_helper.register_property(PropertyInfo(Variant::STRING, "title"), defaults.text, &TabBar::set_tab_title, &TabBar::get_tab_title); base_property_helper.register_property(PropertyInfo(Variant::STRING, "tooltip"), defaults.tooltip, &TabBar::set_tab_tooltip, &TabBar::get_tab_tooltip); base_property_helper.register_property(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), defaults.icon, &TabBar::set_tab_icon, &TabBar::get_tab_icon); @@ -1877,7 +1878,7 @@ void TabBar::_bind_methods() { TabBar::TabBar() { set_size(Size2(get_size().width, get_minimum_size().height)); set_focus_mode(FOCUS_ALL); - connect("mouse_exited", callable_mp(this, &TabBar::_on_mouse_exited)); + connect(SceneStringName(mouse_exited), callable_mp(this, &TabBar::_on_mouse_exited)); property_helper.setup_for_instance(base_property_helper, this); } diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index dc53cf82e6..d0c3f3d65e 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -554,7 +554,7 @@ void TabContainer::add_child_notify(Node *p_child) { } p_child->connect("renamed", callable_mp(this, &TabContainer::_refresh_tab_names)); - p_child->connect(SNAME("visibility_changed"), callable_mp(this, &TabContainer::_on_tab_visibility_changed).bind(c)); + p_child->connect(SceneStringName(visibility_changed), callable_mp(this, &TabContainer::_on_tab_visibility_changed).bind(c)); // TabBar won't emit the "tab_changed" signal when not inside the tree. if (!is_inside_tree()) { @@ -607,7 +607,7 @@ void TabContainer::remove_child_notify(Node *p_child) { p_child->remove_meta("_tab_index"); p_child->remove_meta("_tab_name"); p_child->disconnect("renamed", callable_mp(this, &TabContainer::_refresh_tab_names)); - p_child->disconnect(SNAME("visibility_changed"), callable_mp(this, &TabContainer::_on_tab_visibility_changed)); + p_child->disconnect(SceneStringName(visibility_changed), callable_mp(this, &TabContainer::_on_tab_visibility_changed)); // TabBar won't emit the "tab_changed" signal when not inside the tree. if (!is_inside_tree()) { @@ -1121,5 +1121,5 @@ TabContainer::TabContainer() { tab_bar->connect("tab_button_pressed", callable_mp(this, &TabContainer::_on_tab_button_pressed)); tab_bar->connect("active_tab_rearranged", callable_mp(this, &TabContainer::_on_active_tab_rearranged)); - connect("mouse_exited", callable_mp(this, &TabContainer::_on_mouse_exited)); + connect(SceneStringName(mouse_exited), callable_mp(this, &TabContainer::_on_mouse_exited)); } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 49cfa8a030..1dd00fab4d 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -558,8 +558,6 @@ void TextEdit::_notification(int p_what) { int visible_rows = get_visible_line_count() + 1; - Color color = !editable ? theme_cache.font_readonly_color : theme_cache.font_color; - if (theme_cache.background_color.a > 0.01) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(), get_size()), theme_cache.background_color); } @@ -734,7 +732,7 @@ void TextEdit::_notification(int p_what) { if (draw_minimap) { int minimap_visible_lines = get_minimap_visible_lines(); int minimap_line_height = (minimap_char_size.y + minimap_line_spacing); - int minimap_tab_size = minimap_char_size.x * text.get_tab_size(); + int tab_size = text.get_tab_size(); // Calculate viewport size and y offset. int viewport_height = (draw_amount - 1) * minimap_line_height; @@ -839,68 +837,74 @@ void TextEdit::_notification(int p_what) { } } - Color previous_color; + Color next_color = current_color; int characters = 0; - int tabs = 0; + int tab_alignment = 0; + int xpos = xmargin_end + 2 + indent_px; for (int j = 0; j < str.length(); j++) { - const Variant *color_data = color_map.getptr(last_wrap_column + j); - if (color_data != nullptr) { - current_color = (color_data->operator Dictionary()).get("color", theme_cache.font_color); - if (!editable) { - current_color.a = theme_cache.font_readonly_color.a; + bool next_is_whitespace = false; + bool next_is_tab = false; + // Get the number of characters to draw together. + for (characters = 0; j + characters < str.length(); characters++) { + int next_char_index = j + characters; + const Variant *color_data = color_map.getptr(last_wrap_column + next_char_index); + if (color_data != nullptr) { + next_color = (color_data->operator Dictionary()).get("color", theme_cache.font_color); + if (!editable) { + next_color.a = theme_cache.font_readonly_color.a; + } + next_color.a *= 0.6; } - } - color = current_color; - - if (j == 0) { - previous_color = color; - } - - int xpos = indent_px + ((xmargin_end + minimap_char_size.x) + (minimap_char_size.x * j)) + tabs; - bool out_of_bounds = (xpos >= xmargin_end + minimap_width); - - bool whitespace = is_whitespace(str[j]); - if (!whitespace) { - characters++; - - if (j < str.length() - 1 && color == previous_color && !out_of_bounds) { - continue; + if (characters == 0) { + current_color = next_color; } - - // If we've changed color we are at the start of a new section, therefore we need to go back to the end - // of the previous section to draw it, we'll also add the character back on. - if (color != previous_color) { - characters--; - j--; - - if (str[j] == '\t') { - tabs -= minimap_tab_size; + if (next_color != current_color) { + break; + } + next_is_whitespace = is_whitespace(str[next_char_index]); + if (next_is_whitespace) { + if (str[next_char_index] == '\t') { + next_is_tab = true; } + break; + } + bool out_of_bounds = xpos + minimap_char_size.x * characters >= xmargin_end + minimap_width; + if (out_of_bounds) { + break; } } + if (!next_is_whitespace && characters == 0) { + break; + } if (characters > 0) { - previous_color.a *= 0.6; - // Take one for zero indexing, and if we hit whitespace / the end of a word. - int chars = MAX(0, (j - (characters - 1)) - (whitespace ? 1 : 0)) + 1; - int char_x_ofs = indent_px + ((xmargin_end + minimap_char_size.x) + (minimap_char_size.x * chars)) + tabs; if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(size.width - char_x_ofs - minimap_char_size.x * characters, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), previous_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(size.width - xpos - minimap_char_size.x * characters, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color); } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(char_x_ofs, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), previous_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(xpos, minimap_line_height * i), Point2(minimap_char_size.x * characters, minimap_char_size.y)), current_color); } } - if (out_of_bounds) { - break; - } + j += characters - 1; + xpos += minimap_char_size.x * characters; + tab_alignment += characters; - if (str[j] == '\t') { - tabs += minimap_tab_size; + if (next_is_whitespace) { + if (next_is_tab) { + tab_alignment %= tab_size; + xpos += minimap_char_size.x * (tab_size - tab_alignment); + tab_alignment = 0; + } else { + xpos += minimap_char_size.x; + tab_alignment += 1; + } + j += 1; } - previous_color = color; - characters = 0; + if (xpos >= xmargin_end + minimap_width) { + // Out of bounds. + break; + } } } } @@ -999,23 +1003,12 @@ void TextEdit::_notification(int p_what) { } } - if (str.length() == 0) { - // Draw line background if empty as we won't loop at all. - if (caret_line_wrap_index_map.has(line) && caret_line_wrap_index_map[line].has(line_wrap_index) && highlight_current_line) { - if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); - } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); - } - } - } else { - // If it has text, then draw current line marker in the margin, as line number etc will draw over it, draw the rest of line marker later. - if (caret_line_wrap_index_map.has(line) && caret_line_wrap_index_map[line].has(line_wrap_index) && highlight_current_line) { - if (rtl) { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); - } else { - RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); - } + // Draw current line highlight. + if (highlight_current_line && caret_line_wrap_index_map.has(line) && caret_line_wrap_index_map[line].has(line_wrap_index)) { + if (rtl) { + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - ofs_x - xmargin_end, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); + } else { + RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(ofs_x, ofs_y, xmargin_end, row_height), theme_cache.current_line_color); } } @@ -1188,6 +1181,7 @@ void TextEdit::_notification(int p_what) { if (!clipped && lookup_symbol_word.length() != 0) { // Highlight word if (is_ascii_alphabet_char(lookup_symbol_word[0]) || lookup_symbol_word[0] == '_' || lookup_symbol_word[0] == '.') { + Color highlight_underline_color = !editable ? theme_cache.font_readonly_color : theme_cache.font_color; int lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); int lookup_symbol_word_len = lookup_symbol_word.length(); while (lookup_symbol_word_col != -1) { @@ -1205,7 +1199,7 @@ void TextEdit::_notification(int p_what) { } rect.position.y += ceil(TS->shaped_text_get_ascent(rid)) + ceil(theme_cache.font->get_underline_position(theme_cache.font_size)); rect.size.y = MAX(1, theme_cache.font->get_underline_thickness(theme_cache.font_size)); - draw_rect(rect, color); + draw_rect(rect, highlight_underline_color); } lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, lookup_symbol_word_col + lookup_symbol_word_len); @@ -4243,8 +4237,11 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const { } Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_of_bounds) const { - float rows = p_pos.y; - rows -= theme_cache.style_normal->get_margin(SIDE_TOP); + float rows = p_pos.y - theme_cache.style_normal->get_margin(SIDE_TOP); + if (!editable) { + rows -= theme_cache.style_readonly->get_offset().y / 2; + rows += theme_cache.style_normal->get_offset().y / 2; + } rows /= get_line_height(); rows += _get_v_scroll_offset(); int first_vis_line = get_first_visible_line(); @@ -4275,6 +4272,10 @@ Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_ int col = 0; int colx = p_pos.x - (theme_cache.style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding); colx += first_visible_col; + if (!editable) { + colx -= theme_cache.style_readonly->get_offset().x / 2; + colx += theme_cache.style_normal->get_offset().x / 2; + } col = _get_char_pos_for_line(colx, row, wrap_index); if (get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE && wrap_index < get_line_wrap_count(row)) { // Move back one if we are at the end of the row. @@ -7973,7 +7974,7 @@ void TextEdit::_update_minimap_click() { Point2 mp = get_local_mouse_pos(); int xmargin_end = get_size().width - theme_cache.style_normal->get_margin(SIDE_RIGHT); - if (!dragging_minimap && (mp.x < xmargin_end - minimap_width || mp.y > xmargin_end)) { + if (!dragging_minimap && (mp.x < xmargin_end - minimap_width || mp.x > xmargin_end)) { minimap_clicked = false; return; } diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index df90257e03..c267ff93c6 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -178,13 +178,14 @@ void TextureButton::_notification(int p_what) { texdraw = focused; } - if (texdraw.is_valid()) { - size = texdraw->get_size(); - _texture_region = Rect2(Point2(), texdraw->get_size()); + if (texdraw.is_valid() || click_mask.is_valid()) { + const Size2 texdraw_size = texdraw.is_valid() ? texdraw->get_size() : Size2(click_mask->get_size()); + + size = texdraw_size; + _texture_region = Rect2(Point2(), texdraw_size); _tile = false; switch (stretch_mode) { case STRETCH_KEEP: - size = texdraw->get_size(); break; case STRETCH_SCALE: size = get_size(); @@ -194,18 +195,17 @@ void TextureButton::_notification(int p_what) { _tile = true; break; case STRETCH_KEEP_CENTERED: - ofs = (get_size() - texdraw->get_size()) / 2; - size = texdraw->get_size(); + ofs = (get_size() - texdraw_size) / 2; break; case STRETCH_KEEP_ASPECT_CENTERED: case STRETCH_KEEP_ASPECT: { Size2 _size = get_size(); - float tex_width = texdraw->get_width() * _size.height / texdraw->get_height(); + float tex_width = texdraw_size.width * _size.height / texdraw_size.height; float tex_height = _size.height; if (tex_width > _size.width) { tex_width = _size.width; - tex_height = texdraw->get_height() * tex_width / texdraw->get_width(); + tex_height = texdraw_size.height * tex_width / texdraw_size.width; } if (stretch_mode == STRETCH_KEEP_ASPECT_CENTERED) { @@ -217,10 +217,9 @@ void TextureButton::_notification(int p_what) { } break; case STRETCH_KEEP_ASPECT_COVERED: { size = get_size(); - Size2 tex_size = texdraw->get_size(); - Size2 scale_size(size.width / tex_size.width, size.height / tex_size.height); + Size2 scale_size = size / texdraw_size; float scale = scale_size.width > scale_size.height ? scale_size.width : scale_size.height; - Size2 scaled_tex_size = tex_size * scale; + Size2 scaled_tex_size = texdraw_size * scale; Point2 ofs2 = ((scaled_tex_size - size) / scale).abs() / 2.0f; _texture_region = Rect2(ofs2, size / scale); } break; @@ -233,10 +232,12 @@ void TextureButton::_notification(int p_what) { if (draw_focus_only) { // Do nothing, we only needed to calculate the rectangle. - } else if (_tile) { - draw_texture_rect(texdraw, Rect2(ofs, size), _tile); - } else { - draw_texture_rect_region(texdraw, Rect2(ofs, size), _texture_region); + } else if (texdraw.is_valid()) { + if (_tile) { + draw_texture_rect(texdraw, Rect2(ofs, size), _tile); + } else { + draw_texture_rect_region(texdraw, Rect2(ofs, size), _texture_region); + } } } else { _position_rect = Rect2(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index e2de585a69..fc5b942918 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3152,8 +3152,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int } void Tree::_text_editor_popup_modal_close() { + if (popup_edit_commited) { + return; // Already processed by LineEdit/TextEdit commit. + } + if (popup_editor->get_hide_reason() == Popup::HIDE_REASON_CANCELED) { - return; + return; // ESC pressed, app focus lost, or forced close from code. } if (value_editor->has_point(value_editor->get_local_mouse_position())) { @@ -3172,9 +3176,18 @@ void Tree::_text_editor_popup_modal_close() { } void Tree::_text_editor_gui_input(const Ref<InputEvent> &p_event) { + if (popup_edit_commited) { + return; // Already processed by _text_editor_popup_modal_close + } + + if (popup_editor->get_hide_reason() == Popup::HIDE_REASON_CANCELED) { + return; // ESC pressed, app focus lost, or forced close from code. + } + if (p_event->is_action_pressed("ui_text_newline_blank", true)) { accept_event(); } else if (p_event->is_action_pressed("ui_text_newline")) { + popup_edit_commited = true; // End edit popup processing. popup_editor->hide(); _apply_multiline_edit(); accept_event(); @@ -3205,6 +3218,15 @@ void Tree::_apply_multiline_edit() { } void Tree::_line_editor_submit(String p_text) { + if (popup_edit_commited) { + return; // Already processed by _text_editor_popup_modal_close + } + + if (popup_editor->get_hide_reason() == Popup::HIDE_REASON_CANCELED) { + return; // ESC pressed, app focus lost, or forced close from code. + } + + popup_edit_commited = true; // End edit popup processing. popup_editor->hide(); if (!popup_edited_item) { @@ -4072,6 +4094,7 @@ bool Tree::edit_selected(bool p_force_edit) { if (!popup_editor->is_embedded()) { popup_editor->set_content_scale_factor(popup_scale); } + popup_edit_commited = false; // Start edit popup processing. popup_editor->popup(); popup_editor->child_controls_changed(); @@ -4091,6 +4114,7 @@ bool Tree::edit_selected(bool p_force_edit) { if (!popup_editor->is_embedded()) { popup_editor->set_content_scale_factor(popup_scale); } + popup_edit_commited = false; // Start edit popup processing. popup_editor->popup(); popup_editor->child_controls_changed(); @@ -5795,7 +5819,7 @@ Tree::Tree() { h_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved)); v_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved)); line_editor->connect("text_submitted", callable_mp(this, &Tree::_line_editor_submit)); - text_editor->connect("gui_input", callable_mp(this, &Tree::_text_editor_gui_input)); + text_editor->connect(SceneStringName(gui_input), callable_mp(this, &Tree::_text_editor_gui_input)); popup_editor->connect("popup_hide", callable_mp(this, &Tree::_text_editor_popup_modal_close)); popup_menu->connect("id_pressed", callable_mp(this, &Tree::popup_select)); value_editor->connect("value_changed", callable_mp(this, &Tree::value_editor_changed)); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 311055a2f8..e9c93c6e03 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -479,6 +479,7 @@ private: VBoxContainer *popup_editor_vb = nullptr; + bool popup_edit_commited = true; Popup *popup_editor = nullptr; LineEdit *line_editor = nullptr; TextEdit *text_editor = nullptr; diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp index 687a9e46a0..0b521f926d 100644 --- a/scene/gui/video_stream_player.cpp +++ b/scene/gui/video_stream_player.cpp @@ -31,7 +31,6 @@ #include "video_stream_player.h" #include "core/os/os.h" -#include "scene/scene_string_names.h" #include "servers/audio_server.h" int VideoStreamPlayer::sp_get_channel_count() const { @@ -163,7 +162,7 @@ void VideoStreamPlayer::_notification(int p_notification) { play(); return; } - emit_signal(SceneStringNames::get_singleton()->finished); + emit_signal(SceneStringName(finished)); } } break; @@ -460,7 +459,7 @@ StringName VideoStreamPlayer::get_bus() const { return bus; } } - return SceneStringNames::get_singleton()->Master; + return SceneStringName(Master); } void VideoStreamPlayer::_validate_property(PropertyInfo &p_property) const { diff --git a/scene/main/canvas_item.compat.inc b/scene/main/canvas_item.compat.inc index 7136fded15..9bc3d01a69 100644 --- a/scene/main/canvas_item.compat.inc +++ b/scene/main/canvas_item.compat.inc @@ -30,12 +30,32 @@ #ifndef DISABLE_DEPRECATED -void CanvasItem::_draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) { +void CanvasItem::_draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color) { draw_circle(p_pos, p_radius, p_color, true, -1.0, false); } +void CanvasItem::_draw_rect_bind_compat_84523(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width) { + draw_rect(p_rect, p_color, p_filled, p_width, false); +} + +void CanvasItem::_draw_dashed_line_bind_compat_84523(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) { + draw_dashed_line(p_from, p_to, p_color, p_width, p_dash, p_aligned, false); +} + +void CanvasItem::_draw_multiline_bind_compat_84523(const Vector<Point2> &p_points, const Color &p_color, real_t p_width) { + draw_multiline(p_points, p_color, p_width, false); +} + +void CanvasItem::_draw_multiline_colors_bind_compat_84523(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width) { + draw_multiline_colors(p_points, p_colors, p_width, false); +} + void CanvasItem::_bind_compatibility_methods() { - ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_compat_84472); + ClassDB::bind_compatibility_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::_draw_circle_bind_compat_84472); + ClassDB::bind_compatibility_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::_draw_rect_bind_compat_84523, DEFVAL(true), DEFVAL(-1.0)); + ClassDB::bind_compatibility_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned"), &CanvasItem::_draw_dashed_line_bind_compat_84523, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true)); + ClassDB::bind_compatibility_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::_draw_multiline_bind_compat_84523, DEFVAL(-1.0)); + ClassDB::bind_compatibility_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::_draw_multiline_colors_bind_compat_84523, DEFVAL(-1.0)); } #endif diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 50cae48e34..c0386b056f 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -40,7 +40,6 @@ #include "scene/resources/multimesh.h" #include "scene/resources/style_box.h" #include "scene/resources/world_2d.h" -#include "scene/scene_string_names.h" #define ERR_DRAW_GUARD \ ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside this node's `_draw()`, functions connected to its `draw` signal, or when it receives NOTIFICATION_DRAW.") @@ -96,7 +95,7 @@ void CanvasItem::_handle_visibility_change(bool p_visible) { if (p_visible) { queue_redraw(); } else { - emit_signal(SceneStringNames::get_singleton()->hidden); + emit_signal(SceneStringName(hidden)); } _block(); @@ -142,7 +141,7 @@ void CanvasItem::_redraw_callback() { drawing = true; current_item_drawn = this; notification(NOTIFICATION_DRAW); - emit_signal(SceneStringNames::get_singleton()->draw); + emit_signal(SceneStringName(draw)); GDVIRTUAL_CALL(_draw); current_item_drawn = nullptr; drawing = false; @@ -310,7 +309,7 @@ void CanvasItem::_notification(int p_what) { window = Object::cast_to<Window>(viewport); if (window) { - window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window->connect(SceneStringName(visibility_changed), callable_mp(this, &CanvasItem::_window_visibility_changed)); parent_visible_in_tree = window->is_visible(); } else { parent_visible_in_tree = true; @@ -364,7 +363,7 @@ void CanvasItem::_notification(int p_what) { C = nullptr; } if (window) { - window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed)); + window->disconnect(SceneStringName(visibility_changed), callable_mp(this, &CanvasItem::_window_visibility_changed)); window = nullptr; } _set_global_invalid(true); @@ -384,7 +383,7 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { ERR_MAIN_THREAD_GUARD; - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); } break; case NOTIFICATION_WORLD_2D_CHANGED: { ERR_MAIN_THREAD_GUARD; @@ -556,7 +555,7 @@ void CanvasItem::item_rect_changed(bool p_size_changed) { if (p_size_changed) { queue_redraw(); } - emit_signal(SceneStringNames::get_singleton()->item_rect_changed); + emit_signal(SceneStringName(item_rect_changed)); } void CanvasItem::set_z_index(int p_z) { @@ -610,7 +609,7 @@ bool CanvasItem::is_y_sort_enabled() const { return y_sort_enabled; } -void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) { +void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; ERR_FAIL_COND(p_dash <= 0.0); @@ -619,7 +618,7 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons Vector2 step = p_dash * (p_to - p_from).normalized(); if (length < p_dash || step == Vector2()) { - RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width); + RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased); return; } @@ -643,7 +642,7 @@ void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, cons Vector<Color> colors = { p_color }; - RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, points, colors, p_width, p_antialiased); } void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, bool p_antialiased) { @@ -684,22 +683,22 @@ void CanvasItem::draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_sta draw_polyline(points, p_color, p_width, p_antialiased); } -void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width) { +void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; Vector<Color> colors = { p_color }; - RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased); } -void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width) { +void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; - RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased); } -void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width) { +void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width, bool p_antialiased) { ERR_THREAD_GUARD; ERR_DRAW_GUARD; @@ -710,9 +709,9 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\"."); } - RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect, p_color); + RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect, p_color, p_antialiased); } else if (p_width >= rect.size.width || p_width >= rect.size.height) { - RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color); + RenderingServer::get_singleton()->canvas_item_add_rect(canvas_item, rect.grow(0.5f * p_width), p_color, p_antialiased); } else { Vector<Vector2> points; points.resize(5); @@ -724,7 +723,7 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil Vector<Color> colors = { p_color }; - RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width); + RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, points, colors, p_width, p_antialiased); } } @@ -737,9 +736,9 @@ void CanvasItem::draw_circle(const Point2 &p_pos, real_t p_radius, const Color & WARN_PRINT("The draw_circle() \"width\" argument has no effect when \"filled\" is \"true\"."); } - RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color); + RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color, p_antialiased); } else if (p_width >= 2.0 * p_radius) { - RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius + 0.5 * p_width, p_color); + RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius + 0.5 * p_width, p_color, p_antialiased); } else { // Tessellation count is hardcoded. Keep in sync with the same variable in `RendererCanvasCull::canvas_item_add_circle()`. const int circle_segments = 64; @@ -1197,13 +1196,13 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("is_draw_behind_parent_enabled"), &CanvasItem::is_draw_behind_parent_enabled); ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(-1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned"), &CanvasItem::draw_dashed_line, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash", "aligned", "antialiased"), &CanvasItem::draw_dashed_line, DEFVAL(-1.0), DEFVAL(2.0), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(-1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::draw_multiline, DEFVAL(-1.0)); - ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::draw_multiline_colors, DEFVAL(-1.0)); - ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(-1.0)); + ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(-1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(-1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color", "filled", "width", "antialiased"), &CanvasItem::draw_circle, DEFVAL(true), DEFVAL(-1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false)); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index ae7b195ead..028c2cb2cf 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -168,7 +168,11 @@ protected: static void _bind_methods(); #ifndef DISABLE_DEPRECATED - void _draw_circle_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color); + void _draw_circle_bind_compat_84472(const Point2 &p_pos, real_t p_radius, const Color &p_color); + void _draw_rect_bind_compat_84523(const Rect2 &p_rect, const Color &p_color, bool p_filled, real_t p_width); + void _draw_dashed_line_bind_compat_84523(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned); + void _draw_multiline_bind_compat_84523(const Vector<Point2> &p_points, const Color &p_color, real_t p_width); + void _draw_multiline_colors_bind_compat_84523(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width); static void _bind_compatibility_methods(); #endif @@ -271,14 +275,14 @@ public: /* DRAWING API */ - void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, real_t p_dash = 2.0, bool p_aligned = true); + void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, real_t p_dash = 2.0, bool p_aligned = true, bool p_antialiased = false); void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0, bool p_antialiased = false); void draw_arc(const Vector2 &p_center, real_t p_radius, real_t p_start_angle, real_t p_end_angle, int p_point_count, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); - void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0); - void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0); - void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = -1.0); + void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = -1.0, bool p_antialiased = false); + void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = -1.0, bool p_antialiased = false); + void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, real_t p_width = -1.0, bool p_antialiased = false); void draw_circle(const Point2 &p_pos, real_t p_radius, const Color &p_color, bool p_filled = true, real_t p_width = -1.0, bool p_antialiased = false); void draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1)); void draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false); diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index c9cca76dea..11d074f014 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -52,7 +52,7 @@ void CanvasLayer::set_visible(bool p_visible) { } visible = p_visible; - emit_signal(SNAME("visibility_changed")); + emit_signal(SceneStringName(visibility_changed)); for (int i = 0; i < get_child_count(); i++) { CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i)); diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp index fe23ca1800..f36bbe9395 100644 --- a/scene/main/instance_placeholder.cpp +++ b/scene/main/instance_placeholder.cpp @@ -88,16 +88,16 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene if (!ps.is_valid()) { return nullptr; } - Node *scene = ps->instantiate(); - if (!scene) { + Node *instance = ps->instantiate(); + if (!instance) { return nullptr; } - scene->set_name(get_name()); - scene->set_multiplayer_authority(get_multiplayer_authority()); + instance->set_name(get_name()); + instance->set_multiplayer_authority(get_multiplayer_authority()); int pos = get_index(); for (const PropSet &E : stored_values) { - scene->set(E.name, E.value); + set_value_on_instance(this, instance, E); } if (p_replace) { @@ -105,10 +105,125 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene base->remove_child(this); } - base->add_child(scene); - base->move_child(scene, pos); + base->add_child(instance); + base->move_child(instance, pos); - return scene; + return instance; +} + +// This method will attempt to set the correct values on the placeholder instance +// for regular types this is trivial and unnecessary. +// For nodes however this becomes a bit tricky because they might now have existed until the instantiation, +// so this method will try to find the correct nodes and resolve them. +void InstancePlaceholder::set_value_on_instance(InstancePlaceholder *p_placeholder, Node *p_instance, const PropSet &p_set) { + bool is_valid; + + // If we don't have any info, we can't do anything, + // so try setting the value directly. + Variant current = p_instance->get(p_set.name, &is_valid); + if (!is_valid) { + p_instance->set(p_set.name, p_set.value, &is_valid); + return; + } + + Variant::Type current_type = current.get_type(); + Variant::Type placeholder_type = p_set.value.get_type(); + + // Arrays are a special case, because their containing type might be different. + if (current_type != Variant::Type::ARRAY) { + // Check if the variant types match. + if (Variant::evaluate(Variant::OP_EQUAL, current_type, placeholder_type)) { + p_instance->set(p_set.name, p_set.value, &is_valid); + if (is_valid) { + return; + } + // Types match but setting failed? This is strange, so let's print a warning! + WARN_PRINT(vformat("Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(current_type), p_placeholder->get_name())); + return; + } + } else { + // We are dealing with an Array. + // Let's check if the subtype of the array matches first. + // This is needed because the set method of ScriptInstance checks for type, + // but the ClassDB set method doesn't! So we cannot reliably know what actually happens. + Array current_array = current; + Array placeholder_array = p_set.value; + if (current_array.is_same_typed(placeholder_array)) { + p_instance->set(p_set.name, p_set.value, &is_valid); + if (is_valid) { + return; + } + // Internal array types match but setting failed? This is strange, so let's print a warning! + WARN_PRINT(vformat("Array Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(Variant::Type(current_array.get_typed_builtin())), p_placeholder->get_name())); + } + // Arrays are not the same internal type. This should be happening because we have a NodePath Array, + // but the instance wants a Node Array. + } + + switch (current_type) { + case Variant::Type::NIL: + if (placeholder_type != Variant::Type::NODE_PATH) { + break; + } + // If it's nil but we have a NodePath, we guess what works. + + p_instance->set(p_set.name, p_set.value, &is_valid); + if (is_valid) { + break; + } + + p_instance->set(p_set.name, try_get_node(p_placeholder, p_instance, p_set.value), &is_valid); + break; + case Variant::Type::OBJECT: + if (placeholder_type != Variant::Type::NODE_PATH) { + break; + } + // Easiest case, we want a node, but we have a deferred NodePath. + p_instance->set(p_set.name, try_get_node(p_placeholder, p_instance, p_set.value)); + break; + case Variant::Type::ARRAY: { + // If we have reached here it means our array types don't match, + // so we will convert the placeholder array into the correct type + // and resolve nodes if necessary. + Array current_array = current; + Array converted_array; + Array placeholder_array = p_set.value; + converted_array = current_array.duplicate(); + converted_array.resize(placeholder_array.size()); + + if (Variant::evaluate(Variant::OP_EQUAL, current_array.get_typed_builtin(), Variant::Type::NODE_PATH)) { + // We want a typed NodePath array. + for (int i = 0; i < placeholder_array.size(); i++) { + converted_array.set(i, placeholder_array[i]); + } + } else { + // We want Nodes, convert NodePaths. + for (int i = 0; i < placeholder_array.size(); i++) { + converted_array.set(i, try_get_node(p_placeholder, p_instance, placeholder_array[i])); + } + } + + p_instance->set(p_set.name, converted_array, &is_valid); + if (!is_valid) { + WARN_PRINT(vformat("Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(current_type), p_placeholder->get_name())); + } + break; + } + default: + WARN_PRINT(vformat("Property '%s' with type '%s' could not be set when creating instance of '%s'.", p_set.name, Variant::get_type_name(current_type), p_placeholder->get_name())); + break; + } +} + +Node *InstancePlaceholder::try_get_node(InstancePlaceholder *p_placeholder, Node *p_instance, const NodePath &p_path) { + // First try to resolve internally, + // if that fails try resolving externally. + Node *node = p_instance->get_node_or_null(p_path); + if (node == nullptr) { + node = p_placeholder->get_node_or_null(p_path); + } + + return node; } Dictionary InstancePlaceholder::get_stored_values(bool p_with_order) { diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h index 480474d0bd..ccf1e63a16 100644 --- a/scene/main/instance_placeholder.h +++ b/scene/main/instance_placeholder.h @@ -46,6 +46,10 @@ class InstancePlaceholder : public Node { List<PropSet> stored_values; +private: + void set_value_on_instance(InstancePlaceholder *p_placeholder, Node *p_instance, const PropSet &p_set); + Node *try_get_node(InstancePlaceholder *p_placeholder, Node *p_instance, const NodePath &p_path); + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e54209c1dd..884fc6de07 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -31,7 +31,6 @@ #include "node.h" #include "core/config/project_settings.h" -#include "core/core_string_names.h" #include "core/io/resource_loader.h" #include "core/object/message_queue.h" #include "core/object/script_language.h" @@ -42,7 +41,6 @@ #include "scene/main/multiplayer_api.h" #include "scene/main/window.h" #include "scene/resources/packed_scene.h" -#include "scene/scene_string_names.h" #include "viewport.h" #include <stdint.h> @@ -266,7 +264,7 @@ void Node::_propagate_ready() { if (data.ready_first) { data.ready_first = false; notification(NOTIFICATION_READY); - emit_signal(SceneStringNames::get_singleton()->ready); + emit_signal(SceneStringName(ready)); } } @@ -295,7 +293,7 @@ void Node::_propagate_enter_tree() { GDVIRTUAL_CALL(_enter_tree); - emit_signal(SceneStringNames::get_singleton()->tree_entered); + emit_signal(SceneStringName(tree_entered)); data.tree->node_added(this); @@ -350,7 +348,7 @@ void Node::_propagate_after_exit_tree() { data.blocked--; - emit_signal(SceneStringNames::get_singleton()->tree_exited); + emit_signal(SceneStringName(tree_exited)); } void Node::_propagate_exit_tree() { @@ -372,7 +370,7 @@ void Node::_propagate_exit_tree() { GDVIRTUAL_CALL(_exit_tree); - emit_signal(SceneStringNames::get_singleton()->tree_exiting); + emit_signal(SceneStringName(tree_exiting)); notification(NOTIFICATION_EXIT_TREE, true); if (data.tree) { @@ -1738,12 +1736,10 @@ Node *Node::get_node_or_null(const NodePath &p_path) const { StringName name = p_path.get_name(i); Node *next = nullptr; - if (name == SceneStringNames::get_singleton()->dot) { // . - + if (name == SNAME(".")) { next = current; - } else if (name == SceneStringNames::get_singleton()->doubledot) { // .. - + } else if (name == SNAME("..")) { if (current == nullptr || !current->data.parent) { return nullptr; } @@ -2667,8 +2663,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c node->data.editable_instance = data.editable_instance; } - StringName script_property_name = CoreStringNames::get_singleton()->_script; - List<const Node *> hidden_roots; List<const Node *> node_tree; node_tree.push_front(this); @@ -2770,45 +2764,6 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c parent->move_child(dup, pos); } } - - for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { - Node *current_node = node->get_node(get_path_to(N->get())); - ERR_CONTINUE(!current_node); - - if (p_flags & DUPLICATE_SCRIPTS) { - bool is_valid = false; - Variant scr = N->get()->get(script_property_name, &is_valid); - if (is_valid) { - current_node->set(script_property_name, scr); - } - } - - List<PropertyInfo> plist; - N->get()->get_property_list(&plist); - - for (const PropertyInfo &E : plist) { - if (!(E.usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - String name = E.name; - if (name == script_property_name) { - continue; - } - - Variant value = N->get()->get(name).duplicate(true); - - if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) { - Resource *res = Object::cast_to<Resource>(value); - if (res) { // Duplicate only if it's a resource - current_node->set(name, res->duplicate()); - } - - } else { - current_node->set(name, value); - } - } - } - return node; } @@ -2820,7 +2775,7 @@ Node *Node::duplicate(int p_flags) const { _duplicate_signals(this, dupe); } - _duplicate_properties_node(this, this, dupe); + _duplicate_properties(this, this, dupe, p_flags); return dupe; } @@ -2831,7 +2786,8 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap) con } Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, const HashMap<Ref<Resource>, Ref<Resource>> &p_resource_remap) const { - Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR, &r_duplimap); + int flags = DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANTIATION | DUPLICATE_FROM_EDITOR; + Node *dupe = _duplicate(flags, &r_duplimap); // This is used by SceneTreeDock's paste functionality. When pasting to foreign scene, resources are duplicated. if (!p_resource_remap.is_empty()) { @@ -2843,7 +2799,7 @@ Node *Node::duplicate_from_editor(HashMap<const Node *, Node *> &r_duplimap, con // if the emitter node comes later in tree order than the receiver _duplicate_signals(this, dupe); - _duplicate_properties_node(this, this, dupe); + _duplicate_properties(this, this, dupe, flags); return dupe; } @@ -2897,34 +2853,58 @@ void Node::remap_nested_resources(Ref<Resource> p_resource, const HashMap<Ref<Re } #endif -// Duplicates properties that store a Node. -// This has to be called after nodes have been duplicated since -// only then do we get a full picture of how the duplicated node tree looks like. -void Node::_duplicate_properties_node(const Node *p_root, const Node *p_original, Node *p_copy) const { +// Duplicate node's properties. +// This has to be called after nodes have been duplicated since there might be properties +// of type Node that can be updated properly only if duplicated node tree is complete. +void Node::_duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const { List<PropertyInfo> props; - p_copy->get_property_list(&props); + p_original->get_property_list(&props); + const StringName &script_property_name = CoreStringName(script); + if (p_flags & DUPLICATE_SCRIPTS) { + bool is_valid = false; + Variant scr = p_original->get(script_property_name, &is_valid); + if (is_valid) { + p_copy->set(script_property_name, scr); + } + } for (const PropertyInfo &E : props) { if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - String name = E.name; + const StringName name = E.name; + + if (name == script_property_name) { + continue; + } + Variant value = p_original->get(name).duplicate(true); - if (value.get_type() == Variant::OBJECT) { - Node *property_node = Object::cast_to<Node>(value); - if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { - value = p_copy->get_node_or_null(p_original->get_path_to(property_node)); - p_copy->set(name, value); + + if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) { + Resource *res = Object::cast_to<Resource>(value); + if (res) { // Duplicate only if it's a resource + p_copy->set(name, res->duplicate()); } - } else if (value.get_type() == Variant::ARRAY) { - Array arr = value; - if (arr.get_typed_builtin() == Variant::OBJECT) { - for (int i = 0; i < arr.size(); i++) { - Node *property_node = Object::cast_to<Node>(arr[i]); - if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { - arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node)); + } else { + if (value.get_type() == Variant::OBJECT) { + Node *property_node = Object::cast_to<Node>(value); + Variant out_value = value; + if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { + out_value = p_copy->get_node_or_null(p_original->get_path_to(property_node)); + } + p_copy->set(name, out_value); + } else if (value.get_type() == Variant::ARRAY) { + Array arr = value; + if (arr.get_typed_builtin() == Variant::OBJECT) { + for (int i = 0; i < arr.size(); i++) { + Node *property_node = Object::cast_to<Node>(arr[i]); + if (property_node && (p_root == property_node || p_root->is_ancestor_of(property_node))) { + arr[i] = p_copy->get_node_or_null(p_original->get_path_to(property_node)); + } } + value = arr; + p_copy->set(name, value); } - value = arr; + } else { p_copy->set(name, value); } } @@ -2933,7 +2913,7 @@ void Node::_duplicate_properties_node(const Node *p_root, const Node *p_original for (int i = 0; i < p_original->get_child_count(); i++) { Node *copy_child = p_copy->get_child(i); ERR_FAIL_NULL_MSG(copy_child, "Child node disappeared while duplicating."); - _duplicate_properties_node(p_root, p_original->get_child(i), copy_child); + _duplicate_properties(p_root, p_original->get_child(i), copy_child, p_flags); } } @@ -3323,7 +3303,7 @@ void Node::update_configuration_warnings() { return; } if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_ancestor_of(this))) { - get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed, this); + get_tree()->emit_signal(SceneStringName(node_configuration_warning_changed), this); } #endif } diff --git a/scene/main/node.h b/scene/main/node.h index fe212ae0f7..6b93724478 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -35,6 +35,7 @@ #include "core/templates/rb_map.h" #include "core/variant/typed_array.h" #include "scene/main/scene_tree.h" +#include "scene/scene_string_names.h" class Viewport; class Window; @@ -266,7 +267,7 @@ private: void _propagate_groups_dirty(); Array _get_node_and_resource(const NodePath &p_path); - void _duplicate_properties_node(const Node *p_root, const Node *p_original, Node *p_copy) const; + void _duplicate_properties(const Node *p_root, const Node *p_original, Node *p_copy, int p_flags) const; void _duplicate_signals(const Node *p_original, Node *p_copy) const; Node *_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap = nullptr) const; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 870bed7409..ced6d9aaa6 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -55,7 +55,6 @@ #include "scene/resources/mesh.h" #include "scene/resources/packed_scene.h" #include "scene/resources/world_2d.h" -#include "scene/scene_string_names.h" #include "servers/display_server.h" #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" @@ -1876,7 +1875,7 @@ SceneTree::SceneTree() { root->connect("close_requested", callable_mp(this, &SceneTree::_main_window_close)); root->connect("go_back_requested", callable_mp(this, &SceneTree::_main_window_go_back)); - root->connect("focus_entered", callable_mp(this, &SceneTree::_main_window_focus_in)); + root->connect(SceneStringName(focus_entered), callable_mp(this, &SceneTree::_main_window_focus_in)); #ifdef TOOLS_ENABLED edited_scene_root = nullptr; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 091e6249bf..41e0aa739e 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -31,7 +31,6 @@ #include "shader_globals_override.h" #include "scene/main/node.h" -#include "scene/scene_string_names.h" StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const { StringName *r = param_remaps.getptr(p_name); @@ -223,11 +222,11 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const void ShaderGlobalsOverride::_activate() { ERR_FAIL_NULL(get_tree()); List<Node *> nodes; - get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes); + get_tree()->get_nodes_in_group(SceneStringName(shader_overrides_group_active), &nodes); if (nodes.size() == 0) { //good we are the only override, enable all active = true; - add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active); + add_to_group(SceneStringName(shader_overrides_group_active)); for (const KeyValue<StringName, Override> &E : overrides) { const Override *o = &E.value; @@ -248,7 +247,7 @@ void ShaderGlobalsOverride::_activate() { void ShaderGlobalsOverride::_notification(int p_what) { switch (p_what) { case Node::NOTIFICATION_ENTER_TREE: { - add_to_group(SceneStringNames::get_singleton()->shader_overrides_group); + add_to_group(SceneStringName(shader_overrides_group)); _activate(); } break; @@ -263,9 +262,9 @@ void ShaderGlobalsOverride::_notification(int p_what) { } } - remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active); - remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group); - get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed + remove_from_group(SceneStringName(shader_overrides_group_active)); + remove_from_group(SceneStringName(shader_overrides_group)); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFERRED, SceneStringName(shader_overrides_group), "_activate"); //another may want to activate when this is removed active = false; } break; } diff --git a/scene/main/status_indicator.cpp b/scene/main/status_indicator.cpp index 891974f68f..f0ba5db1a0 100644 --- a/scene/main/status_indicator.cpp +++ b/scene/main/status_indicator.cpp @@ -91,7 +91,7 @@ void StatusIndicator::_bind_methods() { } void StatusIndicator::_callback(MouseButton p_index, const Point2i &p_pos) { - emit_signal(SNAME("pressed"), p_index, p_pos); + emit_signal(SceneStringName(pressed), p_index, p_pos); } void StatusIndicator::set_icon(const Ref<Texture2D> &p_icon) { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index b8c691c6e7..26128a08ab 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -54,7 +54,6 @@ #include "scene/resources/mesh.h" #include "scene/resources/text_line.h" #include "scene/resources/world_2d.h" -#include "scene/scene_string_names.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_globals.h" @@ -81,7 +80,7 @@ void ViewportTexture::setup_local_to_scene() { if (loc_scene->is_ready()) { _setup_local_to_scene(loc_scene); } else { - loc_scene->connect(SNAME("ready"), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT); + loc_scene->connect(SceneStringName(ready), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT); vp_pending = true; } } @@ -1465,7 +1464,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_label->set_theme_type_variation(SNAME("TooltipLabel")); gui.tooltip_label->set_text(gui.tooltip_text); base_tooltip = gui.tooltip_label; - panel->connect("mouse_entered", callable_mp(this, &Viewport::_gui_cancel_tooltip)); + panel->connect(SceneStringName(mouse_entered), callable_mp(this, &Viewport::_gui_cancel_tooltip)); } base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 929720fcf4..addbd6078a 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -37,7 +37,6 @@ #include "core/string/translation.h" #include "core/variant/variant_parser.h" #include "scene/gui/control.h" -#include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" #include "scene/theme/theme_owner.h" @@ -307,10 +306,21 @@ String Window::get_title() const { return title; } +void Window::_settings_changed() { + if (visible && initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE && is_in_edited_scene_root()) { + Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height")); + position = (screen_size - size) / 2; + if (embedder) { + embedder->_sub_window_update(this); + } + } +} + void Window::set_initial_position(Window::WindowInitialPosition p_initial_position) { ERR_MAIN_THREAD_GUARD; initial_position = p_initial_position; + _settings_changed(); notify_property_list_changed(); } @@ -742,13 +752,13 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) { case DisplayServer::WINDOW_EVENT_FOCUS_IN: { focused = true; _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_IN); - emit_signal(SNAME("focus_entered")); + emit_signal(SceneStringName(focus_entered)); } break; case DisplayServer::WINDOW_EVENT_FOCUS_OUT: { focused = false; _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_OUT); - emit_signal(SNAME("focus_exited")); + emit_signal(SceneStringName(focus_exited)); } break; case DisplayServer::WINDOW_EVENT_CLOSE_REQUEST: { if (exclusive_child != nullptr) { @@ -830,7 +840,12 @@ void Window::set_visible(bool p_visible) { if (visible) { embedder = embedder_vp; if (initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) { - position = (embedder->get_visible_rect().size - size) / 2; + if (is_in_edited_scene_root()) { + Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height")); + position = (screen_size - size) / 2; + } else { + position = (embedder->get_visible_rect().size - size) / 2; + } } embedder->_sub_window_register(this); RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE); @@ -846,7 +861,7 @@ void Window::set_visible(bool p_visible) { focused = false; } notification(NOTIFICATION_VISIBILITY_CHANGED); - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); RS::get_singleton()->viewport_set_active(get_viewport_rid(), visible); @@ -1266,6 +1281,12 @@ void Window::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: { + if (is_in_edited_scene_root()) { + if (!ProjectSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &Window::_settings_changed))) { + ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Window::_settings_changed)); + } + } + bool embedded = false; { embedder = get_embedder(); @@ -1281,7 +1302,12 @@ void Window::_notification(int p_what) { // Create as embedded. if (embedder) { if (initial_position != WINDOW_INITIAL_POSITION_ABSOLUTE) { - position = (embedder->get_visible_rect().size - size) / 2; + if (is_in_edited_scene_root()) { + Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height")); + position = (screen_size - size) / 2; + } else { + position = (embedder->get_visible_rect().size - size) / 2; + } } embedder->_sub_window_register(this); RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE); @@ -1321,7 +1347,7 @@ void Window::_notification(int p_what) { } if (visible) { notification(NOTIFICATION_VISIBILITY_CHANGED); - emit_signal(SceneStringNames::get_singleton()->visibility_changed); + emit_signal(SceneStringName(visibility_changed)); RS::get_singleton()->viewport_set_active(get_viewport_rid(), true); } @@ -1337,7 +1363,7 @@ void Window::_notification(int p_what) { } break; case NOTIFICATION_THEME_CHANGED: { - emit_signal(SceneStringNames::get_singleton()->theme_changed); + emit_signal(SceneStringName(theme_changed)); _invalidate_theme_cache(); _update_theme_item_cache(); } break; @@ -1378,6 +1404,10 @@ void Window::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { + if (ProjectSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &Window::_settings_changed))) { + ProjectSettings::get_singleton()->disconnect("settings_changed", callable_mp(this, &Window::_settings_changed)); + } + set_theme_context(nullptr, false); if (transient) { @@ -1404,11 +1434,11 @@ void Window::_notification(int p_what) { } break; case NOTIFICATION_VP_MOUSE_ENTER: { - emit_signal(SceneStringNames::get_singleton()->mouse_entered); + emit_signal(SceneStringName(mouse_entered)); } break; case NOTIFICATION_VP_MOUSE_EXIT: { - emit_signal(SceneStringNames::get_singleton()->mouse_exited); + emit_signal(SceneStringName(mouse_exited)); } break; } } @@ -1622,7 +1652,7 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) { _input_from_window(p_ev); if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL && is_inside_tree()) { - emit_signal(SceneStringNames::get_singleton()->window_input, p_ev); + emit_signal(SceneStringName(window_input), p_ev); } if (is_inside_tree()) { diff --git a/scene/main/window.h b/scene/main/window.h index ffcf50ccdd..33d593711f 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -214,6 +214,8 @@ private: int resize_margin = 0; } theme_cache; + void _settings_changed(); + Viewport *embedder = nullptr; Transform2D window_transform; diff --git a/scene/property_list_helper.cpp b/scene/property_list_helper.cpp index b666e4c52d..152ecaf89d 100644 --- a/scene/property_list_helper.cpp +++ b/scene/property_list_helper.cpp @@ -36,14 +36,17 @@ const PropertyListHelper::Property *PropertyListHelper::_get_property(const Stri return nullptr; } - { - const String index_string = components[0].trim_prefix(prefix); - if (!index_string.is_valid_int()) { - return nullptr; - } - *r_index = index_string.to_int(); + const String index_string = components[0].trim_prefix(prefix); + if (!index_string.is_valid_int()) { + return nullptr; + } + + int index = index_string.to_int(); + if (index < 0 || index >= _call_array_length_getter()) { + return nullptr; } + *r_index = index; return property_list.getptr(components[1]); } @@ -66,6 +69,11 @@ Variant PropertyListHelper::_call_getter(const Property *p_property, int p_index return p_property->getter->call(object, argptrs, 1, ce); } +int PropertyListHelper::_call_array_length_getter() const { + Callable::CallError ce; + return array_length_getter->call(object, nullptr, 0, ce); +} + void PropertyListHelper::set_prefix(const String &p_prefix) { prefix = p_prefix; } @@ -83,7 +91,13 @@ bool PropertyListHelper::is_initialized() const { } void PropertyListHelper::setup_for_instance(const PropertyListHelper &p_base, Object *p_object) { + DEV_ASSERT(!p_base.prefix.is_empty()); + DEV_ASSERT(p_base.array_length_getter != nullptr); + DEV_ASSERT(!p_base.property_list.is_empty()); + DEV_ASSERT(p_object != nullptr); + prefix = p_base.prefix; + array_length_getter = p_base.array_length_getter; property_list = p_base.property_list; object = p_object; } diff --git a/scene/property_list_helper.h b/scene/property_list_helper.h index eac6b03d47..e19e7cd22e 100644 --- a/scene/property_list_helper.h +++ b/scene/property_list_helper.h @@ -43,15 +43,22 @@ class PropertyListHelper { }; String prefix; + MethodBind *array_length_getter = nullptr; HashMap<String, Property> property_list; Object *object = nullptr; const Property *_get_property(const String &p_property, int *r_index) const; void _call_setter(const MethodBind *p_setter, int p_index, const Variant &p_value) const; Variant _call_getter(const Property *p_property, int p_index) const; + int _call_array_length_getter() const; public: void set_prefix(const String &p_prefix); + template <typename G> + void set_array_length_getter(G p_array_length_getter) { + array_length_getter = create_method_bind(p_array_length_getter); + } + // Register property without setter/getter. Only use when you don't need PropertyListHelper for _set/_get logic. void register_property(const PropertyInfo &p_info, const Variant &p_default); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 6fac096c93..aa8ff75c6a 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -155,7 +155,6 @@ #include "scene/resources/visual_shader_particle_nodes.h" #include "scene/resources/visual_shader_sdf_nodes.h" #include "scene/resources/world_2d.h" -#include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" // 2D @@ -589,7 +588,7 @@ void register_scene_types() { GDREGISTER_CLASS(CPUParticles3D); GDREGISTER_CLASS(Marker3D); GDREGISTER_CLASS(RootMotionView); - GDREGISTER_ABSTRACT_CLASS(SkeletonModifier3D); + GDREGISTER_VIRTUAL_CLASS(SkeletonModifier3D); OS::get_singleton()->yield(); // may take time to init @@ -744,6 +743,7 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeVarying); GDREGISTER_CLASS(VisualShaderNodeVaryingSetter); GDREGISTER_CLASS(VisualShaderNodeVaryingGetter); + GDREGISTER_CLASS(VisualShaderNodeReroute); GDREGISTER_CLASS(VisualShaderNodeSDFToScreenUV); GDREGISTER_CLASS(VisualShaderNodeScreenUVToSDF); diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp index 6649cb9b82..6c3356a205 100644 --- a/scene/resources/2d/tile_set.cpp +++ b/scene/resources/2d/tile_set.cpp @@ -74,7 +74,7 @@ void TileMapPattern::_set_tile_data(const Vector<int> &p_data) { uint16_t alternative_tile = decode_uint16(&local[10]); set_cell(Vector2i(x, y), source_id, Vector2i(atlas_coords_x, atlas_coords_y), alternative_tile); } - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Vector<int> TileMapPattern::_get_tile_data() const { @@ -4969,7 +4969,7 @@ void TileSetAtlasSource::create_tile(const Vector2i p_atlas_coords, const Vector tad.alternatives[0] = memnew(TileData); tad.alternatives[0]->set_tile_set(tile_set); tad.alternatives[0]->set_allow_transform(false); - tad.alternatives[0]->connect("changed", callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed)); + tad.alternatives[0]->connect(CoreStringName(changed), callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed)); tad.alternatives[0]->notify_property_list_changed(); tad.alternatives_ids.push_back(0); @@ -5353,7 +5353,7 @@ int TileSetAtlasSource::create_alternative_tile(const Vector2i p_atlas_coords, i tiles[p_atlas_coords].alternatives[new_alternative_id] = memnew(TileData); tiles[p_atlas_coords].alternatives[new_alternative_id]->set_tile_set(tile_set); tiles[p_atlas_coords].alternatives[new_alternative_id]->set_allow_transform(true); - tiles[p_atlas_coords].alternatives[new_alternative_id]->connect("changed", callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed)); + tiles[p_atlas_coords].alternatives[new_alternative_id]->connect(CoreStringName(changed), callable_mp((Resource *)this, &TileSetAtlasSource::emit_changed)); tiles[p_atlas_coords].alternatives[new_alternative_id]->notify_property_list_changed(); tiles[p_atlas_coords].alternatives_ids.push_back(new_alternative_id); tiles[p_atlas_coords].alternatives_ids.sort(); @@ -5938,7 +5938,7 @@ void TileData::notify_tile_data_properties_should_change() { } notify_property_list_changed(); - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } void TileData::add_occlusion_layer(int p_to_pos) { @@ -6139,7 +6139,7 @@ TileData *TileData::duplicate() { void TileData::set_flip_h(bool p_flip_h) { ERR_FAIL_COND_MSG(!allow_transform && p_flip_h, "Transform is only allowed for alternative tiles (with its alternative_id != 0)"); flip_h = p_flip_h; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } bool TileData::get_flip_h() const { return flip_h; @@ -6148,7 +6148,7 @@ bool TileData::get_flip_h() const { void TileData::set_flip_v(bool p_flip_v) { ERR_FAIL_COND_MSG(!allow_transform && p_flip_v, "Transform is only allowed for alternative tiles (with its alternative_id != 0)"); flip_v = p_flip_v; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } bool TileData::get_flip_v() const { @@ -6158,7 +6158,7 @@ bool TileData::get_flip_v() const { void TileData::set_transpose(bool p_transpose) { ERR_FAIL_COND_MSG(!allow_transform && p_transpose, "Transform is only allowed for alternative tiles (with its alternative_id != 0)"); transpose = p_transpose; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } bool TileData::get_transpose() const { return transpose; @@ -6166,7 +6166,7 @@ bool TileData::get_transpose() const { void TileData::set_texture_origin(Vector2i p_texture_origin) { texture_origin = p_texture_origin; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Vector2i TileData::get_texture_origin() const { @@ -6175,7 +6175,7 @@ Vector2i TileData::get_texture_origin() const { void TileData::set_material(Ref<Material> p_material) { material = p_material; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Ref<Material> TileData::get_material() const { return material; @@ -6183,7 +6183,7 @@ Ref<Material> TileData::get_material() const { void TileData::set_modulate(Color p_modulate) { modulate = p_modulate; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Color TileData::get_modulate() const { return modulate; @@ -6191,7 +6191,7 @@ Color TileData::get_modulate() const { void TileData::set_z_index(int p_z_index) { z_index = p_z_index; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } int TileData::get_z_index() const { return z_index; @@ -6199,7 +6199,7 @@ int TileData::get_z_index() const { void TileData::set_y_sort_origin(int p_y_sort_origin) { y_sort_origin = p_y_sort_origin; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } int TileData::get_y_sort_origin() const { return y_sort_origin; @@ -6209,7 +6209,7 @@ void TileData::set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_po ERR_FAIL_INDEX(p_layer_id, occluders.size()); occluders.write[p_layer_id].occluder = p_occluder_polygon; occluders.write[p_layer_id].transformed_occluders.clear(); - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const { @@ -6242,7 +6242,7 @@ Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, boo void TileData::set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity) { ERR_FAIL_INDEX(p_layer_id, physics.size()); physics.write[p_layer_id].linear_velocity = p_velocity; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const { @@ -6253,7 +6253,7 @@ Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const { void TileData::set_constant_angular_velocity(int p_layer_id, real_t p_velocity) { ERR_FAIL_INDEX(p_layer_id, physics.size()); physics.write[p_layer_id].angular_velocity = p_velocity; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } real_t TileData::get_constant_angular_velocity(int p_layer_id) const { @@ -6269,7 +6269,7 @@ void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count } physics.write[p_layer_id].polygons.resize(p_polygons_count); notify_property_list_changed(); - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } int TileData::get_collision_polygons_count(int p_layer_id) const { @@ -6280,14 +6280,14 @@ int TileData::get_collision_polygons_count(int p_layer_id) const { void TileData::add_collision_polygon(int p_layer_id) { ERR_FAIL_INDEX(p_layer_id, physics.size()); physics.write[p_layer_id].polygons.push_back(PhysicsLayerTileData::PolygonShapeTileData()); - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } void TileData::remove_collision_polygon(int p_layer_id, int p_polygon_index) { ERR_FAIL_INDEX(p_layer_id, physics.size()); ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size()); physics.write[p_layer_id].polygons.remove_at(p_polygon_index); - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon) { @@ -6314,7 +6314,7 @@ void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index, } polygon_shape_tile_data.transformed_shapes.clear(); polygon_shape_tile_data.polygon = p_polygon; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Vector<Vector2> TileData::get_collision_polygon_points(int p_layer_id, int p_polygon_index) const { @@ -6327,7 +6327,7 @@ void TileData::set_collision_polygon_one_way(int p_layer_id, int p_polygon_index ERR_FAIL_INDEX(p_layer_id, physics.size()); ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size()); physics.write[p_layer_id].polygons.write[p_polygon_index].one_way = p_one_way; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } bool TileData::is_collision_polygon_one_way(int p_layer_id, int p_polygon_index) const { @@ -6340,7 +6340,7 @@ void TileData::set_collision_polygon_one_way_margin(int p_layer_id, int p_polygo ERR_FAIL_INDEX(p_layer_id, physics.size()); ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size()); physics.write[p_layer_id].polygons.write[p_polygon_index].one_way_margin = p_one_way_margin; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } float TileData::get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const { @@ -6378,7 +6378,7 @@ Ref<ConvexPolygonShape2D> TileData::get_collision_polygon_shape(int p_layer_id, for (int i = 0; i < size; i++) { Ref<ConvexPolygonShape2D> transformed_polygon; transformed_polygon.instantiate(); - transformed_polygon->set_points(get_transformed_vertices(shapes_data.shapes[shape_index]->get_points(), p_flip_h, p_flip_v, p_transpose)); + transformed_polygon->set_points(get_transformed_vertices(shapes_data.shapes[i]->get_points(), p_flip_h, p_flip_v, p_transpose)); shapes_data.transformed_shapes[key][i] = transformed_polygon; } return shapes_data.transformed_shapes[key][shape_index]; @@ -6402,7 +6402,7 @@ void TileData::set_terrain_set(int p_terrain_set) { } terrain_set = p_terrain_set; notify_property_list_changed(); - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } int TileData::get_terrain_set() const { @@ -6416,7 +6416,7 @@ void TileData::set_terrain(int p_terrain) { ERR_FAIL_COND(p_terrain >= tile_set->get_terrains_count(terrain_set)); } terrain = p_terrain; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } int TileData::get_terrain() const { @@ -6432,7 +6432,7 @@ void TileData::set_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit, int ERR_FAIL_COND(!is_valid_terrain_peering_bit(p_peering_bit)); } terrain_peering_bits[p_peering_bit] = p_terrain_index; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } int TileData::get_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit) const { @@ -6464,7 +6464,7 @@ void TileData::set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_n ERR_FAIL_INDEX(p_layer_id, navigation.size()); navigation.write[p_layer_id].navigation_polygon = p_navigation_polygon; navigation.write[p_layer_id].transformed_navigation_polygon.clear(); - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const { @@ -6512,7 +6512,7 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_f void TileData::set_probability(float p_probability) { ERR_FAIL_COND(p_probability < 0.0); probability = p_probability; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } float TileData::get_probability() const { return probability; @@ -6536,7 +6536,7 @@ Variant TileData::get_custom_data(String p_layer_name) const { void TileData::set_custom_data_by_layer_id(int p_layer_id, Variant p_value) { ERR_FAIL_INDEX(p_layer_id, custom_data.size()); custom_data.write[p_layer_id] = p_value; - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } Variant TileData::get_custom_data_by_layer_id(int p_layer_id) const { diff --git a/scene/resources/3d/world_3d.cpp b/scene/resources/3d/world_3d.cpp index 7948a8bfd5..b743b24262 100644 --- a/scene/resources/3d/world_3d.cpp +++ b/scene/resources/3d/world_3d.cpp @@ -35,7 +35,6 @@ #include "scene/3d/visible_on_screen_notifier_3d.h" #include "scene/resources/camera_attributes.h" #include "scene/resources/environment.h" -#include "scene/scene_string_names.h" #include "servers/navigation_server_3d.h" void World3D::_register_camera(Camera3D *p_camera) { diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index d7b9528248..a3bfa987c6 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -33,7 +33,6 @@ #include "core/io/marshalls.h" #include "core/math/geometry_3d.h" -#include "scene/scene_string_names.h" bool Animation::_set(const StringName &p_name, const Variant &p_value) { String prop_name = p_name; diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp index 79d06c4d66..22666876ae 100644 --- a/scene/resources/animation_library.cpp +++ b/scene/resources/animation_library.cpp @@ -30,6 +30,8 @@ #include "animation_library.h" +#include "scene/scene_string_names.h" + bool AnimationLibrary::is_valid_animation_name(const String &p_name) { return !(p_name.is_empty() || p_name.contains("/") || p_name.contains(":") || p_name.contains(",") || p_name.contains("[")); } @@ -106,7 +108,7 @@ TypedArray<StringName> AnimationLibrary::_get_animation_list() const { } void AnimationLibrary::_animation_changed(const StringName &p_name) { - emit_signal(SNAME("animation_changed"), p_name); + emit_signal(SceneStringName(animation_changed), p_name); } void AnimationLibrary::get_animation_list(List<StringName> *p_animations) const { diff --git a/scene/resources/atlas_texture.cpp b/scene/resources/atlas_texture.cpp index 6aed68849b..ef2f1eb135 100644 --- a/scene/resources/atlas_texture.cpp +++ b/scene/resources/atlas_texture.cpp @@ -30,8 +30,6 @@ #include "atlas_texture.h" -#include "core/core_string_names.h" - int AtlasTexture::get_width() const { if (region.size.width == 0) { if (atlas.is_valid()) { diff --git a/scene/resources/canvas_item_material.cpp b/scene/resources/canvas_item_material.cpp index 31c8e68ea5..76e99aca92 100644 --- a/scene/resources/canvas_item_material.cpp +++ b/scene/resources/canvas_item_material.cpp @@ -33,13 +33,11 @@ #include "core/version.h" Mutex CanvasItemMaterial::material_mutex; -SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = nullptr; +SelfList<CanvasItemMaterial>::List CanvasItemMaterial::dirty_materials; HashMap<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData, CanvasItemMaterial::MaterialKey> CanvasItemMaterial::shader_map; CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = nullptr; void CanvasItemMaterial::init_shaders() { - dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); - shader_names = memnew(ShaderNames); shader_names->particles_anim_h_frames = "particles_anim_h_frames"; @@ -48,14 +46,13 @@ void CanvasItemMaterial::init_shaders() { } void CanvasItemMaterial::finish_shaders() { - memdelete(dirty_materials); + dirty_materials.clear(); + memdelete(shader_names); - dirty_materials = nullptr; + shader_names = nullptr; } void CanvasItemMaterial::_update_shader() { - dirty_materials->remove(&element); - MaterialKey mk = _compute_key(); if (mk.key == current_key.key) { return; //no update required in the end @@ -153,8 +150,9 @@ void CanvasItemMaterial::_update_shader() { void CanvasItemMaterial::flush_changes() { MutexLock lock(material_mutex); - while (dirty_materials->first()) { - dirty_materials->first()->self()->_update_shader(); + while (dirty_materials.first()) { + dirty_materials.first()->self()->_update_shader(); + dirty_materials.first()->remove_from_list(); } } @@ -162,16 +160,10 @@ void CanvasItemMaterial::_queue_shader_change() { MutexLock lock(material_mutex); if (_is_initialized() && !element.in_list()) { - dirty_materials->add(&element); + dirty_materials.add(&element); } } -bool CanvasItemMaterial::_is_shader_dirty() const { - MutexLock lock(material_mutex); - - return element.in_list(); -} - void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) { blend_mode = p_blend_mode; _queue_shader_change(); @@ -288,7 +280,7 @@ CanvasItemMaterial::CanvasItemMaterial() : current_key.invalid_key = 1; - _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change)); + _mark_initialized(callable_mp(this, &CanvasItemMaterial::_queue_shader_change), callable_mp(this, &CanvasItemMaterial::_update_shader)); } CanvasItemMaterial::~CanvasItemMaterial() { diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h index 7dddd74a31..ef498c2ff6 100644 --- a/scene/resources/canvas_item_material.h +++ b/scene/resources/canvas_item_material.h @@ -98,12 +98,11 @@ private: } static Mutex material_mutex; - static SelfList<CanvasItemMaterial>::List *dirty_materials; + static SelfList<CanvasItemMaterial>::List dirty_materials; SelfList<CanvasItemMaterial> element; void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; BlendMode blend_mode = BLEND_MODE_MIX; LightMode light_mode = LIGHT_MODE_NORMAL; diff --git a/scene/resources/curve_texture.cpp b/scene/resources/curve_texture.cpp index 488a527bbb..4ba5393110 100644 --- a/scene/resources/curve_texture.cpp +++ b/scene/resources/curve_texture.cpp @@ -30,8 +30,6 @@ #include "curve_texture.h" -#include "core/core_string_names.h" - void CurveTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width); diff --git a/scene/resources/gradient_texture.cpp b/scene/resources/gradient_texture.cpp index 327a99c6ad..6ec9422d2d 100644 --- a/scene/resources/gradient_texture.cpp +++ b/scene/resources/gradient_texture.cpp @@ -30,7 +30,6 @@ #include "gradient_texture.h" -#include "core/core_string_names.h" #include "core/math/geometry_2d.h" GradientTexture1D::GradientTexture1D() { @@ -137,6 +136,7 @@ void GradientTexture1D::_update() { texture = RS::get_singleton()->texture_2d_create(image); } } + RS::get_singleton()->texture_set_path(texture, get_path()); } void GradientTexture1D::set_width(int p_width) { @@ -276,6 +276,7 @@ void GradientTexture2D::_update() { } else { texture = RS::get_singleton()->texture_2d_create(image); } + RS::get_singleton()->texture_set_path(texture, get_path()); } float GradientTexture2D::_get_gradient_offset_at(int x, int y) const { diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 15b40e776c..8e49a8b56f 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -35,7 +35,6 @@ #include "core/error/error_macros.h" #include "core/version.h" #include "scene/main/scene_tree.h" -#include "scene/scene_string_names.h" void Material::set_next_pass(const Ref<Material> &p_pass) { for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) { @@ -82,24 +81,25 @@ void Material::_validate_property(PropertyInfo &p_property) const { } } -void Material::_mark_initialized(const Callable &p_queue_shader_change_callable) { +void Material::_mark_ready() { + init_state = INIT_STATE_INITIALIZING; +} + +void Material::_mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader) { // If this is happening as part of resource loading, it is not safe to queue the update - // as an addition to the dirty list, unless the load is happening on the main thread. - if (ResourceLoader::is_within_load() && Thread::get_caller_id() != Thread::get_main_id()) { + // as an addition to the dirty list. It would be if the load is happening on the main thread, + // but even so we'd rather perform the update directly instead of using the dirty list. + if (ResourceLoader::is_within_load()) { DEV_ASSERT(init_state != INIT_STATE_READY); if (init_state == INIT_STATE_UNINITIALIZED) { // Prevent queueing twice. - // Let's mark this material as being initialized. init_state = INIT_STATE_INITIALIZING; - // Knowing that the ResourceLoader will eventually feed deferred calls into the main message queue, let's do these: - // 1. Queue setting the init state to INIT_STATE_READY finally. - callable_mp(this, &Material::_mark_initialized).bind(p_queue_shader_change_callable).call_deferred(); - // 2. Queue an individual update of this material. - p_queue_shader_change_callable.call_deferred(); + callable_mp(this, &Material::_mark_ready).call_deferred(); + p_update_shader.call_deferred(); } } else { // Straightforward conditions. init_state = INIT_STATE_READY; - p_queue_shader_change_callable.callv(Array()); + p_add_to_dirty_list.call(); } } @@ -603,8 +603,6 @@ void BaseMaterial3D::finish_shaders() { } void BaseMaterial3D::_update_shader() { - dirty_materials.remove(&element); - MaterialKey mk = _compute_key(); if (mk == current_key) { return; //no update required in the end @@ -824,7 +822,18 @@ uniform float distance_fade_max : hint_range(0.0, 4096.0, 0.01); )"; } - if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) { + if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && flags[FLAG_UV1_USE_TRIPLANAR]) { + String msg = "MSDF is not supported on triplanar materials. Ignoring MSDF in favor of triplanar mapping."; + if (textures[TEXTURE_ALBEDO].is_valid()) { + WARN_PRINT(vformat("%s (albedo %s): " + msg, get_path(), textures[TEXTURE_ALBEDO]->get_path())); + } else if (!get_path().is_empty()) { + WARN_PRINT(vformat("%s: " + msg, get_path())); + } else { + WARN_PRINT(msg); + } + } + + if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) { code += R"( uniform float msdf_pixel_range : hint_range(1.0, 100.0, 1.0); uniform float msdf_outline_size : hint_range(0.0, 250.0, 1.0); @@ -1273,7 +1282,7 @@ void vertex() {)"; code += "}\n"; - if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) { + if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) { code += R"( float msdf_median(float r, float g, float b, float a) { return min(max(min(r, g), min(max(r, g), b)), a); @@ -1416,7 +1425,7 @@ void fragment() {)"; } } - if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) { + if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) { code += R"( { // Albedo Texture MSDF: Enabled @@ -1429,11 +1438,7 @@ void fragment() {)"; if (flags[FLAG_USE_POINT_SIZE]) { code += " vec2 dest_size = vec2(1.0) / fwidth(POINT_COORD);\n"; } else { - if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += " vec2 dest_size = vec2(1.0) / fwidth(uv1_triplanar_pos);\n"; - } else { - code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n"; - } + code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n"; } code += R"( float px_size = max(0.5 * dot(msdf_size, dest_size), 1.0); @@ -1855,6 +1860,7 @@ void BaseMaterial3D::flush_changes() { while (dirty_materials.first()) { dirty_materials.first()->self()->_update_shader(); + dirty_materials.first()->remove_from_list(); } } @@ -1866,12 +1872,6 @@ void BaseMaterial3D::_queue_shader_change() { } } -bool BaseMaterial3D::_is_shader_dirty() const { - MutexLock lock(material_mutex); - - return element.in_list(); -} - void BaseMaterial3D::set_albedo(const Color &p_albedo) { albedo = p_albedo; @@ -2824,7 +2824,7 @@ BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const { RID BaseMaterial3D::get_shader_rid() const { MutexLock lock(material_mutex); - if (element.in_list()) { // _is_shader_dirty() would create anoder mutex lock + if (element.in_list()) { ((BaseMaterial3D *)this)->_update_shader(); } ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); @@ -3412,7 +3412,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : current_key.invalid_key = 1; - _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change)); + _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change), callable_mp(this, &BaseMaterial3D::_update_shader)); } BaseMaterial3D::~BaseMaterial3D() { diff --git a/scene/resources/material.h b/scene/resources/material.h index ecf79c581b..50a774e961 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -62,7 +62,8 @@ protected: void _validate_property(PropertyInfo &p_property) const; - void _mark_initialized(const Callable &p_queue_shader_change_callable); + void _mark_ready(); + void _mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader); bool _is_initialized() { return init_state == INIT_STATE_READY; } GDVIRTUAL0RC(RID, _get_shader_rid) @@ -466,7 +467,6 @@ private: void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; bool orm; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 407b12d72f..0c57c6b7ba 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -32,7 +32,6 @@ #include "core/config/engine.h" #include "core/config/project_settings.h" -#include "core/core_string_names.h" #include "core/io/missing_resource.h" #include "core/io/resource_loader.h" #include "core/templates/local_vector.h" @@ -315,6 +314,16 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { ERR_FAIL_INDEX_V(nprops[j].value, prop_count, nullptr); if (nprops[j].name & FLAG_PATH_PROPERTY_IS_NODE) { + if (!Engine::get_singleton()->is_editor_hint() && node->get_scene_instance_load_placeholder()) { + // We cannot know if the referenced nodes exist yet, so instead of deferring, we write the NodePaths directly. + + uint32_t name_idx = nprops[j].name & (FLAG_PATH_PROPERTY_IS_NODE - 1); + ERR_FAIL_UNSIGNED_INDEX_V(name_idx, (uint32_t)sname_count, nullptr); + + node->set(snames[name_idx], props[nprops[j].value], &valid); + continue; + } + uint32_t name_idx = nprops[j].name & (FLAG_PATH_PROPERTY_IS_NODE - 1); ERR_FAIL_UNSIGNED_INDEX_V(name_idx, (uint32_t)sname_count, nullptr); @@ -328,7 +337,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr); - if (snames[nprops[j].name] == CoreStringNames::get_singleton()->_script) { + if (snames[nprops[j].name] == CoreStringName(script)) { //work around to avoid old script variables from disappearing, should be the proper fix to: //https://github.com/godotengine/godot/issues/2958 diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index 0b65b33240..01d26a8bed 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -33,14 +33,12 @@ #include "core/version.h" Mutex ParticleProcessMaterial::material_mutex; -SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr; +SelfList<ParticleProcessMaterial>::List ParticleProcessMaterial::dirty_materials; HashMap<ParticleProcessMaterial::MaterialKey, ParticleProcessMaterial::ShaderData, ParticleProcessMaterial::MaterialKey> ParticleProcessMaterial::shader_map; RBSet<String> ParticleProcessMaterial::min_max_properties; ParticleProcessMaterial::ShaderNames *ParticleProcessMaterial::shader_names = nullptr; void ParticleProcessMaterial::init_shaders() { - dirty_materials = memnew(SelfList<ParticleProcessMaterial>::List); - shader_names = memnew(ShaderNames); shader_names->direction = "direction"; @@ -140,15 +138,13 @@ void ParticleProcessMaterial::init_shaders() { } void ParticleProcessMaterial::finish_shaders() { - memdelete(dirty_materials); - dirty_materials = nullptr; + dirty_materials.clear(); memdelete(shader_names); + shader_names = nullptr; } void ParticleProcessMaterial::_update_shader() { - dirty_materials->remove(&element); - MaterialKey mk = _compute_key(); if (mk == current_key) { return; //no update required in the end @@ -634,7 +630,7 @@ void ParticleProcessMaterial::_update_shader() { if (emission_shape == EMISSION_SHAPE_RING) { code += " \n"; code += " float ring_spawn_angle = rand_from_seed(alt_seed) * 2.0 * pi;\n"; - code += " float ring_random_radius = sqrt(rand_from_seed(alt_seed) * (emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);\n"; + code += " float ring_random_radius = sqrt(rand_from_seed(alt_seed) * (emission_ring_radius * emission_ring_radius - emission_ring_inner_radius * emission_ring_inner_radius) + emission_ring_inner_radius * emission_ring_inner_radius);\n"; code += " vec3 axis = emission_ring_axis == vec3(0.0) ? vec3(0.0, 0.0, 1.0) : normalize(emission_ring_axis);\n"; code += " vec3 ortho_axis = vec3(0.0);\n"; code += " if (abs(axis) == vec3(1.0, 0.0, 0.0)) {\n"; @@ -995,13 +991,15 @@ void ParticleProcessMaterial::_update_shader() { code += " \n"; if (collision_mode == COLLISION_RIGID) { code += " if (COLLIDED) {\n"; - code += " if (length(VELOCITY) > 3.0) {\n"; - code += " TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;\n"; - code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n"; - code += " VELOCITY = mix(VELOCITY,vec3(0.0),clamp(collision_friction, 0.0, 1.0));\n"; - code += " } else {\n"; - code += " VELOCITY = vec3(0.0);\n"; - code += " }\n"; + code += " float collision_response = dot(COLLISION_NORMAL, VELOCITY);\n"; + code += " float slide_to_bounce_trigger = step(2.0/clamp(collision_bounce + 1.0, 1.0, 2.0), abs(collision_response));\n"; + code += " TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;\n"; + code += " // Remove all components of VELOCITY that is not tangent to COLLISION_NORMAL\n"; + code += " VELOCITY -= COLLISION_NORMAL * collision_response;\n"; + code += " // Apply friction only to VELOCITY across the surface (Effectively decouples friction and bounce behavior).\n"; + code += " VELOCITY = mix(VELOCITY,vec3(0.0),clamp(collision_friction, 0.0, 1.0));\n"; + code += " // Add bounce velocity to VELOCITY\n"; + code += " VELOCITY -= COLLISION_NORMAL * collision_response * (collision_bounce * slide_to_bounce_trigger);\n"; code += " }\n"; } else if (collision_mode == COLLISION_HIDE_ON_CONTACT) { code += " if (COLLIDED) {\n"; @@ -1170,8 +1168,9 @@ void ParticleProcessMaterial::_update_shader() { void ParticleProcessMaterial::flush_changes() { MutexLock lock(material_mutex); - while (dirty_materials->first()) { - dirty_materials->first()->self()->_update_shader(); + while (dirty_materials.first()) { + dirty_materials.first()->self()->_update_shader(); + dirty_materials.first()->remove_from_list(); } } @@ -1179,16 +1178,10 @@ void ParticleProcessMaterial::_queue_shader_change() { MutexLock lock(material_mutex); if (_is_initialized() && !element.in_list()) { - dirty_materials->add(&element); + dirty_materials.add(&element); } } -bool ParticleProcessMaterial::_is_shader_dirty() const { - MutexLock lock(material_mutex); - - return element.in_list(); -} - bool ParticleProcessMaterial::has_min_max_property(const String &p_name) { return min_max_properties.has(p_name); } @@ -2330,7 +2323,7 @@ ParticleProcessMaterial::ParticleProcessMaterial() : current_key.invalid_key = 1; - _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change)); + _mark_initialized(callable_mp(this, &ParticleProcessMaterial::_queue_shader_change), callable_mp(this, &ParticleProcessMaterial::_update_shader)); } ParticleProcessMaterial::~ParticleProcessMaterial() { diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h index 94b2009654..25046b51cd 100644 --- a/scene/resources/particle_process_material.h +++ b/scene/resources/particle_process_material.h @@ -186,7 +186,7 @@ private: } static Mutex material_mutex; - static SelfList<ParticleProcessMaterial>::List *dirty_materials; + static SelfList<ParticleProcessMaterial>::List dirty_materials; struct ShaderNames { StringName direction; @@ -293,7 +293,6 @@ private: void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; Vector3 direction; float spread = 0.0f; diff --git a/scene/resources/portable_compressed_texture.cpp b/scene/resources/portable_compressed_texture.cpp index 918b5c0b41..002db30379 100644 --- a/scene/resources/portable_compressed_texture.cpp +++ b/scene/resources/portable_compressed_texture.cpp @@ -153,14 +153,14 @@ void PortableCompressedTexture2D::create_from_image(const Ref<Image> &p_image, C for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) { Vector<uint8_t> data; if (p_compression_mode == COMPRESSION_MODE_LOSSY) { - data = Image::webp_lossy_packer(p_image->get_image_from_mipmap(i), p_lossy_quality); + data = Image::webp_lossy_packer(i ? p_image->get_image_from_mipmap(i) : p_image, p_lossy_quality); encode_uint16(DATA_FORMAT_WEBP, buffer.ptrw() + 2); } else { if (use_webp) { - data = Image::webp_lossless_packer(p_image->get_image_from_mipmap(i)); + data = Image::webp_lossless_packer(i ? p_image->get_image_from_mipmap(i) : p_image); encode_uint16(DATA_FORMAT_WEBP, buffer.ptrw() + 2); } else { - data = Image::png_packer(p_image->get_image_from_mipmap(i)); + data = Image::png_packer(i ? p_image->get_image_from_mipmap(i) : p_image); encode_uint16(DATA_FORMAT_PNG, buffer.ptrw() + 2); } } diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 2e27ac9198..7c13e623c2 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -33,9 +33,7 @@ #include "core/config/project_settings.h" #include "core/io/dir_access.h" #include "core/io/missing_resource.h" -#include "core/io/resource_format_binary.h" #include "core/object/script_language.h" -#include "core/version.h" // Version 2: Changed names for Basis, AABB, Vectors, etc. // Version 3: New string ID for ext/subresources, breaks forward compat. @@ -44,11 +42,6 @@ // For compat, save as version 3 if not using PackedVector4Array or no big PackedByteArray. #define FORMAT_VERSION_COMPAT 3 -#define BINARY_FORMAT_VERSION 4 - -#include "core/io/dir_access.h" -#include "core/version.h" - #define _printerr() ERR_PRINT(String(res_path + ":" + itos(lines) + " - Parse Error: " + error_text).utf8().get_data()); /// @@ -1127,298 +1120,6 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) { rp.userdata = this; } -static void bs_save_unicode_string(Ref<FileAccess> p_f, const String &p_string, bool p_bit_on_len = false) { - CharString utf8 = p_string.utf8(); - if (p_bit_on_len) { - p_f->store_32((utf8.length() + 1) | 0x80000000); - } else { - p_f->store_32(utf8.length() + 1); - } - p_f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1); -} - -Error ResourceLoaderText::save_as_binary(const String &p_path) { - if (error) { - return error; - } - - Ref<FileAccess> wf = FileAccess::open(p_path, FileAccess::WRITE); - if (wf.is_null()) { - return ERR_CANT_OPEN; - } - - //save header compressed - static const uint8_t header[4] = { 'R', 'S', 'R', 'C' }; - wf->store_buffer(header, 4); - - wf->store_32(0); //endianness, little endian - wf->store_32(0); //64 bits file, false for now - wf->store_32(VERSION_MAJOR); - wf->store_32(VERSION_MINOR); - static const int save_format_version = BINARY_FORMAT_VERSION; - wf->store_32(save_format_version); - - bs_save_unicode_string(wf, is_scene ? "PackedScene" : resource_type); - wf->store_64(0); //offset to import metadata, this is no longer used - - wf->store_32(ResourceFormatSaverBinaryInstance::FORMAT_FLAG_NAMED_SCENE_IDS | ResourceFormatSaverBinaryInstance::FORMAT_FLAG_UIDS); - - wf->store_64(res_uid); - - for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) { - wf->store_32(0); // reserved - } - - wf->store_32(0); //string table size, will not be in use - uint64_t ext_res_count_pos = wf->get_position(); - - wf->store_32(0); //zero ext resources, still parsing them - - //go with external resources - - DummyReadData dummy_read; - VariantParser::ResourceParser rp_new; - rp_new.ext_func = _parse_ext_resource_dummys; - rp_new.sub_func = _parse_sub_resource_dummys; - rp_new.userdata = &dummy_read; - - while (next_tag.name == "ext_resource") { - if (!next_tag.fields.has("path")) { - error = ERR_FILE_CORRUPT; - error_text = "Missing 'path' in external resource tag"; - _printerr(); - return error; - } - - if (!next_tag.fields.has("type")) { - error = ERR_FILE_CORRUPT; - error_text = "Missing 'type' in external resource tag"; - _printerr(); - return error; - } - - if (!next_tag.fields.has("id")) { - error = ERR_FILE_CORRUPT; - error_text = "Missing 'id' in external resource tag"; - _printerr(); - return error; - } - - String path = next_tag.fields["path"]; - String type = next_tag.fields["type"]; - String id = next_tag.fields["id"]; - ResourceUID::ID uid = ResourceUID::INVALID_ID; - if (next_tag.fields.has("uid")) { - String uidt = next_tag.fields["uid"]; - uid = ResourceUID::get_singleton()->text_to_id(uidt); - } - - bs_save_unicode_string(wf, type); - bs_save_unicode_string(wf, path); - wf->store_64(uid); - - int lindex = dummy_read.external_resources.size(); - Ref<DummyResource> dr; - dr.instantiate(); - dr->set_path("res://dummy" + itos(lindex)); //anything is good to detect it for saving as external - dummy_read.external_resources[dr] = lindex; - dummy_read.rev_external_resources[id] = dr; - - error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp_new); - - if (error) { - _printerr(); - return error; - } - } - - // save external resource table - wf->seek(ext_res_count_pos); - wf->store_32(dummy_read.external_resources.size()); - wf->seek_end(); - - //now, save resources to a separate file, for now - - uint64_t sub_res_count_pos = wf->get_position(); - wf->store_32(0); //zero sub resources, still parsing them - - String temp_file = p_path + ".temp"; - Vector<uint64_t> local_offsets; - Vector<uint64_t> local_pointers_pos; - { - Ref<FileAccess> wf2 = FileAccess::open(temp_file, FileAccess::WRITE); - if (wf2.is_null()) { - return ERR_CANT_OPEN; - } - - while (next_tag.name == "sub_resource" || next_tag.name == "resource") { - String type; - String id; - bool main_res; - - if (next_tag.name == "sub_resource") { - if (!next_tag.fields.has("type")) { - error = ERR_FILE_CORRUPT; - error_text = "Missing 'type' in external resource tag"; - _printerr(); - return error; - } - - if (!next_tag.fields.has("id")) { - error = ERR_FILE_CORRUPT; - error_text = "Missing 'id' in external resource tag"; - _printerr(); - return error; - } - - type = next_tag.fields["type"]; - id = next_tag.fields["id"]; - main_res = false; - - if (!dummy_read.resource_map.has(id)) { - Ref<DummyResource> dr; - dr.instantiate(); - dr->set_scene_unique_id(id); - dummy_read.resource_map[id] = dr; - uint32_t im_size = dummy_read.resource_index_map.size(); - dummy_read.resource_index_map.insert(dr, im_size); - } - - } else { - type = res_type; - String uid_text = ResourceUID::get_singleton()->id_to_text(res_uid); - id = type + "_" + uid_text.replace("uid://", "").replace("<invalid>", "0"); - main_res = true; - } - - local_offsets.push_back(wf2->get_position()); - - bs_save_unicode_string(wf, "local://" + id); - local_pointers_pos.push_back(wf->get_position()); - wf->store_64(0); //temp local offset - - bs_save_unicode_string(wf2, type); - uint64_t propcount_ofs = wf2->get_position(); - wf2->store_32(0); - - int prop_count = 0; - - while (true) { - String assign; - Variant value; - - error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp_new); - - if (error) { - if (main_res && error == ERR_FILE_EOF) { - next_tag.name = ""; //exit - break; - } - - _printerr(); - return error; - } - - if (!assign.is_empty()) { - HashMap<StringName, int> empty_string_map; //unused - bs_save_unicode_string(wf2, assign, true); - ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map); - prop_count++; - - } else if (!next_tag.name.is_empty()) { - error = OK; - break; - } else { - error = ERR_FILE_CORRUPT; - error_text = "Premature end of file while parsing [sub_resource]"; - _printerr(); - return error; - } - } - - wf2->seek(propcount_ofs); - wf2->store_32(prop_count); - wf2->seek_end(); - } - - if (next_tag.name == "node") { - // This is a node, must save one more! - - if (!is_scene) { - error_text += "found the 'node' tag on a resource file!"; - _printerr(); - error = ERR_FILE_CORRUPT; - return error; - } - - Ref<PackedScene> packed_scene = _parse_node_tag(rp_new); - - if (!packed_scene.is_valid()) { - return error; - } - - error = OK; - //get it here - List<PropertyInfo> props; - packed_scene->get_property_list(&props); - - String id = "PackedScene_" + ResourceUID::get_singleton()->id_to_text(res_uid).replace("uid://", "").replace("<invalid>", "0"); - bs_save_unicode_string(wf, "local://" + id); - local_pointers_pos.push_back(wf->get_position()); - wf->store_64(0); //temp local offset - - local_offsets.push_back(wf2->get_position()); - bs_save_unicode_string(wf2, "PackedScene"); - uint64_t propcount_ofs = wf2->get_position(); - wf2->store_32(0); - - int prop_count = 0; - - for (const PropertyInfo &E : props) { - if (!(E.usage & PROPERTY_USAGE_STORAGE)) { - continue; - } - - String name = E.name; - Variant value = packed_scene->get(name); - - HashMap<StringName, int> empty_string_map; //unused - bs_save_unicode_string(wf2, name, true); - ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_index_map, dummy_read.external_resources, empty_string_map); - prop_count++; - } - - wf2->seek(propcount_ofs); - wf2->store_32(prop_count); - wf2->seek_end(); - } - } - - uint64_t offset_from = wf->get_position(); - wf->seek(sub_res_count_pos); //plus one because the saved one - wf->store_32(local_offsets.size()); - - for (int i = 0; i < local_offsets.size(); i++) { - wf->seek(local_pointers_pos[i]); - wf->store_64(local_offsets[i] + offset_from); - } - - wf->seek_end(); - - Vector<uint8_t> data = FileAccess::get_file_as_bytes(temp_file); - wf->store_buffer(data.ptr(), data.size()); - { - Ref<DirAccess> dar = DirAccess::open(temp_file.get_base_dir()); - ERR_FAIL_COND_V(dar.is_null(), FAILED); - - dar->remove(temp_file); - } - - wf->store_buffer((const uint8_t *)"RSRC", 4); //magic at end - - return OK; -} - Error ResourceLoaderText::get_classes_used(HashSet<StringName> *r_classes) { if (error) { return error; @@ -1835,29 +1536,6 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = nullptr; -Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &p_dst_path) { - Error err; - Ref<FileAccess> f = FileAccess::open(p_src_path, FileAccess::READ, &err); - - ERR_FAIL_COND_V_MSG(err != OK, ERR_CANT_OPEN, "Cannot open file '" + p_src_path + "'."); - - ResourceLoaderText loader; - const String &path = p_src_path; - loader.local_path = ProjectSettings::get_singleton()->localize_path(path); - loader.res_path = loader.local_path; - loader.open(f); - return loader.save_as_binary(p_dst_path); -} - -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ -/*****************************************************************************************************/ /*****************************************************************************************************/ String ResourceFormatSaverTextInstance::_write_resources(void *ud, const Ref<Resource> &p_resource) { diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 41363fd975..b5542f77ba 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -87,11 +87,6 @@ class ResourceLoaderText { Error _parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); Error _parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); - // for converter - class DummyResource : public Resource { - public: - }; - struct DummyReadData { bool no_placeholders = false; HashMap<Ref<Resource>, int> external_resources; @@ -133,7 +128,6 @@ public: Error rename_dependencies(Ref<FileAccess> p_f, const String &p_path, const HashMap<String, String> &p_map); Error get_classes_used(HashSet<StringName> *r_classes); - Error save_as_binary(const String &p_path); ResourceLoaderText(); }; @@ -152,8 +146,6 @@ public: virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override; virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override; - static Error convert_file_to_binary(const String &p_src_path, const String &p_dst_path); - ResourceFormatLoaderText() { singleton = this; } }; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 0087a5e7f2..dfe5bd4a47 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -31,7 +31,6 @@ #include "shader.h" #include "core/io/file_access.h" -#include "scene/scene_string_names.h" #include "servers/rendering/shader_language.h" #include "servers/rendering/shader_preprocessor.h" #include "servers/rendering_server.h" @@ -156,7 +155,7 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr DocData::PropertyDoc prop_doc; prop_doc.name = "shader_parameter/" + pi.name; #ifdef MODULE_REGEX_ENABLED - const RegEx pattern("/\\*\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/\\s*uniform\\s+\\w+\\s+" + pi.name + "(?=[\\s:;=])"); + const RegEx pattern("/\\*\\*\\s([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/\\s*uniform\\s+\\w+\\s+" + pi.name + "(?=[\\s:;=])"); Ref<RegExMatch> pattern_ref = pattern.search(code); if (pattern_ref != nullptr) { RegExMatch *match = pattern_ref.ptr(); @@ -174,7 +173,7 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr } } #ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_editor_hint() && !class_doc.name.is_empty() && p_params) { + if (EditorHelp::get_doc_data() != nullptr && Engine::get_singleton()->is_editor_hint() && !class_doc.name.is_empty() && p_params) { EditorHelp::get_doc_data()->add_doc(class_doc); } #endif diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index 42ffa2d25a..6e43ea9b17 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -277,5 +277,5 @@ void SpriteFrames::_bind_methods() { } SpriteFrames::SpriteFrames() { - add_animation(SceneStringNames::get_singleton()->_default); + add_animation(SceneStringName(default_)); } diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index a57af6886d..601e8c52a4 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1101,6 +1101,42 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod return result; } +bool VisualShader::_check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes) const { + const Graph *g = &graph[p_type]; + + // BFS to check whether connecting to the given subgraph (rooted at p_reroute_node) is valid. + List<int> queue; + queue.push_back(p_reroute_node); + if (r_visited_reroute_nodes != nullptr) { + r_visited_reroute_nodes->push_back(p_reroute_node); + } + while (!queue.is_empty()) { + int current_node_id = queue.front()->get(); + VisualShader::Node current_node = g->nodes[current_node_id]; + queue.pop_front(); + for (const int &next_node_id : current_node.next_connected_nodes) { + Ref<VisualShaderNodeReroute> next_vsnode = g->nodes[next_node_id].node; + if (next_vsnode.is_valid()) { + queue.push_back(next_node_id); + if (r_visited_reroute_nodes != nullptr) { + r_visited_reroute_nodes->push_back(next_node_id); + } + continue; + } + // Check whether all ports connected with the reroute node are compatible. + for (const Connection &c : g->connections) { + VisualShaderNode::PortType to_port_type = g->nodes[next_node_id].node->get_input_port_type(c.to_port); + if (c.from_node == current_node_id && + c.to_node == next_node_id && + !is_port_types_compatible(p_target_port_type, to_port_type)) { + return false; + } + } + } + } + return true; +} + bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false); const Graph *g = &graph[p_type]; @@ -1128,7 +1164,12 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port); VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port); - if (!is_port_types_compatible(from_port_type, to_port_type)) { + Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node; + if (to_node_reroute.is_valid()) { + if (!_check_reroute_subgraph(p_type, from_port_type, p_to_node)) { + return false; + } + } else if (!is_port_types_compatible(from_port_type, to_port_type)) { return false; } @@ -1141,7 +1182,6 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po if (is_nodes_connected_relatively(g, p_from_node, p_to_node)) { return false; } - return true; } @@ -1179,6 +1219,28 @@ void VisualShader::detach_node_from_frame(Type p_type, int p_node) { g->nodes[p_node].node->set_frame(-1); } +String VisualShader::get_reroute_parameter_name(Type p_type, int p_reroute_node) const { + ERR_FAIL_INDEX_V(p_type, TYPE_MAX, ""); + const Graph *g = &graph[p_type]; + + ERR_FAIL_COND_V(!g->nodes.has(p_reroute_node), ""); + + const VisualShader::Node *node = &g->nodes[p_reroute_node]; + while (node->prev_connected_nodes.size() > 0) { + int connected_node_id = node->prev_connected_nodes[0]; + node = &g->nodes[connected_node_id]; + Ref<VisualShaderNodeParameter> parameter_node = node->node; + if (parameter_node.is_valid() && parameter_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) { + return parameter_node->get_parameter_name(); + } + Ref<VisualShaderNodeInput> input_node = node->node; + if (input_node.is_valid() && input_node->get_output_port_type(0) == VisualShaderNode::PORT_TYPE_SAMPLER) { + return input_node->get_input_real_name(); + } + } + return ""; +} + void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { ERR_FAIL_INDEX(p_type, TYPE_MAX); Graph *g = &graph[p_type]; @@ -1217,10 +1279,30 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port, ERR_FAIL_COND_V(!g->nodes.has(p_to_node), ERR_INVALID_PARAMETER); ERR_FAIL_INDEX_V(p_to_port, g->nodes[p_to_node].node->get_input_port_count(), ERR_INVALID_PARAMETER); + Ref<VisualShaderNodeReroute> from_node_reroute = g->nodes[p_from_node].node; + Ref<VisualShaderNodeReroute> to_node_reroute = g->nodes[p_to_node].node; + + // Allow connection with incompatible port types only if the reroute node isn't connected to anything. VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port); VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port); + bool port_types_are_compatible = is_port_types_compatible(from_port_type, to_port_type); + + if (to_node_reroute.is_valid()) { + List<int> visited_reroute_nodes; + port_types_are_compatible = _check_reroute_subgraph(p_type, from_port_type, p_to_node, &visited_reroute_nodes); + if (port_types_are_compatible) { + // Set the port type of all reroute nodes. + for (const int &E : visited_reroute_nodes) { + Ref<VisualShaderNodeReroute> reroute_node = g->nodes[E].node; + reroute_node->_set_port_type(from_port_type); + } + } + } else if (from_node_reroute.is_valid() && !from_node_reroute->is_input_port_connected(0)) { + from_node_reroute->_set_port_type(to_port_type); + port_types_are_compatible = true; + } - ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform."); + ERR_FAIL_COND_V_MSG(!port_types_are_compatible, ERR_INVALID_PARAMETER, "Incompatible port types."); for (const Connection &E : g->connections) { if (E.from_node == p_from_node && E.from_port == p_from_port && E.to_node == p_to_node && E.to_port == p_to_port) { @@ -1904,12 +1986,18 @@ Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringB if (in_type == VisualShaderNode::PORT_TYPE_SAMPLER && out_type == VisualShaderNode::PORT_TYPE_SAMPLER) { VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr()); + // FIXME: This needs to be refactored at some point. if (ptr->has_method("get_input_real_name")) { inputs[i] = ptr->call("get_input_real_name"); } else if (ptr->has_method("get_parameter_name")) { inputs[i] = ptr->call("get_parameter_name"); } else { - inputs[i] = ""; + Ref<VisualShaderNodeReroute> reroute = graph[type].nodes[from_node].node; + if (reroute.is_valid()) { + inputs[i] = get_reroute_parameter_name(type, from_node); + } else { + inputs[i] = ""; + } } } else if (in_type == out_type) { inputs[i] = src_var; @@ -2798,7 +2886,7 @@ void VisualShader::_update_shader() const { } } if (previous_code != final_code) { - const_cast<VisualShader *>(this)->emit_signal(SNAME("changed")); + const_cast<VisualShader *>(this)->emit_signal(CoreStringName(changed)); } previous_code = final_code; } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index d32e2465b9..18cdc8342b 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -163,6 +163,8 @@ private: void _input_type_changed(Type p_type, int p_id); bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const; + bool _check_reroute_subgraph(Type p_type, int p_target_port_type, int p_reroute_node, List<int> *r_visited_reroute_nodes = nullptr) const; + protected: virtual void _update_shader() const override; static void _bind_methods(); @@ -229,6 +231,8 @@ public: // internal methods void attach_node_to_frame(Type p_type, int p_node, int p_frame); void detach_node_from_frame(Type p_type, int p_node); + String get_reroute_parameter_name(Type p_type, int p_reroute_node) const; + void rebuild(); void get_node_connections(Type p_type, List<Connection> *r_connections) const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index ccd730eef2..d5394c8af5 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -8150,3 +8150,82 @@ VisualShaderNodeRotationByAxis::VisualShaderNodeRotationByAxis() { simple_decl = false; } + +String VisualShaderNodeReroute::get_caption() const { + return "Reroute"; +} + +int VisualShaderNodeReroute::get_input_port_count() const { + return 1; +} + +VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_input_port_type(int p_port) const { + return input_port_type; +} + +String VisualShaderNodeReroute::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeReroute::get_output_port_count() const { + return 1; +} + +VisualShaderNodeReroute::PortType VisualShaderNodeReroute::get_output_port_type(int p_port) const { + return input_port_type; +} + +String VisualShaderNodeReroute::get_output_port_name(int p_port) const { + return String(); +} + +String VisualShaderNodeReroute::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String code; + for (int i = 0; i < get_output_port_count(); i++) { + if (input_port_type == PORT_TYPE_SAMPLER) { + continue; + } + + String input = p_input_vars[0]; + if (input.is_empty()) { + code += vformat(" %s;\n", p_output_vars[i]); + continue; + } + code += vformat(" %s = %s;\n", p_output_vars[i], input); + } + return code; +} + +void VisualShaderNodeReroute::_set_port_type(PortType p_type) { + input_port_type = p_type; + switch (p_type) { + case PORT_TYPE_SCALAR: + set_input_port_default_value(0, 0.0); + break; + case PORT_TYPE_VECTOR_2D: + set_input_port_default_value(0, Vector2()); + break; + case PORT_TYPE_VECTOR_3D: + set_input_port_default_value(0, Vector3()); + break; + case PORT_TYPE_VECTOR_4D: + set_input_port_default_value(0, Vector4()); + break; + case PORT_TYPE_TRANSFORM: + set_input_port_default_value(0, Transform3D()); + break; + default: + break; + } +} + +void VisualShaderNodeReroute::_bind_methods() { + ClassDB::bind_method(D_METHOD("_set_port_type", "port_type"), &VisualShaderNodeReroute::_set_port_type); + ClassDB::bind_method(D_METHOD("get_port_type"), &VisualShaderNodeReroute::get_port_type); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "port_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_port_type", "get_port_type"); +} + +VisualShaderNodeReroute::VisualShaderNodeReroute() { + set_input_port_default_value(0, 0.0); +} diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 0bd0c631b8..a23ae72def 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -3092,4 +3092,35 @@ public: VisualShaderNodeRotationByAxis(); }; +class VisualShaderNodeReroute : public VisualShaderNode { + GDCLASS(VisualShaderNodeReroute, VisualShaderNode); + + PortType input_port_type = PORT_TYPE_SCALAR; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + virtual bool has_output_port_preview(int p_port) const override { return false; } + virtual bool is_output_port_expandable(int p_port) const override { return false; } + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + virtual Category get_category() const override { return CATEGORY_SPECIAL; } + + void _set_port_type(PortType p_type); + PortType get_port_type() const { return input_port_type; } + + VisualShaderNodeReroute(); +}; + #endif // VISUAL_SHADER_NODES_H diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 5610b2f642..2ee27c95e1 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -33,20 +33,12 @@ SceneStringNames *SceneStringNames::singleton = nullptr; SceneStringNames::SceneStringNames() { - _estimate_cost = StaticCString::create("_estimate_cost"); - _compute_cost = StaticCString::create("_compute_cost"); - resized = StaticCString::create("resized"); - dot = StaticCString::create("."); - doubledot = StaticCString::create(".."); draw = StaticCString::create("draw"); - _draw = StaticCString::create("_draw"); hidden = StaticCString::create("hidden"); visibility_changed = StaticCString::create("visibility_changed"); input_event = StaticCString::create("input_event"); shader = StaticCString::create("shader"); - shader_unshaded = StaticCString::create("shader/unshaded"); - shading_mode = StaticCString::create("shader/shading_mode"); tree_entered = StaticCString::create("tree_entered"); tree_exiting = StaticCString::create("tree_exiting"); tree_exited = StaticCString::create("tree_exited"); @@ -86,103 +78,33 @@ SceneStringNames::SceneStringNames() { area_shape_entered = StaticCString::create("area_shape_entered"); area_shape_exited = StaticCString::create("area_shape_exited"); - _body_inout = StaticCString::create("_body_inout"); - _area_inout = StaticCString::create("_area_inout"); - - idle = StaticCString::create("idle"); - iteration = StaticCString::create("iteration"); update = StaticCString::create("update"); updated = StaticCString::create("updated"); - _physics_process = StaticCString::create("_physics_process"); - _process = StaticCString::create("_process"); - - _enter_tree = StaticCString::create("_enter_tree"); - _exit_tree = StaticCString::create("_exit_tree"); - _enter_world = StaticCString::create("_enter_world"); - _exit_world = StaticCString::create("_exit_world"); _ready = StaticCString::create("_ready"); - _update_scroll = StaticCString::create("_update_scroll"); - _update_xform = StaticCString::create("_update_xform"); - - _structured_text_parser = StaticCString::create("_structured_text_parser"); - - _proxgroup_add = StaticCString::create("_proxgroup_add"); - _proxgroup_remove = StaticCString::create("_proxgroup_remove"); - - grouped = StaticCString::create("grouped"); - ungrouped = StaticCString::create("ungrouped"); - screen_entered = StaticCString::create("screen_entered"); screen_exited = StaticCString::create("screen_exited"); - viewport_entered = StaticCString::create("viewport_entered"); - viewport_exited = StaticCString::create("viewport_exited"); - - camera_entered = StaticCString::create("camera_entered"); - camera_exited = StaticCString::create("camera_exited"); - - _input = StaticCString::create("_input"); - _input_event = StaticCString::create("_input_event"); - gui_input = StaticCString::create("gui_input"); - _gui_input = StaticCString::create("_gui_input"); - - _unhandled_input = StaticCString::create("_unhandled_input"); - _unhandled_key_input = StaticCString::create("_unhandled_key_input"); - - changed = StaticCString::create("changed"); - _shader_changed = StaticCString::create("_shader_changed"); _spatial_editor_group = StaticCString::create("_spatial_editor_group"); _request_gizmo = StaticCString::create("_request_gizmo"); - _set_subgizmo_selection = StaticCString::create("_set_subgizmo_selection"); - _clear_subgizmo_selection = StaticCString::create("_clear_subgizmo_selection"); offset = StaticCString::create("offset"); - unit_offset = StaticCString::create("unit_offset"); rotation_mode = StaticCString::create("rotation_mode"); rotate = StaticCString::create("rotate"); h_offset = StaticCString::create("h_offset"); v_offset = StaticCString::create("v_offset"); - transform_pos = StaticCString::create("position"); - transform_rot = StaticCString::create("rotation"); - transform_scale = StaticCString::create("scale"); - - _update_remote = StaticCString::create("_update_remote"); - _update_pairs = StaticCString::create("_update_pairs"); - - _get_minimum_size = StaticCString::create("_get_minimum_size"); - area_entered = StaticCString::create("area_entered"); area_exited = StaticCString::create("area_exited"); - _has_point = StaticCString::create("_has_point"); - line_separation = StaticCString::create("line_separation"); - _get_drag_data = StaticCString::create("_get_drag_data"); - _drop_data = StaticCString::create("_drop_data"); - _can_drop_data = StaticCString::create("_can_drop_data"); - - baked_light_changed = StaticCString::create("baked_light_changed"); - _baked_light_changed = StaticCString::create("_baked_light_changed"); - - _mouse_enter = StaticCString::create("_mouse_enter"); - _mouse_exit = StaticCString::create("_mouse_exit"); - _mouse_shape_enter = StaticCString::create("_mouse_shape_enter"); - _mouse_shape_exit = StaticCString::create("_mouse_shape_exit"); - - _pressed = StaticCString::create("_pressed"); - _toggled = StaticCString::create("_toggled"); - frame_changed = StaticCString::create("frame_changed"); texture_changed = StaticCString::create("texture_changed"); - playback_speed = StaticCString::create("playback/speed"); - playback_active = StaticCString::create("playback/active"); autoplay = StaticCString::create("autoplay"); blend_times = StaticCString::create("blend_times"); speed = StaticCString::create("speed"); @@ -196,13 +118,9 @@ SceneStringNames::SceneStringNames() { // Audio bus name. Master = StaticCString::create("Master"); - _default = StaticCString::create("default"); + default_ = StaticCString::create("default"); - _window_group = StaticCString::create("_window_group"); - _window_input = StaticCString::create("_window_input"); window_input = StaticCString::create("window_input"); - _window_unhandled_input = StaticCString::create("_window_unhandled_input"); - _get_contents_minimum_size = StaticCString::create("_get_contents_minimum_size"); theme_changed = StaticCString::create("theme_changed"); parameters_base_path = "parameters/"; @@ -210,8 +128,5 @@ SceneStringNames::SceneStringNames() { shader_overrides_group = StaticCString::create("_shader_overrides_group_"); shader_overrides_group_active = StaticCString::create("_shader_overrides_group_active_"); -#ifndef DISABLE_DEPRECATED - use_in_baked_light = StaticCString::create("use_in_baked_light"); - use_dynamic_gi = StaticCString::create("use_dynamic_gi"); -#endif + pressed = StaticCString::create("pressed"); } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 60254e3006..7ed86cde46 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -51,23 +51,14 @@ class SceneStringNames { public: _FORCE_INLINE_ static SceneStringNames *get_singleton() { return singleton; } - StringName _estimate_cost; - StringName _compute_cost; - StringName resized; - StringName dot; - StringName doubledot; StringName draw; StringName hidden; StringName visibility_changed; StringName input_event; - StringName _input_event; StringName gui_input; - StringName _gui_input; StringName item_rect_changed; StringName shader; - StringName shader_unshaded; - StringName shading_mode; StringName tree_entered; StringName tree_exiting; StringName tree_exited; @@ -75,8 +66,6 @@ public: StringName size_flags_changed; StringName minimum_size_changed; StringName sleeping_state_changed; - StringName idle; - StringName iteration; StringName update; StringName updated; @@ -111,94 +100,33 @@ public: StringName area_shape_entered; StringName area_shape_exited; - StringName _body_inout; - StringName _area_inout; - - StringName _physics_process; - StringName _process; - StringName _enter_world; - StringName _exit_world; - StringName _enter_tree; - StringName _exit_tree; - StringName _draw; - StringName _input; StringName _ready; - StringName _unhandled_input; - StringName _unhandled_key_input; - - StringName _pressed; - StringName _toggled; - - StringName _update_scroll; - StringName _update_xform; - - StringName _structured_text_parser; - - StringName _proxgroup_add; - StringName _proxgroup_remove; - - StringName grouped; - StringName ungrouped; - - StringName _has_point; - StringName _get_drag_data; - StringName _can_drop_data; - StringName _drop_data; StringName screen_entered; StringName screen_exited; - StringName viewport_entered; - StringName viewport_exited; - StringName camera_entered; - StringName camera_exited; - - StringName changed; - StringName _shader_changed; StringName _spatial_editor_group; StringName _request_gizmo; - StringName _set_subgizmo_selection; - StringName _clear_subgizmo_selection; StringName offset; - StringName unit_offset; StringName rotation_mode; StringName rotate; StringName v_offset; StringName h_offset; - StringName transform_pos; - StringName transform_rot; - StringName transform_scale; - - StringName _update_remote; - StringName _update_pairs; - StringName area_entered; StringName area_exited; - StringName _get_minimum_size; - - StringName baked_light_changed; - StringName _baked_light_changed; - - StringName _mouse_enter; - StringName _mouse_exit; - StringName _mouse_shape_enter; - StringName _mouse_shape_exit; - StringName frame_changed; StringName texture_changed; - StringName playback_speed; - StringName playback_active; StringName autoplay; StringName blend_times; StringName speed; NodePath path_pp; - StringName _default; + StringName default_; // "default", conflict with C++ keyword. StringName node_configuration_warning_changed; @@ -207,21 +135,15 @@ public: StringName Master; StringName parameters_base_path; - - StringName _window_group; - StringName _window_input; - StringName _window_unhandled_input; StringName window_input; - StringName _get_contents_minimum_size; StringName theme_changed; StringName shader_overrides_group; StringName shader_overrides_group_active; -#ifndef DISABLE_DEPRECATED - StringName use_in_baked_light; - StringName use_dynamic_gi; -#endif + StringName pressed; }; +#define SceneStringName(m_name) SceneStringNames::get_singleton()->m_name + #endif // SCENE_STRING_NAMES_H diff --git a/scene/theme/SCsub b/scene/theme/SCsub index 5f62ae4b05..2372d1820a 100644 --- a/scene/theme/SCsub +++ b/scene/theme/SCsub @@ -4,7 +4,6 @@ Import("env") import default_theme_builders - env.add_source_files(env.scene_sources, "*.cpp") SConscript("icons/SCsub") diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp index d1d8854b18..aa4d669238 100644 --- a/scene/theme/default_theme.cpp +++ b/scene/theme/default_theme.cpp @@ -39,6 +39,7 @@ #include "scene/resources/style_box_flat.h" #include "scene/resources/style_box_line.h" #include "scene/resources/theme.h" +#include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" #include "servers/text_server.h" @@ -160,7 +161,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("normal", "Button", button_normal); theme->set_stylebox("hover", "Button", button_hover); - theme->set_stylebox("pressed", "Button", button_pressed); + theme->set_stylebox(SceneStringName(pressed), "Button", button_pressed); theme->set_stylebox("disabled", "Button", button_disabled); theme->set_stylebox("focus", "Button", focus); @@ -189,7 +190,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // MenuBar theme->set_stylebox("normal", "MenuBar", button_normal); theme->set_stylebox("hover", "MenuBar", button_hover); - theme->set_stylebox("pressed", "MenuBar", button_pressed); + theme->set_stylebox(SceneStringName(pressed), "MenuBar", button_pressed); theme->set_stylebox("disabled", "MenuBar", button_disabled); theme->set_font("font", "MenuBar", Ref<Font>()); @@ -232,7 +233,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("normal", "OptionButton", sb_optbutton_normal); theme->set_stylebox("hover", "OptionButton", sb_optbutton_hover); - theme->set_stylebox("pressed", "OptionButton", sb_optbutton_pressed); + theme->set_stylebox(SceneStringName(pressed), "OptionButton", sb_optbutton_pressed); theme->set_stylebox("disabled", "OptionButton", sb_optbutton_disabled); Ref<StyleBox> sb_optbutton_normal_mirrored = make_flat_stylebox(style_normal_color, 2 * default_margin, default_margin, 2 * default_margin, default_margin); @@ -266,7 +267,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // MenuButton theme->set_stylebox("normal", "MenuButton", button_normal); - theme->set_stylebox("pressed", "MenuButton", button_pressed); + theme->set_stylebox(SceneStringName(pressed), "MenuButton", button_pressed); theme->set_stylebox("hover", "MenuButton", button_hover); theme->set_stylebox("disabled", "MenuButton", button_disabled); theme->set_stylebox("focus", "MenuButton", focus); @@ -292,7 +293,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const cbx_focus->set_content_margin_all(Math::round(4 * scale)); theme->set_stylebox("normal", "CheckBox", cbx_empty); - theme->set_stylebox("pressed", "CheckBox", cbx_empty); + theme->set_stylebox(SceneStringName(pressed), "CheckBox", cbx_empty); theme->set_stylebox("disabled", "CheckBox", cbx_empty); theme->set_stylebox("hover", "CheckBox", cbx_empty); theme->set_stylebox("hover_pressed", "CheckBox", cbx_empty); @@ -328,7 +329,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const cb_empty->set_content_margin_individual(Math::round(6 * scale), Math::round(4 * scale), Math::round(6 * scale), Math::round(4 * scale)); theme->set_stylebox("normal", "CheckButton", cb_empty); - theme->set_stylebox("pressed", "CheckButton", cb_empty); + theme->set_stylebox(SceneStringName(pressed), "CheckButton", cb_empty); theme->set_stylebox("disabled", "CheckButton", cb_empty); theme->set_stylebox("hover", "CheckButton", cb_empty); theme->set_stylebox("hover_pressed", "CheckButton", cb_empty); @@ -373,12 +374,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("normal", "FlatButton", flat_button_normal); theme->set_stylebox("hover", "FlatButton", flat_button_normal); - theme->set_stylebox("pressed", "FlatButton", flat_button_pressed); + theme->set_stylebox(SceneStringName(pressed), "FlatButton", flat_button_pressed); theme->set_stylebox("disabled", "FlatButton", flat_button_normal); theme->set_stylebox("normal", "FlatMenuButton", flat_button_normal); theme->set_stylebox("hover", "FlatMenuButton", flat_button_normal); - theme->set_stylebox("pressed", "FlatMenuButton", flat_button_pressed); + theme->set_stylebox(SceneStringName(pressed), "FlatMenuButton", flat_button_pressed); theme->set_stylebox("disabled", "FlatMenuButton", flat_button_normal); // Label @@ -864,7 +865,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("h_separation", "ItemList", Math::round(4 * scale)); theme->set_constant("v_separation", "ItemList", Math::round(4 * scale)); theme->set_constant("icon_margin", "ItemList", Math::round(4 * scale)); - theme->set_constant("line_separation", "ItemList", Math::round(2 * scale)); + theme->set_constant(SceneStringName(line_separation), "ItemList", Math::round(2 * scale)); theme->set_font("font", "ItemList", Ref<Font>()); theme->set_font_size("font_size", "ItemList", -1); @@ -1050,7 +1051,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("bg", "ColorPickerButton", icons["mini_checkerboard"]); theme->set_stylebox("normal", "ColorPickerButton", button_normal); - theme->set_stylebox("pressed", "ColorPickerButton", button_pressed); + theme->set_stylebox(SceneStringName(pressed), "ColorPickerButton", button_pressed); theme->set_stylebox("hover", "ColorPickerButton", button_hover); theme->set_stylebox("disabled", "ColorPickerButton", button_disabled); theme->set_stylebox("focus", "ColorPickerButton", focus); @@ -1125,7 +1126,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("shadow_offset_y", "RichTextLabel", Math::round(1 * scale)); theme->set_constant("shadow_outline_size", "RichTextLabel", Math::round(1 * scale)); - theme->set_constant("line_separation", "RichTextLabel", 0); + theme->set_constant(SceneStringName(line_separation), "RichTextLabel", 0); theme->set_constant("table_h_separation", "RichTextLabel", Math::round(3 * scale)); theme->set_constant("table_v_separation", "RichTextLabel", Math::round(3 * scale)); diff --git a/scene/theme/icons/SCsub b/scene/theme/icons/SCsub index 46133ccceb..1f3b7f6d17 100644 --- a/scene/theme/icons/SCsub +++ b/scene/theme/icons/SCsub @@ -4,7 +4,6 @@ Import("env") import default_theme_icons_builders - env["BUILDERS"]["MakeDefaultThemeIconsBuilder"] = Builder( action=env.Run(default_theme_icons_builders.make_default_theme_icons_action), suffix=".h", diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp index 4c82e5ba5f..7249fd7ba8 100644 --- a/scene/theme/theme_db.cpp +++ b/scene/theme/theme_db.cpp @@ -225,7 +225,7 @@ ThemeContext *ThemeDB::create_theme_context(Node *p_node, List<Ref<Theme>> &p_th theme_contexts[p_node] = context; _propagate_theme_context(p_node, context); - p_node->connect("tree_exited", callable_mp(this, &ThemeDB::destroy_theme_context).bind(p_node)); + p_node->connect(SceneStringName(tree_exited), callable_mp(this, &ThemeDB::destroy_theme_context).bind(p_node)); return context; } @@ -233,7 +233,7 @@ ThemeContext *ThemeDB::create_theme_context(Node *p_node, List<Ref<Theme>> &p_th void ThemeDB::destroy_theme_context(Node *p_node) { ERR_FAIL_COND(!theme_contexts.has(p_node)); - p_node->disconnect("tree_exited", callable_mp(this, &ThemeDB::destroy_theme_context)); + p_node->disconnect(SceneStringName(tree_exited), callable_mp(this, &ThemeDB::destroy_theme_context)); ThemeContext *context = theme_contexts[p_node]; @@ -472,7 +472,7 @@ ThemeDB::~ThemeDB() { } void ThemeContext::_emit_changed() { - emit_signal(SNAME("changed")); + emit_signal(CoreStringName(changed)); } void ThemeContext::set_themes(List<Ref<Theme>> &p_themes) { diff --git a/scene/theme/theme_owner.cpp b/scene/theme/theme_owner.cpp index 8cdffe8c73..a25adddc09 100644 --- a/scene/theme/theme_owner.cpp +++ b/scene/theme/theme_owner.cpp @@ -69,18 +69,18 @@ bool ThemeOwner::has_owner_node() const { void ThemeOwner::set_owner_context(ThemeContext *p_context, bool p_propagate) { ThemeContext *default_context = ThemeDB::get_singleton()->get_default_theme_context(); - if (owner_context && owner_context->is_connected("changed", callable_mp(this, &ThemeOwner::_owner_context_changed))) { - owner_context->disconnect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed)); - } else if (default_context->is_connected("changed", callable_mp(this, &ThemeOwner::_owner_context_changed))) { - default_context->disconnect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed)); + if (owner_context && owner_context->is_connected(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed))) { + owner_context->disconnect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed)); + } else if (default_context->is_connected(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed))) { + default_context->disconnect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed)); } owner_context = p_context; if (owner_context) { - owner_context->connect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed)); + owner_context->connect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed)); } else { - default_context->connect("changed", callable_mp(this, &ThemeOwner::_owner_context_changed)); + default_context->connect(CoreStringName(changed), callable_mp(this, &ThemeOwner::_owner_context_changed)); } if (p_propagate) { |