You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
[MP] Make replication mode an enum + optimizations
REPLICATION_MODE_ALWAYS (sync) and REPLICATION_MODE_ON_CHANGE (watch) are now mutually exclusive. Prevent invalid NodePath from being added to the config. Optimize the replication config loading by composing the lists on demand.
This commit is contained in:
@@ -47,38 +47,26 @@ bool SceneReplicationConfig::_set(const StringName &p_name, const Variant &p_val
|
||||
add_property(path);
|
||||
return true;
|
||||
}
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false);
|
||||
ERR_FAIL_INDEX_V(idx, properties.size(), false);
|
||||
ReplicationProperty &prop = properties[idx];
|
||||
if (what == "sync") {
|
||||
if ((bool)p_value == prop.sync) {
|
||||
return true;
|
||||
}
|
||||
prop.sync = p_value;
|
||||
if (prop.sync) {
|
||||
sync_props.push_back(prop.name);
|
||||
} else {
|
||||
sync_props.erase(prop.name);
|
||||
}
|
||||
if (what == "replication_mode") {
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
|
||||
ReplicationMode mode = (ReplicationMode)p_value.operator int();
|
||||
ERR_FAIL_COND_V(mode < REPLICATION_MODE_NEVER || mode > REPLICATION_MODE_ON_CHANGE, false);
|
||||
property_set_replication_mode(prop.name, mode);
|
||||
return true;
|
||||
} else if (what == "spawn") {
|
||||
if ((bool)p_value == prop.spawn) {
|
||||
return true;
|
||||
}
|
||||
prop.spawn = p_value;
|
||||
if (prop.spawn) {
|
||||
spawn_props.push_back(prop.name);
|
||||
} else {
|
||||
spawn_props.erase(prop.name);
|
||||
}
|
||||
}
|
||||
ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false);
|
||||
if (what == "spawn") {
|
||||
property_set_spawn(prop.name, p_value);
|
||||
return true;
|
||||
} else if (what == "sync") {
|
||||
// Deprecated.
|
||||
property_set_sync(prop.name, p_value);
|
||||
return true;
|
||||
} else if (what == "watch") {
|
||||
prop.watch = p_value;
|
||||
if (prop.watch) {
|
||||
watch_props.push_back(prop.name);
|
||||
} else {
|
||||
watch_props.erase(prop.name);
|
||||
}
|
||||
// Deprecated.
|
||||
property_set_watch(prop.name, p_value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -96,14 +84,11 @@ bool SceneReplicationConfig::_get(const StringName &p_name, Variant &r_ret) cons
|
||||
if (what == "path") {
|
||||
r_ret = prop.name;
|
||||
return true;
|
||||
} else if (what == "sync") {
|
||||
r_ret = prop.sync;
|
||||
return true;
|
||||
} else if (what == "spawn") {
|
||||
r_ret = prop.spawn;
|
||||
return true;
|
||||
} else if (what == "watch") {
|
||||
r_ret = prop.watch;
|
||||
} else if (what == "replication_mode") {
|
||||
r_ret = prop.mode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -114,8 +99,7 @@ void SceneReplicationConfig::_get_property_list(List<PropertyInfo> *p_list) cons
|
||||
for (int i = 0; i < properties.size(); i++) {
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/spawn", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/sync", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/watch", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "properties/" + itos(i) + "/replication_mode", PROPERTY_HINT_ENUM, "Never,Always,On Change", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,11 +113,11 @@ TypedArray<NodePath> SceneReplicationConfig::get_properties() const {
|
||||
|
||||
void SceneReplicationConfig::add_property(const NodePath &p_path, int p_index) {
|
||||
ERR_FAIL_COND(properties.find(p_path));
|
||||
ERR_FAIL_COND(p_path == NodePath());
|
||||
|
||||
if (p_index < 0 || p_index == properties.size()) {
|
||||
properties.push_back(ReplicationProperty(p_path));
|
||||
sync_props.push_back(p_path);
|
||||
spawn_props.push_back(p_path);
|
||||
dirty = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -146,23 +130,12 @@ void SceneReplicationConfig::add_property(const NodePath &p_path, int p_index) {
|
||||
c++;
|
||||
}
|
||||
properties.insert_before(I, ReplicationProperty(p_path));
|
||||
sync_props.clear();
|
||||
spawn_props.clear();
|
||||
for (const ReplicationProperty &prop : properties) {
|
||||
if (prop.sync) {
|
||||
sync_props.push_back(prop.name);
|
||||
}
|
||||
if (prop.spawn) {
|
||||
spawn_props.push_back(prop.name);
|
||||
}
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void SceneReplicationConfig::remove_property(const NodePath &p_path) {
|
||||
properties.erase(p_path);
|
||||
sync_props.erase(p_path);
|
||||
spawn_props.erase(p_path);
|
||||
watch_props.clear();
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
bool SceneReplicationConfig::has_property(const NodePath &p_path) const {
|
||||
@@ -196,56 +169,99 @@ void SceneReplicationConfig::property_set_spawn(const NodePath &p_path, bool p_e
|
||||
return;
|
||||
}
|
||||
E->get().spawn = p_enabled;
|
||||
spawn_props.clear();
|
||||
for (const ReplicationProperty &prop : properties) {
|
||||
if (prop.spawn) {
|
||||
spawn_props.push_back(prop.name);
|
||||
}
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
bool SceneReplicationConfig::property_get_sync(const NodePath &p_path) {
|
||||
List<ReplicationProperty>::Element *E = properties.find(p_path);
|
||||
ERR_FAIL_COND_V(!E, false);
|
||||
return E->get().sync;
|
||||
return E->get().mode == REPLICATION_MODE_ALWAYS;
|
||||
}
|
||||
|
||||
void SceneReplicationConfig::property_set_sync(const NodePath &p_path, bool p_enabled) {
|
||||
List<ReplicationProperty>::Element *E = properties.find(p_path);
|
||||
ERR_FAIL_COND(!E);
|
||||
if (E->get().sync == p_enabled) {
|
||||
return;
|
||||
}
|
||||
E->get().sync = p_enabled;
|
||||
sync_props.clear();
|
||||
for (const ReplicationProperty &prop : properties) {
|
||||
if (prop.sync) {
|
||||
sync_props.push_back(prop.name);
|
||||
}
|
||||
if (p_enabled) {
|
||||
property_set_replication_mode(p_path, REPLICATION_MODE_ALWAYS);
|
||||
} else if (property_get_replication_mode(p_path) == REPLICATION_MODE_ALWAYS) {
|
||||
property_set_replication_mode(p_path, REPLICATION_MODE_NEVER);
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneReplicationConfig::property_get_watch(const NodePath &p_path) {
|
||||
List<ReplicationProperty>::Element *E = properties.find(p_path);
|
||||
ERR_FAIL_COND_V(!E, false);
|
||||
return E->get().watch;
|
||||
return E->get().mode == REPLICATION_MODE_ON_CHANGE;
|
||||
}
|
||||
|
||||
void SceneReplicationConfig::property_set_watch(const NodePath &p_path, bool p_enabled) {
|
||||
if (p_enabled) {
|
||||
property_set_replication_mode(p_path, REPLICATION_MODE_ON_CHANGE);
|
||||
} else if (property_get_replication_mode(p_path) == REPLICATION_MODE_ON_CHANGE) {
|
||||
property_set_replication_mode(p_path, REPLICATION_MODE_NEVER);
|
||||
}
|
||||
}
|
||||
|
||||
SceneReplicationConfig::ReplicationMode SceneReplicationConfig::property_get_replication_mode(const NodePath &p_path) {
|
||||
List<ReplicationProperty>::Element *E = properties.find(p_path);
|
||||
ERR_FAIL_COND_V(!E, REPLICATION_MODE_NEVER);
|
||||
return E->get().mode;
|
||||
}
|
||||
|
||||
void SceneReplicationConfig::property_set_replication_mode(const NodePath &p_path, ReplicationMode p_mode) {
|
||||
List<ReplicationProperty>::Element *E = properties.find(p_path);
|
||||
ERR_FAIL_COND(!E);
|
||||
if (E->get().watch == p_enabled) {
|
||||
if (E->get().mode == p_mode) {
|
||||
return;
|
||||
}
|
||||
E->get().watch = p_enabled;
|
||||
E->get().mode = p_mode;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void SceneReplicationConfig::_update() {
|
||||
if (!dirty) {
|
||||
return;
|
||||
}
|
||||
dirty = false;
|
||||
sync_props.clear();
|
||||
spawn_props.clear();
|
||||
watch_props.clear();
|
||||
for (const ReplicationProperty &prop : properties) {
|
||||
if (prop.watch) {
|
||||
watch_props.push_back(p_path);
|
||||
if (prop.spawn) {
|
||||
spawn_props.push_back(prop.name);
|
||||
}
|
||||
switch (prop.mode) {
|
||||
case REPLICATION_MODE_ALWAYS:
|
||||
sync_props.push_back(prop.name);
|
||||
break;
|
||||
case REPLICATION_MODE_ON_CHANGE:
|
||||
watch_props.push_back(prop.name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const List<NodePath> &SceneReplicationConfig::get_spawn_properties() {
|
||||
if (dirty) {
|
||||
_update();
|
||||
}
|
||||
return spawn_props;
|
||||
}
|
||||
|
||||
const List<NodePath> &SceneReplicationConfig::get_sync_properties() {
|
||||
if (dirty) {
|
||||
_update();
|
||||
}
|
||||
return sync_props;
|
||||
}
|
||||
|
||||
const List<NodePath> &SceneReplicationConfig::get_watch_properties() {
|
||||
if (dirty) {
|
||||
_update();
|
||||
}
|
||||
return watch_props;
|
||||
}
|
||||
|
||||
void SceneReplicationConfig::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_properties"), &SceneReplicationConfig::get_properties);
|
||||
ClassDB::bind_method(D_METHOD("add_property", "path", "index"), &SceneReplicationConfig::add_property, DEFVAL(-1));
|
||||
@@ -254,6 +270,14 @@ void SceneReplicationConfig::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("property_get_index", "path"), &SceneReplicationConfig::property_get_index);
|
||||
ClassDB::bind_method(D_METHOD("property_get_spawn", "path"), &SceneReplicationConfig::property_get_spawn);
|
||||
ClassDB::bind_method(D_METHOD("property_set_spawn", "path", "enabled"), &SceneReplicationConfig::property_set_spawn);
|
||||
ClassDB::bind_method(D_METHOD("property_get_replication_mode", "path"), &SceneReplicationConfig::property_get_replication_mode);
|
||||
ClassDB::bind_method(D_METHOD("property_set_replication_mode", "path", "mode"), &SceneReplicationConfig::property_set_replication_mode);
|
||||
|
||||
BIND_ENUM_CONSTANT(REPLICATION_MODE_NEVER);
|
||||
BIND_ENUM_CONSTANT(REPLICATION_MODE_ALWAYS);
|
||||
BIND_ENUM_CONSTANT(REPLICATION_MODE_ON_CHANGE);
|
||||
|
||||
// Deprecated.
|
||||
ClassDB::bind_method(D_METHOD("property_get_sync", "path"), &SceneReplicationConfig::property_get_sync);
|
||||
ClassDB::bind_method(D_METHOD("property_set_sync", "path", "enabled"), &SceneReplicationConfig::property_set_sync);
|
||||
ClassDB::bind_method(D_METHOD("property_get_watch", "path"), &SceneReplicationConfig::property_get_watch);
|
||||
|
||||
Reference in New Issue
Block a user