[Net] Allow branch-specific MultiplayerAPIs.
Removes custom_multiplayer from Node. MultiplayerAPI overrides are now set at SceneTree level, and apply to whole branches. Impact on performance when using only the default multiplayer or overriding it is minimal, the use of branches can likely be further optimized by caching nodes and relevant MultiplayerAPI IDs.
This commit is contained in:
+1
-15
@@ -653,21 +653,10 @@ void Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg
|
||||
}
|
||||
|
||||
Ref<MultiplayerAPI> Node::get_multiplayer() const {
|
||||
if (multiplayer.is_valid()) {
|
||||
return multiplayer;
|
||||
}
|
||||
if (!is_inside_tree()) {
|
||||
return Ref<MultiplayerAPI>();
|
||||
}
|
||||
return get_tree()->get_multiplayer();
|
||||
}
|
||||
|
||||
Ref<MultiplayerAPI> Node::get_custom_multiplayer() const {
|
||||
return multiplayer;
|
||||
}
|
||||
|
||||
void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
|
||||
multiplayer = p_multiplayer;
|
||||
return get_tree()->get_multiplayer(get_path());
|
||||
}
|
||||
|
||||
Vector<Multiplayer::RPCConfig> Node::get_node_rpc_methods() const {
|
||||
@@ -2892,8 +2881,6 @@ void Node::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("is_multiplayer_authority"), &Node::is_multiplayer_authority);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer);
|
||||
ClassDB::bind_method(D_METHOD("get_custom_multiplayer"), &Node::get_custom_multiplayer);
|
||||
ClassDB::bind_method(D_METHOD("set_custom_multiplayer", "api"), &Node::set_custom_multiplayer);
|
||||
ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "call_local", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(false), DEFVAL(Multiplayer::TRANSFER_MODE_RELIABLE), DEFVAL(0));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description);
|
||||
@@ -2999,7 +2986,6 @@ void Node::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_file_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_scene_file_path", "get_scene_file_path");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_owner", "get_owner");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "", "get_multiplayer");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "set_custom_multiplayer", "get_custom_multiplayer");
|
||||
|
||||
ADD_GROUP("Process", "process_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,When Paused,Always,Disabled"), "set_process_mode", "get_process_mode");
|
||||
|
||||
@@ -515,8 +515,6 @@ public:
|
||||
void rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount);
|
||||
|
||||
Ref<MultiplayerAPI> get_multiplayer() const;
|
||||
Ref<MultiplayerAPI> get_custom_multiplayer() const;
|
||||
void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
|
||||
|
||||
Node();
|
||||
~Node();
|
||||
|
||||
+51
-12
@@ -438,6 +438,10 @@ bool SceneTree::process(double p_time) {
|
||||
|
||||
if (multiplayer_poll) {
|
||||
multiplayer->poll();
|
||||
const NodePath *rpath = nullptr;
|
||||
while ((rpath = custom_multiplayers.next(rpath))) {
|
||||
custom_multiplayers[*rpath]->poll();
|
||||
}
|
||||
}
|
||||
|
||||
emit_signal(SNAME("process_frame"));
|
||||
@@ -1133,8 +1137,51 @@ Array SceneTree::get_processed_tweens() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ref<MultiplayerAPI> SceneTree::get_multiplayer() const {
|
||||
return multiplayer;
|
||||
Ref<MultiplayerAPI> SceneTree::get_multiplayer(const NodePath &p_for_path) const {
|
||||
Ref<MultiplayerAPI> out = multiplayer;
|
||||
const NodePath *spath = nullptr;
|
||||
while ((spath = custom_multiplayers.next(spath))) {
|
||||
const Vector<StringName> snames = (*spath).get_names();
|
||||
const Vector<StringName> tnames = p_for_path.get_names();
|
||||
if (tnames.size() < snames.size()) {
|
||||
continue;
|
||||
}
|
||||
const StringName *sptr = snames.ptr();
|
||||
const StringName *nptr = tnames.ptr();
|
||||
bool valid = true;
|
||||
for (int i = 0; i < snames.size(); i++) {
|
||||
if (sptr[i] != nptr[i]) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
out = custom_multiplayers[*spath];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer, const NodePath &p_root_path) {
|
||||
if (p_root_path.is_empty()) {
|
||||
ERR_FAIL_COND(!p_multiplayer.is_valid());
|
||||
if (multiplayer.is_valid()) {
|
||||
multiplayer->set_root_path(NodePath());
|
||||
}
|
||||
multiplayer = p_multiplayer;
|
||||
multiplayer->set_root_path("/" + root->get_name());
|
||||
} else {
|
||||
if (p_multiplayer.is_valid()) {
|
||||
custom_multiplayers[p_root_path] = p_multiplayer;
|
||||
p_multiplayer->set_root_path(p_root_path);
|
||||
} else {
|
||||
if (custom_multiplayers.has(p_root_path)) {
|
||||
custom_multiplayers[p_root_path]->set_root_path(NodePath());
|
||||
custom_multiplayers.erase(p_root_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneTree::set_multiplayer_poll_enabled(bool p_enabled) {
|
||||
@@ -1145,13 +1192,6 @@ bool SceneTree::is_multiplayer_poll_enabled() const {
|
||||
return multiplayer_poll;
|
||||
}
|
||||
|
||||
void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
|
||||
ERR_FAIL_COND(!p_multiplayer.is_valid());
|
||||
|
||||
multiplayer = p_multiplayer;
|
||||
multiplayer->set_root_path("/" + root->get_name());
|
||||
}
|
||||
|
||||
void SceneTree::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_root"), &SceneTree::get_root);
|
||||
ClassDB::bind_method(D_METHOD("has_group", "name"), &SceneTree::has_group);
|
||||
@@ -1214,8 +1254,8 @@ void SceneTree::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_change_scene"), &SceneTree::_change_scene);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_multiplayer", "multiplayer"), &SceneTree::set_multiplayer);
|
||||
ClassDB::bind_method(D_METHOD("get_multiplayer"), &SceneTree::get_multiplayer);
|
||||
ClassDB::bind_method(D_METHOD("set_multiplayer", "multiplayer", "root_path"), &SceneTree::set_multiplayer, DEFVAL(NodePath()));
|
||||
ClassDB::bind_method(D_METHOD("get_multiplayer", "for_path"), &SceneTree::get_multiplayer, DEFVAL(NodePath()));
|
||||
ClassDB::bind_method(D_METHOD("set_multiplayer_poll_enabled", "enabled"), &SceneTree::set_multiplayer_poll_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_multiplayer_poll_enabled"), &SceneTree::is_multiplayer_poll_enabled);
|
||||
|
||||
@@ -1225,7 +1265,6 @@ void SceneTree::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "edited_scene_root", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_edited_scene_root", "get_edited_scene_root");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "current_scene", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_current_scene", "get_current_scene");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "root", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "", "get_root");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "set_multiplayer", "get_multiplayer");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multiplayer_poll"), "set_multiplayer_poll_enabled", "is_multiplayer_poll_enabled");
|
||||
|
||||
ADD_SIGNAL(MethodInfo("tree_changed"));
|
||||
|
||||
@@ -159,6 +159,7 @@ private:
|
||||
///network///
|
||||
|
||||
Ref<MultiplayerAPI> multiplayer;
|
||||
HashMap<NodePath, Ref<MultiplayerAPI>> custom_multiplayers;
|
||||
bool multiplayer_poll = true;
|
||||
|
||||
static SceneTree *singleton;
|
||||
@@ -351,10 +352,10 @@ public:
|
||||
|
||||
//network API
|
||||
|
||||
Ref<MultiplayerAPI> get_multiplayer() const;
|
||||
Ref<MultiplayerAPI> get_multiplayer(const NodePath &p_for_path = NodePath()) const;
|
||||
void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer, const NodePath &p_root_path = NodePath());
|
||||
void set_multiplayer_poll_enabled(bool p_enabled);
|
||||
bool is_multiplayer_poll_enabled() const;
|
||||
void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
|
||||
|
||||
static void add_idle_callback(IdleCallback p_callback);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user