4646
4747NS_NAMESPACE_BEGIN
4848
49+ namespace MathFunc {
50+ template <typename F>
51+ F lerp (F a, F b, F alpha) {
52+ return a + alpha * (b - a);
53+ }
54+ } // namespace MathFunc
55+
4956namespace MapFunc {
5057
5158template <class K , class V >
@@ -254,174 +261,6 @@ struct ListenerHandle {
254261};
255262inline static const ListenerHandle nulllistenerhandle = { 0 };
256263
257- template <class T >
258- class StatisticalRingBuffer {
259- LocalVector<T> data;
260- uint32_t index = 0 ;
261-
262- T avg_sum = 0 ;
263-
264- public:
265- StatisticalRingBuffer (uint32_t p_size, T p_default);
266- void resize (uint32_t p_size, T p_default);
267- void reset (T p_default);
268-
269- void push (T p_value);
270-
271- // / Maximum value.
272- T max () const ;
273-
274- // / Minumum value.
275- T min (uint32_t p_consider_last = UINT32_MAX) const ;
276-
277- // / Median value.
278- T average () const ;
279- T average_rounded () const ;
280-
281- T get_deviation (T p_mean) const ;
282-
283- private:
284- // Used to avoid accumulate precision loss.
285- void force_recompute_avg_sum ();
286- };
287-
288- template <class T >
289- StatisticalRingBuffer<T>::StatisticalRingBuffer(uint32_t p_size, T p_default) {
290- resize (p_size, p_default);
291- }
292-
293- template <class T >
294- void StatisticalRingBuffer<T>::resize(uint32_t p_size, T p_default) {
295- data.resize (p_size);
296-
297- reset (p_default);
298- }
299-
300- template <class T >
301- void StatisticalRingBuffer<T>::reset(T p_default) {
302- for (uint32_t i = 0 ; i < data.size (); i += 1 ) {
303- data[i] = p_default;
304- }
305-
306- index = 0 ;
307- force_recompute_avg_sum ();
308- }
309-
310- template <class T >
311- void StatisticalRingBuffer<T>::push(T p_value) {
312- avg_sum -= data[index];
313- avg_sum += p_value;
314- data[index] = p_value;
315-
316- index = (index + 1 ) % data.size ();
317- if (index == 0 ) {
318- // Each cycle recompute the sum.
319- force_recompute_avg_sum ();
320- }
321- }
322-
323- template <class T >
324- T StatisticalRingBuffer<T>::max() const {
325- CRASH_COND (data.size () == 0 );
326-
327- T a = data[0 ];
328- for (uint32_t i = 1 ; i < data.size (); i += 1 ) {
329- a = MAX (a, data[i]);
330- }
331- return a;
332- }
333-
334- template <class T >
335- T StatisticalRingBuffer<T>::min(uint32_t p_consider_last) const {
336- CRASH_COND (data.size () == 0 );
337- p_consider_last = MIN (p_consider_last, data.size ());
338-
339- const uint32_t youngest = (index == 0 ? data.size () : index) - 1 ;
340- const uint32_t oldest = (index + (data.size () - p_consider_last)) % data.size ();
341-
342- T a = data[oldest];
343-
344- uint32_t i = oldest;
345- do {
346- i = (i + 1 ) % data.size ();
347- a = MIN (a, data[i]);
348- } while (i != youngest);
349-
350- return a;
351- }
352-
353- template <class T >
354- T StatisticalRingBuffer<T>::average() const {
355- CRASH_COND (data.size () == 0 );
356-
357- #ifdef DEBUG_ENABLED
358- T a = data[0 ];
359- for (uint32_t i = 1 ; i < data.size (); i += 1 ) {
360- a += data[i];
361- }
362- a = a / T (data.size ());
363- T b = avg_sum / T (data.size ());
364- const T difference = a > b ? a - b : b - a;
365- ERR_FAIL_COND_V_MSG (difference > (std::numeric_limits<T>::epsilon () * 4.0 ), b, " The `avg_sum` accumulated a sensible precision loss: " + rtos (difference));
366- return b;
367- #else
368- // Divide it by the buffer size is wrong when the buffer is not yet fully
369- // initialized. However, this is wrong just for the first run.
370- // I'm leaving it as is because solve it mean do more operations. All this
371- // just to get the right value for the first few frames.
372- return avg_sum / T (data.size ());
373- #endif
374- }
375-
376- template <class T >
377- T StatisticalRingBuffer<T>::average_rounded() const {
378- CRASH_COND (data.size () == 0 );
379-
380- #ifdef DEBUG_ENABLED
381- T a = data[0 ];
382- for (uint32_t i = 1 ; i < data.size (); i += 1 ) {
383- a += data[i];
384- }
385- a = round (double (a) / double (data.size ()));
386- T b = round (double (avg_sum) / double (data.size ()));
387- const T difference = a > b ? a - b : b - a;
388- ERR_FAIL_COND_V_MSG (difference > (std::numeric_limits<T>::epsilon () * 4.0 ), b, " The `avg_sum` accumulated a sensible precision loss: " + rtos (difference));
389- return b;
390- #else
391- // Divide it by the buffer size is wrong when the buffer is not yet fully
392- // initialized. However, this is wrong just for the first run.
393- // I'm leaving it as is because solve it mean do more operations. All this
394- // just to get the right value for the first few frames.
395- return round (double (avg_sum) / double (data.size ()));
396- #endif
397- }
398-
399- template <class T >
400- T StatisticalRingBuffer<T>::get_deviation(T p_mean) const {
401- if (data.size () <= 0 ) {
402- return T ();
403- }
404-
405- double r = 0 ;
406- for (uint32_t i = 0 ; i < data.size (); i += 1 ) {
407- r += pow (double (data[i]) - double (p_mean), 2.0 );
408- }
409-
410- return sqrt (r / double (data.size ()));
411- }
412-
413- template <class T >
414- void StatisticalRingBuffer<T>::force_recompute_avg_sum() {
415- #ifdef DEBUG_ENABLED
416- // This class is not supposed to be used with 0 size.
417- CRASH_COND (data.size () <= 0 );
418- #endif
419- avg_sum = data[0 ];
420- for (uint32_t i = 1 ; i < data.size (); i += 1 ) {
421- avg_sum += data[i];
422- }
423- }
424-
425264// These data are used by the server and are never synchronized.
426265struct PeerAuthorityData {
427266 // Used to know if the peer is enabled.
@@ -451,7 +290,7 @@ struct PeerData {
451290 // / 100ms; the jitter will be 0.
452291 // / - If the time difference is either 150ms or 100ms, the jitter will tend
453292 // / towards 50ms.
454- float average_jitter_in_ms = 0.0 ;
293+ float latency_jitter_ms = 0.0 ;
455294
456295public:
457296 // In ms
@@ -463,11 +302,11 @@ struct PeerData {
463302 void set_compressed_latency (std::uint8_t p_compressed_latency) { compressed_latency = p_compressed_latency; }
464303 std::uint8_t get_compressed_latency () const { return compressed_latency; }
465304
466- void set_out_packet_loss_percentage (float p_packet_loss) { out_packet_loss_percentage = p_packet_loss; }
305+ void set_out_packet_loss_percentage (float p_packet_loss) { out_packet_loss_percentage = std::clamp ( p_packet_loss, 0 . 0f , 1 . 0f ) ; }
467306 float get_out_packet_loss_percentage () const { return out_packet_loss_percentage; }
468307
469- void set_average_jitter_in_ms (float p_jitter_ms) { average_jitter_in_ms = p_jitter_ms; }
470- float get_average_jitter_in_ms () const { return average_jitter_in_ms ; }
308+ void set_latency_jitter_ms (float p_jitter_ms) { latency_jitter_ms = p_jitter_ms; }
309+ float get_latency_jitter_ms () const { return latency_jitter_ms ; }
471310
472311 void make_controller ();
473312 PeerNetworkedController *get_controller () {
@@ -485,8 +324,11 @@ struct PeerServerData {
485324 // For new peers a full snapshot is needed.
486325 bool need_full_snapshot = true ;
487326
488- // How much time (seconds) from the latest net_stats update.
489- float netstats_update_sec = 0.0 ;
327+ // How much time (seconds) from the latest latency update sent via snapshot.
328+ float latency_update_via_snapshot_sec = 0.0 ;
329+
330+ // How much time (seconds) from the latest update sent to the client.
331+ float netstats_peer_update_sec = 0.0 ;
490332};
491333
492334struct SyncGroup {
0 commit comments