ReplicationState.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. #include "Precompiled.h"
  24. #include "Protocol.h"
  25. #include "ReplicationState.h"
  26. #include <cstring>
  27. #include "DebugNew.h"
  28. VectorBuffer RevisionBuffer::emptyBaseRevision;
  29. void RevisionBuffer::PurgeOld(unsigned short frameNumber)
  30. {
  31. // Remove revisions which are older than last ack, but make sure at least 1 revision remains
  32. if (!revisions_.size())
  33. return;
  34. unsigned eraseCount = 0;
  35. for (std::vector<Revision>::iterator i = revisions_.begin(); (i != revisions_.end() - 1) &&
  36. (revisions_.size() - eraseCount > 1); ++i)
  37. {
  38. // If oldest and second-oldest are both older than framenumber, or if the second-oldest is on the exact same frame,
  39. // can delete the oldest
  40. std::vector<Revision>::iterator j = i + 1;
  41. if ((j->frameNumber_ == frameNumber) || ((!CheckFrameNumber(i->frameNumber_, frameNumber)) &&
  42. (!CheckFrameNumber(j->frameNumber_, frameNumber))))
  43. eraseCount++;
  44. else
  45. break;
  46. }
  47. if (eraseCount)
  48. {
  49. revisions_.erase(revisions_.begin(), revisions_.begin() + eraseCount);
  50. // Move the data and datapointers
  51. unsigned delta = revisions_[0].offset_;
  52. void* src = GetModifiableData() + delta;
  53. void* dest = GetModifiableData();
  54. memmove(dest, src, GetSize() - delta);
  55. Resize(GetSize() - delta);
  56. for (std::vector<Revision>::iterator i = revisions_.begin(); i != revisions_.end(); ++i)
  57. i->offset_ -= delta;
  58. }
  59. }
  60. bool RevisionBuffer::HasUnAcked(unsigned short frameNumber) const
  61. {
  62. for (std::vector<Revision>::const_iterator i = revisions_.begin(); i != revisions_.end(); ++i)
  63. {
  64. if (CheckFrameNumber(i->frameNumber_, frameNumber, false))
  65. return true;
  66. }
  67. return false;
  68. }
  69. ComponentReplicationState::ComponentReplicationState() :
  70. exists_(true),
  71. createdFrame_(0),
  72. removedFrame_(0)
  73. {
  74. }
  75. void ComponentReplicationState::Created(unsigned short frameNumber)
  76. {
  77. exists_ = true;
  78. createdFrame_ = frameNumber;
  79. removedFrame_ = 0;
  80. }
  81. void ComponentReplicationState::Removed(unsigned short frameNumber)
  82. {
  83. exists_ = false;
  84. createdFrame_ = 0;
  85. removedFrame_ = frameNumber;
  86. // Clear revisions in case this component gets recreated
  87. revisions_.Clear();
  88. }
  89. void ComponentReplicationState::Acked(unsigned short lastAck)
  90. {
  91. // If ack is newer or same age than the creation or removal event, reset it
  92. if ((createdFrame_) && (CheckFrameNumber(lastAck, createdFrame_)))
  93. createdFrame_ = 0;
  94. if ((removedFrame_) && (CheckFrameNumber(lastAck, removedFrame_)))
  95. removedFrame_ = 0;
  96. // Remove old data revisions
  97. revisions_.PurgeOld(lastAck);
  98. }
  99. bool ComponentReplicationState::CanRemove() const
  100. {
  101. // Can be removed from the replication state if no longer exists, and the remove has been acked
  102. return (!exists_) && (!removedFrame_);
  103. }
  104. NodeReplicationState::NodeReplicationState() :
  105. exists_(true),
  106. createdFrame_(0),
  107. removedFrame_(0),
  108. stayRelevantTime_(0)
  109. {
  110. }
  111. void NodeReplicationState::Created(unsigned short frameNumber)
  112. {
  113. exists_ = true;
  114. createdFrame_ = frameNumber;
  115. removedFrame_ = 0;
  116. }
  117. void NodeReplicationState::Removed(unsigned short frameNumber)
  118. {
  119. exists_ = false;
  120. createdFrame_ = 0;
  121. removedFrame_ = frameNumber;
  122. // Clear property revisions & components in case this node gets recreated
  123. revisions_.Clear();
  124. components_.clear();
  125. }
  126. void NodeReplicationState::Acked(unsigned short lastAck)
  127. {
  128. // If ack is newer or same age than the creation or removal event, reset it
  129. if ((createdFrame_) && (CheckFrameNumber(lastAck, createdFrame_)))
  130. createdFrame_ = 0;
  131. if ((removedFrame_) && (CheckFrameNumber(lastAck, removedFrame_)))
  132. removedFrame_ = 0;
  133. // Remove old property revisions
  134. revisions_.PurgeOld(lastAck);
  135. // Ack each component and remove if necessary
  136. for (std::map<ShortStringHash, ComponentReplicationState>::iterator j = components_.begin(); j != components_.end();)
  137. {
  138. std::map<ShortStringHash, ComponentReplicationState>::iterator component = j;
  139. ++j;
  140. component->second.Acked(lastAck);
  141. if (component->second.CanRemove())
  142. components_.erase(component);
  143. }
  144. }
  145. bool NodeReplicationState::HasUnAcked(unsigned short frameNumber) const
  146. {
  147. if (revisions_.HasUnAcked(frameNumber))
  148. return true;
  149. for (std::map<ShortStringHash, ComponentReplicationState>::const_iterator i = components_.begin(); i != components_.end(); ++i)
  150. {
  151. if (i->second.revisions_.HasUnAcked(frameNumber))
  152. return true;
  153. }
  154. return false;
  155. }
  156. bool NodeReplicationState::CanRemove() const
  157. {
  158. // Can be removed from the replication state if no longer exists, and the remove has been acked
  159. return (!exists_) && (!removedFrame_);
  160. }
  161. unsigned NodeReplicationState::GetRevisionCount() const
  162. {
  163. // Return the highest of property revisions and component revisions
  164. int maxRevisions = revisions_.GetCount();
  165. for (std::map<ShortStringHash, ComponentReplicationState>::const_iterator i = components_.begin(); i != components_.end(); ++i)
  166. maxRevisions = Max((int)maxRevisions, (int)i->second.GetRevisionCount());
  167. return maxRevisions;
  168. }
  169. void SceneReplicationState::Clear()
  170. {
  171. nodes_.clear();
  172. }
  173. void SceneReplicationState::Acked(unsigned short lastAck)
  174. {
  175. // Ack each node and remove if necessary
  176. for (std::map<unsigned, NodeReplicationState>::iterator i = nodes_.begin(); i != nodes_.end();)
  177. {
  178. std::map<unsigned, NodeReplicationState>::iterator node = i;
  179. ++i;
  180. node->second.Acked(lastAck);
  181. if (node->second.CanRemove())
  182. nodes_.erase(node);
  183. }
  184. }
  185. unsigned SceneReplicationState::GetRevisionCount() const
  186. {
  187. // Get the highest revision count of all nodes;
  188. int maxRevisions = 0;
  189. for (std::map<unsigned, NodeReplicationState>::const_iterator i = nodes_.begin(); i != nodes_.end(); ++i)
  190. maxRevisions = Max((int)maxRevisions, (int)i->second.GetRevisionCount());
  191. return maxRevisions;
  192. }