Bladeren bron

Added virtual function to Component for handling node enabled/disabled change. This optimizes StaticModelGroup to not have to subscribe to the scene-global change event.

Lasse Öörni 12 jaren geleden
bovenliggende
commit
2e178f1976

+ 1 - 1
Bin/Data/Scripts/Editor/EditorScene.as

@@ -48,7 +48,7 @@ void ClearSceneSelection()
 void CreateScene()
 {
     // Create a scene only once here
-    editorScene = Scene("");
+    editorScene = Scene();
 
     // Allow access to the scene from the console
     script.defaultScene = editorScene;

+ 9 - 24
Source/Engine/Graphics/StaticModelGroup.cpp

@@ -25,7 +25,6 @@
 #include "Camera.h"
 #include "Context.h"
 #include "Scene.h"
-#include "SceneEvents.h"
 #include "StaticModelGroup.h"
 
 #include "DebugNew.h"
@@ -95,7 +94,7 @@ void StaticModelGroup::AddInstanceNode(Node* node)
     if (instanceNodes_.Contains(instanceWeak))
         return;
     
-    // Add as a transform listener, so that we know to dirty the instance transforms
+    // Add as a listener for the instance node, so that we know to dirty the transforms when the node moves or is enabled/disabled
     node->AddListener(this);
     instanceNodes_.Push(instanceWeak);
 }
@@ -115,20 +114,13 @@ Node* StaticModelGroup::GetInstanceNode(unsigned index) const
     return index < instanceNodes_.Size() ? instanceNodes_[index] : (Node*)0;
 }
 
-void StaticModelGroup::OnNodeSet(Node* node)
+void StaticModelGroup::OnMarkedDirty(Node* node)
 {
-    Drawable::OnNodeSet(node);
-
-    if (node)
-    {
-        Scene* scene = GetScene();
-        /// \todo It is non-optimal to listen to enabled/disabled change events from the whole scene. The nodes themselves should send an event
-        if (scene)
-            SubscribeToEvent(scene, E_NODEENABLEDCHANGED, HANDLER(StaticModelGroup, HandleNodeEnabledChanged));
-    }
+    Drawable::OnMarkedDirty(node);
+    transformsDirty_ = true;
 }
 
-void StaticModelGroup::OnMarkedDirty(Node* node)
+void StaticModelGroup::OnNodeSetEnabled(Node* node)
 {
     Drawable::OnMarkedDirty(node);
     transformsDirty_ = true;
@@ -146,26 +138,19 @@ void StaticModelGroup::OnWorldBoundingBoxUpdate()
 
 void StaticModelGroup::UpdateTransforms()
 {
-    worldTransforms_.Clear();
+    worldTransforms_.Resize(instanceNodes_.Size());
+    unsigned index = 0;
 
     for (unsigned i = 0; i < instanceNodes_.Size(); ++i)
     {
         Node* instanceNode = instanceNodes_[i];
         if (!instanceNode || !instanceNode->IsEnabled())
             continue;
-        worldTransforms_.Push(instanceNode->GetWorldTransform());
+        worldTransforms_[index++] = instanceNode->GetWorldTransform();
     }
     
+    worldTransforms_.Resize(index);
     transformsDirty_ = false;
 }
 
-void StaticModelGroup::HandleNodeEnabledChanged(StringHash eventType, VariantMap& eventData)
-{
-    using namespace NodeEnabledChanged;
-
-    WeakPtr<Node> instanceWeak((Node*)eventData[P_NODE].GetPtr());
-    if (instanceNodes_.Contains(instanceWeak))
-        OnMarkedDirty(instanceWeak);
-}
-
 }

+ 2 - 4
Source/Engine/Graphics/StaticModelGroup.h

@@ -60,18 +60,16 @@ public:
     Node* GetInstanceNode(unsigned index) const;
     
 protected:
-    /// Handle node being assigned.
-    virtual void OnNodeSet(Node* node);
    /// Handle node transform being dirtied.
     virtual void OnMarkedDirty(Node* node);
+    /// Handle scene node enabled status changing.
+    virtual void OnNodeSetEnabled(Node* node);
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     
 private:
     /// Gather the instances' transforms.
     void UpdateTransforms();
-    /// Handle an instance node being enabled/disabled.
-    void HandleNodeEnabledChanged(StringHash eventType, VariantMap& eventData);
     
     /// Instance nodes.
     Vector<WeakPtr<Node> > instanceNodes_;

+ 2 - 0
Source/Engine/Scene/Component.h

@@ -98,6 +98,8 @@ protected:
     virtual void OnNodeSet(Node* node) {};
     /// Handle scene node transform dirtied.
     virtual void OnMarkedDirty(Node* node) {};
+    /// Handle scene node enabled status changing.
+    virtual void OnNodeSetEnabled(Node* node) {};
     /// Set ID. Called by Scene.
     void SetID(unsigned id);
     /// Set scene node. Called by Node when creating the component.

+ 27 - 11
Source/Engine/Scene/Node.cpp

@@ -230,21 +230,24 @@ bool Node::SaveXML(Serializer& dest) const
 
 void Node::SetName(const String& name)
 {
-    name_ = name;
-    nameHash_ = name_;
+    if (name != name_)
+    {
+        name_ = name;
+        nameHash_ = name_;
 
-    MarkNetworkUpdate();
+        MarkNetworkUpdate();
 
-    // Send change event
-    if (scene_)
-    {
-        using namespace NodeNameChanged;
+        // Send change event
+        if (scene_)
+        {
+            using namespace NodeNameChanged;
 
-        VariantMap eventData;
-        eventData[P_SCENE] = (void*)scene_;
-        eventData[P_NODE] = (void*)this;
+            VariantMap eventData;
+            eventData[P_SCENE] = (void*)scene_;
+            eventData[P_NODE] = (void*)this;
 
-        scene_->SendEvent(E_NODENAMECHANGED, eventData);
+            scene_->SendEvent(E_NODENAMECHANGED, eventData);
+        }
     }
 }
 
@@ -437,6 +440,19 @@ void Node::SetEnabled(bool enable, bool recursive)
 
         MarkNetworkUpdate();
 
+        // Notify listener components of the state change
+        for (Vector<WeakPtr<Component> >::Iterator i = listeners_.Begin(); i != listeners_.End();)
+        {
+            if (*i)
+            {
+                (*i)->OnNodeSetEnabled(this);
+                ++i;
+            }
+            // If listener has expired, erase from list
+            else
+                i = listeners_.Erase(i);
+        }
+
         // Send change event
         if (scene_)
         {

+ 1 - 1
Source/Engine/UI/UIElement.h

@@ -575,7 +575,7 @@ private:
     SharedPtr<XMLFile> defaultStyle_;
     /// Traversal mode.
     TraversalMode traversalMode_;
-    /// Element creation/deletion event sender flag.
+    /// Flag whether node should send child added / removed events by itself.
     bool elementEventSender_;
     /// XPath query for selecting UI-style.
     static XPathQuery styleXPathQuery_;