Fixed compile for all network synchronizer classes, and added them to the build.

This commit is contained in:
Relintai 2022-03-23 15:07:15 +01:00
parent efddf93a8e
commit b4973c944d
11 changed files with 135 additions and 137 deletions

View File

@ -5,9 +5,4 @@ Import("env_modules")
env_network_synchronizer = env_modules.Clone()
#env_network_synchronizer.add_source_files(env.modules_sources, "*.cpp")
env_network_synchronizer.add_source_files(env.modules_sources, "bit_array.cpp")
env_network_synchronizer.add_source_files(env.modules_sources, "data_buffer.cpp")
env_network_synchronizer.add_source_files(env.modules_sources, "register_types.cpp")
env_network_synchronizer.add_source_files(env.modules_sources, "*.cpp")

View File

@ -207,7 +207,7 @@ Vector<Variant> Interpolator::pop_epoch(uint32_t p_epoch, real_t p_fraction) {
ptr[i] = variables[i].default_value;
if (cache_object_id != variables[i].custom_interpolator_object) {
ERR_CONTINUE_MSG(variables[i].custom_interpolator_object.is_null(), "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
ERR_CONTINUE_MSG(!variables[i].custom_interpolator_object, "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
Object *o = ObjectDB::get_instance(variables[i].custom_interpolator_object);
ERR_CONTINUE_MSG(o == nullptr, "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
@ -252,7 +252,7 @@ Vector<Variant> Interpolator::pop_epoch(uint32_t p_epoch, real_t p_fraction) {
case FALLBACK_CUSTOM_INTERPOLATOR:
ptr[i] = variables[i].default_value;
if (cache_object_id != variables[i].custom_interpolator_object) {
ERR_CONTINUE_MSG(variables[i].custom_interpolator_object.is_null(), "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
ERR_CONTINUE_MSG(!variables[i].custom_interpolator_object, "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
Object *o = ObjectDB::get_instance(variables[i].custom_interpolator_object);
ERR_CONTINUE_MSG(o == nullptr, "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
@ -302,7 +302,7 @@ Vector<Variant> Interpolator::pop_epoch(uint32_t p_epoch, real_t p_fraction) {
ptr[i] = variables[i].default_value;
if (cache_object_id != variables[i].custom_interpolator_object) {
ERR_CONTINUE_MSG(variables[i].custom_interpolator_object.is_null(), "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
ERR_CONTINUE_MSG(!variables[i].custom_interpolator_object, "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
Object *o = ObjectDB::get_instance(variables[i].custom_interpolator_object);
ERR_CONTINUE_MSG(o == nullptr, "The variable: " + itos(i) + " has a custom interpolator, but the function is invalid.");
@ -386,10 +386,10 @@ Variant Interpolator::interpolate(const Variant &p_v1, const Variant &p_v2, real
switch (p_v1.get_type()) {
case Variant::Type::INT:
return int(Math::round(Math::lerp(p_v1.operator real_t(), p_v2.operator real_t(), p_delta)));
case Variant::Type::FLOAT:
case Variant::Type::REAL:
return Math::lerp(p_v1, p_v2, p_delta);
case Variant::Type::VECTOR2:
return p_v1.operator Vector2().lerp(p_v2.operator Vector2(), p_delta);
return p_v1.operator Vector2().linear_interpolate(p_v2.operator Vector2(), p_delta);
case Variant::Type::VECTOR2I:
return Vector2i(
int(Math::round(Math::lerp(p_v1.operator Vector2i()[0], p_v2.operator Vector2i()[0], p_delta))),
@ -397,18 +397,18 @@ Variant Interpolator::interpolate(const Variant &p_v1, const Variant &p_v2, real
case Variant::Type::TRANSFORM2D:
return p_v1.operator Transform2D().interpolate_with(p_v2.operator Transform2D(), p_delta);
case Variant::Type::VECTOR3:
return p_v1.operator Vector3().lerp(p_v2.operator Vector3(), p_delta);
return p_v1.operator Vector3().linear_interpolate(p_v2.operator Vector3(), p_delta);
case Variant::Type::VECTOR3I:
return Vector3i(
int(Math::round(Math::lerp(p_v1.operator Vector3i()[0], p_v2.operator Vector3i()[0], p_delta))),
int(Math::round(Math::lerp(p_v1.operator Vector3i()[1], p_v2.operator Vector3i()[1], p_delta))),
int(Math::round(Math::lerp(p_v1.operator Vector3i()[2], p_v2.operator Vector3i()[2], p_delta))));
case Variant::Type::QUATERNION:
return p_v1.operator Quaternion().slerp(p_v2.operator Quaternion(), p_delta);
case Variant::Type::QUAT:
return p_v1.operator Quat().slerp(p_v2.operator Quat(), p_delta);
case Variant::Type::BASIS:
return p_v1.operator Basis().slerp(p_v2.operator Basis(), p_delta);
case Variant::Type::TRANSFORM3D:
return p_v1.operator Transform3D().interpolate_with(p_v2.operator Transform3D(), p_delta);
case Variant::Type::TRANSFORM:
return p_v1.operator Transform().interpolate_with(p_v2.operator Transform(), p_delta);
default:
return p_delta > 0.5 ? p_v2 : p_v1;
}

View File

@ -1,3 +1,6 @@
#ifndef INTERPOLATOR_H
#define INTERPOLATOR_H
/*************************************************************************/
/* interpolator.h */
/*************************************************************************/
@ -32,9 +35,6 @@
@author AndreaCatania
*/
#ifndef INTERPOLATOR_H
#define INTERPOLATOR_H
#include "core/class_db.h"
#include "core/vector.h"

View File

@ -64,7 +64,7 @@ void NetUtility::NodeData::process(const real_t p_delta) const {
const Variant var_delta = p_delta;
const Variant *fake_array_vars = &var_delta;
Callable::CallError e;
Variant::CallError e;
for (uint32_t i = 0; i < functions.size(); i += 1) {
node->call(functions[i], &fake_array_vars, 1, e);
}

View File

@ -1,3 +1,6 @@
#ifndef NET_UTILITIES_H
#define NET_UTILITIES_H
/*************************************************************************/
/* net_utilities.h */
/*************************************************************************/
@ -32,12 +35,9 @@
@author AndreaCatania
*/
#ifndef NET_UTILITIES_H
#define NET_UTILITIES_H
#include "core/math/math_funcs.h"
#include "core/templates/local_vector.h"
#include "core/variant/variant.h"
#include "core/local_vector.h"
#include "core/variant.h"
#ifdef DEBUG_ENABLED
#define NET_DEBUG_PRINT(msg) \

View File

@ -34,10 +34,12 @@
#include "networked_controller.h"
#include "core/config/engine.h"
#include "core/engine.h"
#include "core/io/marshalls.h"
#include "scene_synchronizer.h"
#include <algorithm>
#include "core/project_settings.h"
#include "core/os/os.h"
#define METADATA_SIZE 1
@ -117,30 +119,30 @@ void NetworkedController::_bind_methods() {
ClassDB::bind_method(D_METHOD("__on_sync_paused"), &NetworkedController::__on_sync_paused);
BIND_VMETHOD(MethodInfo("_collect_inputs", PropertyInfo(Variant::FLOAT, "delta"), PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo("_controller_process", PropertyInfo(Variant::FLOAT, "delta"), PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo("_collect_inputs", PropertyInfo(Variant::REAL, "delta"), PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo("_controller_process", PropertyInfo(Variant::REAL, "delta"), PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_are_inputs_different", PropertyInfo(Variant::OBJECT, "inputs_A", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer"), PropertyInfo(Variant::OBJECT, "inputs_B", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo(Variant::INT, "_count_input_size", PropertyInfo(Variant::OBJECT, "inputs", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo("_collect_epoch_data", PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo("_setup_interpolator", PropertyInfo(Variant::OBJECT, "interpolator", PROPERTY_HINT_RESOURCE_TYPE, "Interpolator")));
BIND_VMETHOD(MethodInfo("_parse_epoch_data", PropertyInfo(Variant::OBJECT, "interpolator", PROPERTY_HINT_RESOURCE_TYPE, "Interpolator"), PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "DataBuffer")));
BIND_VMETHOD(MethodInfo("_apply_epoch", PropertyInfo(Variant::FLOAT, "delta"), PropertyInfo(Variant::ARRAY, "interpolated_data")));
BIND_VMETHOD(MethodInfo("_apply_epoch", PropertyInfo(Variant::REAL, "delta"), PropertyInfo(Variant::ARRAY, "interpolated_data")));
ADD_PROPERTY(PropertyInfo(Variant::INT, "input_storage_size", PROPERTY_HINT_RANGE, "5,2000,1"), "set_player_input_storage_size", "get_player_input_storage_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redundant_inputs", PROPERTY_HINT_RANGE, "0,1000,1"), "set_max_redundant_inputs", "get_max_redundant_inputs");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tick_speedup_notification_delay", PROPERTY_HINT_RANGE, "0.001,2.0,0.001"), "set_tick_speedup_notification_delay", "get_tick_speedup_notification_delay");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tick_speedup_notification_delay", PROPERTY_HINT_RANGE, "0.001,2.0,0.001"), "set_tick_speedup_notification_delay", "get_tick_speedup_notification_delay");
ADD_PROPERTY(PropertyInfo(Variant::INT, "network_traced_frames", PROPERTY_HINT_RANGE, "1,1000,1"), "set_network_traced_frames", "get_network_traced_frames");
ADD_PROPERTY(PropertyInfo(Variant::INT, "min_frames_delay", PROPERTY_HINT_RANGE, "0,100,1"), "set_min_frames_delay", "get_min_frames_delay");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_frames_delay", PROPERTY_HINT_RANGE, "0,100,1"), "set_max_frames_delay", "get_max_frames_delay");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "net_sensitivity", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_net_sensitivity", "get_net_sensitivity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tick_acceleration", PROPERTY_HINT_RANGE, "0.1,20.0,0.01"), "set_tick_acceleration", "get_tick_acceleration");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "net_sensitivity", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_net_sensitivity", "get_net_sensitivity");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tick_acceleration", PROPERTY_HINT_RANGE, "0.1,20.0,0.01"), "set_tick_acceleration", "get_tick_acceleration");
ADD_PROPERTY(PropertyInfo(Variant::INT, "doll_epoch_collect_rate", PROPERTY_HINT_RANGE, "1,100,1"), "set_doll_epoch_collect_rate", "get_doll_epoch_collect_rate");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "doll_epoch_batch_sync_rate", PROPERTY_HINT_RANGE, "0.01,5.0,0.01"), "set_doll_epoch_batch_sync_rate", "get_doll_epoch_batch_sync_rate");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "doll_epoch_batch_sync_rate", PROPERTY_HINT_RANGE, "0.01,5.0,0.01"), "set_doll_epoch_batch_sync_rate", "get_doll_epoch_batch_sync_rate");
ADD_PROPERTY(PropertyInfo(Variant::INT, "doll_min_frames_delay", PROPERTY_HINT_RANGE, "0,10,1"), "set_doll_min_frames_delay", "get_doll_min_frames_delay");
ADD_PROPERTY(PropertyInfo(Variant::INT, "doll_max_frames_delay", PROPERTY_HINT_RANGE, "0,10,1"), "set_doll_max_frames_delay", "get_doll_max_frames_delay");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "doll_interpolation_max_speedup", PROPERTY_HINT_RANGE, "0.01,5.0,0.01"), "set_doll_interpolation_max_speedup", "get_doll_interpolation_max_speedup");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "doll_interpolation_max_speedup", PROPERTY_HINT_RANGE, "0.01,5.0,0.01"), "set_doll_interpolation_max_speedup", "get_doll_interpolation_max_speedup");
ADD_PROPERTY(PropertyInfo(Variant::INT, "doll_connection_stats_frame_span", PROPERTY_HINT_RANGE, "0,1000,1"), "set_doll_connection_stats_frame_span", "get_doll_connection_stats_frame_span");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "doll_net_sensitivity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_doll_net_sensitivity", "get_doll_net_sensitivity");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "doll_net_sensitivity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_doll_net_sensitivity", "get_doll_net_sensitivity");
ADD_PROPERTY(PropertyInfo(Variant::INT, "doll_max_delay", PROPERTY_HINT_RANGE, "1,1000,1"), "set_doll_max_delay", "get_doll_max_delay");
ADD_SIGNAL(MethodInfo("doll_sync_started"));
@ -148,10 +150,10 @@ void NetworkedController::_bind_methods() {
}
NetworkedController::NetworkedController() {
rpc_config(SNAME("_rpc_server_send_inputs"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_UNRELIABLE);
rpc_config(SNAME("_rpc_send_tick_additional_speed"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_UNRELIABLE);
rpc_config(SNAME("_rpc_doll_notify_sync_pause"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_RELIABLE);
rpc_config(SNAME("_rpc_doll_send_epoch_batch"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_UNRELIABLE);
rpc_config("_rpc_server_send_inputs", MultiplayerAPI::RPC_MODE_REMOTE);
rpc_config("_rpc_send_tick_additional_speed", MultiplayerAPI::RPC_MODE_REMOTE);
rpc_config("_rpc_doll_notify_sync_pause", MultiplayerAPI::RPC_MODE_REMOTE);
rpc_config("_rpc_doll_send_epoch_batch", MultiplayerAPI::RPC_MODE_REMOTE);
}
void NetworkedController::set_player_input_storage_size(int p_size) {
@ -329,7 +331,7 @@ void NetworkedController::set_doll_peer_active(int p_peer_id, bool p_active) {
if (p_active == false) {
// Notify the doll only for deactivations. The activations are automatically
// handled when the first epoch is received.
rpc_id(p_peer_id, SNAME("_rpc_doll_notify_sync_pause"), server_controller->epoch);
rpc_id(p_peer_id, "_rpc_doll_notify_sync_pause", server_controller->epoch);
}
}
@ -341,7 +343,7 @@ void NetworkedController::pause_notify_dolls() {
for (uint32_t i = 0; i < server_controller->peers.size(); i += 1) {
if (server_controller->peers[i].active) {
// Notify this actor is no more active.
rpc_id(server_controller->peers[i].peer, SNAME("_rpc_doll_notify_sync_pause"), server_controller->epoch);
rpc_id(server_controller->peers[i].peer, "_rpc_doll_notify_sync_pause", server_controller->epoch);
}
}
}
@ -414,13 +416,13 @@ void NetworkedController::set_inputs_buffer(const BitArray &p_new_buffer, uint32
void NetworkedController::set_scene_synchronizer(SceneSynchronizer *p_synchronizer) {
if (scene_synchronizer) {
scene_synchronizer->disconnect(SNAME("sync_paused"), Callable(this, SNAME("__on_sync_paused")));
scene_synchronizer->disconnect("sync_paused", this, "__on_sync_paused");
}
scene_synchronizer = p_synchronizer;
if (scene_synchronizer) {
scene_synchronizer->connect(SNAME("sync_paused"), Callable(this, SNAME("__on_sync_paused")));
scene_synchronizer->connect("sync_paused", this, "__on_sync_paused");
}
}
@ -432,12 +434,12 @@ bool NetworkedController::has_scene_synchronizer() const {
return scene_synchronizer;
}
void NetworkedController::_rpc_server_send_inputs(const Vector<uint8_t> &p_data) {
void NetworkedController::_rpc_server_send_inputs(const PoolVector<uint8_t> &p_data) {
ERR_FAIL_COND(is_server_controller() == false);
static_cast<ServerController *>(controller)->receive_inputs(p_data);
}
void NetworkedController::_rpc_send_tick_additional_speed(const Vector<uint8_t> &p_data) {
void NetworkedController::_rpc_send_tick_additional_speed(const PoolVector<uint8_t> &p_data) {
ERR_FAIL_COND(is_player_controller() == false);
ERR_FAIL_COND(p_data.size() != 1);
@ -454,7 +456,7 @@ void NetworkedController::_rpc_doll_notify_sync_pause(uint32_t p_epoch) {
static_cast<DollController *>(controller)->pause(p_epoch);
}
void NetworkedController::_rpc_doll_send_epoch_batch(const Vector<uint8_t> &p_data) {
void NetworkedController::_rpc_doll_send_epoch_batch(const PoolVector<uint8_t> &p_data) {
ERR_FAIL_COND_MSG(is_doll_controller() == false, "Only dolls are supposed to receive this function call.");
ERR_FAIL_COND_MSG(p_data.size() <= 0, "It's not supposed to receive a 0 size data.");
@ -533,7 +535,7 @@ void ServerController::process(real_t p_delta) {
node->get_inputs_buffer_mut().begin_read();
node->get_inputs_buffer_mut().seek(METADATA_SIZE);
node->call(
SNAME("_controller_process"),
"_controller_process",
p_delta,
&node->get_inputs_buffer_mut());
@ -613,7 +615,7 @@ void ServerController::deactivate_peer(int p_peer) {
}
}
void ServerController::receive_inputs(const Vector<uint8_t> &p_data) {
void ServerController::receive_inputs(const PoolVector<uint8_t> &p_data) {
// The packet is composed as follow:
// |- The following four bytes for the first input ID.
// \- Array of inputs:
@ -632,7 +634,7 @@ void ServerController::receive_inputs(const Vector<uint8_t> &p_data) {
int ofs = 0;
ERR_FAIL_COND(data_len < 4);
const uint32_t first_input_id = decode_uint32(p_data.ptr() + ofs);
const uint32_t first_input_id = decode_uint32(p_data.read().ptr() + ofs);
ofs += 4;
uint32_t inserted_input_count = 0;
@ -659,7 +661,7 @@ void ServerController::receive_inputs(const Vector<uint8_t> &p_data) {
// Read metadata
const bool has_data = pir.read_bool();
const int input_size_in_bits = (has_data ? int(node->call(SNAME("_count_input_size"), &pir)) : 0) + METADATA_SIZE;
const int input_size_in_bits = (has_data ? int(node->call("_count_input_size", &pir)) : 0) + METADATA_SIZE;
// Pad to 8 bits.
const int input_size_padded =
Math::ceil((static_cast<float>(input_size_in_bits)) / 8.0);
@ -688,8 +690,8 @@ void ServerController::receive_inputs(const Vector<uint8_t> &p_data) {
rfs.buffer_size_bit = input_size_in_bits;
rfs.inputs_buffer.get_bytes_mut().resize(input_size_padded);
memcpy(
rfs.inputs_buffer.get_bytes_mut().ptrw(),
p_data.ptr() + ofs,
rfs.inputs_buffer.get_bytes_mut().write().ptr(),
p_data.read().ptr() + ofs,
input_size_padded);
snapshots.push_back(rfs);
@ -842,7 +844,7 @@ bool ServerController::fetch_next_input() {
pir_B.begin_read();
pir_B.seek(METADATA_SIZE);
const bool is_meaningful = node->call(SNAME("_are_inputs_different"), &pir_A, &pir_B);
const bool is_meaningful = node->call("_are_inputs_different", &pir_A, &pir_B);
if (is_meaningful) {
break;
}
@ -910,7 +912,7 @@ void ServerController::doll_sync(real_t p_delta) {
if (epoch_state_collected == false) {
epoch_state_data_cache.begin_write(0);
epoch_state_data_cache.add_int(epoch, DataBuffer::COMPRESSION_LEVEL_1);
node->call(SNAME("_collect_epoch_data"), &epoch_state_data_cache);
node->call("_collect_epoch_data", &epoch_state_data_cache);
epoch_state_data_cache.dry();
epoch_state_collected = true;
}
@ -972,7 +974,7 @@ void ServerController::doll_sync(real_t p_delta) {
// Send the data
node->rpc_id(
peers[i].peer,
SNAME("_rpc_doll_send_epoch_batch"),
"_rpc_doll_send_epoch_batch",
data);
}
}
@ -1039,7 +1041,7 @@ void ServerController::adjust_player_tick_rate(real_t p_delta) {
node->rpc_id(
node->get_network_master(),
SNAME("_rpc_send_tick_additional_speed"),
"_rpc_send_tick_additional_speed",
packet_data);
}
}
@ -1074,7 +1076,7 @@ void PlayerController::process(real_t p_delta) {
node->get_inputs_buffer_mut().begin_write(METADATA_SIZE);
node->get_inputs_buffer_mut().seek(1);
node->call(SNAME("_collect_inputs"), p_delta, &node->get_inputs_buffer_mut());
node->call("_collect_inputs", p_delta, &node->get_inputs_buffer_mut());
// Set metadata data.
node->get_inputs_buffer_mut().seek(0);
@ -1094,7 +1096,7 @@ void PlayerController::process(real_t p_delta) {
// The physics process is always emitted, because we still need to simulate
// the character motion even if we don't store the player inputs.
node->call(SNAME("_controller_process"), p_delta, &node->get_inputs_buffer());
node->call("_controller_process", p_delta, &node->get_inputs_buffer());
node->player_set_has_new_input(false);
if (accept_new_inputs) {
@ -1179,7 +1181,7 @@ bool PlayerController::process_instant(int p_i, real_t p_delta) {
ib.shrink_to(METADATA_SIZE, frames_snapshot[i].buffer_size_bit - METADATA_SIZE);
ib.begin_read();
ib.seek(METADATA_SIZE);
node->call(SNAME("_controller_process"), p_delta, &ib);
node->call("_controller_process", p_delta, &ib);
return (i + 1) < frames_snapshot.size();
} else {
return false;
@ -1254,7 +1256,7 @@ void PlayerController::send_frame_input_buffer_to_server() {
pir_B.begin_read();
pir_B.seek(METADATA_SIZE);
const bool are_different = node->call(SNAME("_are_inputs_different"), &pir_A, &pir_B);
const bool are_different = node->call("_are_inputs_different", &pir_A, &pir_B);
is_similar = are_different == false;
} else if (frames_snapshot[i].similarity == previous_input_similarity) {
@ -1301,7 +1303,7 @@ void PlayerController::send_frame_input_buffer_to_server() {
MAKE_ROOM(buffer_size);
memcpy(
cached_packet_data.ptr() + ofs,
frames_snapshot[i].inputs_buffer.get_bytes().ptr(),
frames_snapshot[i].inputs_buffer.get_bytes().read().ptr(),
buffer_size);
ofs += buffer_size;
@ -1330,7 +1332,7 @@ void PlayerController::send_frame_input_buffer_to_server() {
const int server_peer_id = 1;
node->rpc_id(
server_peer_id,
SNAME("_rpc_server_send_inputs"),
"_rpc_server_send_inputs",
packet_data);
}
@ -1346,7 +1348,7 @@ DollController::DollController(NetworkedController *p_node) :
void DollController::ready() {
interpolator.reset();
node->call(
SNAME("_setup_interpolator"),
"_setup_interpolator",
&interpolator);
interpolator.terminate_init();
}
@ -1361,7 +1363,7 @@ void DollController::process(real_t p_delta) {
const real_t fractional_part = advancing_epoch;
node->call(
SNAME("_apply_epoch"),
"_apply_epoch",
p_delta,
interpolator.pop_epoch(frame_epoch, fractional_part));
}
@ -1370,7 +1372,7 @@ uint32_t DollController::get_current_input_id() const {
return current_epoch;
}
void DollController::receive_batch(const Vector<uint8_t> &p_data) {
void DollController::receive_batch(const PoolVector<uint8_t> &p_data) {
if (unlikely(node->get_scene_synchronizer()->is_enabled() == false)) {
// The sync is disabled, nothing to do.
return;
@ -1397,7 +1399,7 @@ void DollController::receive_batch(const Vector<uint8_t> &p_data) {
while (buffer_start_position < p_data.size()) {
const int buffer_size = p_data[buffer_start_position];
const Vector<uint8_t> buffer = p_data.subarray(
const PoolVector<uint8_t> buffer = p_data.subarray(
buffer_start_position + 1,
buffer_start_position + 1 + buffer_size - 1);
@ -1439,7 +1441,7 @@ void DollController::receive_batch(const Vector<uint8_t> &p_data) {
net_poorness);
// TODO cache this?
const double frames_per_batch = node->get_doll_epoch_batch_sync_rate() * real_t(Engine::get_singleton()->get_physics_ticks_per_second());
const double frames_per_batch = node->get_doll_epoch_batch_sync_rate() * real_t(Engine::get_singleton()->get_iterations_per_second());
const double next_batch_arrives_in = Math::ceil(double(next_collect_rate) / frames_per_batch) * frames_per_batch;
const real_t doll_interpolation_max_speedup = node->get_doll_interpolation_max_speedup();
@ -1454,7 +1456,7 @@ void DollController::receive_batch(const Vector<uint8_t> &p_data) {
#endif
}
uint32_t DollController::receive_epoch(const Vector<uint8_t> &p_data) {
uint32_t DollController::receive_epoch(const PoolVector<uint8_t> &p_data) {
DataBuffer buffer(p_data);
buffer.begin_read();
const uint32_t epoch = buffer.read_int(DataBuffer::COMPRESSION_LEVEL_1);
@ -1466,7 +1468,7 @@ uint32_t DollController::receive_epoch(const Vector<uint8_t> &p_data) {
}
interpolator.begin_write(epoch);
node->call(SNAME("_parse_epoch_data"), &interpolator, &buffer);
node->call("_parse_epoch_data", &interpolator, &buffer);
interpolator.end_write();
return epoch;
@ -1559,10 +1561,10 @@ NoNetController::NoNetController(NetworkedController *p_node) :
void NoNetController::process(real_t p_delta) {
node->get_inputs_buffer_mut().begin_write(0); // No need of meta in this case.
node->call(SNAME("_collect_inputs"), p_delta, &node->get_inputs_buffer_mut());
node->call("_collect_inputs", p_delta, &node->get_inputs_buffer_mut());
node->get_inputs_buffer_mut().dry();
node->get_inputs_buffer_mut().begin_read();
node->call(SNAME("_controller_process"), p_delta, &node->get_inputs_buffer_mut());
node->call("_controller_process", p_delta, &node->get_inputs_buffer_mut());
frame_id += 1;
}

View File

@ -1,3 +1,6 @@
#ifndef NETWORKED_CONTROLLER_H
#define NETWORKED_CONTROLLER_H
/*************************************************************************/
/* networked_controller.h */
/*************************************************************************/
@ -39,9 +42,6 @@
#include "net_utilities.h"
#include <deque>
#ifndef NETWORKED_CONTROLLER_H
#define NETWORKED_CONTROLLER_H
class SceneSynchronizer;
struct Controller;
struct ServerController;
@ -320,14 +320,14 @@ public:
bool has_scene_synchronizer() const;
/* On server rpc functions. */
void _rpc_server_send_inputs(const Vector<uint8_t> &p_data);
void _rpc_server_send_inputs(const PoolVector<uint8_t> &p_data);
/* On client rpc functions. */
void _rpc_send_tick_additional_speed(const Vector<uint8_t> &p_data);
void _rpc_send_tick_additional_speed(const PoolVector<uint8_t> &p_data);
/* On puppet rpc functions. */
void _rpc_doll_notify_sync_pause(uint32_t p_epoch);
void _rpc_doll_send_epoch_batch(const Vector<uint8_t> &p_data);
void _rpc_doll_send_epoch_batch(const PoolVector<uint8_t> &p_data);
void process(real_t p_delta);
@ -378,7 +378,7 @@ struct ServerController : public Controller {
real_t update_rate_factor = 1.0;
int collect_timer = 0; // In frames
int collect_threshold = 0; // In frames
LocalVector<Vector<uint8_t>> epoch_batch;
LocalVector<PoolVector<uint8_t>> epoch_batch;
uint32_t batch_size = 0;
};
@ -415,7 +415,7 @@ struct ServerController : public Controller {
virtual void activate_peer(int p_peer) override;
virtual void deactivate_peer(int p_peer) override;
void receive_inputs(const Vector<uint8_t> &p_data);
void receive_inputs(const PoolVector<uint8_t> &p_data);
int get_inputs_count() const;
/// Fetch the next inputs, returns true if the input is new.
@ -504,8 +504,8 @@ struct DollController : public Controller {
// TODO consider make this non virtual
virtual uint32_t get_current_input_id() const override;
void receive_batch(const Vector<uint8_t> &p_data);
uint32_t receive_epoch(const Vector<uint8_t> &p_data);
void receive_batch(const PoolVector<uint8_t> &p_data);
uint32_t receive_epoch(const PoolVector<uint8_t> &p_data);
uint32_t next_epoch();
void pause(uint32_t p_epoch);

View File

@ -35,24 +35,22 @@
#include "register_types.h"
#include "data_buffer.h"
/*
#include "interpolator.h"
#include "networked_controller.h"
#include "scene_diff.h"
#include "scene_synchronizer.h"
*/
#include "core/project_settings.h"
void register_network_synchronizer_types() {
ClassDB::register_class<DataBuffer>();
/*
GDREGISTER_CLASS(SceneDiff);
GDREGISTER_CLASS(Interpolator);
GDREGISTER_CLASS(NetworkedController);
GDREGISTER_CLASS(SceneSynchronizer);
*/
// GLOBAL_DEF("NetworkSynchronizer/debug_server_speedup", false);
// GLOBAL_DEF("NetworkSynchronizer/debug_doll_speedup", false);
ClassDB::register_class<SceneDiff>();
ClassDB::register_class<Interpolator>();
ClassDB::register_class<NetworkedController>();
ClassDB::register_class<SceneSynchronizer>();
GLOBAL_DEF("NetworkSynchronizer/debug_server_speedup", false);
GLOBAL_DEF("NetworkSynchronizer/debug_doll_speedup", false);
}
void unregister_network_synchronizer_types() {

View File

@ -1,3 +1,6 @@
#ifndef SCENE_DIFF_H
#define SCENE_DIFF_H
/*************************************************************************/
/* scene_diff.h */
/*************************************************************************/
@ -32,10 +35,8 @@
@author AndreaCatania
*/
#ifndef SCENE_DIFF_H
#define SCENE_DIFF_H
#include "core/object/class_db.h"
#include "core/class_db.h"
#include "core/local_vector.h"
#include "net_utilities.h"
class SceneSynchronizer;

View File

@ -35,8 +35,10 @@
#include "scene_synchronizer.h"
#include "networked_controller.h"
#include "scene/main/window.h"
#include "core/engine.h"
#include "core/class_db.h"
#include "scene_diff.h"
#include "scene/main/viewport.h"
void SceneSynchronizer::_bind_methods() {
BIND_ENUM_CONSTANT(CHANGE)
@ -115,8 +117,8 @@ void SceneSynchronizer::_bind_methods() {
ClassDB::bind_method(D_METHOD("_rpc_set_network_enabled", "enabled"), &SceneSynchronizer::_rpc_set_network_enabled);
ClassDB::bind_method(D_METHOD("_rpc_notify_peer_status", "enabled"), &SceneSynchronizer::_rpc_notify_peer_status);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "server_notify_state_interval", PROPERTY_HINT_RANGE, "0.001,10.0,0.0001"), "set_server_notify_state_interval", "get_server_notify_state_interval");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "comparison_float_tolerance", PROPERTY_HINT_RANGE, "0.000001,0.01,0.000001"), "set_comparison_float_tolerance", "get_comparison_float_tolerance");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "server_notify_state_interval", PROPERTY_HINT_RANGE, "0.001,10.0,0.0001"), "set_server_notify_state_interval", "get_server_notify_state_interval");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "comparison_float_tolerance", PROPERTY_HINT_RANGE, "0.000001,0.01,0.000001"), "set_comparison_float_tolerance", "get_comparison_float_tolerance");
ADD_SIGNAL(MethodInfo("sync_started"));
ADD_SIGNAL(MethodInfo("sync_paused"));
@ -145,10 +147,10 @@ void SceneSynchronizer::_notification(int p_what) {
clear();
reset_synchronizer_mode();
get_multiplayer()->connect(SNAME("network_peer_connected"), Callable(this, SNAME("_on_peer_connected")));
get_multiplayer()->connect(SNAME("network_peer_disconnected"), Callable(this, SNAME("_on_peer_disconnected")));
get_multiplayer()->connect("network_peer_connected", this, "_on_peer_connected");
get_multiplayer()->connect("network_peer_disconnected", this, "_on_peer_disconnected");
get_tree()->connect(SNAME("node_removed"), Callable(this, SNAME("_on_node_removed")));
get_tree()->connect("node_removed", this, "_on_node_removed");
// Make sure to reset all the assigned controllers.
reset_controllers();
@ -169,10 +171,10 @@ void SceneSynchronizer::_notification(int p_what) {
clear_peers();
get_multiplayer()->disconnect(SNAME("network_peer_connected"), Callable(this, SNAME("_on_peer_connected")));
get_multiplayer()->disconnect(SNAME("network_peer_disconnected"), Callable(this, SNAME("_on_peer_disconnected")));
get_multiplayer()->disconnect("network_peer_connected", this, "_on_peer_connected");
get_multiplayer()->disconnect("network_peer_disconnected", this, "_on_peer_disconnected");
get_tree()->disconnect(SNAME("node_removed"), Callable(this, SNAME("_on_node_removed")));
get_tree()->disconnect("node_removed", this, "_on_node_removed");
clear();
@ -191,10 +193,10 @@ void SceneSynchronizer::_notification(int p_what) {
}
SceneSynchronizer::SceneSynchronizer() {
rpc_config(SNAME("_rpc_send_state"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_RELIABLE);
rpc_config(SNAME("_rpc_notify_need_full_snapshot"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_RELIABLE);
rpc_config(SNAME("_rpc_set_network_enabled"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_RELIABLE);
rpc_config(SNAME("_rpc_notify_peer_status"), MultiplayerAPI::RPC_MODE_REMOTE, MultiplayerPeer::TRANSFER_MODE_RELIABLE);
rpc_config("_rpc_send_state", MultiplayerAPI::RPC_MODE_REMOTE);
rpc_config("_rpc_notify_need_full_snapshot", MultiplayerAPI::RPC_MODE_REMOTE);
rpc_config("_rpc_set_network_enabled", MultiplayerAPI::RPC_MODE_REMOTE);
rpc_config("_rpc_notify_peer_status", MultiplayerAPI::RPC_MODE_REMOTE);
// Avoid too much useless re-allocations.
event_listener.reserve(100);
@ -781,7 +783,7 @@ void SceneSynchronizer::dirty_peers() {
void SceneSynchronizer::set_enabled(bool p_enable) {
ERR_FAIL_COND_MSG(synchronizer_type == SYNCHRONIZER_TYPE_SERVER, "The server is always enabled.");
if (synchronizer_type == SYNCHRONIZER_TYPE_CLIENT) {
rpc_id(1, SNAME("_rpc_set_network_enabled"), p_enable);
rpc_id(1, "_rpc_set_network_enabled", p_enable);
if (p_enable == false) {
// If the peer want to disable, we can disable it locally
// immediately. When it wants to enable the networking, the server
@ -825,7 +827,7 @@ void SceneSynchronizer::set_peer_networking_enable(int p_peer, bool p_enable) {
dirty_peers();
// Just notify the peer status.
rpc_id(p_peer, SNAME("_rpc_notify_peer_status"), p_enable);
rpc_id(p_peer, "_rpc_notify_peer_status", p_enable);
} else {
ERR_FAIL_COND_MSG(synchronizer_type != SYNCHRONIZER_TYPE_NONETWORK, "At this point no network is expected.");
static_cast<NoNetSynchronizer *>(synchronizer)->set_enabled(p_enable);
@ -946,10 +948,10 @@ void SceneSynchronizer::clear() {
}
}
node_data.reset();
organized_node_data.reset();
node_data_controllers.reset();
event_listener.reset();
node_data.clear();
organized_node_data.clear();
node_data_controllers.clear();
event_listener.clear();
// Avoid too much useless re-allocations.
event_listener.reserve(100);
@ -1145,7 +1147,7 @@ void SceneSynchronizer::change_events_flush() {
vars_ptr[v] = vars.ptr() + v;
}
Callable::CallError e;
Variant::CallError e;
obj->call(listener.method, vars_ptr.ptr(), vars_ptr.size(), e);
}
@ -1307,7 +1309,7 @@ bool SceneSynchronizer::compare(const Variant &p_first, const Variant &p_second,
// Custom evaluation methods
switch (p_first.get_type()) {
case Variant::FLOAT: {
case Variant::REAL: {
return Math::is_equal_approx(p_first, p_second, p_tolerance);
}
case Variant::VECTOR2: {
@ -1338,10 +1340,10 @@ bool SceneSynchronizer::compare(const Variant &p_first, const Variant &p_second,
case Variant::VECTOR3: {
return compare(Vector3(p_first), Vector3(p_second), p_tolerance);
}
case Variant::QUATERNION: {
const Quaternion a = p_first;
const Quaternion b = p_second;
const Quaternion r(a - b); // Element wise subtraction.
case Variant::QUAT: {
const Quat a = p_first;
const Quat b = p_second;
const Quat r(a - b); // Element wise subtraction.
return (r.x * r.x + r.y * r.y + r.z * r.z + r.w * r.w) <= (p_tolerance * p_tolerance);
}
case Variant::PLANE: {
@ -1376,9 +1378,9 @@ bool SceneSynchronizer::compare(const Variant &p_first, const Variant &p_second,
}
return false;
}
case Variant::TRANSFORM3D: {
const Transform3D a = p_first;
const Transform3D b = p_second;
case Variant::TRANSFORM: {
const Transform a = p_first;
const Transform b = p_second;
if (compare(a.origin, b.origin, p_tolerance)) {
if (compare(a.basis.elements[0], b.basis.elements[0], p_tolerance)) {
if (compare(a.basis.elements[1], b.basis.elements[1], p_tolerance)) {
@ -1527,12 +1529,12 @@ const NetUtility::NodeData *SceneSynchronizer::find_node_data(const Node *p_node
}
NetUtility::NodeData *SceneSynchronizer::get_node_data(NetNodeId p_id) {
ERR_FAIL_UNSIGNED_INDEX_V(p_id, organized_node_data.size(), nullptr);
ERR_FAIL_INDEX_V(p_id, organized_node_data.size(), nullptr);
return organized_node_data[p_id];
}
const NetUtility::NodeData *SceneSynchronizer::get_node_data(NetNodeId p_id) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_id, organized_node_data.size(), nullptr);
ERR_FAIL_INDEX_V(p_id, organized_node_data.size(), nullptr);
return organized_node_data[p_id];
}
@ -1772,7 +1774,7 @@ void ServerSynchronizer::on_variable_changed(NetUtility::NodeData *p_node_data,
}
void ServerSynchronizer::process_snapshot_notificator(real_t p_delta) {
if (scene_synchronizer->peer_data.is_empty()) {
if (scene_synchronizer->peer_data.empty()) {
// No one is listening.
return;
}
@ -1832,7 +1834,7 @@ void ServerSynchronizer::process_snapshot_notificator(real_t p_delta) {
}
controller->get_server_controller()->notify_send_state();
scene_synchronizer->rpc_id(*peer_it.key, SNAME("_rpc_send_state"), snap);
scene_synchronizer->rpc_id(*peer_it.key, "_rpc_send_state", snap);
}
if (notify_state) {
@ -1918,7 +1920,7 @@ void ServerSynchronizer::generate_snapshot_node_data(
snap_node_data = p_node_data->id;
}
const bool node_has_changes = p_force_full_snapshot || (change != nullptr && change->vars.is_empty() == false);
const bool node_has_changes = p_force_full_snapshot || (change != nullptr && change->vars.empty() == false);
if (p_node_data->is_controller) {
NetworkedController *controller = static_cast<NetworkedController *>(p_node_data->node);
@ -2001,7 +2003,7 @@ void ClientSynchronizer::process() {
}
const real_t delta = scene_synchronizer->get_physics_process_delta_time();
const real_t physics_ticks_per_second = Engine::get_singleton()->get_physics_ticks_per_second();
const real_t physics_ticks_per_second = Engine::get_singleton()->get_iterations_per_second();
#ifdef DEBUG_ENABLED
if (unlikely(Engine::get_singleton()->get_frames_per_second() < physics_ticks_per_second)) {
@ -2040,7 +2042,7 @@ void ClientSynchronizer::process() {
// Pull the changes.
scene_synchronizer->change_events_begin(NetEventFlag::CHANGE);
for (NetNodeId i = 0; i < scene_synchronizer->node_data.size(); i += 1) {
for (uint32_t i = 0; i < scene_synchronizer->node_data.size(); i += 1) {
NetUtility::NodeData *nd = scene_synchronizer->node_data[i];
scene_synchronizer->pull_node_changes(nd);
}
@ -3048,5 +3050,5 @@ void ClientSynchronizer::notify_server_full_snapshot_is_needed() {
// Notify the server that a full snapshot is needed.
need_full_snapshot_notified = true;
scene_synchronizer->rpc_id(1, SNAME("_rpc_notify_need_full_snapshot"));
scene_synchronizer->rpc_id(1, "_rpc_notify_need_full_snapshot");
}

View File

@ -1,3 +1,6 @@
#ifndef SCENE_SYNCHRONIZER_H
#define SCENE_SYNCHRONIZER_H
/*************************************************************************/
/* scene_synchronizer.h */
/*************************************************************************/
@ -34,14 +37,11 @@
#include "scene/main/node.h"
#include "core/templates/local_vector.h"
#include "core/templates/oa_hash_map.h"
#include "core/local_vector.h"
#include "core/oa_hash_map.h"
#include "net_utilities.h"
#include <deque>
#ifndef SCENE_SYNCHRONIZER_H
#define SCENE_SYNCHRONIZER_H
class Synchronizer;
class NetworkedController;