Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/multiplayer/scene_replication_config.cpp
10277 views
1
/**************************************************************************/
2
/* scene_replication_config.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "scene_replication_config.h"
32
33
bool SceneReplicationConfig::_set(const StringName &p_name, const Variant &p_value) {
34
String prop_name = p_name;
35
36
if (prop_name.begins_with("properties/")) {
37
int idx = prop_name.get_slicec('/', 1).to_int();
38
String what = prop_name.get_slicec('/', 2);
39
40
if (properties.size() == idx && what == "path") {
41
ERR_FAIL_COND_V(p_value.get_type() != Variant::NODE_PATH, false);
42
NodePath path = p_value;
43
ERR_FAIL_COND_V(path.is_empty() || path.get_subname_count() == 0, false);
44
add_property(path);
45
return true;
46
}
47
ERR_FAIL_INDEX_V(idx, properties.size(), false);
48
const ReplicationProperty &prop = properties.get(idx);
49
if (what == "replication_mode") {
50
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
51
ReplicationMode mode = (ReplicationMode)p_value.operator int();
52
ERR_FAIL_COND_V(mode < REPLICATION_MODE_NEVER || mode > REPLICATION_MODE_ON_CHANGE, false);
53
property_set_replication_mode(prop.name, mode);
54
return true;
55
}
56
ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false);
57
if (what == "spawn") {
58
property_set_spawn(prop.name, p_value);
59
return true;
60
} else if (what == "sync") {
61
// Deprecated.
62
property_set_sync(prop.name, p_value);
63
return true;
64
} else if (what == "watch") {
65
// Deprecated.
66
property_set_watch(prop.name, p_value);
67
return true;
68
}
69
}
70
return false;
71
}
72
73
bool SceneReplicationConfig::_get(const StringName &p_name, Variant &r_ret) const {
74
String prop_name = p_name;
75
76
if (prop_name.begins_with("properties/")) {
77
int idx = prop_name.get_slicec('/', 1).to_int();
78
String what = prop_name.get_slicec('/', 2);
79
ERR_FAIL_INDEX_V(idx, properties.size(), false);
80
const ReplicationProperty &prop = properties.get(idx);
81
if (what == "path") {
82
r_ret = prop.name;
83
return true;
84
} else if (what == "spawn") {
85
r_ret = prop.spawn;
86
return true;
87
} else if (what == "replication_mode") {
88
r_ret = prop.mode;
89
return true;
90
}
91
}
92
return false;
93
}
94
95
void SceneReplicationConfig::_get_property_list(List<PropertyInfo> *p_list) const {
96
for (int i = 0; i < properties.size(); i++) {
97
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
98
p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/spawn", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
99
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));
100
}
101
}
102
103
void SceneReplicationConfig::reset_state() {
104
dirty = false;
105
properties.clear();
106
sync_props.clear();
107
spawn_props.clear();
108
watch_props.clear();
109
}
110
111
TypedArray<NodePath> SceneReplicationConfig::get_properties() const {
112
TypedArray<NodePath> paths;
113
for (const ReplicationProperty &prop : properties) {
114
paths.push_back(prop.name);
115
}
116
return paths;
117
}
118
119
void SceneReplicationConfig::add_property(const NodePath &p_path, int p_index) {
120
ERR_FAIL_COND(properties.find(p_path));
121
ERR_FAIL_COND(p_path == NodePath());
122
123
if (p_index < 0 || p_index == properties.size()) {
124
properties.push_back(ReplicationProperty(p_path));
125
dirty = true;
126
return;
127
}
128
129
ERR_FAIL_INDEX(p_index, properties.size());
130
131
List<ReplicationProperty>::Element *I = properties.front();
132
int c = 0;
133
while (c < p_index) {
134
I = I->next();
135
c++;
136
}
137
properties.insert_before(I, ReplicationProperty(p_path));
138
dirty = true;
139
}
140
141
void SceneReplicationConfig::remove_property(const NodePath &p_path) {
142
properties.erase(p_path);
143
dirty = true;
144
}
145
146
bool SceneReplicationConfig::has_property(const NodePath &p_path) const {
147
for (const ReplicationProperty &property : properties) {
148
if (property.name == p_path) {
149
return true;
150
}
151
}
152
return false;
153
}
154
155
int SceneReplicationConfig::property_get_index(const NodePath &p_path) const {
156
int i = 0;
157
for (List<ReplicationProperty>::ConstIterator itr = properties.begin(); itr != properties.end(); ++itr, ++i) {
158
if (itr->name == p_path) {
159
return i;
160
}
161
}
162
ERR_FAIL_V(-1);
163
}
164
165
bool SceneReplicationConfig::property_get_spawn(const NodePath &p_path) {
166
List<ReplicationProperty>::Element *E = properties.find(p_path);
167
ERR_FAIL_COND_V(!E, false);
168
return E->get().spawn;
169
}
170
171
void SceneReplicationConfig::property_set_spawn(const NodePath &p_path, bool p_enabled) {
172
List<ReplicationProperty>::Element *E = properties.find(p_path);
173
ERR_FAIL_COND(!E);
174
if (E->get().spawn == p_enabled) {
175
return;
176
}
177
E->get().spawn = p_enabled;
178
dirty = true;
179
}
180
181
bool SceneReplicationConfig::property_get_sync(const NodePath &p_path) {
182
List<ReplicationProperty>::Element *E = properties.find(p_path);
183
ERR_FAIL_COND_V(!E, false);
184
return E->get().mode == REPLICATION_MODE_ALWAYS;
185
}
186
187
void SceneReplicationConfig::property_set_sync(const NodePath &p_path, bool p_enabled) {
188
if (p_enabled) {
189
property_set_replication_mode(p_path, REPLICATION_MODE_ALWAYS);
190
} else if (property_get_replication_mode(p_path) == REPLICATION_MODE_ALWAYS) {
191
property_set_replication_mode(p_path, REPLICATION_MODE_NEVER);
192
}
193
}
194
195
bool SceneReplicationConfig::property_get_watch(const NodePath &p_path) {
196
List<ReplicationProperty>::Element *E = properties.find(p_path);
197
ERR_FAIL_COND_V(!E, false);
198
return E->get().mode == REPLICATION_MODE_ON_CHANGE;
199
}
200
201
void SceneReplicationConfig::property_set_watch(const NodePath &p_path, bool p_enabled) {
202
if (p_enabled) {
203
property_set_replication_mode(p_path, REPLICATION_MODE_ON_CHANGE);
204
} else if (property_get_replication_mode(p_path) == REPLICATION_MODE_ON_CHANGE) {
205
property_set_replication_mode(p_path, REPLICATION_MODE_NEVER);
206
}
207
}
208
209
SceneReplicationConfig::ReplicationMode SceneReplicationConfig::property_get_replication_mode(const NodePath &p_path) {
210
List<ReplicationProperty>::Element *E = properties.find(p_path);
211
ERR_FAIL_COND_V(!E, REPLICATION_MODE_NEVER);
212
return E->get().mode;
213
}
214
215
void SceneReplicationConfig::property_set_replication_mode(const NodePath &p_path, ReplicationMode p_mode) {
216
List<ReplicationProperty>::Element *E = properties.find(p_path);
217
ERR_FAIL_COND(!E);
218
if (E->get().mode == p_mode) {
219
return;
220
}
221
E->get().mode = p_mode;
222
dirty = true;
223
}
224
225
void SceneReplicationConfig::_update() {
226
if (!dirty) {
227
return;
228
}
229
dirty = false;
230
sync_props.clear();
231
spawn_props.clear();
232
watch_props.clear();
233
for (const ReplicationProperty &prop : properties) {
234
if (prop.spawn) {
235
spawn_props.push_back(prop.name);
236
}
237
switch (prop.mode) {
238
case REPLICATION_MODE_ALWAYS:
239
sync_props.push_back(prop.name);
240
break;
241
case REPLICATION_MODE_ON_CHANGE:
242
watch_props.push_back(prop.name);
243
break;
244
default:
245
break;
246
}
247
}
248
}
249
250
const List<NodePath> &SceneReplicationConfig::get_spawn_properties() {
251
if (dirty) {
252
_update();
253
}
254
return spawn_props;
255
}
256
257
const List<NodePath> &SceneReplicationConfig::get_sync_properties() {
258
if (dirty) {
259
_update();
260
}
261
return sync_props;
262
}
263
264
const List<NodePath> &SceneReplicationConfig::get_watch_properties() {
265
if (dirty) {
266
_update();
267
}
268
return watch_props;
269
}
270
271
void SceneReplicationConfig::_bind_methods() {
272
ClassDB::bind_method(D_METHOD("get_properties"), &SceneReplicationConfig::get_properties);
273
ClassDB::bind_method(D_METHOD("add_property", "path", "index"), &SceneReplicationConfig::add_property, DEFVAL(-1));
274
ClassDB::bind_method(D_METHOD("has_property", "path"), &SceneReplicationConfig::has_property);
275
ClassDB::bind_method(D_METHOD("remove_property", "path"), &SceneReplicationConfig::remove_property);
276
ClassDB::bind_method(D_METHOD("property_get_index", "path"), &SceneReplicationConfig::property_get_index);
277
ClassDB::bind_method(D_METHOD("property_get_spawn", "path"), &SceneReplicationConfig::property_get_spawn);
278
ClassDB::bind_method(D_METHOD("property_set_spawn", "path", "enabled"), &SceneReplicationConfig::property_set_spawn);
279
ClassDB::bind_method(D_METHOD("property_get_replication_mode", "path"), &SceneReplicationConfig::property_get_replication_mode);
280
ClassDB::bind_method(D_METHOD("property_set_replication_mode", "path", "mode"), &SceneReplicationConfig::property_set_replication_mode);
281
282
BIND_ENUM_CONSTANT(REPLICATION_MODE_NEVER);
283
BIND_ENUM_CONSTANT(REPLICATION_MODE_ALWAYS);
284
BIND_ENUM_CONSTANT(REPLICATION_MODE_ON_CHANGE);
285
286
// Deprecated.
287
ClassDB::bind_method(D_METHOD("property_get_sync", "path"), &SceneReplicationConfig::property_get_sync);
288
ClassDB::bind_method(D_METHOD("property_set_sync", "path", "enabled"), &SceneReplicationConfig::property_set_sync);
289
ClassDB::bind_method(D_METHOD("property_get_watch", "path"), &SceneReplicationConfig::property_get_watch);
290
ClassDB::bind_method(D_METHOD("property_set_watch", "path", "enabled"), &SceneReplicationConfig::property_set_watch);
291
}
292
293