ReplicationState.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include "Node.h"
  25. #include "VectorBuffer.h"
  26. #include <list>
  27. /// A revision in the buffer
  28. struct Revision
  29. {
  30. /// Frame number stored on
  31. unsigned short frameNumber_;
  32. /// Offset in buffer
  33. unsigned offset_;
  34. };
  35. /// A buffer that can store several data revisions
  36. class RevisionBuffer : public VectorBuffer
  37. {
  38. public:
  39. /// Return oldest revision
  40. Deserializer& GetBase()
  41. {
  42. if (revisions_.Empty())
  43. return emptyBaseRevision;
  44. else
  45. {
  46. Seek(revisions_[0].offset_);
  47. return *this;
  48. }
  49. }
  50. /// Commit a revision
  51. void Commit(unsigned short frameNumber, VectorBuffer& data)
  52. {
  53. // Do not make zero-length commits
  54. if (!data.GetPosition())
  55. return;
  56. Revision newRevision;
  57. newRevision.frameNumber_ = frameNumber;
  58. newRevision.offset_ = GetSize();
  59. Seek(newRevision.offset_);
  60. // Note: write only up to source's current position, so that can use Seek() instead of resize() to write multiple commits
  61. // to the same buffer
  62. Write(data.GetData(), data.GetPosition());
  63. revisions_.Push(newRevision);
  64. }
  65. /// Clear revisions
  66. void Clear()
  67. {
  68. VectorBuffer::Clear();
  69. revisions_.Clear();
  70. }
  71. /// Purge revisions that are older than frame
  72. void PurgeOld(unsigned short frameNumber);
  73. /// Return whether has unacked revisions newer than frame
  74. bool HasUnAcked(unsigned short frameNumber) const;
  75. /// Return number of revisions
  76. unsigned GetCount() const { return revisions_.Size(); }
  77. private:
  78. /// Revision information
  79. PODVector<Revision> revisions_;
  80. /// Empty revision
  81. static VectorBuffer emptyBaseRevision;
  82. };
  83. /// Per-client component state for delta updates
  84. class ComponentReplicationState
  85. {
  86. public:
  87. /// Construct
  88. ComponentReplicationState();
  89. /// Mark that component was created
  90. void Created(unsigned short frameNumber);
  91. /// Mark that component was removed
  92. void Removed(unsigned short frameNumber);
  93. /// Mark that client acked state up to a specific frame
  94. void Acked(unsigned short lastAck);
  95. /// Return whether exists currently
  96. bool Exists() const { return exists_; }
  97. /// Return whether has no unsent changes and can be removed
  98. bool CanRemove() const;
  99. /// Return number of revisions
  100. unsigned GetRevisionCount() const { return revisions_.GetCount(); }
  101. /// Exists flag
  102. bool exists_;
  103. /// Frame number was created on
  104. unsigned short createdFrame_;
  105. /// Frame number was removed on
  106. unsigned short removedFrame_;
  107. /// Stored state revisions
  108. RevisionBuffer revisions_;
  109. };
  110. /// Per-client node state for delta updates
  111. class NodeReplicationState
  112. {
  113. public:
  114. /// Construct
  115. NodeReplicationState();
  116. /// Return per-client state for a component, or null if not found
  117. ComponentReplicationState* FindComponent(ShortStringHash combinedHash)
  118. {
  119. Map<ShortStringHash, ComponentReplicationState>::Iterator i = components_.Find(combinedHash);
  120. if (i != components_.End())
  121. return &i->second_;
  122. else
  123. return 0;
  124. }
  125. /// Mark that node was created
  126. void Created(unsigned short frameNumber);
  127. /// Mark that node was removed
  128. void Removed(unsigned short frameNumber);
  129. /// Mark that client acked state up to a specific frame
  130. void Acked(unsigned short lastAck);
  131. /// Return whether node exists currently
  132. bool Exists() const { return exists_; }
  133. /// Return whether has unacked state newer than frame
  134. bool HasUnAcked(unsigned short frameNumber) const;
  135. /// Return whether has no unsent changes and can be removed
  136. bool CanRemove() const;
  137. /// Return highest number of state revisions
  138. unsigned GetRevisionCount() const;
  139. /// Exists flag
  140. bool exists_;
  141. /// Frame number was created on
  142. unsigned short createdFrame_;
  143. /// Frame number was removed on
  144. unsigned short removedFrame_;
  145. /// Relevancy time counter in server frames
  146. int stayRelevantTime_;
  147. /// Stored state revisions
  148. RevisionBuffer revisions_;
  149. /// Component states
  150. Map<ShortStringHash, ComponentReplicationState> components_;
  151. };
  152. /// Per-client scene state for delta updates
  153. class SceneReplicationState
  154. {
  155. public:
  156. /// Return per-client state for an node, or null if not found
  157. NodeReplicationState* FindNode(unsigned id)
  158. {
  159. Map<unsigned, NodeReplicationState>::Iterator i = nodes_.Find(id);
  160. if (i != nodes_.End())
  161. return &(i->second_);
  162. else
  163. return 0;
  164. }
  165. /// Clear all stored state
  166. void Clear();
  167. /// Mark that client acked state up to a specific frame
  168. void Acked(unsigned short lastAck);
  169. /// Return highest number of revisions between all nodes
  170. unsigned GetRevisionCount() const;
  171. /// Node states
  172. Map<unsigned, NodeReplicationState> nodes_;
  173. };