From 1c06c8652c8a3204c207ff0cff91e977be83d96b Mon Sep 17 00:00:00 2001
From: Dale Glass <dale@daleglass.net>
Date: Fri, 2 Dec 2022 01:54:22 +0100
Subject: [PATCH] Add serializer size tracker, update documentation

---
 libraries/gpu/src/gpu/Texture.h |  6 +++
 libraries/shared/src/SerDes.h   | 86 +++++++++++++++++++++++++++++++--
 2 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h
index 8370462c5a..05ad70b872 100644
--- a/libraries/gpu/src/gpu/Texture.h
+++ b/libraries/gpu/src/gpu/Texture.h
@@ -94,6 +94,8 @@ typedef std::shared_ptr< SphericalHarmonics > SHPointer;
 
 
 inline DataSerializer &operator<<(DataSerializer &ser, const SphericalHarmonics &h) {
+    DataSerializer::SizeTracker tracker(ser);
+
     ser << h.L00  << h.spare0;
     ser << h.L1m1 << h.spare1;
     ser << h.L10  << h.spare2;
@@ -107,6 +109,8 @@ inline DataSerializer &operator<<(DataSerializer &ser, const SphericalHarmonics
 }
 
 inline DataDeserializer &operator>>(DataDeserializer &des, SphericalHarmonics &h) {
+    DataDeserializer::SizeTracker tracker(des);
+
     des >> h.L00  >> h.spare0;
     des >> h.L1m1 >> h.spare1;
     des >> h.L10  >> h.spare2;
@@ -238,6 +242,7 @@ protected:
 };
 
 inline DataSerializer &operator<<(DataSerializer &ser, const Sampler::Desc &d) {
+    DataSerializer::SizeTracker tracker(ser);
     ser << d._borderColor;
     ser << d._maxAnisotropy;
     ser << d._filter;
@@ -252,6 +257,7 @@ inline DataSerializer &operator<<(DataSerializer &ser, const Sampler::Desc &d) {
 }
 
 inline DataDeserializer &operator>>(DataDeserializer &dsr, Sampler::Desc &d) {
+    DataDeserializer::SizeTracker tracker(dsr);
     dsr >> d._borderColor;
     dsr >> d._maxAnisotropy;
     dsr >> d._filter;
diff --git a/libraries/shared/src/SerDes.h b/libraries/shared/src/SerDes.h
index b0371d4b95..4c97ef193b 100644
--- a/libraries/shared/src/SerDes.h
+++ b/libraries/shared/src/SerDes.h
@@ -49,7 +49,7 @@
  * classes and structures, implement a `operator<<` and `operator>>` functions for that object, eg:
  *
  * @code {.cpp}
- * Serializer &operator<<(Serializer &ser, const Object &o) {
+ * DataSerializer &operator<<(DataSerializer &ser, const Object &o) {
  *  ser << o._borderColor;
  *  ser << o._maxAnisotropy;
  *  ser << o._filter;
@@ -60,6 +60,46 @@
  */
 class DataSerializer {
     public:
+
+        /**
+         * @brief RAII tracker of advance position
+         *
+         * When a custom operator<< is implemented for DataSserializer,
+         * this class allows to easily keep track of how much data has been added and
+         * adjust the parent's lastAdvance() count on this class' destruction.
+         *
+         * @code {.cpp}
+         * DataSerializer &operator<<(DataSerializer &ser, const Object &o) {
+         *  DataSerializer::SizeTracker tracker(ser);
+         *
+         *  ser << o._borderColor;
+         *  ser << o._maxAnisotropy;
+         *  ser << o._filter;
+         *  return ser;
+         * }
+         * @endcode
+         */
+        class SizeTracker {
+            public:
+            SizeTracker(DataSerializer &parent) : _parent(parent) {
+                _start_pos = _parent.pos();
+            }
+
+            ~SizeTracker() {
+                size_t cur_pos = _parent.pos();
+
+                if ( cur_pos >= _start_pos ) {
+                    _parent._lastAdvance = cur_pos - _start_pos;
+                } else {
+                    _parent._lastAdvance = 0;
+                }
+            }
+
+            private:
+            DataSerializer &_parent;
+            size_t _start_pos = 0;
+        };
+
         /**
          * @brief Default size for a dynamically allocated buffer.
          *
@@ -511,7 +551,7 @@ class DataSerializer {
  * uint16_t count;
  * glm::vec3 pos;
  *
- * Deserializer des(buffer, sizeof(buffer));
+ * DataDeserializer des(buffer, sizeof(buffer));
  * des >> version;
  * des >> count;
  * des >> pos;
@@ -521,7 +561,7 @@ class DataSerializer {
  * classes and structures, implement an `operator>>` function for that object, eg:
  *
  * @code {.cpp}
- * Deserializer &operator>>(Deserializer &des, Object &o) {
+ * DataDeserializer &operator>>(DataDeserializer &des, Object &o) {
  *  des >> o._borderColor;
  *  des >> o._maxAnisotropy;
  *  des >> o._filter;
@@ -532,6 +572,46 @@ class DataSerializer {
  */
 class DataDeserializer {
     public:
+
+        /**
+         * @brief RAII tracker of advance position
+         *
+         * When a custom operator>> is implemented for DataDeserializer,
+         * this class allows to easily keep track of how much data has been added and
+         * adjust the parent's lastAdvance() count on this class' destruction.
+         *
+         * @code {.cpp}
+         * DataDeserializer &operator>>(Deserializer &des, Object &o) {
+         *  DataDeserializer::SizeTracker tracker(des);
+         *
+         *  des >> o._borderColor;
+         *  des >> o._maxAnisotropy;
+         *  des >> o._filter;
+         *  return des;
+         * }
+         * @endcode
+         */
+        class SizeTracker {
+            public:
+            SizeTracker(DataDeserializer &parent) : _parent(parent) {
+                _start_pos = _parent.pos();
+            }
+
+            ~SizeTracker() {
+                size_t cur_pos = _parent.pos();
+
+                if ( cur_pos >= _start_pos ) {
+                    _parent._lastAdvance = cur_pos - _start_pos;
+                } else {
+                    _parent._lastAdvance = 0;
+                }
+            }
+
+            private:
+            DataDeserializer &_parent;
+            size_t _start_pos = 0;
+        };
+
         /**
          * @brief Construct a Deserializer
          *         *