summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/func_ref.cpp9
-rw-r--r--core/hashfuncs.h3
-rw-r--r--core/io/marshalls.cpp9
-rw-r--r--core/io/multiplayer_api.cpp497
-rw-r--r--core/io/multiplayer_api.h24
-rw-r--r--core/method_ptrcall.h16
-rw-r--r--core/object.cpp9
-rw-r--r--core/object.h7
-rw-r--r--core/object_id.h32
-rw-r--r--core/reference.cpp9
-rw-r--r--core/script_language.cpp9
-rw-r--r--core/script_language.h45
-rw-r--r--core/type_info.h10
-rw-r--r--core/variant.cpp13
-rw-r--r--core/variant.h4
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp30
-rw-r--r--editor/dictionary_property_edit.cpp1
-rw-r--r--editor/editor_data.cpp14
-rw-r--r--editor/editor_node.cpp8
-rw-r--r--editor/editor_properties.cpp10
-rw-r--r--editor/editor_sectioned_inspector.cpp3
-rw-r--r--editor/inspector_dock.cpp12
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp7
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp30
-rw-r--r--editor/property_editor.cpp8
-rw-r--r--editor/property_selector.cpp12
-rw-r--r--editor/script_editor_debugger.cpp13
-rw-r--r--modules/bullet/area_bullet.cpp6
-rw-r--r--modules/bullet/area_bullet.h3
-rw-r--r--modules/bullet/bullet_physics_server.cpp14
-rw-r--r--modules/bullet/bullet_physics_server.h4
-rw-r--r--modules/bullet/collision_object_bullet.cpp2
-rw-r--r--modules/bullet/godot_result_callbacks.cpp4
-rw-r--r--modules/bullet/rigid_body_bullet.cpp4
-rw-r--r--modules/bullet/space_bullet.cpp2
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp2
-rw-r--r--modules/gdnative/gdnative/string.cpp7
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp28
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp342
-rw-r--r--modules/gdnative/nativescript/nativescript.h29
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp32
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.h9
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp105
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.h17
-rw-r--r--modules/gdnavigation/gd_navigation_server.cpp2
-rw-r--r--modules/gdnavigation/rvo_agent.cpp8
-rw-r--r--modules/gdscript/gdscript.cpp155
-rw-r--r--modules/gdscript/gdscript.h23
-rw-r--r--modules/gdscript/gdscript_function.cpp6
-rw-r--r--modules/gdscript/gdscript_functions.cpp2
-rw-r--r--modules/mono/csharp_script.cpp219
-rw-r--r--modules/mono/csharp_script.h28
-rw-r--r--modules/mono/signal_awaiter_utils.cpp9
-rw-r--r--modules/visual_script/visual_script.cpp133
-rw-r--r--modules/visual_script/visual_script.h23
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp6
-rw-r--r--platform/x11/os_x11.cpp5
-rw-r--r--scene/2d/area_2d.cpp4
-rw-r--r--scene/2d/area_2d.h4
-rw-r--r--scene/2d/camera_2d.cpp4
-rw-r--r--scene/2d/canvas_item.cpp2
-rw-r--r--scene/2d/collision_object_2d.cpp4
-rw-r--r--scene/2d/physics_body_2d.cpp4
-rw-r--r--scene/2d/polygon_2d.cpp4
-rw-r--r--scene/2d/ray_cast_2d.cpp6
-rw-r--r--scene/2d/remote_transform_2d.cpp7
-rw-r--r--scene/3d/area.cpp4
-rw-r--r--scene/3d/area.h4
-rw-r--r--scene/3d/physics_body.cpp4
-rw-r--r--scene/3d/ray_cast.cpp6
-rw-r--r--scene/3d/remote_transform.cpp7
-rw-r--r--scene/3d/skeleton.cpp12
-rw-r--r--scene/3d/skeleton.h2
-rw-r--r--scene/animation/animation_player.cpp2
-rw-r--r--scene/animation/animation_player.h10
-rw-r--r--scene/animation/animation_tree.cpp9
-rw-r--r--scene/animation/animation_tree.h1
-rw-r--r--scene/gui/control.cpp13
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/gui/tree.h2
-rw-r--r--scene/main/canvas_layer.cpp4
-rw-r--r--scene/main/node.cpp128
-rw-r--r--scene/main/node.h31
-rw-r--r--scene/main/viewport.cpp32
-rw-r--r--servers/physics/area_sw.cpp10
-rw-r--r--servers/physics/area_sw.h4
-rw-r--r--servers/physics/body_sw.cpp4
-rw-r--r--servers/physics/body_sw.h2
-rw-r--r--servers/physics/collision_object_sw.cpp2
-rw-r--r--servers/physics/physics_server_sw.cpp14
-rw-r--r--servers/physics/physics_server_sw.h4
-rw-r--r--servers/physics/space_sw.cpp8
-rw-r--r--servers/physics_2d/area_2d_sw.cpp10
-rw-r--r--servers/physics_2d/area_2d_sw.h4
-rw-r--r--servers/physics_2d/body_2d_sw.cpp4
-rw-r--r--servers/physics_2d/body_2d_sw.h2
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp2
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp22
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h8
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h8
-rw-r--r--servers/physics_2d/space_2d_sw.cpp8
-rw-r--r--servers/physics_2d/space_2d_sw.h2
-rw-r--r--servers/physics_2d_server.cpp2
-rw-r--r--servers/physics_2d_server.h12
-rw-r--r--servers/physics_server.h6
-rw-r--r--servers/visual/rasterizer_rd/shader_compiler_rd.cpp30
-rw-r--r--servers/visual/shader_language.cpp238
-rw-r--r--servers/visual/shader_language.h18
-rw-r--r--servers/visual/visual_server_scene.cpp6
-rw-r--r--servers/visual/visual_server_scene.h3
111 files changed, 2221 insertions, 599 deletions
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
index 2dffb30bab..e20188c813 100644
--- a/core/func_ref.cpp
+++ b/core/func_ref.cpp
@@ -32,7 +32,7 @@
Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
- if (id == 0) {
+ if (id.is_null()) {
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
@@ -48,7 +48,7 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::Call
Variant FuncRef::call_funcv(const Array &p_args) {
- ERR_FAIL_COND_V(id == 0, Variant());
+ ERR_FAIL_COND_V(id.is_null(), Variant());
Object *obj = ObjectDB::get_instance(id);
@@ -69,7 +69,7 @@ void FuncRef::set_function(const StringName &p_func) {
}
bool FuncRef::is_valid() const {
- if (id == 0)
+ if (id.is_null())
return false;
Object *obj = ObjectDB::get_instance(id);
@@ -95,6 +95,5 @@ void FuncRef::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid);
}
-FuncRef::FuncRef() :
- id(0) {
+FuncRef::FuncRef() {
}
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index 647e8a40b2..d6cf04e560 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -34,10 +34,10 @@
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
#include "core/node_path.h"
+#include "core/object_id.h"
#include "core/string_name.h"
#include "core/typedefs.h"
#include "core/ustring.h"
-
/**
* Hashing functions
*/
@@ -137,6 +137,7 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
+ static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); }
static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
static _FORCE_INLINE_ uint32_t hash(const float p_float) { return hash_djb2_one_float(p_float); }
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index e847a9cf0c..fdce9db2a0 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -53,8 +53,7 @@ ObjectID EncodedObjectAsID::get_object_id() const {
return id;
}
-EncodedObjectAsID::EncodedObjectAsID() :
- id(0) {
+EncodedObjectAsID::EncodedObjectAsID() {
}
#define _S(a) ((int32_t)a)
@@ -386,11 +385,11 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (type & ENCODE_FLAG_OBJECT_AS_ID) {
//this _is_ allowed
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
- ObjectID val = decode_uint64(buf);
+ ObjectID val = ObjectID(decode_uint64(buf));
if (r_len)
(*r_len) += 8;
- if (val == 0) {
+ if (val.is_null()) {
r_variant = (Object *)NULL;
} else {
Ref<EncodedObjectAsID> obj_as_id;
@@ -1129,7 +1128,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
if (buf) {
Object *obj = p_variant;
- ObjectID id = 0;
+ ObjectID id;
if (obj && ObjectDB::instance_validate(obj)) {
id = obj->get_instance_id();
}
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index fbed460a4e..ce641dd0f5 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -32,6 +32,7 @@
#include "core/io/marshalls.h"
#include "scene/main/node.h"
+#include <stdint.h>
#ifdef DEBUG_ENABLED
#include "core/os/os.h"
@@ -180,7 +181,8 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
}
#endif
- uint8_t packet_type = p_packet[0];
+ // Extract the `packet_type` from the LSB three bits:
+ uint8_t packet_type = p_packet[0] & 7;
switch (packet_type) {
@@ -197,31 +199,80 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
case NETWORK_COMMAND_REMOTE_CALL:
case NETWORK_COMMAND_REMOTE_SET: {
- ERR_FAIL_COND_MSG(p_packet_len < 6, "Invalid packet received. Size too small.");
-
- Node *node = _process_get_node(p_from, p_packet, p_packet_len);
+ // Extract packet meta
+ int packet_min_size = 1;
+ int name_id_offset = 1;
+ ERR_FAIL_COND_MSG(p_packet_len < packet_min_size, "Invalid packet received. Size too small.");
+ // Compute the meta size, which depends on the compression level.
+ int node_id_compression = (p_packet[0] & 24) >> 3;
+ int name_id_compression = (p_packet[0] & 32) >> 5;
+
+ switch (node_id_compression) {
+ case NETWORK_NODE_ID_COMPRESSION_8:
+ packet_min_size += 1;
+ name_id_offset += 1;
+ break;
+ case NETWORK_NODE_ID_COMPRESSION_16:
+ packet_min_size += 2;
+ name_id_offset += 2;
+ break;
+ case NETWORK_NODE_ID_COMPRESSION_32:
+ packet_min_size += 4;
+ name_id_offset += 4;
+ break;
+ default:
+ ERR_FAIL_MSG("Was not possible to extract the node id compression mode.");
+ }
+ switch (name_id_compression) {
+ case NETWORK_NAME_ID_COMPRESSION_8:
+ packet_min_size += 1;
+ break;
+ case NETWORK_NAME_ID_COMPRESSION_16:
+ packet_min_size += 2;
+ break;
+ default:
+ ERR_FAIL_MSG("Was not possible to extract the name id compression mode.");
+ }
+ ERR_FAIL_COND_MSG(p_packet_len < packet_min_size, "Invalid packet received. Size too small.");
+ uint32_t node_target = 0;
+ switch (node_id_compression) {
+ case NETWORK_NODE_ID_COMPRESSION_8:
+ node_target = p_packet[1];
+ break;
+ case NETWORK_NODE_ID_COMPRESSION_16:
+ node_target = decode_uint16(p_packet + 1);
+ break;
+ case NETWORK_NODE_ID_COMPRESSION_32:
+ node_target = decode_uint32(p_packet + 1);
+ break;
+ default:
+ // Unreachable, checked before.
+ CRASH_NOW();
+ }
+ Node *node = _process_get_node(p_from, p_packet, node_target, p_packet_len);
ERR_FAIL_COND_MSG(node == NULL, "Invalid packet received. Requested node was not found.");
- // Detect cstring end.
- int len_end = 5;
- for (; len_end < p_packet_len; len_end++) {
- if (p_packet[len_end] == 0) {
+ uint16_t name_id = 0;
+ switch (name_id_compression) {
+ case NETWORK_NAME_ID_COMPRESSION_8:
+ name_id = p_packet[name_id_offset];
break;
- }
+ case NETWORK_NAME_ID_COMPRESSION_16:
+ name_id = decode_uint16(p_packet + name_id_offset);
+ break;
+ default:
+ // Unreachable, checked before.
+ CRASH_NOW();
}
- ERR_FAIL_COND_MSG(len_end >= p_packet_len, "Invalid packet received. Size too small.");
-
- StringName name = String::utf8((const char *)&p_packet[5]);
-
if (packet_type == NETWORK_COMMAND_REMOTE_CALL) {
- _process_rpc(node, name, p_from, p_packet, p_packet_len, len_end + 1);
+ _process_rpc(node, name_id, p_from, p_packet, p_packet_len, packet_min_size);
} else {
- _process_rset(node, name, p_from, p_packet, p_packet_len, len_end + 1);
+ _process_rset(node, name_id, p_from, p_packet, p_packet_len, packet_min_size);
}
} break;
@@ -233,15 +284,14 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
}
}
-Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int p_packet_len) {
+Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len) {
- uint32_t target = decode_uint32(&p_packet[1]);
Node *node = NULL;
- if (target & 0x80000000) {
+ if (p_node_target & 0x80000000) {
// Use full path (not cached yet).
- int ofs = target & 0x7FFFFFFF;
+ int ofs = p_node_target & 0x7FFFFFFF;
ERR_FAIL_COND_V_MSG(ofs >= p_packet_len, NULL, "Invalid packet received. Size smaller than declared.");
@@ -256,7 +306,7 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
ERR_PRINT("Failed to get path from RPC: " + String(np) + ".");
} else {
// Use cached path.
- int id = target;
+ int id = p_node_target;
Map<int, PathGetCache>::Element *E = path_get_cache.find(p_from);
ERR_FAIL_COND_V_MSG(!E, NULL, "Invalid packet received. Requests invalid peer cache.");
@@ -274,21 +324,21 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int
return node;
}
-void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
+void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
// Check that remote can call the RPC on this node.
- RPCMode rpc_mode = RPC_MODE_DISABLED;
- const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_name);
- if (E) {
- rpc_mode = E->get();
- } else if (p_node->get_script_instance()) {
- rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_name);
+ StringName name = p_node->get_node_rpc_method(p_rpc_method_id);
+ RPCMode rpc_mode = p_node->get_node_rpc_mode_by_id(p_rpc_method_id);
+ if (name == StringName() && p_node->get_script_instance()) {
+ name = p_node->get_script_instance()->get_rpc_method(p_rpc_method_id);
+ rpc_mode = p_node->get_script_instance()->get_rpc_mode_by_id(p_rpc_method_id);
}
+ ERR_FAIL_COND(name == StringName());
bool can_call = _can_call_mode(p_node, rpc_mode, p_from);
- ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
+ ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
int argc = p_packet[p_offset];
Vector<Variant> args;
@@ -311,7 +361,7 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
int vlen;
- Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ Error err = _decode_and_decompress_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RPC argument.");
argp.write[i] = &args[i];
@@ -320,29 +370,29 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
Variant::CallError ce;
- p_node->call(p_name, (const Variant **)argp.ptr(), argc, ce);
+ p_node->call(name, (const Variant **)argp.ptr(), argc, ce);
if (ce.error != Variant::CallError::CALL_OK) {
- String error = Variant::get_call_error_text(p_node, p_name, (const Variant **)argp.ptr(), argc, ce);
+ String error = Variant::get_call_error_text(p_node, name, (const Variant **)argp.ptr(), argc, ce);
error = "RPC - " + error;
ERR_PRINT(error);
}
}
-void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
+void MultiplayerAPI::_process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
// Check that remote can call the RSET on this node.
- RPCMode rset_mode = RPC_MODE_DISABLED;
- const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_name);
- if (E) {
- rset_mode = E->get();
- } else if (p_node->get_script_instance()) {
- rset_mode = p_node->get_script_instance()->get_rset_mode(p_name);
+ StringName name = p_node->get_node_rset_property(p_rpc_property_id);
+ RPCMode rset_mode = p_node->get_node_rset_mode_by_id(p_rpc_property_id);
+ if (name == StringName() && p_node->get_script_instance()) {
+ name = p_node->get_script_instance()->get_rset_property(p_rpc_property_id);
+ rset_mode = p_node->get_script_instance()->get_rset_mode_by_id(p_rpc_property_id);
}
+ ERR_FAIL_COND(name == StringName());
bool can_call = _can_call_mode(p_node, rset_mode, p_from);
- ERR_FAIL_COND_MSG(!can_call, "RSET '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
+ ERR_FAIL_COND_MSG(!can_call, "RSET '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
#ifdef DEBUG_ENABLED
if (profiling) {
@@ -353,26 +403,33 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
#endif
Variant value;
- Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ Error err = _decode_and_decompress_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL);
ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RSET value.");
bool valid;
- p_node->set(p_name, value, &valid);
+ p_node->set(name, value, &valid);
if (!valid) {
- String error = "Error setting remote property '" + String(p_name) + "', not found in object of type " + p_node->get_class() + ".";
+ String error = "Error setting remote property '" + String(name) + "', not found in object of type " + p_node->get_class() + ".";
ERR_PRINT(error);
}
}
void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
- ERR_FAIL_COND_MSG(p_packet_len < 5, "Invalid packet received. Size too small.");
- int id = decode_uint32(&p_packet[1]);
+ ERR_FAIL_COND_MSG(p_packet_len < 38, "Invalid packet received. Size too small.");
+ int ofs = 1;
+
+ String methods_md5;
+ methods_md5.parse_utf8((const char *)(p_packet + ofs), 32);
+ ofs += 33;
+
+ int id = decode_uint32(&p_packet[ofs]);
+ ofs += 4;
String paths;
- paths.parse_utf8((const char *)&p_packet[5], p_packet_len - 5);
+ paths.parse_utf8((const char *)(p_packet + ofs), p_packet_len - ofs);
NodePath path = paths;
@@ -380,9 +437,15 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
path_get_cache[p_from] = PathGetCache();
}
+ Node *node = root_node->get_node(path);
+ ERR_FAIL_COND(node == NULL);
+ const bool valid_rpc_checksum = node->get_rpc_md5() == methods_md5;
+ if (valid_rpc_checksum == false) {
+ ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + path);
+ }
+
PathGetCache::NodeInfo ni;
ni.path = path;
- ni.instance = 0;
path_get_cache[p_from].nodes[id] = ni;
@@ -392,9 +455,10 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
Vector<uint8_t> packet;
- packet.resize(1 + len);
+ packet.resize(1 + 1 + len);
packet.write[0] = NETWORK_COMMAND_CONFIRM_PATH;
- encode_cstring(pname.get_data(), &packet.write[1]);
+ packet.write[1] = valid_rpc_checksum;
+ encode_cstring(pname.get_data(), &packet.write[2]);
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->set_target_peer(p_from);
@@ -403,13 +467,19 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
- ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small.");
+ ERR_FAIL_COND_MSG(p_packet_len < 3, "Invalid packet received. Size too small.");
+
+ const bool valid_rpc_checksum = p_packet[1];
String paths;
- paths.parse_utf8((const char *)&p_packet[1], p_packet_len - 1);
+ paths.parse_utf8((const char *)&p_packet[2], p_packet_len - 2);
NodePath path = paths;
+ if (valid_rpc_checksum == false) {
+ ERR_PRINT("The rpc node checksum failed. Make sure to have the same methods on both nodes. Node path: " + path);
+ }
+
PathSentCache *psc = path_send_cache.getptr(path);
ERR_FAIL_COND_MSG(!psc, "Invalid packet received. Tries to confirm a path which was not found in cache.");
@@ -418,7 +488,7 @@ void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet,
E->get() = true;
}
-bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int p_target) {
+bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, int p_target) {
bool has_all_peers = true;
List<int> peers_to_add; // If one is missing, take note to add it.
@@ -443,31 +513,192 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
}
}
- // Those that need to be added, send a message for this.
+ if (peers_to_add.size() > 0) {
- for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
+ // Those that need to be added, send a message for this.
// Encode function name.
- CharString pname = String(p_path).utf8();
- int len = encode_cstring(pname.get_data(), NULL);
+ const CharString path = String(p_path).utf8();
+ const int path_len = encode_cstring(path.get_data(), NULL);
+
+ // Extract MD5 from rpc methods list.
+ const String methods_md5 = p_node->get_rpc_md5();
+ const int methods_md5_len = 33; // 32 + 1 for the `0` that is added by the encoder.
Vector<uint8_t> packet;
+ packet.resize(1 + 4 + path_len + methods_md5_len);
+ int ofs = 0;
+
+ packet.write[ofs] = NETWORK_COMMAND_SIMPLIFY_PATH;
+ ofs += 1;
+
+ ofs += encode_cstring(methods_md5.utf8().get_data(), &packet.write[ofs]);
+
+ ofs += encode_uint32(psc->id, &packet.write[ofs]);
+
+ ofs += encode_cstring(path.get_data(), &packet.write[ofs]);
- packet.resize(1 + 4 + len);
- packet.write[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
- encode_uint32(psc->id, &packet.write[1]);
- encode_cstring(pname.get_data(), &packet.write[5]);
+ for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
- network_peer->set_target_peer(E->get()); // To all of you.
- network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
- network_peer->put_packet(packet.ptr(), packet.size());
+ network_peer->set_target_peer(E->get()); // To all of you.
+ network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
+ network_peer->put_packet(packet.ptr(), packet.size());
- psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed.
+ psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed.
+ }
}
return has_all_peers;
}
+// The variant is compressed and encoded; The first byte contains all the meta
+// information and the format is:
+// - The first LSB 5 bits are used for the variant type.
+// - The next two bits are used to store the encoding mode.
+// - The most significant is used to store the boolean value.
+#define VARIANT_META_TYPE_MASK 0x1F
+#define VARIANT_META_EMODE_MASK 0x60
+#define VARIANT_META_BOOL_MASK 0x80
+#define ENCODE_8 0 << 5
+#define ENCODE_16 1 << 5
+#define ENCODE_32 2 << 5
+#define ENCODE_64 3 << 5
+Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
+
+ // Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31
+ CRASH_COND(p_variant.get_type() > VARIANT_META_TYPE_MASK);
+
+ uint8_t *buf = r_buffer;
+ r_len = 0;
+ uint8_t encode_mode = 0;
+
+ switch (p_variant.get_type()) {
+ case Variant::BOOL: {
+ if (buf) {
+ // We still have 1 free bit in the meta, so let's use it.
+ buf[0] = (p_variant.operator bool()) ? (1 << 7) : 0;
+ buf[0] |= encode_mode | p_variant.get_type();
+ }
+ r_len += 1;
+ } break;
+ case Variant::INT: {
+ if (buf) {
+ // Reserve the first byte for the meta.
+ buf += 1;
+ }
+ r_len += 1;
+ int64_t val = p_variant;
+ if (val <= (int64_t)INT8_MAX && val >= (int64_t)INT8_MIN) {
+ // Use 8 bit
+ encode_mode = ENCODE_8;
+ if (buf) {
+ buf[0] = val;
+ }
+ r_len += 1;
+ } else if (val <= (int64_t)INT16_MAX && val >= (int64_t)INT16_MIN) {
+ // Use 16 bit
+ encode_mode = ENCODE_16;
+ if (buf) {
+ encode_uint16(val, buf);
+ }
+ r_len += 2;
+ } else if (val <= (int64_t)INT32_MAX && val >= (int64_t)INT32_MIN) {
+ // Use 32 bit
+ encode_mode = ENCODE_32;
+ if (buf) {
+ encode_uint32(val, buf);
+ }
+ r_len += 4;
+ } else {
+ // Use 64 bit
+ encode_mode = ENCODE_64;
+ if (buf) {
+ encode_uint64(val, buf);
+ }
+ r_len += 8;
+ }
+ // Store the meta
+ if (buf) {
+ buf -= 1;
+ buf[0] = encode_mode | p_variant.get_type();
+ }
+ } break;
+ default:
+ // Any other case is not yet compressed.
+ Error err = encode_variant(p_variant, r_buffer, r_len, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ if (err != OK)
+ return err;
+ if (r_buffer) {
+ // The first byte is not used by the marshaling, so store the type
+ // so we know how to decompress and decode this variant.
+ r_buffer[0] = p_variant.get_type();
+ }
+ }
+
+ return OK;
+}
+Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) {
+
+ const uint8_t *buf = p_buffer;
+ int len = p_len;
+
+ ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA);
+ uint8_t type = buf[0] & VARIANT_META_TYPE_MASK;
+ uint8_t encode_mode = buf[0] & VARIANT_META_EMODE_MASK;
+
+ ERR_FAIL_COND_V(type >= Variant::VARIANT_MAX, ERR_INVALID_DATA);
+
+ switch (type) {
+ case Variant::BOOL: {
+ bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0;
+ r_variant = val;
+ if (r_len)
+ *r_len = 1;
+ } break;
+ case Variant::INT: {
+ buf += 1;
+ len -= 1;
+ if (r_len)
+ *r_len = 1;
+ if (encode_mode == ENCODE_8) {
+ // 8 bits.
+ ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA);
+ int8_t val = buf[0];
+ r_variant = val;
+ if (r_len)
+ (*r_len) += 1;
+ } else if (encode_mode == ENCODE_16) {
+ // 16 bits.
+ ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA);
+ int16_t val = decode_uint16(buf);
+ r_variant = val;
+ if (r_len)
+ (*r_len) += 2;
+ } else if (encode_mode == ENCODE_32) {
+ // 32 bits.
+ ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
+ int32_t val = decode_uint32(buf);
+ r_variant = val;
+ if (r_len)
+ (*r_len) += 4;
+ } else {
+ // 64 bits.
+ ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
+ int64_t val = decode_uint64(buf);
+ r_variant = val;
+ if (r_len)
+ (*r_len) += 8;
+ }
+ } break;
+ default:
+ Error err = decode_variant(r_variant, p_buffer, p_len, r_len, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ if (err != OK)
+ return err;
+ }
+
+ return OK;
+}
+
void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) {
ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree.");
@@ -496,6 +727,9 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
psc->id = last_send_cache_id++;
}
+ // See if all peers have cached path (if so, call can be fast).
+ const bool has_all_peers = _send_confirm_path(p_from, from_path, psc, p_to);
+
// Create base packet, lots of hardcode because it must be tight.
int ofs = 0;
@@ -503,45 +737,125 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
#define MAKE_ROOM(m_amount) \
if (packet_cache.size() < m_amount) packet_cache.resize(m_amount);
- // Encode type.
+ // Encode meta.
+ // The meta is composed by a single byte that contains (starting from the least segnificant bit):
+ // - `NetworkCommands` in the first three bits.
+ // - `NetworkNodeIdCompression` in the next 2 bits.
+ // - `NetworkNameIdCompression` in the next 1 bit.
+ // - So we still have the last two bits free!
+ uint8_t command_type = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
+ uint8_t node_id_compression = UINT8_MAX;
+ uint8_t name_id_compression = UINT8_MAX;
+
MAKE_ROOM(1);
- packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
+ // The meta is composed along the way, so just set 0 for now.
+ packet_cache.write[0] = 0;
ofs += 1;
- // Encode ID.
- MAKE_ROOM(ofs + 4);
- encode_uint32(psc->id, &(packet_cache.write[ofs]));
- ofs += 4;
-
- // Encode function name.
- CharString name = String(p_name).utf8();
- int len = encode_cstring(name.get_data(), NULL);
- MAKE_ROOM(ofs + len);
- encode_cstring(name.get_data(), &(packet_cache.write[ofs]));
- ofs += len;
+ // Encode Node ID.
+ if (has_all_peers) {
+ // Compress the node ID only if all the target peers already know it.
+ if (psc->id >= 0 && psc->id <= 255) {
+ // We can encode the id in 1 byte
+ node_id_compression = NETWORK_NODE_ID_COMPRESSION_8;
+ MAKE_ROOM(ofs + 1);
+ packet_cache.write[ofs] = static_cast<uint8_t>(psc->id);
+ ofs += 1;
+ } else if (psc->id >= 0 && psc->id <= 65535) {
+ // We can encode the id in 2 bytes
+ node_id_compression = NETWORK_NODE_ID_COMPRESSION_16;
+ MAKE_ROOM(ofs + 2);
+ encode_uint16(static_cast<uint16_t>(psc->id), &(packet_cache.write[ofs]));
+ ofs += 2;
+ } else {
+ // Too big, let's use 4 bytes.
+ node_id_compression = NETWORK_NODE_ID_COMPRESSION_32;
+ MAKE_ROOM(ofs + 4);
+ encode_uint32(psc->id, &(packet_cache.write[ofs]));
+ ofs += 4;
+ }
+ } else {
+ // The targets doesn't know the node yet, so we need to use 32 bits int.
+ node_id_compression = NETWORK_NODE_ID_COMPRESSION_32;
+ MAKE_ROOM(ofs + 4);
+ encode_uint32(psc->id, &(packet_cache.write[ofs]));
+ ofs += 4;
+ }
if (p_set) {
+
+ // Take the rpc property ID
+ uint16_t property_id = p_from->get_node_rset_property_id(p_name);
+ if (property_id == UINT16_MAX && p_from->get_script_instance()) {
+ property_id = p_from->get_script_instance()->get_rset_property_id(p_name);
+ }
+ ERR_FAIL_COND_MSG(property_id == UINT16_MAX, "Unable to take the `property_id` for the property:" + p_name + ". this can happen only if this property is not marked as `remote`.");
+
+ if (property_id <= UINT8_MAX) {
+ // The ID fits in 1 byte
+ name_id_compression = NETWORK_NAME_ID_COMPRESSION_8;
+ MAKE_ROOM(ofs + 1);
+ packet_cache.write[ofs] = static_cast<uint8_t>(property_id);
+ ofs += 1;
+ } else {
+ // The ID is larger, let's use 2 bytes
+ name_id_compression = NETWORK_NAME_ID_COMPRESSION_16;
+ MAKE_ROOM(ofs + 2);
+ encode_uint16(property_id, &(packet_cache.write[ofs]));
+ ofs += 2;
+ }
+
// Set argument.
- Error err = encode_variant(*p_arg[0], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ int len(0);
+ Error err = _encode_and_compress_variant(*p_arg[0], NULL, len);
ERR_FAIL_COND_MSG(err != OK, "Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
MAKE_ROOM(ofs + len);
- encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ _encode_and_compress_variant(*p_arg[0], &(packet_cache.write[ofs]), len);
ofs += len;
} else {
+ // Take the rpc method ID
+ uint16_t method_id = p_from->get_node_rpc_method_id(p_name);
+ if (method_id == UINT16_MAX && p_from->get_script_instance()) {
+ method_id = p_from->get_script_instance()->get_rpc_method_id(p_name);
+ }
+ ERR_FAIL_COND_MSG(method_id == UINT16_MAX, "Unable to take the `method_id` for the function:" + p_name + ". this can happen only if this method is not marked as `remote`.");
+
+ if (method_id <= UINT8_MAX) {
+ // The ID fits in 1 byte
+ name_id_compression = NETWORK_NAME_ID_COMPRESSION_8;
+ MAKE_ROOM(ofs + 1);
+ packet_cache.write[ofs] = static_cast<uint8_t>(method_id);
+ ofs += 1;
+ } else {
+ // The ID is larger, let's use 2 bytes
+ name_id_compression = NETWORK_NAME_ID_COMPRESSION_16;
+ MAKE_ROOM(ofs + 2);
+ encode_uint16(method_id, &(packet_cache.write[ofs]));
+ ofs += 2;
+ }
+
// Call arguments.
MAKE_ROOM(ofs + 1);
packet_cache.write[ofs] = p_argcount;
ofs += 1;
for (int i = 0; i < p_argcount; i++) {
- Error err = encode_variant(*p_arg[i], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ int len(0);
+ Error err = _encode_and_compress_variant(*p_arg[i], NULL, len);
ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
MAKE_ROOM(ofs + len);
- encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
+ _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
ofs += len;
}
}
+ ERR_FAIL_COND(command_type > 7);
+ ERR_FAIL_COND(node_id_compression > 3);
+ ERR_FAIL_COND(name_id_compression > 1);
+
+ // We can now set the meta
+ packet_cache.write[0] = command_type + (node_id_compression << 3) + (name_id_compression << 5);
+
#ifdef DEBUG_ENABLED
if (profiling) {
bandwidth_outgoing_data.write[bandwidth_outgoing_pointer].timestamp = OS::get_singleton()->get_ticks_msec();
@@ -550,9 +864,6 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
}
#endif
- // See if all peers have cached path (is so, call can be fast).
- bool has_all_peers = _send_confirm_path(from_path, psc, p_to);
-
// Take chance and set transfer mode, since all send methods will use it.
network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
@@ -562,6 +873,9 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
network_peer->set_target_peer(p_to); // To all of you.
network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
} else {
+ // Unreachable because the node ID is never compressed if the peers doesn't know it.
+ CRASH_COND(node_id_compression != NETWORK_NODE_ID_COMPRESSION_32);
+
// Not all verified path, so send one by one.
// Append path at the end, since we will need it for some packets.
@@ -647,16 +961,14 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
// Check that send mode can use local call.
- const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
- if (E) {
- call_local_native = _should_call_local(E->get(), is_master, skip_rpc);
- }
+ RPCMode rpc_mode = p_node->get_node_rpc_mode(p_method);
+ call_local_native = _should_call_local(rpc_mode, is_master, skip_rpc);
if (call_local_native) {
// Done below.
} else if (p_node->get_script_instance()) {
// Attempt with script.
- RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
+ rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc);
}
}
@@ -719,11 +1031,8 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
// Check that send mode can use local call.
- const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_property);
- if (E) {
-
- set_local = _should_call_local(E->get(), is_master, skip_rset);
- }
+ RPCMode rpc_mode = p_node->get_node_rset_mode(p_property);
+ set_local = _should_call_local(rpc_mode, is_master, skip_rset);
if (set_local) {
bool valid;
@@ -740,7 +1049,7 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
} else if (p_node->get_script_instance()) {
// Attempt with script.
- RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
+ rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
set_local = _should_call_local(rpc_mode, is_master, skip_rset);
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index c9f127b6b2..6672cfe155 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -98,23 +98,37 @@ protected:
void _process_packet(int p_from, const uint8_t *p_packet, int p_packet_len);
void _process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len);
void _process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len);
- Node *_process_get_node(int p_from, const uint8_t *p_packet, int p_packet_len);
- void _process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset);
- void _process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset);
+ Node *_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len);
+ void _process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset);
+ void _process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset);
void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len);
void _send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount);
- bool _send_confirm_path(NodePath p_path, PathSentCache *psc, int p_target);
+ bool _send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, int p_target);
+
+ Error _encode_and_compress_variant(const Variant &p_variant, uint8_t *p_buffer, int &r_len);
+ Error _decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len);
public:
enum NetworkCommands {
- NETWORK_COMMAND_REMOTE_CALL,
+ NETWORK_COMMAND_REMOTE_CALL = 0,
NETWORK_COMMAND_REMOTE_SET,
NETWORK_COMMAND_SIMPLIFY_PATH,
NETWORK_COMMAND_CONFIRM_PATH,
NETWORK_COMMAND_RAW,
};
+ enum NetworkNodeIdCompression {
+ NETWORK_NODE_ID_COMPRESSION_8 = 0,
+ NETWORK_NODE_ID_COMPRESSION_16,
+ NETWORK_NODE_ID_COMPRESSION_32,
+ };
+
+ enum NetworkNameIdCompression {
+ NETWORK_NAME_ID_COMPRESSION_8 = 0,
+ NETWORK_NAME_ID_COMPRESSION_16,
+ };
+
enum RPCMode {
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h
index 0f2458d982..118970de80 100644
--- a/core/method_ptrcall.h
+++ b/core/method_ptrcall.h
@@ -32,6 +32,7 @@
#define METHOD_PTRCALL_H
#include "core/math/transform_2d.h"
+#include "core/object_id.h"
#include "core/typedefs.h"
#include "core/variant.h"
@@ -167,6 +168,21 @@ struct PtrToArg<const T *> {
}
};
+//this is for ObjectID
+
+template <>
+struct PtrToArg<ObjectID> {
+ _FORCE_INLINE_ static const ObjectID convert(const void *p_ptr) {
+
+ return ObjectID(*reinterpret_cast<const uint64_t *>(p_ptr));
+ }
+
+ _FORCE_INLINE_ static void encode(const ObjectID &p_val, void *p_ptr) {
+
+ *((uint64_t *)p_ptr) = p_val;
+ }
+};
+
//this is for the special cases used by Variant
#define MAKE_VECARG(m_type) \
diff --git a/core/object.cpp b/core/object.cpp
index 937b1ae8d4..dc1dc2c41f 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1916,7 +1916,6 @@ Object::Object() {
_class_ptr = NULL;
_block_signals = false;
_predelete_ok = 0;
- _instance_id = 0;
_instance_id = ObjectDB::add_instance(this);
_can_translate = true;
_is_queued_for_deletion = false;
@@ -1972,7 +1971,7 @@ Object::~Object() {
}
ObjectDB::remove_instance(this);
- _instance_id = 0;
+ _instance_id = ObjectID();
_predelete_ok = 2;
if (!ScriptServer::are_languages_finished()) {
@@ -1995,14 +1994,14 @@ void postinitialize_handler(Object *p_object) {
}
HashMap<ObjectID, Object *> ObjectDB::instances;
-ObjectID ObjectDB::instance_counter = 1;
+uint64_t ObjectDB::instance_counter = 1;
HashMap<Object *, ObjectID, ObjectDB::ObjectPtrHash> ObjectDB::instance_checks;
ObjectID ObjectDB::add_instance(Object *p_object) {
- ERR_FAIL_COND_V(p_object->get_instance_id() != 0, 0);
+ ERR_FAIL_COND_V(p_object->get_instance_id().is_valid(), ObjectID());
rw_lock->write_lock();
- ObjectID instance_id = ++instance_counter;
+ ObjectID instance_id = ObjectID(++instance_counter);
instances[instance_id] = p_object;
instance_checks[p_object] = instance_id;
diff --git a/core/object.h b/core/object.h
index 865c155764..312fe07a17 100644
--- a/core/object.h
+++ b/core/object.h
@@ -34,6 +34,7 @@
#include "core/hash_map.h"
#include "core/list.h"
#include "core/map.h"
+#include "core/object_id.h"
#include "core/os/rw_lock.h"
#include "core/set.h"
#include "core/variant.h"
@@ -89,6 +90,7 @@ enum PropertyHint {
PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send
PROPERTY_HINT_NODE_PATH_VALID_TYPES,
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
+ PROPERTY_HINT_INT_IS_OBJECTID,
PROPERTY_HINT_MAX,
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
};
@@ -397,7 +399,6 @@ public: \
private:
class ScriptInstance;
-typedef uint64_t ObjectID;
class Object {
public:
@@ -452,7 +453,7 @@ private:
_id(p_id),
method(p_method) {
}
- Target() { _id = 0; }
+ Target() { _id = ObjectID(); }
};
struct Slot {
@@ -775,7 +776,7 @@ class ObjectDB {
static HashMap<ObjectID, Object *> instances;
static HashMap<Object *, ObjectID, ObjectPtrHash> instance_checks;
- static ObjectID instance_counter;
+ static uint64_t instance_counter;
friend class Object;
friend void unregister_core_types();
diff --git a/core/object_id.h b/core/object_id.h
new file mode 100644
index 0000000000..f0ff2a24f5
--- /dev/null
+++ b/core/object_id.h
@@ -0,0 +1,32 @@
+#ifndef OBJECT_ID_H
+#define OBJECT_ID_H
+
+#include "core/typedefs.h"
+
+// Class to store an object ID (int64)
+// needs to be compatile with int64 because this is what Variant uses
+// Also, need to be explicitly only castable to 64 bits integer types
+// to avoid bugs due to loss of precision
+
+class ObjectID {
+ uint64_t id = 0;
+
+public:
+ _ALWAYS_INLINE_ bool is_valid() const { return id != 0; }
+ _ALWAYS_INLINE_ bool is_null() const { return id == 0; }
+ _ALWAYS_INLINE_ operator uint64_t() const { return id; }
+ _ALWAYS_INLINE_ operator int64_t() const { return id; }
+
+ _ALWAYS_INLINE_ bool operator==(const ObjectID &p_id) const { return id == p_id.id; }
+ _ALWAYS_INLINE_ bool operator!=(const ObjectID &p_id) const { return id != p_id.id; }
+ _ALWAYS_INLINE_ bool operator<(const ObjectID &p_id) const { return id < p_id.id; }
+
+ _ALWAYS_INLINE_ void operator=(int64_t p_int64) { id = p_int64; }
+ _ALWAYS_INLINE_ void operator=(uint64_t p_uint64) { id = p_uint64; }
+
+ _ALWAYS_INLINE_ ObjectID() {}
+ _ALWAYS_INLINE_ explicit ObjectID(const uint64_t p_id) { id = p_id; }
+ _ALWAYS_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; }
+};
+
+#endif // OBJECT_ID_H
diff --git a/core/reference.cpp b/core/reference.cpp
index b24b2a3ec0..5c211fe301 100644
--- a/core/reference.cpp
+++ b/core/reference.cpp
@@ -113,7 +113,7 @@ Reference::~Reference() {
Variant WeakRef::get_ref() const {
- if (ref == 0)
+ if (ref.is_null())
return Variant();
Object *obj = ObjectDB::get_instance(ref);
@@ -129,16 +129,15 @@ Variant WeakRef::get_ref() const {
}
void WeakRef::set_obj(Object *p_object) {
- ref = p_object ? p_object->get_instance_id() : 0;
+ ref = p_object ? p_object->get_instance_id() : ObjectID();
}
void WeakRef::set_ref(const REF &p_ref) {
- ref = p_ref.is_valid() ? p_ref->get_instance_id() : 0;
+ ref = p_ref.is_valid() ? p_ref->get_instance_id() : ObjectID();
}
-WeakRef::WeakRef() :
- ref(0) {
+WeakRef::WeakRef() {
}
void WeakRef::_bind_methods() {
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 7392e7a0af..1149feac38 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -32,6 +32,7 @@
#include "core/core_string_names.h"
#include "core/project_settings.h"
+#include <stdint.h>
ScriptLanguage *ScriptServer::_languages[MAX_LANGUAGES];
int ScriptServer::_language_count = 0;
@@ -644,6 +645,14 @@ Variant PlaceHolderScriptInstance::property_get_fallback(const StringName &p_nam
return Variant();
}
+uint16_t PlaceHolderScriptInstance::get_rpc_method_id(const StringName &p_method) const {
+ return UINT16_MAX;
+}
+
+uint16_t PlaceHolderScriptInstance::get_rset_property_id(const StringName &p_method) const {
+ return UINT16_MAX;
+}
+
PlaceHolderScriptInstance::PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner) :
owner(p_owner),
language(p_language),
diff --git a/core/script_language.h b/core/script_language.h
index 22f83080bc..788f5d6976 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -40,6 +40,21 @@ class ScriptLanguage;
typedef void (*ScriptEditRequestFunction)(const String &p_path);
+struct ScriptNetData {
+ StringName name;
+ MultiplayerAPI::RPCMode mode;
+ bool operator==(ScriptNetData const &p_other) const {
+ return name == p_other.name;
+ }
+};
+
+struct SortNetData {
+ StringName::AlphCompare compare;
+ bool operator()(const ScriptNetData &p_a, const ScriptNetData &p_b) const {
+ return compare(p_a.name, p_b.name);
+ }
+};
+
class ScriptServer {
enum {
@@ -154,6 +169,18 @@ public:
virtual bool is_placeholder_fallback_enabled() const { return false; }
+ virtual Vector<ScriptNetData> get_rpc_methods() const = 0;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const = 0;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const = 0;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const = 0;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const = 0;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const = 0;
+ virtual uint16_t get_rset_property_id(const StringName &p_property) const = 0;
+ virtual StringName get_rset_property(const uint16_t p_rset_property_id) const = 0;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const = 0;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const = 0;
+
Script() {}
};
@@ -195,7 +222,16 @@ public:
virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid);
virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid);
+ virtual Vector<ScriptNetData> get_rpc_methods() const = 0;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const = 0;
+ virtual StringName get_rpc_method(uint16_t p_id) const = 0;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const = 0;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const = 0;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const = 0;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const = 0;
+ virtual StringName get_rset_property(uint16_t p_id) const = 0;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const = 0;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const = 0;
virtual ScriptLanguage *get_language() = 0;
@@ -409,7 +445,16 @@ public:
virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid = NULL);
virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid = NULL);
+ virtual Vector<ScriptNetData> get_rpc_methods() const { return Vector<ScriptNetData>(); }
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(uint16_t p_id) const { return StringName(); }
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const { return MultiplayerAPI::RPC_MODE_DISABLED; }
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const { return MultiplayerAPI::RPC_MODE_DISABLED; }
+
+ virtual Vector<ScriptNetData> get_rset_properties() const { return Vector<ScriptNetData>(); }
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(uint16_t p_id) const { return StringName(); }
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const { return MultiplayerAPI::RPC_MODE_DISABLED; }
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const { return MultiplayerAPI::RPC_MODE_DISABLED; }
PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner);
diff --git a/core/type_info.h b/core/type_info.h
index 68bc1cc554..b9e5b61a6a 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -187,6 +187,16 @@ struct GetTypeInfo<const RefPtr &> {
}
};
+//objectID
+template <>
+struct GetTypeInfo<ObjectID> {
+ static const Variant::Type VARIANT_TYPE = Variant::INT;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_OBJECTID);
+ }
+};
+
//for variant
template <>
struct GetTypeInfo<Variant> {
diff --git a/core/variant.cpp b/core/variant.cpp
index f4e4cd5341..0f04710d13 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -1248,6 +1248,14 @@ Variant::operator uint64_t() const {
}
}
+Variant::operator ObjectID() const {
+ if (type == INT) {
+ return ObjectID(_data._int);
+ } else {
+ return ObjectID();
+ }
+}
+
#ifdef NEED_LONG_INT
Variant::operator signed long() const {
@@ -2193,6 +2201,11 @@ Variant::Variant(double p_double) {
_data._real = p_double;
}
+Variant::Variant(const ObjectID &p_id) {
+ type = INT;
+ _data._int = p_id;
+}
+
Variant::Variant(const StringName &p_string) {
type = STRING;
diff --git a/core/variant.h b/core/variant.h
index 06be914408..d8007f9e12 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -44,6 +44,7 @@
#include "core/math/transform_2d.h"
#include "core/math/vector3.h"
#include "core/node_path.h"
+#include "core/object_id.h"
#include "core/pool_vector.h"
#include "core/ref_ptr.h"
#include "core/rid.h"
@@ -177,6 +178,8 @@ public:
operator unsigned long() const;
#endif
+ operator ObjectID() const;
+
operator CharType() const;
operator float() const;
operator double() const;
@@ -248,6 +251,7 @@ public:
Variant(uint64_t p_int);
Variant(float p_float);
Variant(double p_double);
+ Variant(const ObjectID &p_id);
Variant(const String &p_string);
Variant(const StringName &p_string);
Variant(const char *const p_cstring);
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 08047935bd..620fcdbdca 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -332,6 +332,11 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
struct_code += " ";
struct_code += m->name;
+ if (m->array_size > 0) {
+ struct_code += "[";
+ struct_code += itos(m->array_size);
+ struct_code += "]";
+ }
struct_code += ";\n";
}
struct_code += "}";
@@ -558,6 +563,26 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
}
} break;
+ case SL::Node::TYPE_ARRAY_CONSTRUCT: {
+ SL::ArrayConstructNode *arr_con_node = (SL::ArrayConstructNode *)p_node;
+ int sz = arr_con_node->initializer.size();
+ if (acnode->datatype == SL::TYPE_STRUCT) {
+ code += _mkid(arr_con_node->struct_name);
+ } else {
+ code += _typestr(arr_con_node->datatype);
+ }
+ code += "[";
+ code += itos(arr_con_node->initializer.size());
+ code += "]";
+ code += "(";
+ for (int i = 0; i < sz; i++) {
+ code += _dump_node_code(arr_con_node->initializer[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ if (i != sz - 1) {
+ code += ", ";
+ }
+ }
+ code += ")";
+ } break;
case SL::Node::TYPE_ARRAY_DECLARATION: {
SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node;
@@ -898,6 +923,11 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _dump_node_code(member_node->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += ".";
code += member_node->name;
+ if (member_node->index_expression != NULL) {
+ code += "[";
+ code += _dump_node_code(member_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += "]";
+ }
} break;
}
diff --git a/editor/dictionary_property_edit.cpp b/editor/dictionary_property_edit.cpp
index bb01fadb72..82db639379 100644
--- a/editor/dictionary_property_edit.cpp
+++ b/editor/dictionary_property_edit.cpp
@@ -190,5 +190,4 @@ bool DictionaryPropertyEdit::_get(const StringName &p_name, Variant &r_ret) cons
}
DictionaryPropertyEdit::DictionaryPropertyEdit() {
- obj = 0;
}
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index d7c610f109..5cb7720170 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -156,8 +156,8 @@ bool EditorHistory::is_history_obj_inspector_only(int p_obj) const {
}
ObjectID EditorHistory::get_history_obj(int p_obj) const {
- ERR_FAIL_INDEX_V(p_obj, history.size(), 0);
- ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), 0);
+ ERR_FAIL_INDEX_V(p_obj, history.size(), ObjectID());
+ ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), ObjectID());
return history[p_obj].path[history[p_obj].level].object;
}
@@ -204,12 +204,12 @@ bool EditorHistory::is_current_inspector_only() const {
ObjectID EditorHistory::get_current() {
if (current < 0 || current >= history.size())
- return 0;
+ return ObjectID();
History &h = history.write[current];
Object *obj = ObjectDB::get_instance(h.path[h.level].object);
if (!obj)
- return 0;
+ return ObjectID();
return obj->get_instance_id();
}
@@ -226,15 +226,15 @@ int EditorHistory::get_path_size() const {
ObjectID EditorHistory::get_path_object(int p_index) const {
if (current < 0 || current >= history.size())
- return 0;
+ return ObjectID();
const History &h = history[current];
- ERR_FAIL_INDEX_V(p_index, h.path.size(), 0);
+ ERR_FAIL_INDEX_V(p_index, h.path.size(), ObjectID());
Object *obj = ObjectDB::get_instance(h.path[p_index].object);
if (!obj)
- return 0;
+ return ObjectID();
return obj->get_instance_id();
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 4440a747be..a6172faeaa 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1558,7 +1558,7 @@ void EditorNode::_dialog_action(String p_file) {
save_resource_in_path(saving_resource, p_file);
saving_resource = Ref<Resource>();
ObjectID current = editor_history.get_current();
- Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
+ Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : NULL;
ERR_FAIL_COND(!current_obj);
current_obj->_change_notify();
} break;
@@ -1711,7 +1711,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in
return;
}
- uint32_t id = p_object->get_instance_id();
+ ObjectID id = p_object->get_instance_id();
if (id != editor_history.get_current()) {
if (p_inspector_only) {
@@ -1767,8 +1767,8 @@ static bool overrides_external_editor(Object *p_object) {
void EditorNode::_edit_current() {
- uint32_t current = editor_history.get_current();
- Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
+ ObjectID current = editor_history.get_current();
+ Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : NULL;
bool inspector_only = editor_history.is_current_inspector_only();
this->current = current_obj;
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 0794940cb1..905e928c5a 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -388,13 +388,13 @@ void EditorPropertyMember::_property_select() {
} else if (hint == MEMBER_METHOD_OF_INSTANCE) {
- Object *instance = ObjectDB::get_instance(hint_text.to_int64());
+ Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (instance)
selector->select_method_from_instance(instance, current);
} else if (hint == MEMBER_METHOD_OF_SCRIPT) {
- Object *obj = ObjectDB::get_instance(hint_text.to_int64());
+ Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (Object::cast_to<Script>(obj)) {
selector->select_method_from_script(Object::cast_to<Script>(obj), current);
}
@@ -420,13 +420,13 @@ void EditorPropertyMember::_property_select() {
} else if (hint == MEMBER_PROPERTY_OF_INSTANCE) {
- Object *instance = ObjectDB::get_instance(hint_text.to_int64());
+ Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (instance)
selector->select_property_from_instance(instance, current);
} else if (hint == MEMBER_PROPERTY_OF_SCRIPT) {
- Object *obj = ObjectDB::get_instance(hint_text.to_int64());
+ Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (Object::cast_to<Script>(obj)) {
selector->select_property_from_script(Object::cast_to<Script>(obj), current);
}
@@ -858,7 +858,7 @@ void EditorPropertyObjectID::update_property() {
type = "Object";
ObjectID id = get_edited_object()->get(get_edited_property());
- if (id != 0) {
+ if (id.is_valid()) {
edit->set_text(type + " ID: " + itos(id));
edit->set_disabled(false);
edit->set_icon(EditorNode::get_singleton()->get_class_icon(type));
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index 2090c12c91..c4a84bfcdc 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -177,7 +177,7 @@ String SectionedInspector::get_full_item_path(const String &p_item) {
void SectionedInspector::edit(Object *p_object) {
if (!p_object) {
- obj = 0;
+ obj = ObjectID();
sections->clear();
filter->set_edited(NULL);
@@ -308,7 +308,6 @@ EditorInspector *SectionedInspector::get_inspector() {
}
SectionedInspector::SectionedInspector() :
- obj(0),
sections(memnew(Tree)),
filter(memnew(SectionedInspectorFilter)),
inspector(memnew(EditorInspector)),
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index c681cdd033..954a941a96 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -166,8 +166,8 @@ void InspectorDock::_resource_file_selected(String p_file) {
}
void InspectorDock::_save_resource(bool save_as) const {
- uint32_t current = EditorNode::get_singleton()->get_editor_history()->get_current();
- Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
+ ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
+ Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : NULL;
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
@@ -180,8 +180,8 @@ void InspectorDock::_save_resource(bool save_as) const {
}
void InspectorDock::_unref_resource() const {
- uint32_t current = EditorNode::get_singleton()->get_editor_history()->get_current();
- Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
+ ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
+ Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : NULL;
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
@@ -191,8 +191,8 @@ void InspectorDock::_unref_resource() const {
}
void InspectorDock::_copy_resource() const {
- uint32_t current = EditorNode::get_singleton()->get_editor_history()->get_current();
- Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;
+ ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
+ Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : NULL;
ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj));
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index 8dc7e4638d..a729c90160 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -59,7 +59,7 @@ void AnimationTreeEditor::edit(AnimationTree *p_tree) {
path = tree->get_meta("_tree_edit_path");
edit_path(path);
} else {
- current_root = 0;
+ current_root = ObjectID();
}
}
@@ -128,7 +128,7 @@ void AnimationTreeEditor::edit_path(const Vector<String> &p_path) {
}
}
} else {
- current_root = 0;
+ current_root = ObjectID();
edited_path = button_path;
}
@@ -151,7 +151,7 @@ void AnimationTreeEditor::_about_to_show_root() {
void AnimationTreeEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
- ObjectID root = 0;
+ ObjectID root;
if (tree && tree->get_tree_root().is_valid()) {
root = tree->get_tree_root()->get_instance_id();
}
@@ -242,7 +242,6 @@ AnimationTreeEditor::AnimationTreeEditor() {
add_child(memnew(HSeparator));
- current_root = 0;
singleton = this;
editor_base = memnew(PanelContainer);
editor_base->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 27ba518f01..f7a3b50052 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -3659,7 +3659,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) {
// Add a last bone if the Bone2D has no Bone2D child
BoneKey bk;
bk.from = canvas_item->get_instance_id();
- bk.to = 0;
+ bk.to = ObjectID();
if (!bone_list.has(bk)) {
BoneList b;
b.length = 0;
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 88376f6ce6..cf6c8feaed 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -252,7 +252,7 @@ void SpatialEditorViewport::_clear_selected() {
void SpatialEditorViewport::_select_clicked(bool p_append, bool p_single, bool p_allow_locked) {
- if (!clicked)
+ if (clicked.is_null())
return;
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(clicked));
@@ -309,7 +309,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append,
Set<Ref<EditorSpatialGizmo> > found_gizmos;
Node *edited_scene = get_tree()->get_edited_scene_root();
- ObjectID closest = 0;
+ ObjectID closest;
Node *item = NULL;
float closest_dist = 1e20;
int selected_handle = -1;
@@ -356,7 +356,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append,
}
if (!item)
- return 0;
+ return ObjectID();
if (!editor_selection->is_selected(item) || (r_gizmo_handle && selected_handle >= 0)) {
@@ -850,9 +850,9 @@ void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
clicked = selection_results[0].item->get_instance_id();
selection_results.clear();
- if (clicked) {
+ if (clicked.is_valid()) {
_select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() != SpatialEditor::TOOL_MODE_LIST_SELECT);
- clicked = 0;
+ clicked = ObjectID();
}
} else if (!selection_results.empty()) {
@@ -1095,7 +1095,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (_gizmo_select(_edit.mouse_pos))
break;
- clicked = 0;
+ clicked = ObjectID();
clicked_includes_current = false;
if ((spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT && b->get_control()) || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE) {
@@ -1139,7 +1139,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
clicked_wants_append = b->get_shift();
- if (!clicked) {
+ if (clicked.is_null()) {
if (!clicked_wants_append)
_clear_selected();
@@ -1150,7 +1150,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
cursor.region_end = b->get_position();
}
- if (clicked && gizmo_handle >= 0) {
+ if (clicked.is_valid() && gizmo_handle >= 0) {
Spatial *spa = Object::cast_to<Spatial>(ObjectDB::get_instance(clicked));
if (spa) {
@@ -1175,10 +1175,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
_edit.gizmo = Ref<EditorSpatialGizmo>();
break;
}
- if (clicked) {
+ if (clicked.is_valid()) {
_select_clicked(clicked_wants_append, true);
// Processing was deferred.
- clicked = 0;
+ clicked = ObjectID();
}
if (cursor.region_select) {
@@ -1279,7 +1279,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} else if (nav_scheme == NAVIGATION_MODO && m->get_alt()) {
nav_mode = NAVIGATION_ORBIT;
} else {
- if (clicked) {
+ if (clicked.is_valid()) {
if (!clicked_includes_current) {
@@ -1288,7 +1288,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
_compute_edit(_edit.mouse_pos);
- clicked = 0;
+ clicked = ObjectID();
_edit.mode = TRANSFORM_TRANSLATE;
}
@@ -2945,9 +2945,9 @@ void SpatialEditorViewport::_selection_result_pressed(int p_result) {
clicked = selection_results[p_result].item->get_instance_id();
- if (clicked) {
+ if (clicked.is_valid()) {
_select_clicked(clicked_wants_append, true, spatial_editor->get_tool_mode() != SpatialEditor::TOOL_MODE_LIST_SELECT);
- clicked = 0;
+ clicked = ObjectID();
}
}
@@ -3581,7 +3581,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
editor_data = editor->get_scene_tree_dock()->get_editor_data();
editor_selection = editor->get_editor_selection();
undo_redo = editor->get_undo_redo();
- clicked = 0;
+
clicked_includes_current = false;
orthogonal = false;
lock_rotation = false;
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 63f0b02a40..1691ce3a63 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -639,7 +639,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
MAKE_PROPSELECT
- Object *instance = ObjectDB::get_instance(hint_text.to_int64());
+ Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (instance)
property_select->select_method_from_instance(instance, v);
updating = false;
@@ -648,7 +648,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} else if (hint == PROPERTY_HINT_METHOD_OF_SCRIPT) {
MAKE_PROPSELECT
- Object *obj = ObjectDB::get_instance(hint_text.to_int64());
+ Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (Object::cast_to<Script>(obj)) {
property_select->select_method_from_script(Object::cast_to<Script>(obj), v);
}
@@ -688,7 +688,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
MAKE_PROPSELECT
- Object *instance = ObjectDB::get_instance(hint_text.to_int64());
+ Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (instance)
property_select->select_property_from_instance(instance, v);
@@ -698,7 +698,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} else if (hint == PROPERTY_HINT_PROPERTY_OF_SCRIPT) {
MAKE_PROPSELECT
- Object *obj = ObjectDB::get_instance(hint_text.to_int64());
+ Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (Object::cast_to<Script>(obj)) {
property_select->select_property_from_script(Object::cast_to<Script>(obj), v);
}
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index fdb1ce3e62..1de5099c4a 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -404,7 +404,7 @@ void PropertySelector::select_method_from_base_type(const String &p_base, const
base_type = p_base;
selected = p_current;
type = Variant::NIL;
- script = 0;
+ script = ObjectID();
properties = false;
instance = NULL;
virtuals_only = p_virtuals_only;
@@ -437,7 +437,7 @@ void PropertySelector::select_method_from_basic_type(Variant::Type p_type, const
base_type = "";
selected = p_current;
type = p_type;
- script = 0;
+ script = ObjectID();
properties = false;
instance = NULL;
virtuals_only = false;
@@ -453,7 +453,7 @@ void PropertySelector::select_method_from_instance(Object *p_instance, const Str
base_type = p_instance->get_class();
selected = p_current;
type = Variant::NIL;
- script = 0;
+ script = ObjectID();
{
Ref<Script> scr = p_instance->get_script();
if (scr.is_valid())
@@ -474,7 +474,7 @@ void PropertySelector::select_property_from_base_type(const String &p_base, cons
base_type = p_base;
selected = p_current;
type = Variant::NIL;
- script = 0;
+ script = ObjectID();
properties = true;
instance = NULL;
virtuals_only = false;
@@ -509,7 +509,7 @@ void PropertySelector::select_property_from_basic_type(Variant::Type p_type, con
base_type = "";
selected = p_current;
type = p_type;
- script = 0;
+ script = ObjectID();
properties = true;
instance = NULL;
virtuals_only = false;
@@ -525,7 +525,7 @@ void PropertySelector::select_property_from_instance(Object *p_instance, const S
base_type = "";
selected = p_current;
type = Variant::NIL;
- script = 0;
+ script = ObjectID();
properties = true;
instance = p_instance;
virtuals_only = false;
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 3aec50528f..2b28aa87a3 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -172,7 +172,7 @@ public:
}
String get_title() {
- if (remote_object_id)
+ if (remote_object_id.is_valid())
return TTR("Remote ") + String(type_name) + ": " + itos(remote_object_id);
else
return "<null>";
@@ -197,7 +197,6 @@ public:
}
ScriptEditorDebuggerInspectedObject() {
- remote_object_id = 0;
}
};
@@ -302,7 +301,7 @@ void ScriptEditorDebugger::_scene_tree_selected() {
return;
}
- inspected_object_id = item->get_metadata(0);
+ inspected_object_id = item->get_metadata(0).operator ObjectID();
Array msg;
msg.push_back("inspect_object");
@@ -434,7 +433,7 @@ int ScriptEditorDebugger::_update_scene_tree(TreeItem *parent, const Array &node
TreeItem *item = inspect_scene_tree->create_item(parent);
item->set_text(0, item_text);
item->set_tooltip(0, TTR("Type:") + " " + item_type);
- ObjectID id = ObjectID(nodes[current_index + 3]);
+ ObjectID id = nodes[current_index + 3].operator ObjectID();
Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(nodes[current_index + 2], "");
if (icon.is_valid()) {
item->set_icon(0, icon);
@@ -1107,7 +1106,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
int frame_size = 6;
for (int i = 0; i < p_data.size(); i += frame_size) {
MultiplayerAPI::ProfilingInfo pi;
- pi.node = p_data[i + 0];
+ pi.node = p_data[i + 0].operator ObjectID();
pi.node_path = p_data[i + 1];
pi.incoming_rpc = p_data[i + 2];
pi.incoming_rset = p_data[i + 3];
@@ -1253,7 +1252,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
inspect_edited_object_timeout -= get_process_delta_time();
if (inspect_edited_object_timeout < 0) {
inspect_edited_object_timeout = EditorSettings::get_singleton()->get("debugger/remote_inspect_refresh_interval");
- if (inspected_object_id) {
+ if (inspected_object_id.is_valid()) {
if (ScriptEditorDebuggerInspectedObject *obj = Object::cast_to<ScriptEditorDebuggerInspectedObject>(ObjectDB::get_instance(editor->get_editor_history()->get_current()))) {
if (obj->remote_object_id == inspected_object_id) {
//take the chance and re-inspect selected object
@@ -2486,7 +2485,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
auto_switch_remote_scene_tree = EDITOR_DEF("debugger/auto_switch_to_remote_scene_tree", false);
inspect_scene_tree_timeout = EDITOR_DEF("debugger/remote_scene_tree_refresh_interval", 1.0);
inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2);
- inspected_object_id = 0;
+ inspected_object_id = ObjectID();
updating_scene_tree = false;
}
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index 8d03a99556..7806145390 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -107,7 +107,7 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer:
Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id);
if (!areaGodoObject) {
- event.event_callback_id = 0;
+ event.event_callback_id = ObjectID();
return;
}
@@ -279,7 +279,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co
ev.event_callback_method = p_method;
/// Set if monitoring
- if (eventsCallbacks[0].event_callback_id || eventsCallbacks[1].event_callback_id) {
+ if (eventsCallbacks[0].event_callback_id.is_valid() || eventsCallbacks[1].event_callback_id.is_valid()) {
set_godot_object_flags(get_godot_object_flags() | GOF_IS_MONITORING_AREA);
} else {
set_godot_object_flags(get_godot_object_flags() & (~GOF_IS_MONITORING_AREA));
@@ -287,7 +287,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co
}
bool AreaBullet::has_event_callback(Type p_callbackObjectType) {
- return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id;
+ return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id.is_valid();
}
void AreaBullet::on_enter_area(AreaBullet *p_area) {
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index f770c63bcc..18888c6725 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -50,8 +50,7 @@ public:
ObjectID event_callback_id;
StringName event_callback_method;
- InOutEventCallback() :
- event_callback_id(0) {}
+ InOutEventCallback() {}
};
enum OverlapState {
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index fceb5d2b4b..89868babc6 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -359,7 +359,7 @@ void BulletPhysicsServer::area_attach_object_instance_id(RID p_area, ObjectID p_
ObjectID BulletPhysicsServer::area_get_object_instance_id(RID p_area) const {
if (space_owner.owns(p_area)) {
- return 0;
+ return ObjectID();
}
AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, ObjectID());
@@ -428,14 +428,14 @@ void BulletPhysicsServer::area_set_monitor_callback(RID p_area, Object *p_receiv
AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
void BulletPhysicsServer::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
void BulletPhysicsServer::area_set_ray_pickable(RID p_area, bool p_enable) {
@@ -569,16 +569,16 @@ void BulletPhysicsServer::body_clear_shapes(RID p_body) {
body->remove_all_shapes();
}
-void BulletPhysicsServer::body_attach_object_instance_id(RID p_body, uint32_t p_id) {
+void BulletPhysicsServer::body_attach_object_instance_id(RID p_body, ObjectID p_id) {
CollisionObjectBullet *body = get_collisin_object(p_body);
ERR_FAIL_COND(!body);
body->set_instance_id(p_id);
}
-uint32_t BulletPhysicsServer::body_get_object_instance_id(RID p_body) const {
+ObjectID BulletPhysicsServer::body_get_object_instance_id(RID p_body) const {
CollisionObjectBullet *body = get_collisin_object(p_body);
- ERR_FAIL_COND_V(!body, 0);
+ ERR_FAIL_COND_V(!body, ObjectID());
return body->get_instance_id();
}
@@ -844,7 +844,7 @@ bool BulletPhysicsServer::body_is_omitting_force_integration(RID p_body) const {
void BulletPhysicsServer::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata);
+ body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata);
}
void BulletPhysicsServer::body_set_ray_pickable(RID p_body, bool p_enable) {
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index 22032d32e3..6ea9a7a974 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -189,8 +189,8 @@ public:
virtual void body_clear_shapes(RID p_body);
// Used for Rigid and Soft Bodies
- virtual void body_attach_object_instance_id(RID p_body, uint32_t p_id);
- virtual uint32_t body_get_object_instance_id(RID p_body) const;
+ virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id);
+ virtual ObjectID body_get_object_instance_id(RID p_body) const;
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable);
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const;
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index c916c65d2b..5b7e7281e4 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -90,7 +90,7 @@ void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_s
CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
RIDBullet(),
type(p_type),
- instance_id(0),
+ instance_id(ObjectID()),
collisionLayer(0),
collisionMask(0),
collisionsEnabled(true),
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 6e54d10abf..20467e3ef3 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -112,7 +112,7 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo
result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
result.rid = gObj->get_self();
result.collider_id = gObj->get_instance_id();
- result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
+ result.collider = result.collider_id.is_null() ? NULL : ObjectDB::get_instance(result.collider_id);
++count;
return 1; // not used by bullet
@@ -220,7 +220,7 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con
}
result.collider_id = colObj->get_instance_id();
- result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id);
+ result.collider = result.collider_id.is_null() ? NULL : ObjectDB::get_instance(result.collider_id);
result.rid = colObj->get_self();
++m_count;
}
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index dfc9647813..e5804fbde8 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -366,7 +366,7 @@ void RigidBodyBullet::dispatch_callbacks() {
Object *obj = ObjectDB::get_instance(force_integration_callback->id);
if (!obj) {
// Remove integration callback
- set_force_integration_callback(0, StringName());
+ set_force_integration_callback(ObjectID(), StringName());
} else {
const Variant *vp[2] = { &variantBodyDirect, &force_integration_callback->udata };
@@ -395,7 +395,7 @@ void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const String
force_integration_callback = NULL;
}
- if (p_id != 0) {
+ if (p_id.is_valid()) {
force_integration_callback = memnew(ForceIntegrationCallback);
force_integration_callback->id = p_id;
force_integration_callback->method = p_method;
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 69f3d1b393..0e4c4b4731 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -108,7 +108,7 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V
r_result.shape = btResult.m_shapeId;
r_result.rid = gObj->get_self();
r_result.collider_id = gObj->get_instance_id();
- r_result.collider = 0 == r_result.collider_id ? NULL : ObjectDB::get_instance(r_result.collider_id);
+ r_result.collider = r_result.collider_id.is_null() ? NULL : ObjectDB::get_instance(r_result.collider_id);
} else {
WARN_PRINT("The raycast performed has hit a collision object that is not part of Godot scene, please check it.");
}
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 06334556d9..119bb80659 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -171,7 +171,7 @@ bool GDAPI godot_is_instance_valid(const godot_object *p_object) {
}
godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id) {
- return (godot_object *)ObjectDB::get_instance((ObjectID)p_instance_id);
+ return (godot_object *)ObjectDB::get_instance(ObjectID((uint64_t)p_instance_id));
}
void *godot_get_class_tag(const godot_string_name *p_class) {
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 414b9b9eaf..59901f6139 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -250,7 +250,12 @@ godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, co
keys.write[i] = (*keys_proxy)[i];
}
- return self->findmk(keys, p_from, r_key);
+ int key;
+ int ret = self->findmk(keys, p_from, &key);
+ if (r_key) {
+ *r_key = key;
+ }
+ return ret;
}
godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what) {
diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index e19e675344..f953206a34 100644
--- a/modules/gdnative/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -36,6 +36,7 @@
#include "core/project_settings.h"
#include "core/variant.h"
#include "gdnative/gdnative.h"
+#include <stdint.h>
#include "nativescript.h"
@@ -67,6 +68,14 @@ void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char
if (classes->has(p_base)) {
desc.base_data = &(*classes)[p_base];
desc.base_native_type = desc.base_data->base_native_type;
+
+ const NativeScriptDesc *b = desc.base_data;
+ while (b) {
+ desc.rpc_count += b->rpc_count;
+ desc.rset_count += b->rset_count;
+ b = b->base_data;
+ }
+
} else {
desc.base_data = NULL;
desc.base_native_type = p_base;
@@ -87,10 +96,20 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const
desc.destroy_func = p_destroy_func;
desc.is_tool = true;
desc.base = p_base;
+ desc.rpc_count = 0;
+ desc.rset_count = 0;
if (classes->has(p_base)) {
desc.base_data = &(*classes)[p_base];
desc.base_native_type = desc.base_data->base_native_type;
+
+ const NativeScriptDesc *b = desc.base_data;
+ while (b) {
+ desc.rpc_count += b->rpc_count;
+ desc.rset_count += b->rset_count;
+ b = b->base_data;
+ }
+
} else {
desc.base_data = NULL;
desc.base_native_type = p_base;
@@ -109,6 +128,11 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha
NativeScriptDesc::Method method;
method.method = p_method;
method.rpc_mode = p_attr.rpc_type;
+ method.rpc_method_id = UINT16_MAX;
+ if (p_attr.rpc_type != GODOT_METHOD_RPC_MODE_DISABLED) {
+ method.rpc_method_id = E->get().rpc_count;
+ E->get().rpc_count += 1;
+ }
method.info = MethodInfo(p_function_name);
E->get().methods.insert(p_function_name, method);
@@ -125,6 +149,10 @@ void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const c
property.default_value = *(Variant *)&p_attr->default_value;
property.getter = p_get_func;
property.rset_mode = p_attr->rset_type;
+ if (p_attr->rset_type != GODOT_METHOD_RPC_MODE_DISABLED) {
+ property.rset_property_id = E->get().rset_count;
+ E->get().rset_count += 1;
+ }
property.setter = p_set_func;
property.info = PropertyInfo((Variant::Type)p_attr->type,
p_path,
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 8b06af6c7b..df85155ff5 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -30,6 +30,8 @@
#include "nativescript.h"
+#include <stdint.h>
+
#include "gdnative/gdnative.h"
#include "core/core_string_names.h"
@@ -402,6 +404,262 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const {
}
}
+Vector<ScriptNetData> NativeScript::get_rpc_methods() const {
+
+ Vector<ScriptNetData> v;
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
+ if (E->get().rpc_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = MultiplayerAPI::RPCMode(E->get().rpc_mode);
+ v.push_back(nd);
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return v;
+}
+
+uint16_t NativeScript::get_rpc_method_id(const StringName &p_method) const {
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
+ if (E) {
+ return E->get().rpc_method_id;
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return UINT16_MAX;
+}
+
+StringName NativeScript::get_rpc_method(uint16_t p_id) const {
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName());
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
+ if (E->get().rpc_method_id == p_id) {
+ return E->key();
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rpc_mode_by_id(uint16_t p_id) const {
+
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
+ if (E->get().rpc_method_id == p_id) {
+ switch (E->get().rpc_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rpc_mode(const StringName &p_method) const {
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
+ if (E) {
+ switch (E->get().rpc_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+Vector<ScriptNetData> NativeScript::get_rset_properties() const {
+ Vector<ScriptNetData> v;
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
+ if (E.get().rset_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E.key();
+ nd.mode = MultiplayerAPI::RPCMode(E.get().rset_mode);
+ v.push_back(nd);
+ }
+ }
+ script_data = script_data->base_data;
+ }
+
+ return v;
+}
+
+uint16_t NativeScript::get_rset_property_id(const StringName &p_variable) const {
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
+ if (E) {
+ return E.get().rset_property_id;
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return UINT16_MAX;
+}
+
+StringName NativeScript::get_rset_property(uint16_t p_id) const {
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName());
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
+ if (E.get().rset_property_id == p_id) {
+ return E.key();
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rset_mode_by_id(uint16_t p_id) const {
+
+ ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
+ if (E.get().rset_property_id == p_id) {
+ switch (E.get().rset_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode NativeScript::get_rset_mode(const StringName &p_variable) const {
+
+ NativeScriptDesc *script_data = get_script_desc();
+
+ while (script_data) {
+
+ OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
+ if (E) {
+ switch (E.get().rset_mode) {
+ case GODOT_METHOD_RPC_MODE_DISABLED:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ case GODOT_METHOD_RPC_MODE_REMOTE:
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ case GODOT_METHOD_RPC_MODE_MASTER:
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ case GODOT_METHOD_RPC_MODE_PUPPET:
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ case GODOT_METHOD_RPC_MODE_REMOTESYNC:
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ case GODOT_METHOD_RPC_MODE_MASTERSYNC:
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+ default:
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
+ }
+
+ script_data = script_data->base_data;
+ }
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
String NativeScript::get_class_documentation() const {
NativeScriptDesc *script_data = get_script_desc();
@@ -803,72 +1061,44 @@ Ref<Script> NativeScriptInstance::get_script() const {
return script;
}
-MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
-
- NativeScriptDesc *script_data = GET_SCRIPT_DESC();
-
- while (script_data) {
+Vector<ScriptNetData> NativeScriptInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
- if (E) {
- switch (E->get().rpc_mode) {
- case GODOT_METHOD_RPC_MODE_DISABLED:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- case GODOT_METHOD_RPC_MODE_REMOTE:
- return MultiplayerAPI::RPC_MODE_REMOTE;
- case GODOT_METHOD_RPC_MODE_MASTER:
- return MultiplayerAPI::RPC_MODE_MASTER;
- case GODOT_METHOD_RPC_MODE_PUPPET:
- return MultiplayerAPI::RPC_MODE_PUPPET;
- case GODOT_METHOD_RPC_MODE_REMOTESYNC:
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- case GODOT_METHOD_RPC_MODE_MASTERSYNC:
- return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
- return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
- default:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
- }
+uint16_t NativeScriptInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
+}
- script_data = script_data->base_data;
- }
+StringName NativeScriptInstance::get_rpc_method(uint16_t p_id) const {
+ return script->get_rpc_method(p_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const {
+ return script->get_rpc_mode_by_id(p_id);
}
-MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
+}
- NativeScriptDesc *script_data = GET_SCRIPT_DESC();
+Vector<ScriptNetData> NativeScriptInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- while (script_data) {
+uint16_t NativeScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
+}
- OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
- if (E) {
- switch (E.get().rset_mode) {
- case GODOT_METHOD_RPC_MODE_DISABLED:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- case GODOT_METHOD_RPC_MODE_REMOTE:
- return MultiplayerAPI::RPC_MODE_REMOTE;
- case GODOT_METHOD_RPC_MODE_MASTER:
- return MultiplayerAPI::RPC_MODE_MASTER;
- case GODOT_METHOD_RPC_MODE_PUPPET:
- return MultiplayerAPI::RPC_MODE_PUPPET;
- case GODOT_METHOD_RPC_MODE_REMOTESYNC:
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- case GODOT_METHOD_RPC_MODE_MASTERSYNC:
- return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- case GODOT_METHOD_RPC_MODE_PUPPETSYNC:
- return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
- default:
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
- }
+StringName NativeScriptInstance::get_rset_property(uint16_t p_id) const {
+ return script->get_rset_property(p_id);
+}
- script_data = script_data->base_data;
- }
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode_by_id(uint16_t p_id) const {
+ return script->get_rset_mode_by_id(p_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return script->get_rset_mode(p_variable);
}
ScriptLanguage *NativeScriptInstance::get_language() {
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index cf787e1f6a..2ff08e32cd 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -54,6 +54,7 @@ struct NativeScriptDesc {
godot_instance_method method;
MethodInfo info;
int rpc_mode;
+ uint16_t rpc_method_id;
String documentation;
};
struct Property {
@@ -62,6 +63,7 @@ struct NativeScriptDesc {
PropertyInfo info;
Variant default_value;
int rset_mode;
+ uint16_t rset_property_id;
String documentation;
};
@@ -70,7 +72,9 @@ struct NativeScriptDesc {
String documentation;
};
+ uint16_t rpc_count;
Map<StringName, Method> methods;
+ uint16_t rset_count;
OrderedHashMap<StringName, Property> properties;
Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals
StringName base;
@@ -86,7 +90,9 @@ struct NativeScriptDesc {
bool is_tool;
inline NativeScriptDesc() :
+ rpc_count(0),
methods(),
+ rset_count(0),
properties(),
signals_(),
base(),
@@ -174,6 +180,18 @@ public:
virtual void get_script_method_list(List<MethodInfo> *p_list) const;
virtual void get_script_property_list(List<PropertyInfo> *p_list) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
String get_class_documentation() const;
String get_method_documentation(const StringName &p_method) const;
String get_signal_documentation(const StringName &p_signal_name) const;
@@ -210,8 +228,19 @@ public:
virtual void notification(int p_notification);
String to_string(bool *r_valid);
virtual Ref<Script> get_script() const;
+
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
virtual ScriptLanguage *get_language();
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp
index 0d6dac3268..26a1d5f47a 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp
@@ -93,10 +93,42 @@ void PluginScriptInstance::notification(int p_notification) {
_desc->notification(_data, p_notification);
}
+Vector<ScriptNetData> PluginScriptInstance::get_rpc_methods() const {
+ return _script->get_rpc_methods();
+}
+
+uint16_t PluginScriptInstance::get_rpc_method_id(const StringName &p_variable) const {
+ return _script->get_rpc_method_id(p_variable);
+}
+
+StringName PluginScriptInstance::get_rpc_method(uint16_t p_id) const {
+ return _script->get_rpc_method(p_id);
+}
+
+MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const {
+ return _script->get_rpc_mode_by_id(p_id);
+}
+
MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const {
return _script->get_rpc_mode(p_method);
}
+Vector<ScriptNetData> PluginScriptInstance::get_rset_properties() const {
+ return _script->get_rset_properties();
+}
+
+uint16_t PluginScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return _script->get_rset_property_id(p_variable);
+}
+
+StringName PluginScriptInstance::get_rset_property(uint16_t p_id) const {
+ return _script->get_rset_property(p_id);
+}
+
+MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode_by_id(uint16_t p_id) const {
+ return _script->get_rset_mode_by_id(p_id);
+}
+
MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const {
return _script->get_rset_mode(p_variable);
}
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h
index dc1229a44d..154bebd72a 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.h
+++ b/modules/gdnative/pluginscript/pluginscript_instance.h
@@ -76,7 +76,16 @@ public:
void set_path(const String &p_path);
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(uint16_t p_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
virtual void refcount_incremented();
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index cc5bdee0a1..c370062262 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -34,6 +34,8 @@
#include "pluginscript_instance.h"
#include "pluginscript_script.h"
+#include <stdint.h>
+
#ifdef DEBUG_ENABLED
#define __ASSERT_SCRIPT_REASON "Cannot retrieve PluginScript class for this script, is your code correct?"
#define ASSERT_SCRIPT_VALID() \
@@ -298,18 +300,31 @@ Error PluginScript::reload(bool p_keep_state) {
_member_lines[*key] = (*members)[*key];
}
Array *methods = (Array *)&manifest.methods;
+ _rpc_methods.clear();
+ _rpc_variables.clear();
+ if (_ref_base_parent.is_valid()) {
+ _rpc_methods = _ref_base_parent->get_rpc_methods();
+ _rpc_variables = _ref_base_parent->get_rset_properties();
+ }
for (int i = 0; i < methods->size(); ++i) {
Dictionary v = (*methods)[i];
MethodInfo mi = MethodInfo::from_dict(v);
_methods_info[mi.name] = mi;
// rpc_mode is passed as an optional field and is not part of MethodInfo
Variant var = v["rpc_mode"];
- if (var == Variant()) {
- _methods_rpc_mode[mi.name] = MultiplayerAPI::RPC_MODE_DISABLED;
- } else {
- _methods_rpc_mode[mi.name] = MultiplayerAPI::RPCMode(int(var));
+ if (var != Variant()) {
+ ScriptNetData nd;
+ nd.name = mi.name;
+ nd.mode = MultiplayerAPI::RPCMode(int(var));
+ if (_rpc_methods.find(nd) == -1) {
+ _rpc_methods.push_back(nd);
+ }
}
}
+
+ // Sort so we are 100% that they are always the same.
+ _rpc_methods.sort_custom<SortNetData>();
+
Array *signals = (Array *)&manifest.signals;
for (int i = 0; i < signals->size(); ++i) {
Variant v = (*signals)[i];
@@ -324,13 +339,19 @@ Error PluginScript::reload(bool p_keep_state) {
_properties_default_values[pi.name] = v["default_value"];
// rset_mode is passed as an optional field and is not part of PropertyInfo
Variant var = v["rset_mode"];
- if (var == Variant()) {
- _methods_rpc_mode[pi.name] = MultiplayerAPI::RPC_MODE_DISABLED;
- } else {
- _methods_rpc_mode[pi.name] = MultiplayerAPI::RPCMode(int(var));
+ if (var != Variant()) {
+ ScriptNetData nd;
+ nd.name = pi.name;
+ nd.mode = MultiplayerAPI::RPCMode(int(var));
+ if (_rpc_variables.find(nd) == -1) {
+ _rpc_variables.push_back(nd);
+ }
}
}
+ // Sort so we are 100% that they are always the same.
+ _rpc_variables.sort_custom<SortNetData>();
+
#ifdef TOOLS_ENABLED
/*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
@@ -455,24 +476,70 @@ int PluginScript::get_member_line(const StringName &p_member) const {
return -1;
}
-MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
+Vector<ScriptNetData> PluginScript::get_rpc_methods() const {
+ return _rpc_methods;
+}
+
+uint16_t PluginScript::get_rpc_method_id(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(UINT16_MAX);
+ for (int i = 0; i < _rpc_methods.size(); i++) {
+ if (_rpc_methods[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName PluginScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ASSERT_SCRIPT_VALID_V(StringName());
+ if (p_rpc_method_id >= _rpc_methods.size())
+ return StringName();
+ return _rpc_methods[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _methods_rpc_mode.find(p_method);
- if (e != NULL) {
- return e->get();
- } else {
+ if (p_rpc_method_id >= _rpc_methods.size())
return MultiplayerAPI::RPC_MODE_DISABLED;
+ return _rpc_methods[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> PluginScript::get_rset_properties() const {
+ return _rpc_variables;
+}
+
+uint16_t PluginScript::get_rset_property_id(const StringName &p_property) const {
+ ASSERT_SCRIPT_VALID_V(UINT16_MAX);
+ for (int i = 0; i < _rpc_variables.size(); i++) {
+ if (_rpc_variables[i].name == p_property) {
+ return i;
+ }
}
+ return UINT16_MAX;
}
-MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
+StringName PluginScript::get_rset_property(const uint16_t p_rset_property_id) const {
+ ASSERT_SCRIPT_VALID_V(StringName());
+ if (p_rset_property_id >= _rpc_variables.size())
+ return StringName();
+ return _rpc_variables[p_rset_property_id].name;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rset_mode_by_id(const uint16_t p_rset_property_id) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _variables_rset_mode.find(p_variable);
- if (e != NULL) {
- return e->get();
- } else {
+ if (p_rset_property_id >= _rpc_variables.size())
return MultiplayerAPI::RPC_MODE_DISABLED;
- }
+ return _rpc_variables[p_rset_property_id].mode;
+}
+
+MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
+ ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
}
PluginScript::PluginScript() :
diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h
index f67c88c794..f6bca8a9cb 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.h
+++ b/modules/gdnative/pluginscript/pluginscript_script.h
@@ -60,8 +60,8 @@ private:
Map<StringName, PropertyInfo> _properties_info;
Map<StringName, MethodInfo> _signals_info;
Map<StringName, MethodInfo> _methods_info;
- Map<StringName, MultiplayerAPI::RPCMode> _variables_rset_mode;
- Map<StringName, MultiplayerAPI::RPCMode> _methods_rpc_mode;
+ Vector<ScriptNetData> _rpc_methods;
+ Vector<ScriptNetData> _rpc_variables;
Set<Object *> _instances;
//exported members
@@ -118,8 +118,17 @@ public:
virtual int get_member_line(const StringName &p_member) const;
- MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
- MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_property) const;
+ virtual StringName get_rset_property(const uint16_t p_rset_property_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
PluginScript();
void init(PluginScriptLanguage *language);
diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp
index ddfb3c10fa..2780e2a931 100644
--- a/modules/gdnavigation/gd_navigation_server.cpp
+++ b/modules/gdnavigation/gd_navigation_server.cpp
@@ -374,7 +374,7 @@ COMMAND_4(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_
RvoAgent *agent = agent_owner.getornull(p_agent);
ERR_FAIL_COND(agent == NULL);
- agent->set_callback(p_receiver == NULL ? 0 : p_receiver->get_instance_id(), p_method, p_udata);
+ agent->set_callback(p_receiver == NULL ? ObjectID() : p_receiver->get_instance_id(), p_method, p_udata);
if (agent->get_map()) {
if (p_receiver == NULL) {
diff --git a/modules/gdnavigation/rvo_agent.cpp b/modules/gdnavigation/rvo_agent.cpp
index eb66eb3a05..4d19bc15af 100644
--- a/modules/gdnavigation/rvo_agent.cpp
+++ b/modules/gdnavigation/rvo_agent.cpp
@@ -38,7 +38,7 @@
RvoAgent::RvoAgent() :
map(NULL) {
- callback.id = ObjectID(0);
+ callback.id = ObjectID();
}
void RvoAgent::set_map(NavMap *p_map) {
@@ -62,16 +62,16 @@ void RvoAgent::set_callback(ObjectID p_id, const StringName p_method, const Vari
}
bool RvoAgent::has_callback() const {
- return callback.id != 0;
+ return callback.id.is_valid();
}
void RvoAgent::dispatch_callback() {
- if (callback.id == 0) {
+ if (callback.id.is_null()) {
return;
}
Object *obj = ObjectDB::get_instance(callback.id);
if (obj == NULL) {
- callback.id = ObjectID(0);
+ callback.id = ObjectID();
}
Variant::CallError responseCallError;
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index a255b92257..e4da60b5b9 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -30,6 +30,8 @@
#include "gdscript.h"
+#include <stdint.h>
+
#include "core/core_string_names.h"
#include "core/engine.h"
#include "core/global_constants.h"
@@ -610,6 +612,53 @@ Error GDScript::reload(bool p_keep_state) {
_set_subclass_path(E->get(), path);
}
+ // Copy the base rpc methods so we don't mask their IDs.
+ rpc_functions.clear();
+ rpc_variables.clear();
+ if (base.is_valid()) {
+ rpc_functions = base->rpc_functions;
+ rpc_variables = base->rpc_variables;
+ }
+
+ GDScript *cscript = this;
+ Map<StringName, Ref<GDScript> >::Element *sub_E = subclasses.front();
+ while (cscript) {
+ // RPC Methods
+ for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) {
+ if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = E->get()->get_rpc_mode();
+ if (-1 == rpc_functions.find(nd)) {
+ rpc_functions.push_back(nd);
+ }
+ }
+ }
+ // RSet
+ for (Map<StringName, MemberInfo>::Element *E = cscript->member_indices.front(); E; E = E->next()) {
+ if (E->get().rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = E->get().rpc_mode;
+ if (-1 == rpc_variables.find(nd)) {
+ rpc_variables.push_back(nd);
+ }
+ }
+ }
+
+ if (cscript != this)
+ sub_E = sub_E->next();
+
+ if (sub_E)
+ cscript = sub_E->get().ptr();
+ else
+ cscript = NULL;
+ }
+
+ // Sort so we are 100% that they are always the same.
+ rpc_functions.sort_custom<SortNetData>();
+ rpc_variables.sort_custom<SortNetData>();
+
return OK;
}
@@ -635,6 +684,60 @@ void GDScript::get_members(Set<StringName> *p_members) {
}
}
+Vector<ScriptNetData> GDScript::get_rpc_methods() const {
+ return rpc_functions;
+}
+
+uint16_t GDScript::get_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < rpc_functions.size(); i++) {
+ if (rpc_functions[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName GDScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName());
+ return rpc_functions[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rpc_mode(const StringName &p_method) const {
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> GDScript::get_rset_properties() const {
+ return rpc_variables;
+}
+
+uint16_t GDScript::get_rset_property_id(const StringName &p_variable) const {
+ for (int i = 0; i < rpc_variables.size(); i++) {
+ if (rpc_variables[i].name == p_variable) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName());
+ return rpc_variables[p_rset_member_id].name;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rset_member_id].mode;
+}
+
+MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) const {
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
+}
+
Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
GDScript *top = this;
@@ -1291,40 +1394,44 @@ ScriptLanguage *GDScriptInstance::get_language() {
return GDScriptLanguage::get_singleton();
}
-MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
+Vector<ScriptNetData> GDScriptInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- const GDScript *cscript = script.ptr();
+uint16_t GDScriptInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
+}
- while (cscript) {
- const Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.find(p_method);
- if (E) {
+StringName GDScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_method(p_rpc_method_id);
+}
- if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
- return E->get()->get_rpc_mode();
- }
- }
- cscript = cscript->_base;
- }
+MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_mode_by_id(p_rpc_method_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
}
-MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
+Vector<ScriptNetData> GDScriptInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- const GDScript *cscript = script.ptr();
+uint16_t GDScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
+}
- while (cscript) {
- const Map<StringName, GDScript::MemberInfo>::Element *E = cscript->member_indices.find(p_variable);
- if (E) {
+StringName GDScriptInstance::get_rset_property(const uint16_t p_rset_member_id) const {
+ return script->get_rset_property(p_rset_member_id);
+}
- if (E->get().rpc_mode) {
- return E->get().rpc_mode;
- }
- }
- cscript = cscript->_base;
- }
+MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ return script->get_rset_mode_by_id(p_rset_member_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return script->get_rset_mode(p_variable);
}
void GDScriptInstance::reload_members() {
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 4ae52238ce..4af574cd9d 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -85,6 +85,8 @@ class GDScript : public Script {
Map<StringName, MemberInfo> member_indices; //members are just indices to the instanced script.
Map<StringName, Ref<GDScript> > subclasses;
Map<StringName, Vector<StringName> > _signals;
+ Vector<ScriptNetData> rpc_functions;
+ Vector<ScriptNetData> rpc_variables;
#ifdef TOOLS_ENABLED
@@ -213,6 +215,18 @@ public:
virtual void get_constants(Map<StringName, Variant> *p_constants);
virtual void get_members(Set<StringName> *p_members);
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
#ifdef TOOLS_ENABLED
virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; }
#endif
@@ -264,7 +278,16 @@ public:
void reload_members();
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
GDScriptInstance();
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 452b1933eb..7392bbc10a 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -1274,7 +1274,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
gdfs->state.script = Ref<GDScript>(_script);
gdfs->state.ip = ip + ipofs;
gdfs->state.line = line;
- gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : 0;
+ gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : ObjectID();
//gdfs->state.result_pos=ip+ipofs-1;
gdfs->state.defarg = defarg;
gdfs->state.instance = p_instance;
@@ -1829,7 +1829,7 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
if (p_extended_check) {
//class instance gone?
- if (state.instance_id && !ObjectDB::get_instance(state.instance_id))
+ if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id))
return false;
}
@@ -1839,7 +1839,7 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
Variant GDScriptFunctionState::resume(const Variant &p_arg) {
ERR_FAIL_COND_V(!function, Variant());
- if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
+ if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id)) {
#ifdef DEBUG_ENABLED
ERR_FAIL_V_MSG(Variant(), "Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line));
#else
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index c398633dc5..27d67fda6d 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -1374,7 +1374,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
break;
}
- uint32_t id = *p_args[0];
+ ObjectID id = *p_args[0];
r_ret = ObjectDB::get_instance(id);
} break;
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 2847f3b414..10bc3dcb49 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -31,6 +31,7 @@
#include "csharp_script.h"
#include <mono/metadata/threads.h>
+#include <stdint.h>
#include "core/io/json.h"
#include "core/os/file_access.h"
@@ -161,11 +162,11 @@ void CSharpLanguage::finish() {
#ifdef DEBUG_ENABLED
for (Map<ObjectID, int>::Element *E = unsafe_object_references.front(); E; E = E->next()) {
- const ObjectID &id = E->get();
+ const ObjectID &id = E->key();
Object *obj = ObjectDB::get_instance(id);
if (obj) {
- ERR_PRINT("Leaked unsafe reference to object: " + obj->get_class() + ":" + itos(id));
+ ERR_PRINT("Leaked unsafe reference to object: " + obj->to_string());
} else {
ERR_PRINT("Leaked unsafe reference to deleted object: " + itos(id));
}
@@ -1979,67 +1980,44 @@ bool CSharpInstance::refcount_decremented() {
return ref_dying;
}
-MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(IMonoClassMember *p_member) const {
-
- if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
- return MultiplayerAPI::RPC_MODE_REMOTE;
- if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
- return MultiplayerAPI::RPC_MODE_MASTER;
- if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute)))
- return MultiplayerAPI::RPC_MODE_PUPPET;
- if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute)))
- return MultiplayerAPI::RPC_MODE_PUPPET;
- if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute)))
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
- return MultiplayerAPI::RPC_MODE_REMOTESYNC;
- if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute)))
- return MultiplayerAPI::RPC_MODE_MASTERSYNC;
- if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute)))
- return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+Vector<ScriptNetData> CSharpInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+uint16_t CSharpInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
}
-MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const {
+StringName CSharpInstance::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_method(p_rpc_method_id);
+}
- GD_MONO_SCOPE_THREAD_ATTACH;
+MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_mode_by_id(p_rpc_method_id);
+}
- GDMonoClass *top = script->script_class;
+MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
+}
- while (top && top != script->native) {
- GDMonoMethod *method = top->get_fetched_method_unknown_params(p_method);
+Vector<ScriptNetData> CSharpInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- if (method && !method->is_static())
- return _member_get_rpc_mode(method);
+uint16_t CSharpInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
+}
- top = top->get_parent_class();
- }
+StringName CSharpInstance::get_rset_property(const uint16_t p_rset_member_id) const {
+ return script->get_rset_property(p_rset_member_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ return script->get_rset_mode_by_id(p_rset_member_id);
}
MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const {
-
- GD_MONO_SCOPE_THREAD_ATTACH;
-
- GDMonoClass *top = script->script_class;
-
- while (top && top != script->native) {
- GDMonoField *field = top->get_field(p_variable);
-
- if (field && !field->is_static())
- return _member_get_rpc_mode(field);
-
- GDMonoProperty *property = top->get_property(p_variable);
-
- if (property && !property->is_static())
- return _member_get_rpc_mode(property);
-
- top = top->get_parent_class();
- }
-
- return MultiplayerAPI::RPC_MODE_DISABLED;
+ return script->get_rset_mode(p_variable);
}
void CSharpInstance::notification(int p_notification) {
@@ -3251,6 +3229,69 @@ Error CSharpScript::reload(bool p_keep_state) {
_update_exports();
}
+ rpc_functions.clear();
+ rpc_variables.clear();
+
+ GDMonoClass *top = script_class;
+ while (top && top != native) {
+ {
+ Vector<GDMonoMethod *> methods = top->get_all_methods();
+ for (int i = 0; i < methods.size(); i++) {
+ if (!methods[i]->is_static()) {
+ MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(methods[i]);
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
+ ScriptNetData nd;
+ nd.name = methods[i]->get_name();
+ nd.mode = mode;
+ if (-1 == rpc_functions.find(nd)) {
+ rpc_functions.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ {
+ Vector<GDMonoField *> fields = top->get_all_fields();
+ for (int i = 0; i < fields.size(); i++) {
+ if (!fields[i]->is_static()) {
+ MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(fields[i]);
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
+ ScriptNetData nd;
+ nd.name = fields[i]->get_name();
+ nd.mode = mode;
+ if (-1 == rpc_variables.find(nd)) {
+ rpc_variables.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ {
+ Vector<GDMonoProperty *> properties = top->get_all_properties();
+ for (int i = 0; i < properties.size(); i++) {
+ if (!properties[i]->is_static()) {
+ MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(properties[i]);
+ if (MultiplayerAPI::RPC_MODE_DISABLED != mode) {
+ ScriptNetData nd;
+ nd.name = properties[i]->get_name();
+ nd.mode = mode;
+ if (-1 == rpc_variables.find(nd)) {
+ rpc_variables.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ top = top->get_parent_class();
+ }
+
+ // Sort so we are 100% that they are always the same.
+ rpc_functions.sort_custom<SortNetData>();
+ rpc_variables.sort_custom<SortNetData>();
+
return OK;
}
@@ -3324,6 +3365,82 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
return -1;
}
+MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
+
+ if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
+ return MultiplayerAPI::RPC_MODE_REMOTE;
+ if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
+ return MultiplayerAPI::RPC_MODE_MASTER;
+ if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute)))
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute)))
+ return MultiplayerAPI::RPC_MODE_PUPPET;
+ if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ if (p_member->has_attribute(CACHED_CLASS(SyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_REMOTESYNC;
+ if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_MASTERSYNC;
+ if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute)))
+ return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
+
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+Vector<ScriptNetData> CSharpScript::get_rpc_methods() const {
+ return rpc_functions;
+}
+
+uint16_t CSharpScript::get_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < rpc_functions.size(); i++) {
+ if (rpc_functions[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName CSharpScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName());
+ return rpc_functions[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode(const StringName &p_method) const {
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> CSharpScript::get_rset_properties() const {
+ return rpc_variables;
+}
+
+uint16_t CSharpScript::get_rset_property_id(const StringName &p_variable) const {
+ for (int i = 0; i < rpc_variables.size(); i++) {
+ if (rpc_variables[i].name == p_variable) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName CSharpScript::get_rset_property(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName());
+ return rpc_variables[p_rset_member_id].name;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
+ ERR_FAIL_COND_V(p_rset_member_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rset_member_id].mode;
+}
+
+MultiplayerAPI::RPCMode CSharpScript::get_rset_mode(const StringName &p_variable) const {
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
+}
+
Error CSharpScript::load_source_code(const String &p_path) {
Error ferr = read_all_file_utf8(p_path, source);
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index f244bc4119..32a5b30c18 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -113,6 +113,9 @@ class CSharpScript : public Script {
Map<StringName, Vector<Argument> > _signals;
bool signals_invalidated;
+ Vector<ScriptNetData> rpc_functions;
+ Vector<ScriptNetData> rpc_variables;
+
#ifdef TOOLS_ENABLED
List<PropertyInfo> exported_members_cache; // members_cache
Map<StringName, Variant> exported_members_defval_cache; // member_default_values_cache
@@ -146,6 +149,8 @@ class CSharpScript : public Script {
static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native);
static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native);
+ MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const;
+
protected:
static void _bind_methods();
@@ -187,6 +192,18 @@ public:
virtual int get_member_line(const StringName &p_member) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
#ifdef TOOLS_ENABLED
virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; }
#endif
@@ -232,8 +249,6 @@ class CSharpInstance : public ScriptInstance {
void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount);
- MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const;
-
void get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state);
public:
@@ -265,7 +280,16 @@ public:
virtual void refcount_incremented();
virtual bool refcount_decremented();
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_variable) const;
+ virtual StringName get_rset_property(const uint16_t p_variable_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
virtual void notification(int p_notification);
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index d3226762ea..b85d5f2fd9 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -68,7 +68,7 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V_MSG(conn_target_id && !ObjectDB::get_instance(conn_target_id), Variant(),
+ ERR_FAIL_COND_V_MSG(conn_target_id.is_valid() && !ObjectDB::get_instance(conn_target_id), Variant(),
"Resumed after await, but class instance is gone.");
#endif
@@ -116,12 +116,7 @@ void SignalAwaiterHandle::_bind_methods() {
}
SignalAwaiterHandle::SignalAwaiterHandle(MonoObject *p_managed) :
- MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) {
-
-#ifdef DEBUG_ENABLED
- conn_target_id = 0;
-#endif
-}
+ MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) {}
SignalAwaiterHandle::~SignalAwaiterHandle() {
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index c591e3b5c2..e712190344 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -30,6 +30,8 @@
#include "visual_script.h"
+#include <stdint.h>
+
#include "core/core_string_names.h"
#include "core/os/os.h"
#include "core/project_settings.h"
@@ -1102,6 +1104,60 @@ bool VisualScript::are_subnodes_edited() const {
}
#endif
+Vector<ScriptNetData> VisualScript::get_rpc_methods() const {
+ return rpc_functions;
+}
+
+uint16_t VisualScript::get_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < rpc_functions.size(); i++) {
+ if (rpc_functions[i].name == p_method) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName VisualScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName());
+ return rpc_functions[p_rpc_method_id].name;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rpc_method_id].mode;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rpc_mode(const StringName &p_method) const {
+ return get_rpc_mode_by_id(get_rpc_method_id(p_method));
+}
+
+Vector<ScriptNetData> VisualScript::get_rset_properties() const {
+ return rpc_variables;
+}
+
+uint16_t VisualScript::get_rset_property_id(const StringName &p_variable) const {
+ for (int i = 0; i < rpc_variables.size(); i++) {
+ if (rpc_variables[i].name == p_variable) {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName VisualScript::get_rset_property(const uint16_t p_rset_property_id) const {
+ ERR_FAIL_COND_V(p_rset_property_id >= rpc_variables.size(), StringName());
+ return rpc_variables[p_rset_property_id].name;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const {
+ ERR_FAIL_COND_V(p_rset_variable_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ return rpc_functions[p_rset_variable_id].mode;
+}
+
+MultiplayerAPI::RPCMode VisualScript::get_rset_mode(const StringName &p_variable) const {
+ return get_rset_mode_by_id(get_rset_property_id(p_variable));
+}
+
void VisualScript::_set_data(const Dictionary &p_data) {
Dictionary d = p_data;
@@ -1206,6 +1262,30 @@ void VisualScript::_set_data(const Dictionary &p_data) {
is_tool_script = d["is_tool_script"];
else
is_tool_script = false;
+
+ // Takes all the rpc methods
+ rpc_functions.clear();
+ rpc_variables.clear();
+ for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
+ if (E->get().function_id >= 0 && E->get().nodes.find(E->get().function_id)) {
+ Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
+ if (vsf.is_valid()) {
+ if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) {
+ ScriptNetData nd;
+ nd.name = E->key();
+ nd.mode = vsf->get_rpc_mode();
+ if (rpc_functions.find(nd) == -1) {
+ rpc_functions.push_back(nd);
+ }
+ }
+ }
+ }
+ }
+
+ // Visual script doesn't have rset :(
+
+ // Sort so we are 100% that they are always the same.
+ rpc_functions.sort_custom<SortNetData>();
}
Dictionary VisualScript::_get_data() const {
@@ -2043,31 +2123,44 @@ Ref<Script> VisualScriptInstance::get_script() const {
return script;
}
-MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const {
+Vector<ScriptNetData> VisualScriptInstance::get_rpc_methods() const {
+ return script->get_rpc_methods();
+}
- if (p_method == script->get_default_func())
- return MultiplayerAPI::RPC_MODE_DISABLED;
+uint16_t VisualScriptInstance::get_rpc_method_id(const StringName &p_method) const {
+ return script->get_rpc_method_id(p_method);
+}
- const Map<StringName, VisualScript::Function>::Element *E = script->functions.find(p_method);
- if (!E) {
- return MultiplayerAPI::RPC_MODE_DISABLED;
- }
+StringName VisualScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_method(p_rpc_method_id);
+}
- if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) {
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ return script->get_rpc_mode_by_id(p_rpc_method_id);
+}
- Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
- if (vsf.is_valid()) {
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return script->get_rpc_mode(p_method);
+}
- return vsf->get_rpc_mode();
- }
- }
+Vector<ScriptNetData> VisualScriptInstance::get_rset_properties() const {
+ return script->get_rset_properties();
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+uint16_t VisualScriptInstance::get_rset_property_id(const StringName &p_variable) const {
+ return script->get_rset_property_id(p_variable);
}
-MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const {
+StringName VisualScriptInstance::get_rset_property(const uint16_t p_rset_property_id) const {
+ return script->get_rset_property(p_rset_property_id);
+}
- return MultiplayerAPI::RPC_MODE_DISABLED;
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const {
+ return script->get_rset_mode_by_id(p_rset_variable_id);
+}
+
+MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return script->get_rset_mode(p_variable);
}
void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) {
@@ -2321,8 +2414,8 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
- ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+ ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
#endif
@@ -2383,8 +2476,8 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
- ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
+ ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone.");
+ ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone.");
#endif
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 9305226dc6..d3569bb040 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -245,6 +245,8 @@ private:
Map<StringName, Function> functions;
Map<StringName, Variable> variables;
Map<StringName, Vector<Argument> > custom_signals;
+ Vector<ScriptNetData> rpc_functions;
+ Vector<ScriptNetData> rpc_variables;
Map<Object *, VisualScriptInstance *> instances;
@@ -362,6 +364,18 @@ public:
virtual int get_member_line(const StringName &p_member) const;
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_property) const;
+ virtual StringName get_rset_property(const uint16_t p_rset_property_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
+
#ifdef TOOLS_ENABLED
virtual bool are_subnodes_edited() const;
#endif
@@ -441,7 +455,16 @@ public:
virtual ScriptLanguage *get_language();
+ virtual Vector<ScriptNetData> get_rpc_methods() const;
+ virtual uint16_t get_rpc_method_id(const StringName &p_method) const;
+ virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const;
+ virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const;
+
+ virtual Vector<ScriptNetData> get_rset_properties() const;
+ virtual uint16_t get_rset_property_id(const StringName &p_property) const;
+ virtual StringName get_rset_property(const uint16_t p_rset_property_id) const;
+ virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const;
VisualScriptInstance();
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index e629175094..e8c02a41c4 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -529,7 +529,6 @@ void VisualScriptPropertySelector::select_method_from_base_type(const String &p_
base_type = p_base;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = false;
instance = NULL;
virtuals_only = p_virtuals_only;
@@ -554,7 +553,6 @@ void VisualScriptPropertySelector::select_from_base_type(const String &p_base, c
base_type = p_base;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = true;
visual_script_generic = false;
instance = NULL;
@@ -601,7 +599,6 @@ void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type,
base_type = "";
selected = p_current;
type = p_type;
- script = 0;
properties = true;
visual_script_generic = false;
instance = NULL;
@@ -623,7 +620,6 @@ void VisualScriptPropertySelector::select_from_action(const String &p_type, cons
base_type = p_type;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = false;
visual_script_generic = false;
instance = NULL;
@@ -645,7 +641,6 @@ void VisualScriptPropertySelector::select_from_instance(Object *p_instance, cons
base_type = p_basetype;
selected = p_current;
type = Variant::NIL;
- script = 0;
properties = true;
visual_script_generic = false;
instance = p_instance;
@@ -667,7 +662,6 @@ void VisualScriptPropertySelector::select_from_visual_script(const String &p_bas
base_type = p_base;
selected = "";
type = Variant::NIL;
- script = 0;
properties = true;
visual_script_generic = true;
instance = NULL;
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 338194fcae..1fd91ec3c1 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -240,6 +240,11 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
//!!!!!!!!!!!!!!!!!!!!!!!!!!
//TODO - do Vulkan and GLES2 support checks, driver selection and fallback
video_driver_index = p_video_driver;
+#ifndef _MSC_VER
+#warning Forcing vulkan video driver because OpenGL not implemented yet
+#endif
+ video_driver_index = VIDEO_DRIVER_VULKAN;
+
print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]");
//!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 8302ba5336..b661db2e52 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -148,7 +148,7 @@ void Area2D::_body_exit_tree(ObjectID p_id) {
}
}
-void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) {
+void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) {
bool body_in = p_status == Physics2DServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -251,7 +251,7 @@ void Area2D::_area_exit_tree(ObjectID p_id) {
}
}
-void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) {
+void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) {
bool area_in = p_status == Physics2DServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index 6d9386c535..c5e6635412 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -62,7 +62,7 @@ private:
bool monitorable;
bool locked;
- void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape);
+ void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape);
void _body_enter_tree(ObjectID p_id);
void _body_exit_tree(ObjectID p_id);
@@ -94,7 +94,7 @@ private:
Map<ObjectID, BodyState> body_map;
- void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape);
+ void _area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape);
void _area_enter_tree(ObjectID p_id);
void _area_exit_tree(ObjectID p_id);
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index e9f8c5dff2..7ec770597e 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -608,7 +608,7 @@ void Camera2D::set_custom_viewport(Node *p_viewport) {
if (custom_viewport) {
custom_viewport_id = custom_viewport->get_instance_id();
} else {
- custom_viewport_id = 0;
+ custom_viewport_id = ObjectID();
}
if (is_inside_tree()) {
@@ -795,7 +795,7 @@ Camera2D::Camera2D() {
smoothing_enabled = false;
limit_smoothing_enabled = false;
custom_viewport = NULL;
- custom_viewport_id = 0;
+
process_mode = CAMERA2D_PROCESS_IDLE;
smoothing = 5.0;
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index eff58a4fb3..aca0c4c959 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -997,7 +997,7 @@ ObjectID CanvasItem::get_canvas_layer_instance_id() const {
if (canvas_layer) {
return canvas_layer->get_instance_id();
} else {
- return 0;
+ return ObjectID();
}
}
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 3e9e63a7f0..4af2e846f7 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -95,9 +95,9 @@ void CollisionObject2D::_notification(int p_what) {
case NOTIFICATION_EXIT_CANVAS: {
if (area)
- Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, 0);
+ Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID());
else
- Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, 0);
+ Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, ObjectID());
} break;
}
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index d42bd6adaf..d1fe5caf7e 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1544,7 +1544,7 @@ Object *KinematicCollision2D::get_local_shape() const {
Object *KinematicCollision2D::get_collider() const {
- if (collision.collider) {
+ if (collision.collider.is_valid()) {
return ObjectDB::get_instance(collision.collider);
}
@@ -1608,7 +1608,7 @@ void KinematicCollision2D::_bind_methods() {
}
KinematicCollision2D::KinematicCollision2D() {
- collision.collider = 0;
+
collision.collider_shape = 0;
collision.local_shape = 0;
owner = NULL;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index dc953b2d7d..ba5b7d29e7 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -108,7 +108,7 @@ void Polygon2D::_notification(int p_what) {
skeleton_node = Object::cast_to<Skeleton2D>(get_node(skeleton));
}
- ObjectID new_skeleton_id = 0;
+ ObjectID new_skeleton_id;
if (skeleton_node) {
VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton());
@@ -734,7 +734,7 @@ Polygon2D::Polygon2D() {
color = Color(1, 1, 1);
rect_cache_dirty = true;
internal_vertices = 0;
- current_skeleton_id = 0;
+
specular_color = Color(1, 1, 1, 1);
shininess = 1.0;
}
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 3252e02e38..fd6e0aebcc 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -78,7 +78,7 @@ bool RayCast2D::is_colliding() const {
}
Object *RayCast2D::get_collider() const {
- if (against == 0)
+ if (against.is_null())
return NULL;
return ObjectDB::get_instance(against);
@@ -225,7 +225,7 @@ void RayCast2D::_update_raycast_state() {
against_shape = rr.shape;
} else {
collided = false;
- against = 0;
+ against = ObjectID();
against_shape = 0;
}
}
@@ -339,7 +339,7 @@ void RayCast2D::_bind_methods() {
RayCast2D::RayCast2D() {
enabled = false;
- against = 0;
+
collided = false;
against_shape = 0;
collision_mask = 1;
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index 53072f942d..ec50f5f922 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -33,7 +33,7 @@
void RemoteTransform2D::_update_cache() {
- cache = 0;
+ cache = ObjectID();
if (has_node(remote_node)) {
Node *node = get_node(remote_node);
if (!node || this == node || node->is_a_parent_of(this) || this->is_a_parent_of(node)) {
@@ -49,7 +49,7 @@ void RemoteTransform2D::_update_remote() {
if (!is_inside_tree())
return;
- if (!cache)
+ if (cache.is_null())
return;
Node2D *n = Object::cast_to<Node2D>(ObjectDB::get_instance(cache));
@@ -119,7 +119,7 @@ void RemoteTransform2D::_notification(int p_what) {
if (!is_inside_tree())
break;
- if (cache) {
+ if (cache.is_valid()) {
_update_remote();
}
@@ -225,6 +225,5 @@ RemoteTransform2D::RemoteTransform2D() {
update_remote_rotation = true;
update_remote_scale = true;
- cache = 0;
set_notify_transform(true);
}
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 67f57a1aa3..62908e2b0f 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -147,7 +147,7 @@ void Area::_body_exit_tree(ObjectID p_id) {
}
}
-void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) {
+void Area::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) {
bool body_in = p_status == PhysicsServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -340,7 +340,7 @@ void Area::_area_exit_tree(ObjectID p_id) {
}
}
-void Area::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) {
+void Area::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) {
bool area_in = p_status == PhysicsServer::AREA_BODY_ADDED;
ObjectID objid = p_instance;
diff --git a/scene/3d/area.h b/scene/3d/area.h
index ca66f41f60..7fe61430fa 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -62,7 +62,7 @@ private:
bool monitorable;
bool locked;
- void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape);
+ void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape);
void _body_enter_tree(ObjectID p_id);
void _body_exit_tree(ObjectID p_id);
@@ -94,7 +94,7 @@ private:
Map<ObjectID, BodyState> body_map;
- void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape);
+ void _area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape);
void _area_enter_tree(ObjectID p_id);
void _area_exit_tree(ObjectID p_id);
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index fbfd372272..5d5cb4dfce 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1493,7 +1493,7 @@ Object *KinematicCollision::get_local_shape() const {
Object *KinematicCollision::get_collider() const {
- if (collision.collider) {
+ if (collision.collider.is_valid()) {
return ObjectDB::get_instance(collision.collider);
}
@@ -1557,7 +1557,7 @@ void KinematicCollision::_bind_methods() {
}
KinematicCollision::KinematicCollision() {
- collision.collider = 0;
+
collision.collider_shape = 0;
collision.local_shape = 0;
owner = NULL;
diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp
index 0c976b9fb1..be1426f13c 100644
--- a/scene/3d/ray_cast.cpp
+++ b/scene/3d/ray_cast.cpp
@@ -80,7 +80,7 @@ bool RayCast::is_colliding() const {
}
Object *RayCast::get_collider() const {
- if (against == 0)
+ if (against.is_null())
return NULL;
return ObjectDB::get_instance(against);
@@ -219,7 +219,7 @@ void RayCast::_update_raycast_state() {
against_shape = rr.shape;
} else {
collided = false;
- against = 0;
+ against = ObjectID();
against_shape = 0;
}
}
@@ -393,7 +393,7 @@ void RayCast::_clear_debug_shape() {
RayCast::RayCast() {
enabled = false;
- against = 0;
+
collided = false;
against_shape = 0;
collision_mask = 1;
diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp
index 983af7a9ec..9ef43647ba 100644
--- a/scene/3d/remote_transform.cpp
+++ b/scene/3d/remote_transform.cpp
@@ -31,7 +31,7 @@
#include "remote_transform.h"
void RemoteTransform::_update_cache() {
- cache = 0;
+ cache = ObjectID();
if (has_node(remote_node)) {
Node *node = get_node(remote_node);
if (!node || this == node || node->is_a_parent_of(this) || this->is_a_parent_of(node)) {
@@ -47,7 +47,7 @@ void RemoteTransform::_update_remote() {
if (!is_inside_tree())
return;
- if (!cache)
+ if (cache.is_null())
return;
Spatial *n = Object::cast_to<Spatial>(ObjectDB::get_instance(cache));
@@ -114,7 +114,7 @@ void RemoteTransform::_notification(int p_what) {
if (!is_inside_tree())
break;
- if (cache) {
+ if (cache.is_valid()) {
_update_remote();
}
@@ -219,6 +219,5 @@ RemoteTransform::RemoteTransform() {
update_remote_rotation = true;
update_remote_scale = true;
- cache = 0;
set_notify_transform(true);
}
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index 3e4cd54664..aa5c439f8a 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -138,7 +138,7 @@ bool Skeleton::_get(const StringName &p_path, Variant &r_ret) const {
else if (what == "bound_children") {
Array children;
- for (const List<uint32_t>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) {
+ for (const List<ObjectID>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
@@ -302,7 +302,7 @@ void Skeleton::_notification(int p_what) {
b.global_pose_override_amount = 0.0;
}
- for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
+ for (List<ObjectID>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
@@ -505,9 +505,9 @@ void Skeleton::bind_child_node_to_bone(int p_bone, Node *p_node) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX(p_bone, bones.size());
- uint32_t id = p_node->get_instance_id();
+ ObjectID id = p_node->get_instance_id();
- for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
+ for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
if (E->get() == id)
return; // already here
@@ -520,14 +520,14 @@ void Skeleton::unbind_child_node_from_bone(int p_bone, Node *p_node) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX(p_bone, bones.size());
- uint32_t id = p_node->get_instance_id();
+ ObjectID id = p_node->get_instance_id();
bones.write[p_bone].nodes_bound.erase(id);
}
void Skeleton::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const {
ERR_FAIL_INDEX(p_bone, bones.size());
- for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
+ for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h
index 9599510850..b42c2112e3 100644
--- a/scene/3d/skeleton.h
+++ b/scene/3d/skeleton.h
@@ -99,7 +99,7 @@ private:
PhysicalBone *cache_parent_physical_bone;
#endif // _3D_DISABLED
- List<uint32_t> nodes_bound;
+ List<ObjectID> nodes_bound;
Bone() {
parent = -1;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 7ec7037dd7..740dad9a1a 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -249,7 +249,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path);
ERR_CONTINUE_MSG(!child, "On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'."); // couldn't find the child node
- uint32_t id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
+ ObjectID id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
int bone_idx = -1;
if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton>(child)) {
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 06f762e63e..48829b02b9 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -159,17 +159,15 @@ private:
struct TrackNodeCacheKey {
- uint32_t id;
+ ObjectID id;
int bone_idx;
inline bool operator<(const TrackNodeCacheKey &p_right) const {
- if (id < p_right.id)
- return true;
- else if (id > p_right.id)
- return false;
- else
+ if (id == p_right.id)
return bone_idx < p_right.bone_idx;
+ else
+ return id < p_right.id;
}
};
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index c28f8dc824..a08cc0927b 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -767,7 +767,7 @@ void AnimationTree::_process_graph(float p_delta) {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
- ObjectID current_animation_player = 0;
+ ObjectID current_animation_player;
if (player) {
current_animation_player = player->get_instance_id();
@@ -775,7 +775,7 @@ void AnimationTree::_process_graph(float p_delta) {
if (last_animation_player != current_animation_player) {
- if (last_animation_player) {
+ if (last_animation_player.is_valid()) {
Object *old_player = ObjectDB::get_instance(last_animation_player);
if (old_player) {
old_player->disconnect("caches_cleared", this, "_clear_caches");
@@ -1296,7 +1296,7 @@ void AnimationTree::_notification(int p_what) {
if (p_what == NOTIFICATION_EXIT_TREE) {
_clear_caches();
- if (last_animation_player) {
+ if (last_animation_player.is_valid()) {
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
@@ -1304,7 +1304,7 @@ void AnimationTree::_notification(int p_what) {
}
}
} else if (p_what == NOTIFICATION_ENTER_TREE) {
- if (last_animation_player) {
+ if (last_animation_player.is_valid()) {
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
@@ -1584,7 +1584,6 @@ AnimationTree::AnimationTree() {
process_pass = 1;
started = true;
properties_dirty = true;
- last_animation_player = 0;
}
AnimationTree::~AnimationTree() {
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 0a8dc8109f..8769e2c61d 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -187,7 +187,6 @@ private:
setup_pass = 0;
process_pass = 0;
object = NULL;
- object_id = 0;
}
virtual ~TrackCache() {}
};
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index be211504a6..b7bc2f9c9e 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -705,12 +705,12 @@ void Control::set_drag_forwarding(Control *p_target) {
if (p_target)
data.drag_owner = p_target->get_instance_id();
else
- data.drag_owner = 0;
+ data.drag_owner = ObjectID();
}
Variant Control::get_drag_data(const Point2 &p_point) {
- if (data.drag_owner) {
+ if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
Control *c = Object::cast_to<Control>(obj);
@@ -732,7 +732,7 @@ Variant Control::get_drag_data(const Point2 &p_point) {
bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
- if (data.drag_owner) {
+ if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
Control *c = Object::cast_to<Control>(obj);
@@ -753,7 +753,7 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const
}
void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
- if (data.drag_owner) {
+ if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
Control *c = Object::cast_to<Control>(obj);
@@ -2224,7 +2224,7 @@ void Control::_modal_stack_remove() {
get_viewport()->_gui_remove_from_modal_stack(element, data.modal_prev_focus_owner);
- data.modal_prev_focus_owner = 0;
+ data.modal_prev_focus_owner = ObjectID();
}
void Control::_propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool p_assign) {
@@ -3110,7 +3110,7 @@ Control::Control() {
data.rotation = 0;
data.parent_canvas_item = NULL;
data.scale = Vector2(1, 1);
- data.drag_owner = 0;
+
data.modal_frame = 0;
data.block_minimum_size_adjust = false;
data.disable_visibility_clip = false;
@@ -3125,7 +3125,6 @@ Control::Control() {
data.margin[i] = 0;
}
data.focus_mode = FOCUS_NONE;
- data.modal_prev_focus_owner = 0;
}
Control::~Control() {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 7bfe060065..08835be9fd 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1399,7 +1399,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
} break;
case TreeItem::CELL_MODE_CUSTOM: {
- if (p_item->cells[i].custom_draw_obj) {
+ if (p_item->cells[i].custom_draw_obj.is_valid()) {
Object *cdo = ObjectDB::get_instance(p_item->cells[i].custom_draw_obj);
if (cdo)
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 2072d0fd13..b58f937c57 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -112,7 +112,7 @@ private:
Cell() {
- custom_draw_obj = 0;
+ custom_draw_obj = ObjectID();
custom_button = false;
mode = TreeItem::CELL_MODE_STRING;
min = 0;
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index 4ae018a79a..04cf5c6338 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -200,7 +200,7 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) {
if (custom_viewport) {
custom_viewport_id = custom_viewport->get_instance_id();
} else {
- custom_viewport_id = 0;
+ custom_viewport_id = ObjectID();
}
if (is_inside_tree()) {
@@ -327,7 +327,7 @@ CanvasLayer::CanvasLayer() {
layer = 1;
canvas = VS::get_singleton()->canvas_create();
custom_viewport = NULL;
- custom_viewport_id = 0;
+
sort_index = 0;
follow_viewport = false;
follow_viewport_scale = 1.0;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 761fe3f90f..6a7971ddb3 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -30,6 +30,8 @@
#include "node.h"
+#include <stdint.h>
+
#include "core/core_string_names.h"
#include "core/io/resource_loader.h"
#include "core/message_queue.h"
@@ -498,22 +500,38 @@ bool Node::is_network_master() const {
/***** RPC CONFIG ********/
-void Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) {
+uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) {
- if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) {
- data.rpc_methods.erase(p_method);
+ uint16_t mid = get_node_rpc_method_id(p_method);
+ if (mid == UINT16_MAX) {
+ // It's new
+ NetData nd;
+ nd.name = p_method;
+ nd.mode = p_mode;
+ data.rpc_methods.push_back(nd);
+ return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15);
} else {
- data.rpc_methods[p_method] = p_mode;
- };
+ int c_mid = (~(1 << 15)) & mid;
+ data.rpc_methods.write[c_mid].mode = p_mode;
+ return mid;
+ }
}
-void Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) {
+uint16_t Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) {
- if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) {
- data.rpc_properties.erase(p_property);
+ uint16_t pid = get_node_rset_property_id(p_property);
+ if (pid == UINT16_MAX) {
+ // It's new
+ NetData nd;
+ nd.name = p_property;
+ nd.mode = p_mode;
+ data.rpc_properties.push_back(nd);
+ return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15);
} else {
- data.rpc_properties[p_property] = p_mode;
- };
+ int c_pid = (~(1 << 15)) & pid;
+ data.rpc_properties.write[c_pid].mode = p_mode;
+ return pid;
+ }
}
/***** RPC FUNCTIONS ********/
@@ -731,12 +749,94 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
multiplayer = p_multiplayer;
}
-const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) {
- return data.rpc_methods.find(p_method);
+uint16_t Node::get_node_rpc_method_id(const StringName &p_method) const {
+ for (int i = 0; i < data.rpc_methods.size(); i++) {
+ if (data.rpc_methods[i].name == p_method) {
+ // Returns `i` with the high bit set to 1 so we know that this id comes
+ // from the node and not the script.
+ return i | (1 << 15);
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName Node::get_node_rpc_method(const uint16_t p_rpc_method_id) const {
+ // Make sure this is a node generated ID.
+ if (((1 << 15) & p_rpc_method_id) > 0) {
+ int mid = (~(1 << 15)) & p_rpc_method_id;
+ if (mid < data.rpc_methods.size())
+ return data.rpc_methods[mid].name;
+ }
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
+ // Make sure this is a node generated ID.
+ if (((1 << 15) & p_rpc_method_id) > 0) {
+ int mid = (~(1 << 15)) & p_rpc_method_id;
+ if (mid < data.rpc_methods.size())
+ return data.rpc_methods[mid].mode;
+ }
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rpc_mode(const StringName &p_method) const {
+ return get_node_rpc_mode_by_id(get_node_rpc_method_id(p_method));
}
-const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) {
- return data.rpc_properties.find(p_property);
+uint16_t Node::get_node_rset_property_id(const StringName &p_property) const {
+ for (int i = 0; i < data.rpc_properties.size(); i++) {
+ if (data.rpc_properties[i].name == p_property) {
+ // Returns `i` with the high bit set to 1 so we know that this id comes
+ // from the node and not the script.
+ return i | (1 << 15);
+ }
+ }
+ return UINT16_MAX;
+}
+
+StringName Node::get_node_rset_property(const uint16_t p_rset_property_id) const {
+ // Make sure this is a node generated ID.
+ if (((1 << 15) & p_rset_property_id) > 0) {
+ int mid = (~(1 << 15)) & p_rset_property_id;
+ if (mid < data.rpc_properties.size())
+ return data.rpc_properties[mid].name;
+ }
+ return StringName();
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rset_mode_by_id(const uint16_t p_rset_property_id) const {
+ if (((1 << 15) & p_rset_property_id) > 0) {
+ int mid = (~(1 << 15)) & p_rset_property_id;
+ if (mid < data.rpc_properties.size())
+ return data.rpc_properties[mid].mode;
+ }
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+}
+
+MultiplayerAPI::RPCMode Node::get_node_rset_mode(const StringName &p_property) const {
+ return get_node_rset_mode_by_id(get_node_rset_property_id(p_property));
+}
+
+String Node::get_rpc_md5() const {
+ String rpc_list;
+ for (int i = 0; i < data.rpc_methods.size(); i += 1) {
+ rpc_list += String(data.rpc_methods[i].name);
+ }
+ for (int i = 0; i < data.rpc_properties.size(); i += 1) {
+ rpc_list += String(data.rpc_properties[i].name);
+ }
+ if (get_script_instance()) {
+ Vector<ScriptNetData> rpc = get_script_instance()->get_rpc_methods();
+ for (int i = 0; i < rpc.size(); i += 1) {
+ rpc_list += String(rpc[i].name);
+ }
+ rpc = get_script_instance()->get_rset_properties();
+ for (int i = 0; i < rpc.size(); i += 1) {
+ rpc_list += String(rpc[i].name);
+ }
+ }
+ return rpc_list.md5_text();
}
bool Node::can_process_notification(int p_what) const {
diff --git a/scene/main/node.h b/scene/main/node.h
index 6f5544d654..02c828e8ff 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -85,6 +85,11 @@ private:
GroupData() { persistent = false; }
};
+ struct NetData {
+ StringName name;
+ MultiplayerAPI::RPCMode mode;
+ };
+
struct Data {
String filename;
@@ -118,8 +123,8 @@ private:
Node *pause_owner;
int network_master;
- Map<StringName, MultiplayerAPI::RPCMode> rpc_methods;
- Map<StringName, MultiplayerAPI::RPCMode> rpc_properties;
+ Vector<NetData> rpc_methods;
+ Vector<NetData> rpc_properties;
// variables used to properly sort the node when processing, ignored otherwise
//should move all the stuff below to bits
@@ -427,8 +432,8 @@ public:
int get_network_master() const;
bool is_network_master() const;
- void rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC
- void rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC
+ uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC
+ uint16_t rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC
void rpc(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
void rpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode
@@ -446,8 +451,22 @@ public:
Ref<MultiplayerAPI> get_multiplayer() const;
Ref<MultiplayerAPI> get_custom_multiplayer() const;
void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rpc_mode(const StringName &p_method);
- const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rset_mode(const StringName &p_property);
+
+ /// Returns the rpc method ID, otherwise UINT32_MAX
+ uint16_t get_node_rpc_method_id(const StringName &p_method) const;
+ StringName get_node_rpc_method(const uint16_t p_rpc_method_id) const;
+ MultiplayerAPI::RPCMode get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const;
+ MultiplayerAPI::RPCMode get_node_rpc_mode(const StringName &p_method) const;
+
+ /// Returns the rpc property ID, otherwise UINT32_MAX
+ uint16_t get_node_rset_property_id(const StringName &p_property) const;
+ StringName get_node_rset_property(const uint16_t p_rset_property_id) const;
+ MultiplayerAPI::RPCMode get_node_rset_mode_by_id(const uint16_t p_rpc_method_id) const;
+ MultiplayerAPI::RPCMode get_node_rset_mode(const StringName &p_property) const;
+
+ /// Can be used to check if the rpc methods and the rset properties are the
+ /// same across the peers.
+ String get_rpc_md5() const;
Node();
~Node();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index dad2ec4010..748a713110 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -412,7 +412,7 @@ void Viewport::_notification(int p_what) {
#ifndef _3D_DISABLED
Vector2 last_pos(1e20, 1e20);
CollisionObject *last_object = NULL;
- ObjectID last_id = 0;
+ ObjectID last_id;
#endif
PhysicsDirectSpaceState::RayResult result;
Physics2DDirectSpaceState *ss2d = Physics2DServer::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
@@ -532,7 +532,7 @@ void Viewport::_notification(int p_what) {
} else {
// This Viewport's builtin canvas
canvas_transform = get_canvas_transform();
- canvas_layer_id = 0;
+ canvas_layer_id = ObjectID();
}
Vector2 point = canvas_transform.affine_inverse().xform(pos);
@@ -540,7 +540,7 @@ void Viewport::_notification(int p_what) {
int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true);
for (int i = 0; i < rc; i++) {
- if (res[i].collider_id && res[i].collider) {
+ if (res[i].collider_id.is_valid() && res[i].collider) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
if (co) {
bool send_event = true;
@@ -594,18 +594,18 @@ void Viewport::_notification(int p_what) {
#ifndef _3D_DISABLED
bool captured = false;
- if (physics_object_capture != 0) {
+ if (physics_object_capture.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_capture));
if (co && camera) {
_collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0);
captured = true;
if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
- physics_object_capture = 0;
+ physics_object_capture = ObjectID();
}
} else {
- physics_object_capture = 0;
+ physics_object_capture = ObjectID();
}
}
@@ -613,7 +613,7 @@ void Viewport::_notification(int p_what) {
//none
} else if (pos == last_pos) {
- if (last_id) {
+ if (last_id.is_valid()) {
if (ObjectDB::get_instance(last_id) && last_object) {
//good, exists
_collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape);
@@ -633,7 +633,7 @@ void Viewport::_notification(int p_what) {
if (space) {
bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true);
- ObjectID new_collider = 0;
+ ObjectID new_collider;
if (col) {
CollisionObject *co = Object::cast_to<CollisionObject>(result.collider);
@@ -651,7 +651,7 @@ void Viewport::_notification(int p_what) {
if (is_mouse && new_collider != physics_object_over) {
- if (physics_object_over) {
+ if (physics_object_over.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over));
if (co) {
@@ -659,7 +659,7 @@ void Viewport::_notification(int p_what) {
}
}
- if (new_collider) {
+ if (new_collider.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(new_collider));
if (co) {
@@ -2504,7 +2504,7 @@ void Viewport::_gui_remove_from_modal_stack(List<Control *>::Element *MI, Object
gui.modal_stack.erase(MI);
- if (p_prev_focus_owner) {
+ if (p_prev_focus_owner.is_valid()) {
// for previous window in stack, pass the focus so it feels more
// natural
@@ -2701,14 +2701,15 @@ void Viewport::_drop_physics_mouseover() {
}
#ifndef _3D_DISABLED
- if (physics_object_over) {
+ if (physics_object_over.is_valid()) {
CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over));
if (co) {
co->_mouse_exit();
}
}
- physics_object_over = physics_object_capture = 0;
+ physics_object_over = ObjectID();
+ physics_object_capture = ObjectID();
#endif
}
@@ -2718,7 +2719,7 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) {
if (gui.key_focus)
p_control->_modal_set_prev_focus_owner(gui.key_focus->get_instance_id());
else
- p_control->_modal_set_prev_focus_owner(0);
+ p_control->_modal_set_prev_focus_owner(ObjectID());
if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus) && !gui.mouse_click_grabber) {
@@ -3334,8 +3335,6 @@ Viewport::Viewport() {
update_mode = UPDATE_WHEN_VISIBLE;
physics_object_picking = false;
- physics_object_capture = 0;
- physics_object_over = 0;
physics_has_last_mousepos = false;
physics_last_mousepos = Vector2(Math_INF, Math_INF);
@@ -3385,7 +3384,6 @@ Viewport::Viewport() {
physics_last_mouse_state.mouse_mask = 0;
local_input_handled = false;
handle_input_locally = true;
- physics_last_id = 0; //ensures first time there will be a check
default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp
index 398849edb8..1016afcaba 100644
--- a/servers/physics/area_sw.cpp
+++ b/servers/physics/area_sw.cpp
@@ -175,7 +175,7 @@ void AreaSW::set_monitorable(bool p_monitorable) {
void AreaSW::call_queries() {
- if (monitor_callback_id && !monitored_bodies.empty()) {
+ if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) {
Variant res[5];
Variant *resptr[5];
@@ -185,7 +185,7 @@ void AreaSW::call_queries() {
Object *obj = ObjectDB::get_instance(monitor_callback_id);
if (!obj) {
monitored_bodies.clear();
- monitor_callback_id = 0;
+ monitor_callback_id = ObjectID();
return;
}
@@ -207,7 +207,7 @@ void AreaSW::call_queries() {
monitored_bodies.clear();
- if (area_monitor_callback_id && !monitored_areas.empty()) {
+ if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
Variant res[5];
Variant *resptr[5];
@@ -217,7 +217,7 @@ void AreaSW::call_queries() {
Object *obj = ObjectDB::get_instance(area_monitor_callback_id);
if (!obj) {
monitored_areas.clear();
- area_monitor_callback_id = 0;
+ area_monitor_callback_id = ObjectID();
return;
}
@@ -257,8 +257,6 @@ AreaSW::AreaSW() :
linear_damp = 0.1;
priority = 0;
set_ray_pickable(false);
- monitor_callback_id = 0;
- area_monitor_callback_id = 0;
monitorable = false;
}
diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h
index 846243a133..4da2b00d20 100644
--- a/servers/physics/area_sw.h
+++ b/servers/physics/area_sw.h
@@ -111,10 +111,10 @@ public:
//_FORCE_INLINE_ SpaceSW* get_owner() { return owner; }
void set_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id; }
+ _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id.is_valid(); }
void set_area_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id; }
+ _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); }
_FORCE_INLINE_ void add_body_to_query(BodySW *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
_FORCE_INLINE_ void remove_body_from_query(BodySW *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 64e07e1155..b71c9772df 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -709,7 +709,7 @@ void BodySW::call_queries() {
Object *obj = ObjectDB::get_instance(fi_callback->id);
if (!obj) {
- set_force_integration_callback(0, StringName());
+ set_force_integration_callback(ObjectID(), StringName());
} else {
const Variant *vp[2] = { &v, &fi_callback->udata };
@@ -749,7 +749,7 @@ void BodySW::set_force_integration_callback(ObjectID p_id, const StringName &p_m
fi_callback = NULL;
}
- if (p_id != 0) {
+ if (p_id.is_valid()) {
fi_callback = memnew(ForceIntegrationCallback);
fi_callback->id = p_id;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index ee4dd0b310..d712b09878 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -451,7 +451,7 @@ public:
return body->contacts[p_contact_idx].collider_pos;
}
virtual ObjectID get_contact_collider_id(int p_contact_idx) const {
- ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, 0);
+ ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, ObjectID());
return body->contacts[p_contact_idx].collider_instance_id;
}
virtual int get_contact_collider_shape(int p_contact_idx) const {
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index cdae26078c..3cabf75ab6 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -232,7 +232,7 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) :
_static = true;
type = p_type;
space = NULL;
- instance_id = 0;
+
collision_layer = 1;
collision_mask = 1;
ray_pickable = true;
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index cd6fc6c0a5..6024e9ab7f 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -374,7 +374,7 @@ ObjectID PhysicsServerSW::area_get_object_instance_id(RID p_area) const {
p_area = space->get_default_area()->get_self();
}
AreaSW *area = area_owner.getornull(p_area);
- ERR_FAIL_COND_V(!area, 0);
+ ERR_FAIL_COND_V(!area, ObjectID());
return area->get_instance_id();
}
@@ -446,7 +446,7 @@ void PhysicsServerSW::area_set_monitor_callback(RID p_area, Object *p_receiver,
AreaSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
void PhysicsServerSW::area_set_ray_pickable(RID p_area, bool p_enable) {
@@ -470,7 +470,7 @@ void PhysicsServerSW::area_set_area_monitor_callback(RID p_area, Object *p_recei
AreaSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
/* BODY API */
@@ -665,7 +665,7 @@ uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body) const {
return body->get_collision_mask();
}
-void PhysicsServerSW::body_attach_object_instance_id(RID p_body, uint32_t p_id) {
+void PhysicsServerSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) {
BodySW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -673,10 +673,10 @@ void PhysicsServerSW::body_attach_object_instance_id(RID p_body, uint32_t p_id)
body->set_instance_id(p_id);
};
-uint32_t PhysicsServerSW::body_get_object_instance_id(RID p_body) const {
+ObjectID PhysicsServerSW::body_get_object_instance_id(RID p_body) const {
BodySW *body = body_owner.getornull(p_body);
- ERR_FAIL_COND_V(!body, 0);
+ ERR_FAIL_COND_V(!body, ObjectID());
return body->get_instance_id();
};
@@ -934,7 +934,7 @@ void PhysicsServerSW::body_set_force_integration_callback(RID p_body, Object *p_
BodySW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata);
+ body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata);
}
void PhysicsServerSW::body_set_ray_pickable(RID p_body, bool p_enable) {
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 37ebfb09c0..459c7688f0 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -177,8 +177,8 @@ public:
virtual void body_remove_shape(RID p_body, int p_shape_idx);
virtual void body_clear_shapes(RID p_body);
- virtual void body_attach_object_instance_id(RID p_body, uint32_t p_id);
- virtual uint32_t body_get_object_instance_id(RID p_body) const;
+ virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id);
+ virtual ObjectID body_get_object_instance_id(RID p_body) const;
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable);
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const;
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index 49e1a57879..03dca8b9ec 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -80,7 +80,7 @@ int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResu
continue;
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id != 0)
+ if (r_results[cc].collider_id.is_valid())
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
else
r_results[cc].collider = NULL;
@@ -159,7 +159,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto
return false;
r_result.collider_id = res_obj->get_instance_id();
- if (r_result.collider_id != 0)
+ if (r_result.collider_id.is_valid())
r_result.collider = ObjectDB::get_instance(r_result.collider_id);
else
r_result.collider = NULL;
@@ -208,7 +208,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo
if (r_results) {
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id != 0)
+ if (r_results[cc].collider_id.is_valid())
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
else
r_results[cc].collider = NULL;
@@ -705,7 +705,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
//but is it right? who knows at this point..
if (r_result) {
- r_result->collider_id = 0;
+ r_result->collider_id = ObjectID();
r_result->collider_shape = 0;
}
AABB body_aabb;
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index 6f09041af8..c67d870b2a 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -175,7 +175,7 @@ void Area2DSW::set_monitorable(bool p_monitorable) {
void Area2DSW::call_queries() {
- if (monitor_callback_id && !monitored_bodies.empty()) {
+ if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) {
Variant res[5];
Variant *resptr[5];
@@ -185,7 +185,7 @@ void Area2DSW::call_queries() {
Object *obj = ObjectDB::get_instance(monitor_callback_id);
if (!obj) {
monitored_bodies.clear();
- monitor_callback_id = 0;
+ monitor_callback_id = ObjectID();
return;
}
@@ -207,7 +207,7 @@ void Area2DSW::call_queries() {
monitored_bodies.clear();
- if (area_monitor_callback_id && !monitored_areas.empty()) {
+ if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
Variant res[5];
Variant *resptr[5];
@@ -217,7 +217,7 @@ void Area2DSW::call_queries() {
Object *obj = ObjectDB::get_instance(area_monitor_callback_id);
if (!obj) {
monitored_areas.clear();
- area_monitor_callback_id = 0;
+ area_monitor_callback_id = ObjectID();
return;
}
@@ -258,8 +258,6 @@ Area2DSW::Area2DSW() :
angular_damp = 1.0;
linear_damp = 0.1;
priority = 0;
- monitor_callback_id = 0;
- area_monitor_callback_id = 0;
monitorable = false;
}
diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h
index 31bc0f6f23..54ffd9763d 100644
--- a/servers/physics_2d/area_2d_sw.h
+++ b/servers/physics_2d/area_2d_sw.h
@@ -110,10 +110,10 @@ public:
//_FORCE_INLINE_ SpaceSW* get_owner() { return owner; }
void set_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id; }
+ _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id.is_valid(); }
void set_area_monitor_callback(ObjectID p_id, const StringName &p_method);
- _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id; }
+ _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); }
_FORCE_INLINE_ void add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
_FORCE_INLINE_ void remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape);
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index b973fa75a9..4de52cacbd 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -610,7 +610,7 @@ void Body2DSW::call_queries() {
Object *obj = ObjectDB::get_instance(fi_callback->id);
if (!obj) {
- set_force_integration_callback(0, StringName());
+ set_force_integration_callback(ObjectID(), StringName());
} else {
Variant::CallError ce;
if (fi_callback->callback_udata.get_type() != Variant::NIL) {
@@ -653,7 +653,7 @@ void Body2DSW::set_force_integration_callback(ObjectID p_id, const StringName &p
fi_callback = NULL;
}
- if (p_id != 0) {
+ if (p_id.is_valid()) {
fi_callback = memnew(ForceIntegrationCallback);
fi_callback->id = p_id;
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 06cc447526..ea07b8260c 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -400,7 +400,7 @@ public:
return body->contacts[p_contact_idx].collider_pos;
}
virtual ObjectID get_contact_collider_id(int p_contact_idx) const {
- ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, 0);
+ ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, ObjectID());
return body->contacts[p_contact_idx].collider_instance_id;
}
virtual int get_contact_collider_shape(int p_contact_idx) const {
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 85f7b8467a..8fb3296be6 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -267,8 +267,6 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) :
_static = true;
type = p_type;
space = NULL;
- instance_id = 0;
- canvas_instance_id = 0;
collision_mask = 1;
collision_layer = 1;
pickable = true;
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 65873d9612..aa374aa6bc 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -470,7 +470,7 @@ ObjectID Physics2DServerSW::area_get_object_instance_id(RID p_area) const {
p_area = space->get_default_area()->get_self();
}
Area2DSW *area = area_owner.getornull(p_area);
- ERR_FAIL_COND_V(!area, 0);
+ ERR_FAIL_COND_V(!area, ObjectID());
return area->get_instance_id();
}
@@ -491,7 +491,7 @@ ObjectID Physics2DServerSW::area_get_canvas_instance_id(RID p_area) const {
p_area = space->get_default_area()->get_self();
}
Area2DSW *area = area_owner.getornull(p_area);
- ERR_FAIL_COND_V(!area, 0);
+ ERR_FAIL_COND_V(!area, ObjectID());
return area->get_canvas_instance_id();
}
@@ -570,7 +570,7 @@ void Physics2DServerSW::area_set_monitor_callback(RID p_area, Object *p_receiver
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
void Physics2DServerSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
@@ -578,7 +578,7 @@ void Physics2DServerSW::area_set_area_monitor_callback(RID p_area, Object *p_rec
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
+ area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method);
}
/* BODY API */
@@ -756,7 +756,7 @@ Physics2DServerSW::CCDMode Physics2DServerSW::body_get_continuous_collision_dete
return body->get_continuous_collision_detection_mode();
}
-void Physics2DServerSW::body_attach_object_instance_id(RID p_body, uint32_t p_id) {
+void Physics2DServerSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -764,15 +764,15 @@ void Physics2DServerSW::body_attach_object_instance_id(RID p_body, uint32_t p_id
body->set_instance_id(p_id);
};
-uint32_t Physics2DServerSW::body_get_object_instance_id(RID p_body) const {
+ObjectID Physics2DServerSW::body_get_object_instance_id(RID p_body) const {
Body2DSW *body = body_owner.getornull(p_body);
- ERR_FAIL_COND_V(!body, 0);
+ ERR_FAIL_COND_V(!body, ObjectID());
return body->get_instance_id();
};
-void Physics2DServerSW::body_attach_canvas_instance_id(RID p_body, uint32_t p_id) {
+void Physics2DServerSW::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -780,10 +780,10 @@ void Physics2DServerSW::body_attach_canvas_instance_id(RID p_body, uint32_t p_id
body->set_canvas_instance_id(p_id);
};
-uint32_t Physics2DServerSW::body_get_canvas_instance_id(RID p_body) const {
+ObjectID Physics2DServerSW::body_get_canvas_instance_id(RID p_body) const {
Body2DSW *body = body_owner.getornull(p_body);
- ERR_FAIL_COND_V(!body, 0);
+ ERR_FAIL_COND_V(!body, ObjectID());
return body->get_canvas_instance_id();
};
@@ -1025,7 +1025,7 @@ void Physics2DServerSW::body_set_force_integration_callback(RID p_body, Object *
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata);
+ body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata);
}
bool Physics2DServerSW::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) {
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index 6a636bb72a..a95a2ea0dd 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -195,11 +195,11 @@ public:
virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled);
virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin);
- virtual void body_attach_object_instance_id(RID p_body, uint32_t p_id);
- virtual uint32_t body_get_object_instance_id(RID p_body) const;
+ virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id);
+ virtual ObjectID body_get_object_instance_id(RID p_body) const;
- virtual void body_attach_canvas_instance_id(RID p_body, uint32_t p_id);
- virtual uint32_t body_get_canvas_instance_id(RID p_body) const;
+ virtual void body_attach_canvas_instance_id(RID p_body, ObjectID p_id);
+ virtual ObjectID body_get_canvas_instance_id(RID p_body) const;
virtual void body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode);
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const;
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index 6bd0a09de5..9a01344390 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -199,11 +199,11 @@ public:
FUNC2(body_remove_shape, RID, int);
FUNC1(body_clear_shapes, RID);
- FUNC2(body_attach_object_instance_id, RID, uint32_t);
- FUNC1RC(uint32_t, body_get_object_instance_id, RID);
+ FUNC2(body_attach_object_instance_id, RID, ObjectID);
+ FUNC1RC(ObjectID, body_get_object_instance_id, RID);
- FUNC2(body_attach_canvas_instance_id, RID, uint32_t);
- FUNC1RC(uint32_t, body_get_canvas_instance_id, RID);
+ FUNC2(body_attach_canvas_instance_id, RID, ObjectID);
+ FUNC1RC(ObjectID, body_get_canvas_instance_id, RID);
FUNC2(body_set_continuous_collision_detection_mode, RID, CCDMode);
FUNC1RC(CCDMode, body_get_continuous_collision_detection_mode, RID);
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 150fda4322..83bcae4607 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -91,7 +91,7 @@ int Physics2DDirectSpaceStateSW::_intersect_point_impl(const Vector2 &p_point, S
continue;
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id != 0)
+ if (r_results[cc].collider_id.is_valid())
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
r_results[cc].rid = col_obj->get_self();
r_results[cc].shape = shape_idx;
@@ -182,7 +182,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec
return false;
r_result.collider_id = res_obj->get_instance_id();
- if (r_result.collider_id != 0)
+ if (r_result.collider_id.is_valid())
r_result.collider = ObjectDB::get_instance(r_result.collider_id);
r_result.normal = res_normal;
r_result.metadata = res_obj->get_shape_metadata(res_shape);
@@ -226,7 +226,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans
continue;
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id != 0)
+ if (r_results[cc].collider_id.is_valid())
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
r_results[cc].rid = col_obj->get_self();
r_results[cc].shape = shape_idx;
@@ -697,7 +697,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
//but is it right? who knows at this point..
if (r_result) {
- r_result->collider_id = 0;
+ r_result->collider_id = ObjectID();
r_result->collider_shape = 0;
}
Rect2 body_aabb;
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index ba068e9a37..919c65d849 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -45,7 +45,7 @@ class Physics2DDirectSpaceStateSW : public Physics2DDirectSpaceState {
GDCLASS(Physics2DDirectSpaceStateSW, Physics2DDirectSpaceState);
- int _intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = 0);
+ int _intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = ObjectID());
public:
Space2DSW *space;
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index 71e3bf8ae8..925af52eeb 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -523,7 +523,7 @@ void Physics2DTestMotionResult::_bind_methods() {
Physics2DTestMotionResult::Physics2DTestMotionResult() {
colliding = false;
- result.collider_id = 0;
+
result.collider_shape = 0;
}
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 40c58ecac5..c923ef16b7 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -149,7 +149,7 @@ class Physics2DDirectSpaceState : public Object {
Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
Array _intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
- Array _intersect_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclud, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = 0);
+ Array _intersect_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclud, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = ObjectID());
Array _intersect_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32);
Array _cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query);
Array _collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32);
@@ -404,11 +404,11 @@ public:
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
virtual void body_clear_shapes(RID p_body) = 0;
- virtual void body_attach_object_instance_id(RID p_body, uint32_t p_id) = 0;
- virtual uint32_t body_get_object_instance_id(RID p_body) const = 0;
+ virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) = 0;
+ virtual ObjectID body_get_object_instance_id(RID p_body) const = 0;
- virtual void body_attach_canvas_instance_id(RID p_body, uint32_t p_id) = 0;
- virtual uint32_t body_get_canvas_instance_id(RID p_body) const = 0;
+ virtual void body_attach_canvas_instance_id(RID p_body, ObjectID p_id) = 0;
+ virtual ObjectID body_get_canvas_instance_id(RID p_body) const = 0;
enum CCDMode {
CCD_MODE_DISABLED,
@@ -509,7 +509,7 @@ public:
MotionResult() {
collision_local_shape = 0;
collider_shape = 0;
- collider_id = 0;
+ collider_id = ObjectID();
}
};
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 6a66763b2f..f1388c8758 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -385,8 +385,8 @@ public:
virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) = 0;
- virtual void body_attach_object_instance_id(RID p_body, uint32_t p_id) = 0;
- virtual uint32_t body_get_object_instance_id(RID p_body) const = 0;
+ virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) = 0;
+ virtual ObjectID body_get_object_instance_id(RID p_body) const = 0;
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) = 0;
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const = 0;
@@ -495,7 +495,7 @@ public:
Variant collider_metadata;
MotionResult() {
collision_local_shape = 0;
- collider_id = 0;
+ collider_id = ObjectID();
collider_shape = 0;
}
};
diff --git a/servers/visual/rasterizer_rd/shader_compiler_rd.cpp b/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
index 851deb367f..b2cbac8a09 100644
--- a/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/visual/rasterizer_rd/shader_compiler_rd.cpp
@@ -390,6 +390,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
struct_code += " ";
struct_code += m->name;
+ if (m->array_size > 0) {
+ struct_code += "[";
+ struct_code += itos(m->array_size);
+ struct_code += "]";
+ }
struct_code += ";\n";
}
struct_code += "}";
@@ -701,6 +706,26 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
} break;
+ case SL::Node::TYPE_ARRAY_CONSTRUCT: {
+ SL::ArrayConstructNode *acnode = (SL::ArrayConstructNode *)p_node;
+ int sz = acnode->initializer.size();
+ if (acnode->datatype == SL::TYPE_STRUCT) {
+ code += _mkid(acnode->struct_name);
+ } else {
+ code += _typestr(acnode->datatype);
+ }
+ code += "[";
+ code += itos(acnode->initializer.size());
+ code += "]";
+ code += "(";
+ for (int i = 0; i < sz; i++) {
+ code += _dump_node_code(acnode->initializer[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ if (i != sz - 1) {
+ code += ", ";
+ }
+ }
+ code += ")";
+ } break;
case SL::Node::TYPE_ARRAY_DECLARATION: {
SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node;
@@ -1000,6 +1025,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
case SL::Node::TYPE_MEMBER: {
SL::MemberNode *mnode = (SL::MemberNode *)p_node;
code = _dump_node_code(mnode->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + "." + mnode->name;
+ if (mnode->index_expression != NULL) {
+ code += "[";
+ code += _dump_node_code(mnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += "]";
+ }
} break;
}
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index c2bdc6d7e4..2a0492709c 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -3200,17 +3200,159 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
func->arguments.push_back(funcname);
for (int i = 0; i < pstruct->members.size(); i++) {
- Node *nexpr = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!nexpr) {
- return NULL;
- }
- Node *node = pstruct->members[i];
+ Node *nexpr;
- if (!_compare_datatypes_in_nodes(pstruct->members[i], nexpr)) {
- String type_name = nexpr->get_datatype() == TYPE_STRUCT ? nexpr->get_datatype_name() : get_datatype_name(nexpr->get_datatype());
- String type_name2 = node->get_datatype() == TYPE_STRUCT ? node->get_datatype_name() : get_datatype_name(node->get_datatype());
- _set_error("Invalid assignment of '" + type_name + "' to '" + type_name2 + "'");
- return NULL;
+ if (pstruct->members[i]->array_size != 0) {
+
+ DataType type = pstruct->members[i]->get_datatype();
+ String struct_name = pstruct->members[i]->struct_name;
+ int array_size = pstruct->members[i]->array_size;
+
+ DataType type2;
+ String struct_name2 = "";
+ int array_size2 = 0;
+
+ bool auto_size = false;
+
+ tk = _get_token();
+
+ if (tk.type == TK_CURLY_BRACKET_OPEN) {
+ auto_size = true;
+ } else {
+
+ if (shader->structs.has(tk.text)) {
+ type2 = TYPE_STRUCT;
+ struct_name2 = tk.text;
+ } else {
+ if (!is_token_variable_datatype(tk.type)) {
+ _set_error("Invalid data type for array");
+ return NULL;
+ }
+ type2 = get_token_datatype(tk.type);
+ }
+
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_OPEN) {
+ TkPos pos2 = _get_tkpos();
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ array_size2 = array_size;
+ tk = _get_token();
+ } else {
+ _set_tkpos(pos2);
+
+ Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
+ _set_error("Expected single integer constant > 0");
+ return NULL;
+ }
+
+ ConstantNode *cnode = (ConstantNode *)n;
+ if (cnode->values.size() == 1) {
+ array_size2 = cnode->values[0].sint;
+ if (array_size2 <= 0) {
+ _set_error("Expected single integer constant > 0");
+ return NULL;
+ }
+ } else {
+ _set_error("Expected single integer constant > 0");
+ return NULL;
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']'");
+ return NULL;
+ } else {
+ tk = _get_token();
+ }
+ }
+ } else {
+ _set_error("Expected '['");
+ return NULL;
+ }
+
+ if (type != type2 || struct_name != struct_name2 || array_size != array_size2) {
+ String error_str = "Cannot convert from '";
+ if (type2 == TYPE_STRUCT) {
+ error_str += struct_name2;
+ } else {
+ error_str += get_datatype_name(type2);
+ }
+ error_str += "[";
+ error_str += itos(array_size2);
+ error_str += "]'";
+ error_str += " to '";
+ if (type == TYPE_STRUCT) {
+ error_str += struct_name;
+ } else {
+ error_str += get_datatype_name(type);
+ }
+ error_str += "[";
+ error_str += itos(array_size);
+ error_str += "]'";
+ _set_error(error_str);
+ return NULL;
+ }
+ }
+
+ ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
+ an->datatype = type;
+ an->struct_name = struct_name;
+
+ if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
+ while (true) {
+
+ Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!n) {
+ return NULL;
+ }
+
+ if (type != n->get_datatype() || struct_name != n->get_datatype_name()) {
+ _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'");
+ return NULL;
+ }
+
+ tk = _get_token();
+ if (tk.type == TK_COMMA) {
+ an->initializer.push_back(n);
+ continue;
+ } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
+ an->initializer.push_back(n);
+ break;
+ } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
+ an->initializer.push_back(n);
+ break;
+ } else {
+ if (auto_size)
+ _set_error("Expected '}' or ','");
+ else
+ _set_error("Expected ')' or ','");
+ return NULL;
+ }
+ }
+ if (an->initializer.size() != array_size) {
+ _set_error("Array size mismatch");
+ return NULL;
+ }
+ } else {
+ _set_error("Expected array initialization!");
+ return NULL;
+ }
+
+ nexpr = an;
+ } else {
+ nexpr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!nexpr) {
+ return NULL;
+ }
+ Node *node = pstruct->members[i];
+ if (!_compare_datatypes_in_nodes(pstruct->members[i], nexpr)) {
+ String type_name = nexpr->get_datatype() == TYPE_STRUCT ? nexpr->get_datatype_name() : get_datatype_name(nexpr->get_datatype());
+ String type_name2 = node->get_datatype() == TYPE_STRUCT ? node->get_datatype_name() : get_datatype_name(node->get_datatype());
+ _set_error("Invalid assignment of '" + type_name + "' to '" + type_name2 + "'");
+ return NULL;
+ }
}
if (i + 1 < pstruct->members.size()) {
@@ -3463,7 +3605,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = varname;
}
}
-
} else if (tk.type == TK_OP_ADD) {
continue; //this one does nothing
} else if (tk.type == TK_OP_SUB || tk.type == TK_OP_NOT || tk.type == TK_OP_BIT_INVERT || tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
@@ -3482,7 +3623,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.push_back(e);
continue;
-
} else {
_set_error("Expected expression, found: " + get_token_text(tk));
return NULL;
@@ -3526,6 +3666,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
bool ok = true;
DataType member_type = TYPE_VOID;
StringName member_struct_name = "";
+ int array_size = 0;
switch (dt) {
case TYPE_STRUCT: {
ok = false;
@@ -3535,6 +3676,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
for (List<MemberNode *>::Element *E = n->members.front(); E; E = E->next()) {
if (String(E->get()->name) == member_name) {
member_type = E->get()->datatype;
+ array_size = E->get()->array_size;
if (member_type == TYPE_STRUCT) {
member_struct_name = E->get()->struct_name;
}
@@ -3673,8 +3815,52 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
mn->datatype = member_type;
mn->base_struct_name = st;
mn->struct_name = member_struct_name;
+ mn->array_size = array_size;
mn->name = ident;
mn->owner = expr;
+ if (array_size > 0) {
+
+ tk = _get_token();
+ if (tk.type == TK_PERIOD) {
+ _set_error("Nested array length() is not yet implemented");
+ return NULL;
+ } else if (tk.type == TK_BRACKET_OPEN) {
+
+ Node *index_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!index_expression)
+ return NULL;
+
+ if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) {
+ _set_error("Only integer expressions are allowed for indexing");
+ return NULL;
+ }
+
+ if (index_expression->type == Node::TYPE_CONSTANT) {
+ ConstantNode *cnode = (ConstantNode *)index_expression;
+ if (cnode) {
+ if (!cnode->values.empty()) {
+ int value = cnode->values[0].sint;
+ if (value < 0 || value >= array_size) {
+ _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1));
+ return NULL;
+ }
+ }
+ }
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']'");
+ return NULL;
+ }
+ mn->index_expression = index_expression;
+
+ } else {
+ _set_error("Expected '[' or '.'");
+ return NULL;
+ }
+ }
+
expr = mn;
//todo
@@ -3769,7 +3955,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
break;
default: {
- _set_error("Object of type '" + get_datatype_name(expr->get_datatype()) + "' can't be indexed");
+ _set_error("Object of type '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' can't be indexed");
return NULL;
}
}
@@ -5353,11 +5539,33 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
member->datatype = type;
member->struct_name = struct_name;
member->name = tk.text;
- st_node->members.push_back(member);
tk = _get_token();
+ if (tk.type == TK_BRACKET_OPEN) {
+ tk = _get_token();
+ if (tk.type == TK_INT_CONSTANT && tk.constant > 0) {
+ member->array_size = (int)tk.constant;
+
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_error("Expected ']'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_error("Expected single integer constant > 0");
+ return ERR_PARSE_ERROR;
+ }
+ }
+ st_node->members.push_back(member);
+
if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
+ _set_error("Expected ']' or ';'");
return ERR_PARSE_ERROR;
}
member_count++;
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index 4d474086a6..aac5795e85 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -332,6 +332,7 @@ public:
TYPE_MEMBER,
TYPE_ARRAY,
TYPE_ARRAY_DECLARATION,
+ TYPE_ARRAY_CONSTRUCT,
TYPE_STRUCT,
};
@@ -427,6 +428,17 @@ public:
is_const(false) {}
};
+ struct ArrayConstructNode : public Node {
+ DataType datatype;
+ String struct_name;
+ Vector<Node *> initializer;
+
+ ArrayConstructNode() :
+ Node(TYPE_ARRAY_CONSTRUCT),
+ datatype(TYPE_VOID) {
+ }
+ };
+
struct ArrayDeclarationNode : public Node {
DataPrecision precision;
DataType datatype;
@@ -520,9 +532,11 @@ public:
StringName base_struct_name;
DataPrecision precision;
DataType datatype;
+ int array_size;
StringName struct_name;
StringName name;
Node *owner;
+ Node *index_expression;
virtual DataType get_datatype() const { return datatype; }
virtual String get_datatype_name() const { return String(struct_name); }
@@ -531,7 +545,9 @@ public:
Node(TYPE_MEMBER),
basetype(TYPE_VOID),
datatype(TYPE_VOID),
- owner(NULL) {}
+ array_size(0),
+ owner(NULL),
+ index_expression(NULL) {}
};
struct StructNode : public Node {
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 0df8853f12..61c885cba3 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -805,7 +805,7 @@ Vector<ObjectID> VisualServerScene::instances_cull_aabb(const AABB &p_aabb, RID
Instance *instance = cull[i];
ERR_CONTINUE(!instance);
- if (instance->object_id == 0)
+ if (instance->object_id.is_null())
continue;
instances.push_back(instance->object_id);
@@ -827,7 +827,7 @@ Vector<ObjectID> VisualServerScene::instances_cull_ray(const Vector3 &p_from, co
for (int i = 0; i < culled; i++) {
Instance *instance = cull[i];
ERR_CONTINUE(!instance);
- if (instance->object_id == 0)
+ if (instance->object_id.is_null())
continue;
instances.push_back(instance->object_id);
@@ -851,7 +851,7 @@ Vector<ObjectID> VisualServerScene::instances_cull_convex(const Vector<Plane> &p
Instance *instance = cull[i];
ERR_CONTINUE(!instance);
- if (instance->object_id == 0)
+ if (instance->object_id.is_null())
continue;
instances.push_back(instance->object_id);
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index a811e8b27a..8dbd60d3ff 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -162,7 +162,7 @@ public:
AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better?
float extra_margin;
- uint32_t object_id;
+ ObjectID object_id;
float lod_begin;
float lod_end;
@@ -203,7 +203,6 @@ public:
extra_margin = 0;
- object_id = 0;
visible = true;
lod_begin = 0;