diff options
Diffstat (limited to 'modules')
32 files changed, 220 insertions, 89 deletions
diff --git a/modules/camera/camera_osx.h b/modules/camera/camera_osx.h index 9d67235839..b0db844599 100644 --- a/modules/camera/camera_osx.h +++ b/modules/camera/camera_osx.h @@ -39,7 +39,6 @@ class CameraOSX : public CameraServer { public: CameraOSX(); - ~CameraOSX(); void update_feeds(); }; diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_osx.mm index 391006bfc2..d199c31b2f 100644 --- a/modules/camera/camera_osx.mm +++ b/modules/camera/camera_osx.mm @@ -114,18 +114,12 @@ if (output) { [self removeOutput:output]; [output setSampleBufferDelegate:nil queue:nullptr]; - [output release]; output = nullptr; } [self commitConfiguration]; } -- (void)dealloc { - // bye bye - [super dealloc]; -} - - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { // This gets called every time our camera has a new image for us to process. // May need to investigate in a way to throttle this if we get more images then we're rendering frames.. @@ -208,7 +202,6 @@ public: AVCaptureDevice *get_device() const; CameraFeedOSX(); - ~CameraFeedOSX(); void set_device(AVCaptureDevice *p_device); @@ -227,7 +220,6 @@ CameraFeedOSX::CameraFeedOSX() { void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { device = p_device; - [device retain]; // get some info NSString *device_name = p_device.localizedName; @@ -240,18 +232,6 @@ void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { }; }; -CameraFeedOSX::~CameraFeedOSX() { - if (capture_session != nullptr) { - [capture_session release]; - capture_session = nullptr; - }; - - if (device != nullptr) { - [device release]; - device = nullptr; - }; -}; - bool CameraFeedOSX::activate_feed() { if (capture_session) { // Already recording! @@ -282,7 +262,6 @@ void CameraFeedOSX::deactivate_feed() { // end camera capture if we have one if (capture_session) { [capture_session cleanup]; - [capture_session release]; capture_session = nullptr; }; }; @@ -317,8 +296,6 @@ void CameraFeedOSX::deactivate_feed() { // remove notifications [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil]; - - [super dealloc]; } @end @@ -376,7 +353,3 @@ CameraOSX::CameraOSX() { // should only have one of these.... device_notifications = [[MyDeviceNotifications alloc] initForServer:this]; }; - -CameraOSX::~CameraOSX() { - [device_notifications release]; -}; diff --git a/modules/csg/doc_classes/CSGBox3D.xml b/modules/csg/doc_classes/CSGBox3D.xml index 4b479ed42e..64b07a6cbb 100644 --- a/modules/csg/doc_classes/CSGBox3D.xml +++ b/modules/csg/doc_classes/CSGBox3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> This node allows you to create a box for use with the CSG system. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <members> <member name="material" type="Material" setter="set_material" getter="get_material"> diff --git a/modules/csg/doc_classes/CSGCombiner3D.xml b/modules/csg/doc_classes/CSGCombiner3D.xml index 422c5d35b7..16903141de 100644 --- a/modules/csg/doc_classes/CSGCombiner3D.xml +++ b/modules/csg/doc_classes/CSGCombiner3D.xml @@ -5,7 +5,9 @@ </brief_description> <description> For complex arrangements of shapes, it is sometimes needed to add structure to your CSG nodes. The CSGCombiner3D node allows you to create this structure. The node encapsulates the result of the CSG operations of its children. In this way, it is possible to do operations on one set of shapes that are children of one CSGCombiner3D node, and a set of separate operations on a second set of shapes that are children of a second CSGCombiner3D node, and then do an operation that takes the two end results as its input to create the final shape. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> </class> diff --git a/modules/csg/doc_classes/CSGCylinder3D.xml b/modules/csg/doc_classes/CSGCylinder3D.xml index 1fe2025bab..fa61957c84 100644 --- a/modules/csg/doc_classes/CSGCylinder3D.xml +++ b/modules/csg/doc_classes/CSGCylinder3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> This node allows you to create a cylinder (or cone) for use with the CSG system. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <members> <member name="cone" type="bool" setter="set_cone" getter="is_cone" default="false"> diff --git a/modules/csg/doc_classes/CSGMesh3D.xml b/modules/csg/doc_classes/CSGMesh3D.xml index 42fcb7bd2b..660659a98b 100644 --- a/modules/csg/doc_classes/CSGMesh3D.xml +++ b/modules/csg/doc_classes/CSGMesh3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> This CSG node allows you to use any mesh resource as a CSG shape, provided it is closed, does not self-intersect, does not contain internal faces and has no edges that connect to more than two faces. See also [CSGPolygon3D] for drawing 2D extruded polygons to be used as CSG nodes. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <members> <member name="material" type="Material" setter="set_material" getter="get_material"> diff --git a/modules/csg/doc_classes/CSGPolygon3D.xml b/modules/csg/doc_classes/CSGPolygon3D.xml index 5a49eebc7b..e8ef79a9e5 100644 --- a/modules/csg/doc_classes/CSGPolygon3D.xml +++ b/modules/csg/doc_classes/CSGPolygon3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> An array of 2D points is extruded to quickly and easily create a variety of 3D meshes. See also [CSGMesh3D] for using 3D meshes as CSG nodes. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <members> <member name="depth" type="float" setter="set_depth" getter="get_depth" default="1.0"> diff --git a/modules/csg/doc_classes/CSGPrimitive3D.xml b/modules/csg/doc_classes/CSGPrimitive3D.xml index 8f4c8b9451..7eac85368e 100644 --- a/modules/csg/doc_classes/CSGPrimitive3D.xml +++ b/modules/csg/doc_classes/CSGPrimitive3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> Parent class for various CSG primitives. It contains code and functionality that is common between them. It cannot be used directly. Instead use one of the various classes that inherit from it. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <members> <member name="invert_faces" type="bool" setter="set_invert_faces" getter="is_inverting_faces" default="false"> diff --git a/modules/csg/doc_classes/CSGShape3D.xml b/modules/csg/doc_classes/CSGShape3D.xml index f5031064d6..b2513703c0 100644 --- a/modules/csg/doc_classes/CSGShape3D.xml +++ b/modules/csg/doc_classes/CSGShape3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> This is the CSG base class that provides CSG operation support to the various CSG nodes in Godot. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <methods> <method name="get_collision_layer_value" qualifiers="const"> diff --git a/modules/csg/doc_classes/CSGSphere3D.xml b/modules/csg/doc_classes/CSGSphere3D.xml index b8dfb4cf5f..1ef20bc7ca 100644 --- a/modules/csg/doc_classes/CSGSphere3D.xml +++ b/modules/csg/doc_classes/CSGSphere3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> This node allows you to create a sphere for use with the CSG system. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <members> <member name="material" type="Material" setter="set_material" getter="get_material"> diff --git a/modules/csg/doc_classes/CSGTorus3D.xml b/modules/csg/doc_classes/CSGTorus3D.xml index 2c0eef8f09..09256af109 100644 --- a/modules/csg/doc_classes/CSGTorus3D.xml +++ b/modules/csg/doc_classes/CSGTorus3D.xml @@ -5,8 +5,10 @@ </brief_description> <description> This node allows you to create a torus for use with the CSG system. + [b]Note:[/b] CSG nodes are intended to be used for level prototyping. Creating CSG nodes has a significant CPU cost compared to creating a [MeshInstance3D] with a [PrimitiveMesh]. Moving a CSG node within another CSG node also has a significant CPU cost, so it should be avoided during gameplay. </description> <tutorials> + <link title="Prototyping levels with CSG">$DOCS_URL/tutorials/3d/csg_tools.html</link> </tutorials> <members> <member name="inner_radius" type="float" setter="set_inner_radius" getter="get_inner_radius" default="0.5"> diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index be304a43f0..5d5414c694 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -766,7 +766,7 @@ Variant NativeScriptInstance::call(const StringName &p_method, const Variant **p void NativeScriptInstance::notification(int p_notification) { #ifdef DEBUG_ENABLED if (p_notification == MainLoop::NOTIFICATION_CRASH) { - if (current_method_call != StringName("")) { + if (current_method_call != StringName()) { ERR_PRINT("NativeScriptInstance detected crash on method: " + current_method_call); current_method_call = ""; } diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index 71ab8ef0a2..ec3c9eb4ff 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -93,7 +93,7 @@ Variant PluginScript::_new(const Variant **p_args, int p_argcount, Callable::Cal REF ref; Object *owner = nullptr; - if (get_instance_base_type() == "") { + if (get_instance_base_type() == StringName()) { owner = memnew(RefCounted); } else { owner = ClassDB::instantiate(get_instance_base_type()); diff --git a/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd b/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd index 0824d894c5..edaccae018 100644 --- a/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd +++ b/modules/gdscript/editor_templates/CharacterBody2D/basic_movement.gd @@ -3,7 +3,7 @@ extends _BASE_ const SPEED: float = 300.0 -const JUMP_FORCE: float = -400.0 +const JUMP_VELOCITY: float = -400.0 # Get the gravity from the project settings to be synced with RigidDynamicBody nodes. var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") @@ -16,7 +16,7 @@ func _physics_process(delta: float) -> void: # Handle Jump. if Input.is_action_just_pressed("ui_accept") and is_on_floor(): - motion_velocity.y = JUMP_FORCE + motion_velocity.y = JUMP_VELOCITY # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd b/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd index ce6d67ae84..e191e5451a 100644 --- a/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd +++ b/modules/gdscript/editor_templates/CharacterBody3D/basic_movement.gd @@ -3,7 +3,7 @@ extends _BASE_ const SPEED: float = 5.0 -const JUMP_FORCE: float = 4.5 +const JUMP_VELOCITY: float = 4.5 # Get the gravity from the project settings to be synced with RigidDynamicBody nodes. var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") @@ -16,7 +16,7 @@ func _physics_process(delta: float) -> void: # Handle Jump. if Input.is_action_just_pressed("ui_accept") and is_on_floor(): - motion_velocity.y = JUMP_FORCE + motion_velocity.y = JUMP_VELOCITY # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd index 27383b878d..d71f2592fe 100644 --- a/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd +++ b/modules/gdscript/editor_templates/VisualShaderNodeCustom/basic.gd @@ -34,8 +34,5 @@ func _get_output_port_name(port: int) -> String: func _get_output_port_type(port: int) -> int: return PORT_TYPE_SCALAR -func _get_global_code(mode: Shader.Mode) -> String: - return "" - func _get_code(input_vars: Array[String], output_vars: Array[String], mode: Shader.Mode, type: VisualShader.Type) -> String: return output_vars[0] + " = 0.0;" diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index a80874d785..58a788e255 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -43,6 +43,7 @@ #include "gdscript_cache.h" #include "gdscript_compiler.h" #include "gdscript_parser.h" +#include "gdscript_rpc_callable.h" #include "gdscript_warning.h" #ifdef TESTS_ENABLED @@ -1375,7 +1376,13 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { while (sl) { const Map<StringName, GDScriptFunction *>::Element *E = sl->member_functions.find(p_name); if (E) { - r_ret = Callable(this->owner, E->key()); + Multiplayer::RPCConfig config; + config.name = p_name; + if (sptr->rpc_functions.find(config) != -1) { + r_ret = Callable(memnew(GDScriptRPCCallable(this->owner, E->key()))); + } else { + r_ret = Callable(this->owner, E->key()); + } return true; //index found } sl = sl->_base; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 9ff52347e9..94daba4bf6 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -196,7 +196,7 @@ Error GDScriptAnalyzer::check_class_member_name_conflict(const GDScriptParser::C } if (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::NATIVE) { - if (current_data_type->native_type != StringName("")) { + if (current_data_type->native_type != StringName()) { return check_native_member_name_conflict( p_member_name, p_member_node, @@ -250,7 +250,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class, if (!p_class->extends_used) { result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED; result.kind = GDScriptParser::DataType::NATIVE; - result.native_type = "RefCounted"; + result.native_type = SNAME("RefCounted"); } else { result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; @@ -438,7 +438,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type StringName first = p_type->type_chain[0]->name; - if (first == "Variant") { + if (first == SNAME("Variant")) { result.kind = GDScriptParser::DataType::VARIANT; if (p_type->type_chain.size() > 1) { push_error(R"("Variant" type don't contain nested types.)", p_type->type_chain[1]); @@ -447,9 +447,9 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type return result; } - if (first == "Object") { + if (first == SNAME("Object")) { result.kind = GDScriptParser::DataType::NATIVE; - result.native_type = "Object"; + result.native_type = SNAME("Object"); if (p_type->type_chain.size() > 1) { push_error(R"("Object" type don't contain nested types.)", p_type->type_chain[1]); return GDScriptParser::DataType(); @@ -2552,7 +2552,7 @@ void GDScriptAnalyzer::reduce_get_node(GDScriptParser::GetNodeNode *p_get_node) GDScriptParser::DataType result; result.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; result.kind = GDScriptParser::DataType::NATIVE; - result.native_type = "Node"; + result.native_type = SNAME("Node"); result.builtin_type = Variant::OBJECT; if (!ClassDB::is_parent_class(parser->current_class->base_type.native_type, result.native_type)) { @@ -3524,7 +3524,7 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo result.builtin_type = p_property.type; if (p_property.type == Variant::OBJECT) { result.kind = GDScriptParser::DataType::NATIVE; - result.native_type = p_property.class_name == StringName() ? "Object" : p_property.class_name; + result.native_type = p_property.class_name == StringName() ? SNAME("Object") : p_property.class_name; } else { result.kind = GDScriptParser::DataType::BUILTIN; result.builtin_type = p_property.type; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 33a88dd2dd..f0dc830ed8 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -652,7 +652,7 @@ static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String } static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_annotation, int p_argument, const String p_quote_style, Map<String, ScriptCodeCompletionOption> &r_result) { - if (p_annotation->name == "@export_range") { + if (p_annotation->name == SNAME("@export_range")) { if (p_argument == 3 || p_argument == 4) { // Slider hint. ScriptCodeCompletionOption slider1("or_greater", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); @@ -662,7 +662,7 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a slider2.insert_text = slider2.display.quote(p_quote_style); r_result.insert(slider2.display, slider2); } - } else if (p_annotation->name == "@export_exp_easing") { + } else if (p_annotation->name == SNAME("@export_exp_easing")) { if (p_argument == 0 || p_argument == 1) { // Easing hint. ScriptCodeCompletionOption hint1("attenuation", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); @@ -672,7 +672,7 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a hint2.insert_text = hint2.display.quote(p_quote_style); r_result.insert(hint2.display, hint2); } - } else if (p_annotation->name == "@export_node_path") { + } else if (p_annotation->name == SNAME("@export_node_path")) { ScriptCodeCompletionOption node("Node", ScriptCodeCompletionOption::KIND_CLASS); r_result.insert(node.display, node); List<StringName> node_types; @@ -684,7 +684,7 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a ScriptCodeCompletionOption option(E, ScriptCodeCompletionOption::KIND_CLASS); r_result.insert(option.display, option); } - } else if (p_annotation->name == "@warning_ignore") { + } else if (p_annotation->name == SNAME("@warning_ignore")) { for (int warning_code = 0; warning_code < GDScriptWarning::WARNING_MAX; warning_code++) { ScriptCodeCompletionOption warning(GDScriptWarning::get_name_from_code((GDScriptWarning::Code)warning_code).to_lower(), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); r_result.insert(warning.display, warning); @@ -1384,7 +1384,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, Object *baseptr = base.value; - if (all_is_const && String(call->function_name) == "get_node" && ClassDB::is_parent_class(native_type.native_type, "Node") && args.size()) { + if (all_is_const && call->function_name == SNAME("get_node") && ClassDB::is_parent_class(native_type.native_type, SNAME("Node")) && args.size()) { String arg1 = args[0]; if (arg1.begins_with("/root/")) { String which = arg1.get_slice("/", 2); @@ -2085,7 +2085,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex GDScriptParser::DataType base_type = p_base.type; bool is_static = base_type.is_meta_type; - if (is_static && p_method == "new") { + if (is_static && p_method == SNAME("new")) { r_type.type = base_type; r_type.type.is_meta_type = false; r_type.type.is_constant = false; @@ -2274,7 +2274,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c r_arghint = _make_arguments_hint(info, p_argidx); } - if (p_argidx == 0 && ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node")) { + if (p_argidx == 0 && ClassDB::is_parent_class(class_name, SNAME("Node")) && (p_method == SNAME("get_node") || p_method == SNAME("has_node"))) { // Get autoloads List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); @@ -2291,7 +2291,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } } - if (p_argidx == 0 && method_args > 0 && ClassDB::is_parent_class(class_name, "InputEvent") && p_method.operator String().contains("action")) { + if (p_argidx == 0 && method_args > 0 && ClassDB::is_parent_class(class_name, SNAME("InputEvent")) && p_method.operator String().contains("action")) { // Get input actions List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index cfad832a6c..8e4e457ec1 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -519,7 +519,7 @@ void GDScriptParser::parse_program() { // Check for @tool annotation. AnnotationNode *annotation = parse_annotation(AnnotationInfo::SCRIPT | AnnotationInfo::CLASS_LEVEL); if (annotation != nullptr) { - if (annotation->name == "@tool") { + if (annotation->name == SNAME("@tool")) { // TODO: don't allow @tool anywhere else. (Should all script annotations be the first thing?). _is_tool = true; if (previous.type != GDScriptTokenizer::Token::NEWLINE) { @@ -573,7 +573,7 @@ void GDScriptParser::parse_program() { // Check for @icon annotation. AnnotationNode *annotation = parse_annotation(AnnotationInfo::SCRIPT | AnnotationInfo::CLASS_LEVEL); if (annotation != nullptr) { - if (annotation->name == "@icon") { + if (annotation->name == SNAME("@icon")) { if (previous.type != GDScriptTokenizer::Token::NEWLINE) { push_error(R"(Expected newline after "@icon" annotation.)"); } @@ -3503,7 +3503,7 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node // This is called after the analyzer is done finding the type, so this should be set here. DataType export_type = variable->get_datatype(); - if (p_annotation->name == "@export") { + if (p_annotation->name == SNAME("@export")) { if (variable->datatype_specifier == nullptr && variable->initializer == nullptr) { push_error(R"(Cannot use simple "@export" annotation with variable without type or initializer, since type can't be inferred.)", p_annotation); return false; @@ -3528,7 +3528,7 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node variable->export_info.hint_string = Variant::get_type_name(export_type.builtin_type); break; case GDScriptParser::DataType::NATIVE: - if (ClassDB::is_parent_class(export_type.native_type, "Resource")) { + if (ClassDB::is_parent_class(export_type.native_type, SNAME("Resource"))) { variable->export_info.type = Variant::OBJECT; variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE; variable->export_info.hint_string = export_type.native_type; diff --git a/modules/gdscript/gdscript_rpc_callable.cpp b/modules/gdscript/gdscript_rpc_callable.cpp new file mode 100644 index 0000000000..07e5ed4171 --- /dev/null +++ b/modules/gdscript/gdscript_rpc_callable.cpp @@ -0,0 +1,86 @@ +/*************************************************************************/ +/* gdscript_rpc_callable.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "gdscript_rpc_callable.h" + +#include "core/templates/hashfuncs.h" +#include "scene/main/node.h" + +bool GDScriptRPCCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) { + return p_a->hash() == p_b->hash(); +} + +bool GDScriptRPCCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { + return p_a->hash() < p_b->hash(); +} + +uint32_t GDScriptRPCCallable::hash() const { + return h; +} + +String GDScriptRPCCallable::get_as_text() const { + String class_name = object->get_class(); + Ref<Script> script = object->get_script(); + return class_name + "(" + script->get_path().get_file() + ")::" + String(method) + " (rpc)"; +} + +CallableCustom::CompareEqualFunc GDScriptRPCCallable::get_compare_equal_func() const { + return compare_equal; +} + +CallableCustom::CompareLessFunc GDScriptRPCCallable::get_compare_less_func() const { + return compare_less; +} + +ObjectID GDScriptRPCCallable::get_object() const { + return object->get_instance_id(); +} + +void GDScriptRPCCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { + r_return_value = object->call(method, p_arguments, p_argcount, r_call_error); +} + +GDScriptRPCCallable::GDScriptRPCCallable(Object *p_object, const StringName &p_method) { + object = p_object; + method = p_method; + h = method.hash(); + h = hash_djb2_one_64(object->get_instance_id(), h); + node = Object::cast_to<Node>(object); + ERR_FAIL_COND_MSG(!node, "RPC can only be defined on class that extends Node."); +} + +void GDScriptRPCCallable::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { + if (unlikely(!node)) { + r_call_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return; + } + r_call_error.error = Callable::CallError::CALL_OK; + node->rpcp(p_peer_id, method, p_arguments, p_argcount); +} diff --git a/modules/gdscript/gdscript_rpc_callable.h b/modules/gdscript/gdscript_rpc_callable.h new file mode 100644 index 0000000000..2c8734a74b --- /dev/null +++ b/modules/gdscript/gdscript_rpc_callable.h @@ -0,0 +1,61 @@ +/*************************************************************************/ +/* gdscript_rpc_callable.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GDSCRIPT_RPC_CALLABLE +#define GDSCRIPT_RPC_CALLABLE + +#include "core/variant/callable.h" +#include "core/variant/variant.h" + +class Node; + +class GDScriptRPCCallable : public CallableCustom { + Object *object = nullptr; + Node *node = nullptr; + StringName method; + uint32_t h = 0; + + static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b); + static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b); + +public: + uint32_t hash() const override; + String get_as_text() const override; + CompareEqualFunc get_compare_equal_func() const override; + CompareLessFunc get_compare_less_func() const override; + ObjectID get_object() const override; + void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + void rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; + + GDScriptRPCCallable(Object *p_object, const StringName &p_method); + virtual ~GDScriptRPCCallable() = default; +}; + +#endif // GDSCRIPT_RPC_CALLABLE diff --git a/modules/gdscript/tests/gdscript_test_runner.cpp b/modules/gdscript/tests/gdscript_test_runner.cpp index 73a424dae4..c2bb2caa29 100644 --- a/modules/gdscript/tests/gdscript_test_runner.cpp +++ b/modules/gdscript/tests/gdscript_test_runner.cpp @@ -73,23 +73,21 @@ void init_autoloads() { RES res = ResourceLoader::load(info.path); ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path); Node *n = nullptr; - if (res->is_class("PackedScene")) { - Ref<PackedScene> ps = res; - n = ps->instantiate(); - } else if (res->is_class("Script")) { - Ref<Script> script_res = res; - StringName ibt = script_res->get_instance_base_type(); + Ref<PackedScene> scn = res; + Ref<Script> script = res; + if (scn.is_valid()) { + n = scn->instantiate(); + } else if (script.is_valid()) { + StringName ibt = script->get_instance_base_type(); bool valid_type = ClassDB::is_parent_class(ibt, "Node"); ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + info.path); Object *obj = ClassDB::instantiate(ibt); - ERR_CONTINUE_MSG(obj == nullptr, - "Cannot instance script for autoload, expected 'Node' inheritance, got: " + - String(ibt)); + ERR_CONTINUE_MSG(!obj, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt) + "."); n = Object::cast_to<Node>(obj); - n->set_script(script_res); + n->set_script(script); } ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + info.path); diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 67deedf839..6df7835855 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -813,6 +813,7 @@ void GridMap::_update_octants_callback() { } while (to_delete.front()) { + memdelete(octant_map[to_delete.front()->get()]); octant_map.erase(to_delete.front()->get()); to_delete.pop_front(); } diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 26436e3ec0..085ab9a467 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -3245,6 +3245,8 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { CRASH_COND(!valid); #endif + GD_MONO_SCOPE_THREAD_ATTACH; + if (native) { StringName native_name = NATIVE_GDMONOCLASS_NAME(native); if (!ClassDB::is_parent_class(p_this->get_class_name(), native_name)) { @@ -3257,8 +3259,6 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { } } - GD_MONO_SCOPE_THREAD_ATTACH; - Callable::CallError unchecked_error; return _create_instance(nullptr, 0, p_this, Object::cast_to<RefCounted>(p_this) != nullptr, unchecked_error); } diff --git a/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs index 6e9547ce9b..b0ded3133f 100644 --- a/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs +++ b/modules/mono/editor_templates/CharacterBody2D/basic_movement.cs @@ -6,7 +6,7 @@ using System; public partial class _CLASS_ : _BASE_ { public const float Speed = 300.0f; - public const float JumpForce = -400.0f; + public const float JumpVelocity = -400.0f; // Get the gravity from the project settings to be synced with RigidDynamicBody nodes. public float gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity"); @@ -21,7 +21,7 @@ public partial class _CLASS_ : _BASE_ // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - motionVelocity.y = JumpForce; + motionVelocity.y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs index 13be4bbcb1..d8c2f67ac8 100644 --- a/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs +++ b/modules/mono/editor_templates/CharacterBody3D/basic_movement.cs @@ -6,7 +6,7 @@ using System; public partial class _CLASS_ : _BASE_ { public const float Speed = 5.0f; - public const float JumpForce = 4.5f; + public const float JumpVelocity = 4.5f; // Get the gravity from the project settings to be synced with RigidDynamicBody nodes. public float gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity"); @@ -21,7 +21,7 @@ public partial class _CLASS_ : _BASE_ // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - motionVelocity.y = JumpForce; + motionVelocity.y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. diff --git a/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs index 00fdc9968e..a1b93e7daa 100644 --- a/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs +++ b/modules/mono/editor_templates/VisualShaderNodeCustom/basic.cs @@ -55,11 +55,6 @@ public partial class VisualShaderNode_CLASS_ : _BASE_ return 0; } - public override string _GetGlobalCode(Shader.Mode mode) - { - return ""; - } - public override string _GetCode(Godot.Collections.Array inputVars, Godot.Collections.Array outputVars, Shader.Mode mode, VisualShader.Type type) { return ""; diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 1a7d473bd4..5ea8eaff00 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -653,7 +653,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) { List<int> ids; script->get_node_list(&ids); - StringName editor_icons = "EditorIcons"; for (int &E : ids) { if (p_only_id >= 0 && p_only_id != E) { diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp index 4072dcebe5..bba5410629 100644 --- a/modules/visual_script/editor/visual_script_property_selector.cpp +++ b/modules/visual_script/editor/visual_script_property_selector.cpp @@ -1114,14 +1114,14 @@ TreeItem *VisualScriptPropertySelector::SearchRunner::_create_class_item(TreeIte String details = p_doc->name; if (p_doc->category.begins_with("VisualScriptCustomNode/")) { Vector<String> path = p_doc->name.split("/"); - icon = ui_service->get_theme_icon("VisualScript", "EditorIcons"); + icon = ui_service->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); text_0 = path[path.size() - 1]; text_1 = "VisualScriptCustomNode"; what = "VisualScriptCustomNode"; details = "CustomNode"; } else if (p_doc->category.begins_with("VisualScriptNode/")) { Vector<String> path = p_doc->name.split("/"); - icon = ui_service->get_theme_icon("VisualScript", "EditorIcons"); + icon = ui_service->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); text_0 = path[path.size() - 1]; if (p_doc->category.begins_with("VisualScriptNode/deconstruct")) { text_0 = "deconstruct " + text_0; diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index fbdf3a654b..88445f2f98 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -1164,9 +1164,6 @@ void VisualScript::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_custom_signal", "name"), &VisualScript::remove_custom_signal); ClassDB::bind_method(D_METHOD("rename_custom_signal", "name", "new_name"), &VisualScript::rename_custom_signal); - //ClassDB::bind_method(D_METHOD("set_variable_info","name","info"),&VScript::set_variable_info); - //ClassDB::bind_method(D_METHOD("get_variable_info","name"),&VScript::set_variable_info); - ClassDB::bind_method(D_METHOD("set_instance_base_type", "type"), &VisualScript::set_instance_base_type); ClassDB::bind_method(D_METHOD("_set_data", "data"), &VisualScript::_set_data); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index f3594e5164..e7f4e542c1 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -2495,7 +2495,7 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const VisualScriptSceneNode::TypeGuess VisualScriptSceneNode::guess_output_type(TypeGuess *p_inputs, int p_output) const { VisualScriptSceneNode::TypeGuess tg; tg.type = Variant::OBJECT; - tg.gdclass = "Node"; + tg.gdclass = SNAME("Node"); #ifdef TOOLS_ENABLED Ref<Script> script = get_visual_script(); @@ -2649,7 +2649,7 @@ VisualScriptNodeInstance *VisualScriptSceneTree::instantiate(VisualScriptInstanc VisualScriptSceneTree::TypeGuess VisualScriptSceneTree::guess_output_type(TypeGuess *p_inputs, int p_output) const { TypeGuess tg; tg.type = Variant::OBJECT; - tg.gdclass = "SceneTree"; + tg.gdclass = SNAME("SceneTree"); return tg; } @@ -2766,11 +2766,11 @@ PropertyInfo VisualScriptSelf::get_input_value_port_info(int p_idx) const { } PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const { - String type_name; + StringName type_name; if (get_visual_script().is_valid()) { type_name = get_visual_script()->get_instance_base_type(); } else { - type_name = "instance"; + type_name = SNAME("instance"); } return PropertyInfo(Variant::OBJECT, type_name); @@ -2801,7 +2801,7 @@ VisualScriptNodeInstance *VisualScriptSelf::instantiate(VisualScriptInstance *p_ VisualScriptSelf::TypeGuess VisualScriptSelf::guess_output_type(TypeGuess *p_inputs, int p_output) const { VisualScriptSceneNode::TypeGuess tg; tg.type = Variant::OBJECT; - tg.gdclass = "Object"; + tg.gdclass = SNAME("Object"); Ref<Script> script = get_visual_script(); if (!script.is_valid()) { |