Przeglądaj źródła

Removed NetworkState pointer from Serializable for better class memory layout control.

Lasse Öörni 13 lat temu
rodzic
commit
a7494cedc4

+ 7 - 7
Engine/Network/Connection.cpp

@@ -1049,7 +1049,7 @@ void Connection::ProcessNewNode(Node* node)
     node->AddReplicationState(&nodeState);
     
     // Write node's attributes
-    node->WriteInitialDeltaUpdate(msg_);
+    node->WriteInitialDeltaUpdate(msg_, node->GetNetworkState());
     
     // Write node's user variables
     const VariantMap& vars = node->GetVars();
@@ -1078,7 +1078,7 @@ void Connection::ProcessNewNode(Node* node)
         
         msg_.WriteShortStringHash(component->GetType());
         msg_.WriteNetID(component->GetID());
-        component->WriteInitialDeltaUpdate(msg_);
+        component->WriteInitialDeltaUpdate(msg_, component->GetNetworkState());
     }
     
     SendMessage(MSG_CREATENODE, true, true, msg_);
@@ -1129,7 +1129,7 @@ void Connection::ProcessExistingNode(Node* node, NodeReplicationState& nodeState
         {
             msg_.Clear();
             msg_.WriteNetID(node->GetID());
-            node->WriteLatestDataUpdate(msg_);
+            node->WriteLatestDataUpdate(msg_, node->GetNetworkState());
             
             SendMessage(MSG_NODELATESTDATA, true, false, msg_, node->GetID());
         }
@@ -1139,7 +1139,7 @@ void Connection::ProcessExistingNode(Node* node, NodeReplicationState& nodeState
         {
             msg_.Clear();
             msg_.WriteNetID(node->GetID());
-            node->WriteDeltaUpdate(msg_, nodeState.dirtyAttributes_);
+            node->WriteDeltaUpdate(msg_, node->GetNetworkState(), nodeState.dirtyAttributes_);
             
             // Write changed variables
             msg_.WriteVLE(nodeState.dirtyVars_.Size());
@@ -1207,7 +1207,7 @@ void Connection::ProcessExistingNode(Node* node, NodeReplicationState& nodeState
                 {
                     msg_.Clear();
                     msg_.WriteNetID(component->GetID());
-                    component->WriteLatestDataUpdate(msg_);
+                    component->WriteLatestDataUpdate(msg_, component->GetNetworkState());
                     
                     SendMessage(MSG_COMPONENTLATESTDATA, true, false, msg_, component->GetID());
                 }
@@ -1217,7 +1217,7 @@ void Connection::ProcessExistingNode(Node* node, NodeReplicationState& nodeState
                 {
                     msg_.Clear();
                     msg_.WriteNetID(component->GetID());
-                    component->WriteDeltaUpdate(msg_, componentState.dirtyAttributes_);
+                    component->WriteDeltaUpdate(msg_, component->GetNetworkState(), componentState.dirtyAttributes_);
                     
                     SendMessage(MSG_COMPONENTDELTAUPDATE, true, true, msg_);
                     
@@ -1252,7 +1252,7 @@ void Connection::ProcessExistingNode(Node* node, NodeReplicationState& nodeState
                 msg_.WriteNetID(node->GetID());
                 msg_.WriteShortStringHash(component->GetType());
                 msg_.WriteNetID(component->GetID());
-                component->WriteInitialDeltaUpdate(msg_);
+                component->WriteInitialDeltaUpdate(msg_, component->GetNetworkState());
                 
                 SendMessage(MSG_CREATECOMPONENT, true, true, msg_);
             }

+ 20 - 11
Engine/Scene/Component.cpp

@@ -36,12 +36,15 @@ Component::Component(Context* context) :
     Serializable(context),
     node_(0),
     id_(0),
+    networkState_(0),
     networkUpdate_(false)
 {
 }
 
 Component::~Component()
 {
+    delete networkState_;
+    networkState_ = 0;
 }
 
 void Component::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -88,41 +91,47 @@ Scene* Component::GetScene() const
 void Component::AddReplicationState(ComponentReplicationState* state)
 {
     if (!networkState_)
+    {
         networkState_ = new NetworkState();
+        networkState_->attributes_ = GetNetworkAttributes();
+    }
     
     networkState_->replicationStates_.Push(state);
 }
 
 void Component::PrepareNetworkUpdate()
 {
-    const Vector<AttributeInfo>* attributes = GetNetworkAttributes();
+    if (!networkState_)
+    {
+        networkState_ = new NetworkState();
+        networkState_->attributes_ = GetNetworkAttributes();
+    }
+    
+    const Vector<AttributeInfo>* attributes = networkState_->attributes_;
     if (!attributes)
         return;
     
     unsigned numAttributes = attributes->Size();
     
-    if (!networkState_)
-        networkState_ = new NetworkState();
-    
-    if (networkState_->attributes_.Size() != numAttributes)
+    if (networkState_->currentValues_.Size() != numAttributes)
     {
-        networkState_->attributes_.Resize(numAttributes);
-        networkState_->previousAttributes_.Resize(numAttributes);
+        networkState_->currentValues_.Resize(numAttributes);
+        networkState_->previousValues_.Resize(numAttributes);
         
         // Copy the default attribute values to the previous state as a starting point
         for (unsigned i = 0; i < numAttributes; ++i)
-            networkState_->previousAttributes_[i] = attributes->At(i).defaultValue_;
+            networkState_->previousValues_[i] = attributes->At(i).defaultValue_;
     }
     
     // Check for attribute changes
     for (unsigned i = 0; i < numAttributes; ++i)
     {
         const AttributeInfo& attr = attributes->At(i);
-        OnGetAttribute(attr, networkState_->attributes_[i]);
+        OnGetAttribute(attr, networkState_->currentValues_[i]);
         
-        if (networkState_->attributes_[i] != networkState_->previousAttributes_[i])
+        if (networkState_->currentValues_[i] != networkState_->previousValues_[i])
         {
-            networkState_->previousAttributes_[i] = networkState_->attributes_[i];
+            networkState_->previousValues_[i] = networkState_->currentValues_[i];
             
             // Mark the attribute dirty in all replication states that are tracking this component
             for (PODVector<ReplicationState*>::Iterator j = networkState_->replicationStates_.Begin(); j !=

+ 4 - 0
Engine/Scene/Component.h

@@ -80,6 +80,8 @@ public:
     void CleanupConnection(Connection* connection);
     /// Mark for attribute check on the next network update.
     void MarkNetworkUpdate();
+    /// Return the network attribute state.
+    NetworkState* GetNetworkState() const { return networkState_; }
     
 protected:
     /// Handle scene node being assigned at creation.
@@ -95,6 +97,8 @@ protected:
     Node* node_;
     /// Unique ID within the scene.
     unsigned id_;
+    /// Network attribute state.
+    NetworkState* networkState_;
     /// Network update queued flag.
     bool networkUpdate_;
 };

+ 22 - 12
Engine/Scene/Node.cpp

@@ -51,7 +51,8 @@ Node::Node(Context* context) :
     position_(Vector3::ZERO),
     rotation_(Quaternion::IDENTITY),
     scale_(Vector3::ONE),
-    owner_(0)
+    owner_(0),
+    networkState_(0)
 {
 }
 
@@ -63,6 +64,9 @@ Node::~Node()
     // Remove from the scene
     if (scene_)
         scene_->NodeRemoved(this);
+    
+    delete networkState_;
+    networkState_ = 0;
 }
 
 void Node::RegisterObject(Context* context)
@@ -221,7 +225,10 @@ void Node::ApplyAttributes()
 void Node::AddReplicationState(NodeReplicationState* state)
 {
     if (!networkState_)
+    {
         networkState_ = new NetworkState();
+        networkState_->attributes_ = GetNetworkAttributes();
+    }
     
     networkState_->replicationStates_.Push(state);
 }
@@ -857,31 +864,34 @@ void Node::PrepareNetworkUpdate()
     }
     
     // Then check for node attribute changes
-    const Vector<AttributeInfo>* attributes = GetNetworkAttributes();
-    unsigned numAttributes = attributes->Size();
-    
     if (!networkState_)
+    {
         networkState_ = new NetworkState();
+        networkState_->attributes_ = GetNetworkAttributes();
+    }
+    
+    const Vector<AttributeInfo>* attributes = networkState_->attributes_;
+    unsigned numAttributes = attributes->Size();
     
-    if (networkState_->attributes_.Size() != numAttributes)
+    if (networkState_->currentValues_.Size() != numAttributes)
     {
-        networkState_->attributes_.Resize(numAttributes);
-        networkState_->previousAttributes_.Resize(numAttributes);
+        networkState_->currentValues_.Resize(numAttributes);
+        networkState_->previousValues_.Resize(numAttributes);
         
         // Copy the default attribute values to the previous state as a starting point
         for (unsigned i = 0; i < numAttributes; ++i)
-            networkState_->previousAttributes_[i] = attributes->At(i).defaultValue_;
+            networkState_->previousValues_[i] = attributes->At(i).defaultValue_;
     }
     
     // Check for attribute changes
     for (unsigned i = 0; i < numAttributes; ++i)
     {
         const AttributeInfo& attr = attributes->At(i);
-        OnGetAttribute(attr, networkState_->attributes_[i]);
+        OnGetAttribute(attr, networkState_->currentValues_[i]);
         
-        if (networkState_->attributes_[i] != networkState_->previousAttributes_[i])
+        if (networkState_->currentValues_[i] != networkState_->previousValues_[i])
         {
-            networkState_->previousAttributes_[i] = networkState_->attributes_[i];
+            networkState_->previousValues_[i] = networkState_->currentValues_[i];
             
             // Mark the attribute dirty in all replication states that are tracking this node
             for (PODVector<ReplicationState*>::Iterator j = networkState_->replicationStates_.Begin(); j !=
@@ -900,7 +910,7 @@ void Node::PrepareNetworkUpdate()
             }
         }
     }
-
+    
     // Finally check for user var changes
     for (VariantMap::ConstIterator i = vars_.Begin(); i != vars_.End(); ++i)
     {

+ 5 - 1
Engine/Scene/Node.h

@@ -317,6 +317,8 @@ public:
     void MarkNetworkUpdate();
     /// Mark node dirty in scene replication states.
     void MarkReplicationDirty();
+    /// Return the network attribute state.
+    NetworkState* GetNetworkState() const { return networkState_; }
     
 protected:
     /// Create a component with specific ID.
@@ -364,7 +366,7 @@ private:
     Vector<WeakPtr<Component> > listeners_;
     /// Nodes this node depends on for network updates.
     PODVector<Node*> dependencyNodes_;
-    /// Owner connection in networking.
+    /// Network owner connection.
     Connection* owner_;
     /// Name.
     String name_;
@@ -374,6 +376,8 @@ private:
     mutable VectorBuffer attrBuffer_;
     
 protected:
+    /// Network attribute state.
+    NetworkState* networkState_;
     /// User variables.
     VariantMap vars_;
 };

+ 6 - 4
Engine/Scene/ReplicationState.h

@@ -121,10 +121,12 @@ struct DirtyBits
 /// Per-object attribute state for network replication, allocated on demand.
 struct NetworkState
 {
-    /// Current network attributes.
-    Vector<Variant> attributes_;
-    /// Previous network attributes.
-    Vector<Variant> previousAttributes_;
+    /// Cached network attribute infos.
+    const Vector<AttributeInfo>* attributes_;
+    /// Current network attribute values.
+    Vector<Variant> currentValues_;
+    /// Previous network attribute values.
+    Vector<Variant> previousValues_;
     /// Replication states that are tracking this object.
     PODVector<ReplicationState*> replicationStates_;
     /// Previous user variables.

+ 23 - 26
Engine/Scene/Serializable.cpp

@@ -35,15 +35,12 @@
 OBJECTTYPESTATIC(Serializable);
 
 Serializable::Serializable(Context* context) :
-    Object(context),
-    networkState_(0)
+    Object(context)
 {
 }
 
 Serializable::~Serializable()
 {
-    delete networkState_;
-    networkState_ = 0;
 }
 
 void Serializable::OnSetAttribute(const AttributeInfo& attr, const Variant& src)
@@ -415,18 +412,18 @@ bool Serializable::SetAttribute(const String& name, const Variant& value)
     return false;
 }
 
-void Serializable::WriteInitialDeltaUpdate(Serializer& dest)
+void Serializable::WriteInitialDeltaUpdate(Serializer& dest, NetworkState* state)
 {
-    const Vector<AttributeInfo>* attributes = GetNetworkAttributes();
-    if (!attributes)
-        return;
-    
-    if (!networkState_)
+    if (!state)
     {
         LOGERROR("WriteInitialDeltaUpdate called without allocated NetworkState");
         return;
     }
     
+    const Vector<AttributeInfo>* attributes = state->attributes_;
+    if (!attributes)
+        return;
+    
     unsigned numAttributes = attributes->Size();
     DirtyBits attributeBits;
     
@@ -434,7 +431,7 @@ void Serializable::WriteInitialDeltaUpdate(Serializer& dest)
     for (unsigned i = 0; i < numAttributes; ++i)
     {
         const AttributeInfo& attr = attributes->At(i);
-        if (networkState_->attributes_[i] != attr.defaultValue_)
+        if (state->currentValues_[i] != attr.defaultValue_)
             attributeBits.Set(i);
     }
     
@@ -444,22 +441,22 @@ void Serializable::WriteInitialDeltaUpdate(Serializer& dest)
     for (unsigned i = 0; i < numAttributes; ++i)
     {
         if (attributeBits.IsSet(i))
-            dest.WriteVariantData(networkState_->attributes_[i]);
+            dest.WriteVariantData(state->currentValues_[i]);
     }
 }
 
-void Serializable::WriteDeltaUpdate(Serializer& dest, const DirtyBits& attributeBits)
+void Serializable::WriteDeltaUpdate(Serializer& dest, NetworkState* state, const DirtyBits& attributeBits)
 {
-    const Vector<AttributeInfo>* attributes = GetNetworkAttributes();
-    if (!attributes)
-        return;
-    
-    if (!networkState_)
+    if (!state)
     {
         LOGERROR("WriteDeltaUpdate called without allocated NetworkState");
         return;
     }
     
+    const Vector<AttributeInfo>* attributes = state->attributes_;
+    if (!attributes)
+        return;
+    
     unsigned numAttributes = attributes->Size();
     
     // First write the change bitfield, then attribute data for changed attributes
@@ -469,28 +466,28 @@ void Serializable::WriteDeltaUpdate(Serializer& dest, const DirtyBits& attribute
     for (unsigned i = 0; i < numAttributes; ++i)
     {
         if (attributeBits.IsSet(i))
-            dest.WriteVariantData(networkState_->attributes_[i]);
+            dest.WriteVariantData(state->currentValues_[i]);
     }
 }
 
-void Serializable::WriteLatestDataUpdate(Serializer& dest)
+void Serializable::WriteLatestDataUpdate(Serializer& dest, NetworkState* state)
 {
-    const Vector<AttributeInfo>* attributes = GetNetworkAttributes();
-    if (!attributes)
-        return;
-    
-    if (!networkState_)
+    if (!state)
     {
         LOGERROR("WriteLatestDataUpdate called without allocated NetworkState");
         return;
     }
     
+    const Vector<AttributeInfo>* attributes = state->attributes_;
+    if (!attributes)
+        return;
+    
     unsigned numAttributes = attributes->Size();
     
     for (unsigned i = 0; i < numAttributes; ++i)
     {
         if (attributes->At(i).mode_ & AM_LATESTDATA)
-            dest.WriteVariantData(networkState_->attributes_[i]);
+            dest.WriteVariantData(state->currentValues_[i]);
     }
 }
 

+ 3 - 7
Engine/Scene/Serializable.h

@@ -68,11 +68,11 @@ public:
     /// %Set attribute by name. Return true if successfully set.
     bool SetAttribute(const String& name, const Variant& value);
     /// Write initial delta network update.
-    void WriteInitialDeltaUpdate(Serializer& dest);
+    void WriteInitialDeltaUpdate(Serializer& dest, NetworkState* state);
     /// Write a delta network update according to dirty attribute bits.
-    void WriteDeltaUpdate(Serializer& dest, const DirtyBits& attributeBits);
+    void WriteDeltaUpdate(Serializer& dest, NetworkState* state, const DirtyBits& attributeBits);
     /// Write a latest data network update.
-    void WriteLatestDataUpdate(Serializer& dest);
+    void WriteLatestDataUpdate(Serializer& dest, NetworkState* state);
     /// Read and apply a network delta update.
     void ReadDeltaUpdate(Deserializer& source);
     /// Read and apply a network latest data update.
@@ -90,10 +90,6 @@ public:
     const Vector<AttributeInfo>* GetAttributes() const;
     /// Return network replication attribute descriptions, or null if none defined.
     const Vector<AttributeInfo>* GetNetworkAttributes() const;
-    
-protected:
-    /// Network attribute state.
-    NetworkState* networkState_;
 };
 
 /// Template implementation of the attribute accessor invoke helper class.