Make NodePropertyFlags typesafe by using enum class 67/191467/6
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Wed, 17 Oct 2018 09:24:49 +0000 (10:24 +0100)
committerKimmo Hoikka <kimmo.hoikka@samsung.com>
Wed, 17 Oct 2018 14:28:47 +0000 (15:28 +0100)
Change-Id: I994270523f319cf30c23edff4d7a6bd42cc62270

automated-tests/src/dali/utc-Dali-Actor.cpp
dali/devel-api/common/bitwise-enum.h [new file with mode: 0644]
dali/devel-api/file.list
dali/internal/update/manager/update-algorithms.cpp
dali/internal/update/manager/update-algorithms.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/nodes/node-declarations.h
dali/internal/update/nodes/node.cpp
dali/internal/update/nodes/node.h
dali/internal/update/render-tasks/scene-graph-camera.cpp

index b0a5138..2fede1b 100644 (file)
@@ -1660,6 +1660,41 @@ int UtcDaliActorSetInheritPosition(void)
   END_TEST;
 }
 
+int UtcDaliActorInheritOpacity(void)
+{
+  tet_infoline("Testing Actor::Inherit Opacity");
+  TestApplication application;
+
+  Actor parent = Actor::New();
+  Actor child = Actor::New();
+  parent.Add( child );
+  Stage::GetCurrent().Add( parent );
+
+  DALI_TEST_EQUALS( parent.GetProperty( Actor::Property::COLOR_ALPHA ).Get<float>(), 1.0f, 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( child.GetProperty( Actor::Property::COLOR_ALPHA ).Get<float>(), 1.0f, 0.0001f, TEST_LOCATION );
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  parent.SetOpacity( 0.1f );
+
+  DALI_TEST_EQUALS( parent.GetProperty( Actor::Property::COLOR_ALPHA ).Get<float>(), 0.1f, 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( child.GetProperty( Actor::Property::COLOR_ALPHA ).Get<float>(), 1.0f, 0.0001f, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( parent.GetProperty( Actor::Property::WORLD_COLOR ).Get<Vector4>(), Vector4(1.f, 1.f, 1.f, 0.1f), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( parent.GetCurrentProperty( Actor::Property::COLOR_ALPHA ).Get<float>(), 0.1f, 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( parent.GetCurrentProperty( Actor::Property::WORLD_COLOR ).Get<Vector4>(), Vector4(1.f, 1.f, 1.f, 0.1f), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( child.GetProperty( Actor::Property::WORLD_COLOR ).Get<Vector4>(), Vector4(1.f, 1.f, 1.f, 0.1f), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( child.GetCurrentProperty( Actor::Property::WORLD_COLOR ).Get<Vector4>(), Vector4(1.f, 1.f, 1.f, 0.1f), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( child.GetCurrentProperty( Actor::Property::COLOR_ALPHA ).Get<float>(), 1.f, 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
 // SetOrientation(float angleRadians, Vector3 axis)
 int UtcDaliActorSetOrientation01(void)
 {
diff --git a/dali/devel-api/common/bitwise-enum.h b/dali/devel-api/common/bitwise-enum.h
new file mode 100644 (file)
index 0000000..2717a92
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef DALI_BITWISE_ENUM_H
+#define DALI_BITWISE_ENUM_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <type_traits> // std::enable_if, std::underlying_type
+
+namespace Dali
+{
+
+/**
+ * Type traits and methods to enable type safe bit field operators for an enum.
+ * usage:
+ *   template<> struct EnableBitMaskOperators< MyEnumType > { static const bool ENABLE = true; };
+ * after this one can set bitfields with | and |=, like
+ *   MyEnumType value = FLAG1 | FLAG2;
+ * and test them with &, like:
+ *   if( myFlag & FLAG2 )
+ *    // do something
+ */
+template< typename Enum >
+struct EnableBitMaskOperators
+{
+  static const bool ENABLE = false; // can't be constexpr as it's a data member
+};
+
+/**
+ * Combine two bitfields
+ * @param lhs bitfield to or
+ * @param rhs bitfield to or
+ * @return EnumType with both flags set
+ */
+template < typename EnumType >
+inline typename std::enable_if< EnableBitMaskOperators< EnumType >::ENABLE, EnumType >::type operator|( EnumType lhs, EnumType rhs )
+{
+  using UnderlyingType = typename std::underlying_type<EnumType>::type;
+  return static_cast<EnumType>( static_cast<UnderlyingType>( lhs ) | static_cast<UnderlyingType>(rhs ) );
+}
+
+/**
+ * Combine two bitfields
+ * @param lhs bitfield to or
+ * @param rhs bitfield to or
+ * @return reference to lhs with both flags set
+ */
+template < typename EnumType >
+inline typename std::enable_if< EnableBitMaskOperators< EnumType >::ENABLE, EnumType& >::type operator|=( EnumType& lhs, EnumType rhs )
+{
+  using UnderlyingType = typename std::underlying_type<EnumType>::type;
+  lhs = static_cast<EnumType>(static_cast<UnderlyingType>( lhs ) | static_cast<UnderlyingType>( rhs ) );
+  return lhs;
+}
+
+/**
+ * Test two bitfields.
+ * @param lhs bitfield to AND
+ * @param rhs bitfield to AND
+ * @return true if at least one flag is same in both
+ */
+template < typename EnumType >
+inline typename std::enable_if< EnableBitMaskOperators< EnumType >::ENABLE, bool >::type operator&( EnumType lhs, EnumType rhs )
+{
+  using UnderlyingType = typename std::underlying_type<EnumType>::type;
+  return static_cast<bool>( static_cast<UnderlyingType>( lhs ) & static_cast<UnderlyingType>(rhs ) );
+}
+
+} // namespace Dali
+
+#endif // DALI_BITWISE_ENUM_H
index 831620d..7a953c8 100644 (file)
@@ -35,6 +35,7 @@ devel_api_core_animation_header_files = \
   $(devel_api_src_dir)/animation/animation-devel.h
 
 devel_api_core_common_header_files = \
+  $(devel_api_src_dir)/common/bitwise-enum.h \
   $(devel_api_src_dir)/common/circular-queue.h \
   $(devel_api_src_dir)/common/hash.h \
   $(devel_api_src_dir)/common/map-wrapper.h \
index ead7154..b767b58 100644 (file)
@@ -71,9 +71,9 @@ void ConstrainPropertyOwner( PropertyOwner& propertyOwner, BufferIndex updateBuf
  ************************** Update node hierarchy *****************************
  ******************************************************************************/
 
-inline void UpdateRootNodeOpacity( Layer& rootNode, int nodeDirtyFlags, BufferIndex updateBufferIndex )
+inline void UpdateRootNodeOpacity( Layer& rootNode, NodePropertyFlags nodeDirtyFlags, BufferIndex updateBufferIndex )
 {
-  if ( nodeDirtyFlags & ColorFlag )
+  if ( nodeDirtyFlags & NodePropertyFlags::COLOR )
   {
     rootNode.SetWorldColor( rootNode.GetColor( updateBufferIndex ), updateBufferIndex );
   }
@@ -84,10 +84,10 @@ inline void UpdateRootNodeOpacity( Layer& rootNode, int nodeDirtyFlags, BufferIn
   }
 }
 
-inline void UpdateNodeOpacity( Node& node, int nodeDirtyFlags, BufferIndex updateBufferIndex )
+inline void UpdateNodeOpacity( Node& node, NodePropertyFlags nodeDirtyFlags, BufferIndex updateBufferIndex )
 {
   // If opacity needs to be recalculated
-  if ( nodeDirtyFlags & ColorFlag )
+  if ( nodeDirtyFlags & NodePropertyFlags::COLOR )
   {
     node.InheritWorldColor( updateBufferIndex );
   }
@@ -101,12 +101,12 @@ inline void UpdateNodeOpacity( Node& node, int nodeDirtyFlags, BufferIndex updat
 /**
  * This is called recursively for all children of the root Node
  */
-inline int UpdateNodes( Node& node,
-                        int parentFlags,
-                        BufferIndex updateBufferIndex,
-                        RenderQueue& renderQueue,
-                        Layer& currentLayer,
-                        int inheritedDrawMode )
+inline NodePropertyFlags UpdateNodes( Node& node,
+                                      NodePropertyFlags parentFlags,
+                                      BufferIndex updateBufferIndex,
+                                      RenderQueue& renderQueue,
+                                      Layer& currentLayer,
+                                      uint32_t inheritedDrawMode )
 {
   // Apply constraints to the node
   ConstrainPropertyOwner( node, updateBufferIndex );
@@ -114,7 +114,7 @@ inline int UpdateNodes( Node& node,
   // Short-circuit for invisible nodes
   if ( !node.IsVisible( updateBufferIndex ) )
   {
-    return 0;
+    return NodePropertyFlags::NOTHING;
   }
 
   // If the node was not previously visible
@@ -126,9 +126,9 @@ inline int UpdateNodes( Node& node,
   }
 
   // Some dirty flags are inherited from parent
-  int nodeDirtyFlags( node.GetDirtyFlags() | ( parentFlags & InheritedDirtyFlags ) );
+  NodePropertyFlags nodeDirtyFlags = node.GetInheritedDirtyFlags( parentFlags );
 
-  int cumulativeDirtyFlags = nodeDirtyFlags;
+  NodePropertyFlags cumulativeDirtyFlags = nodeDirtyFlags;
 
   Layer* layer = &currentLayer;
   Layer* nodeIsLayer( node.GetLayer() );
@@ -179,16 +179,16 @@ inline int UpdateNodes( Node& node,
 /**
  * The root node is treated separately; it cannot inherit values since it has no parent
  */
-int UpdateNodeTree( Layer& rootNode,
-                    BufferIndex updateBufferIndex,
-                    RenderQueue& renderQueue )
+NodePropertyFlags UpdateNodeTree( Layer& rootNode,
+                                  BufferIndex updateBufferIndex,
+                                  RenderQueue& renderQueue )
 {
   DALI_ASSERT_DEBUG( rootNode.IsRoot() );
 
   // Short-circuit for invisible nodes
   if ( DALI_UNLIKELY( !rootNode.IsVisible( updateBufferIndex ) ) ) // almost never ever true
   {
-    return 0;
+    return NodePropertyFlags::NOTHING;
   }
 
   // If the root node was not previously visible
@@ -199,9 +199,9 @@ int UpdateNodeTree( Layer& rootNode,
     rootNode.SetAllDirtyFlags();
   }
 
-  int nodeDirtyFlags( rootNode.GetDirtyFlags() );
+  NodePropertyFlags nodeDirtyFlags( rootNode.GetDirtyFlags() );
 
-  int cumulativeDirtyFlags = nodeDirtyFlags;
+  NodePropertyFlags cumulativeDirtyFlags = nodeDirtyFlags;
 
   UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
 
index 62f2411..8bfa09a 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTERNAL_SCENE_GRAPH_UPDATE_ALGORITHMS_H__
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/internal/common/buffer-index.h>
+#include <dali/internal/update/nodes/node-declarations.h>
 
 namespace Dali
 {
@@ -31,7 +32,6 @@ namespace SceneGraph
 {
 
 class Layer;
-class Node;
 class PropertyOwner;
 class RenderQueue;
 
@@ -50,9 +50,9 @@ void ConstrainPropertyOwner( PropertyOwner& propertyOwner, BufferIndex updateBuf
  * @param[in] renderQueue Used to query messages for the next Render.
  * @return The cumulative (ORed) dirty flags for the updated nodes
  */
-int UpdateNodeTree( Layer& rootNode,
-                    BufferIndex updateBufferIndex,
-                    RenderQueue& renderQueue );
+NodePropertyFlags UpdateNodeTree( Layer& rootNode,
+                                  BufferIndex updateBufferIndex,
+                                  RenderQueue& renderQueue );
 
 } // namespace SceneGraph
 
index 84722e4..ff35064 100644 (file)
@@ -198,7 +198,7 @@ struct UpdateManager::Impl
     messageQueue( renderController, sceneGraphBuffers ),
     frameCallbackProcessor( NULL ),
     keepRenderingSeconds( 0.0f ),
-    nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
+    nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
     frameCounter( 0 ),
     renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
     animationFinishedDuringUpdate( false ),
@@ -317,7 +317,7 @@ struct UpdateManager::Impl
   OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor;        ///< Owned FrameCallbackProcessor, only created if required.
 
   float                                keepRenderingSeconds;          ///< Set via Dali::Stage::KeepRendering
-  int                                  nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
+  NodePropertyFlags                    nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
   int                                  frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
 
   DevelStage::Rendering                renderingBehavior;             ///< Set via DevelStage::SetRenderingBehavior
@@ -420,7 +420,7 @@ void UpdateManager::DisconnectNode( Node* node )
 {
   Node* parent = node->GetParent();
   DALI_ASSERT_ALWAYS( NULL != parent );
-  parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
+  parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
 
   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
 
@@ -812,7 +812,7 @@ void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
 
 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
 {
-  mImpl->nodeDirtyFlags = NothingFlag;
+  mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
 
   if ( !mImpl->root )
   {
index 131ba19..0c288f8 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTERNAL_SCENE_GRAPH_NODE_DECLARATIONS_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-vector.h>
+#include <dali/devel-api/common/bitwise-enum.h>
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/internal/common/owner-pointer.h>
 
@@ -38,10 +39,27 @@ typedef Dali::Vector< Node* > NodeContainer;
 typedef NodeContainer::Iterator NodeIter;
 typedef NodeContainer::ConstIterator NodeConstIter;
 
+/**
+ * Flag whether property has changed, during the Update phase.
+ */
+enum class NodePropertyFlags : uint8_t
+// 8 bits is enough for 4 flags (compiler will check it)
+{
+  NOTHING          = 0x000,
+  TRANSFORM        = 0x001,
+  VISIBLE          = 0x002,
+  COLOR            = 0x004,
+  CHILD_DELETED    = 0x008,
+  ALL = ( CHILD_DELETED << 1 ) - 1 // all the flags
+};
+
 } // namespace SceneGraph
 
 } // namespace Internal
 
+// specialization has to be done in the same namespace
+template<> struct EnableBitMaskOperators< Internal::SceneGraph::NodePropertyFlags > { static const bool ENABLE = true; };
+
 } // namespace Dali
 
 #endif // __DALI_INTERNAL_SCENE_GRAPH_NODE_DECLARATIONS_H__
index 6c39e87..eaef08e 100755 (executable)
@@ -32,7 +32,7 @@ namespace //Unnamed namespace
 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Node> gNodeMemoryPool;
 #ifdef DEBUG_ENABLED
 // keep track of nodes created / deleted, to ensure we have 0 when the process exits or DALi library is unloaded
-int gNodeCount =0;
+int32_t gNodeCount =0;
 
 // Called when the process is about to exit, Node count should be zero at this point.
 void __attribute__ ((destructor)) ShutDown(void)
@@ -54,8 +54,7 @@ namespace SceneGraph
 const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
 
-
-Node* Node::New( unsigned int id )
+Node* Node::New( uint32_t id )
 {
   return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node( id );
 }
@@ -78,7 +77,7 @@ void Node::Delete( Node* node )
   }
 }
 
-Node::Node( unsigned int id )
+Node::Node( uint32_t id )
 : mTransformManager( NULL ),
   mTransformId( INVALID_TRANSFORM_ID ),
   mParentOrigin( TRANSFORM_PROPERTY_PARENT_ORIGIN ),
@@ -103,8 +102,8 @@ Node::Node( unsigned int id )
   mClippingDepth( 0u ),
   mScissorDepth( 0u ),
   mDepthIndex( 0u ),
+  mDirtyFlags( NodePropertyFlags::ALL ),
   mRegenerateUniformMap( 0 ),
-  mDirtyFlags( AllFlags ),
   mDrawMode( DrawMode::NORMAL ),
   mColorMode( DEFAULT_COLOR_MODE ),
   mClippingMode( ClippingMode::DISABLED ),
@@ -184,14 +183,14 @@ void Node::RemoveUniformMapping( const std::string& uniformName )
 
 void Node::PrepareRender( BufferIndex bufferIndex )
 {
-  if(mRegenerateUniformMap != 0 )
+  if( mRegenerateUniformMap != 0 )
   {
     if( mRegenerateUniformMap == 2 )
     {
       CollectedUniformMap& localMap = mCollectedUniformMap[ bufferIndex ];
       localMap.Resize(0);
 
-      for( unsigned int i=0, count=mUniformMaps.Count(); i<count; ++i )
+      for( uint32_t i = 0, count=mUniformMaps.Count(); i<count; ++i )
       {
         localMap.PushBack( &mUniformMaps[i] );
       }
@@ -203,7 +202,7 @@ void Node::PrepareRender( BufferIndex bufferIndex )
 
       localMap.Resize( oldMap.Count() );
 
-      unsigned int index=0;
+      CollectedUniformMap::SizeType index = 0;
       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
       {
         localMap[index] = *iter;
@@ -258,22 +257,23 @@ void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode )
 
 void Node::AddRenderer( Renderer* renderer )
 {
-  // Check that it has not been already added.
-  unsigned int rendererCount( mRenderer.Size() );
-  for( unsigned int i(0); i < rendererCount; ++i )
-  {
-    if( mRenderer[i] == renderer )
-    {
-      // Renderer is already in the list.
-      return;
-    }
-  }
-
   // If it is the first renderer added, make sure the world transform will be calculated
   // in the next update as world transform is not computed if node has no renderers.
-  if( rendererCount == 0 )
+  if( mRenderer.Empty() )
   {
-    mDirtyFlags |= TransformFlag;
+    mDirtyFlags |= NodePropertyFlags::TRANSFORM;
+  }
+  else
+  {
+    // Check that it has not been already added.
+    for( auto&& existingRenderer : mRenderer )
+    {
+      if( existingRenderer == renderer )
+      {
+        // Renderer is already in the list.
+        return;
+      }
+    }
   }
 
   mRenderer.PushBack( renderer );
@@ -281,8 +281,8 @@ void Node::AddRenderer( Renderer* renderer )
 
 void Node::RemoveRenderer( Renderer* renderer )
 {
-  unsigned int rendererCount( mRenderer.Size() );
-  for( unsigned int i(0); i<rendererCount; ++i )
+  RendererContainer::SizeType rendererCount( mRenderer.Size() );
+  for( RendererContainer::SizeType i = 0; i < rendererCount; ++i )
   {
     if( mRenderer[i] == renderer )
     {
@@ -292,29 +292,39 @@ void Node::RemoveRenderer( Renderer* renderer )
   }
 }
 
-int Node::GetDirtyFlags() const
+NodePropertyFlags Node::GetDirtyFlags() const
 {
   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
-  int flags = mDirtyFlags;
+  NodePropertyFlags flags = mDirtyFlags;
 
   // Check whether the visible property has changed
   if ( !mVisible.IsClean() )
   {
-    flags |= VisibleFlag;
+    flags |= NodePropertyFlags::VISIBLE;
   }
 
   // Check whether the color property has changed
   if ( !mColor.IsClean() )
   {
-    flags |= ColorFlag;
+    flags |= NodePropertyFlags::COLOR;
   }
 
   return flags;
 }
 
+NodePropertyFlags Node::GetInheritedDirtyFlags( NodePropertyFlags parentFlags ) const
+{
+  // Size is not inherited. VisibleFlag is inherited
+  static const NodePropertyFlags InheritedDirtyFlags = NodePropertyFlags::TRANSFORM | NodePropertyFlags::VISIBLE | NodePropertyFlags::COLOR;
+  using UnderlyingType = typename std::underlying_type<NodePropertyFlags>::type;
+
+  return static_cast<NodePropertyFlags>( static_cast<UnderlyingType>( mDirtyFlags ) |
+                                         ( static_cast<UnderlyingType>( parentFlags ) & static_cast<UnderlyingType>( InheritedDirtyFlags ) ) );
+}
+
 void Node::ResetDirtyFlags( BufferIndex updateBufferIndex )
 {
-  mDirtyFlags = NothingFlag;
+  mDirtyFlags = NodePropertyFlags::NOTHING;
 }
 
 void Node::SetParent( Node& parentNode )
index f025726..903f8c2 100755 (executable)
@@ -57,30 +57,9 @@ class Layer;
 class RenderTask;
 class UpdateManager;
 
-/**
- * Flag whether property has changed, during the Update phase.
- */
-enum NodePropertyFlags
-{
-  NothingFlag          = 0x000,
-  TransformFlag        = 0x001,
-  VisibleFlag          = 0x002,
-  ColorFlag            = 0x004,
-  SizeFlag             = 0x008,
-  OverlayFlag          = 0x010,
-  SortModifierFlag     = 0x020,
-  ChildDeletedFlag     = 0x040,
-};
-
-static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags
-
-/**
- * Size is not inherited. VisibleFlag is inherited
- */
-static const int InheritedDirtyFlags = TransformFlag | VisibleFlag | ColorFlag | OverlayFlag;
 
 // Flags which require the scene renderable lists to be updated
-static const int RenderableUpdateFlags = TransformFlag | SortModifierFlag | ChildDeletedFlag;
+static NodePropertyFlags RenderableUpdateFlags = NodePropertyFlags::TRANSFORM | NodePropertyFlags::CHILD_DELETED;
 
 /**
  * Node is the base class for all nodes in the Scene Graph.
@@ -104,7 +83,7 @@ public:
    * Construct a new Node.
    * @param[in] id The unique ID of the node
    */
-  static Node* New( unsigned int id );
+  static Node* New( uint32_t id );
 
   /**
    * Deletes a Node.
@@ -230,7 +209,7 @@ public:
    * Get the renderer at the given index
    * @param[in] index
    */
-  Renderer* GetRendererAt( unsigned int index ) const
+  Renderer* GetRendererAt( uint32_t index ) const
   {
     return mRenderer[index];
   }
@@ -238,9 +217,9 @@ public:
   /**
    * Retrieve the number of renderers for the node
    */
-  unsigned int GetRendererCount()
+  uint32_t GetRendererCount() const
   {
-    return mRenderer.Size();
+    return static_cast<uint32_t>( mRenderer.Size() );
   }
 
   // Containment methods
@@ -323,7 +302,7 @@ public:
    * Flag that one of the node values has changed in the current frame.
    * @param[in] flag The flag to set.
    */
-  void SetDirtyFlag(NodePropertyFlags flag)
+  void SetDirtyFlag( NodePropertyFlags flag )
   {
     mDirtyFlags |= flag;
   }
@@ -333,14 +312,22 @@ public:
    */
   void SetAllDirtyFlags()
   {
-    mDirtyFlags = AllFlags;
+    mDirtyFlags = NodePropertyFlags::ALL;
   }
 
   /**
    * Query whether a node is dirty.
    * @return The dirty flags
    */
-  int GetDirtyFlags() const;
+  NodePropertyFlags GetDirtyFlags() const;
+
+  /**
+   * Query inherited dirty flags.
+   *
+   * @param The parentFlags to or with
+   * @return The inherited dirty flags
+   */
+  NodePropertyFlags GetInheritedDirtyFlags( NodePropertyFlags parentFlags ) const;
 
   /**
    * Retrieve the parent-origin of the node.
@@ -586,11 +573,11 @@ public:
    * or inherits its parent color.
    * @param[in] colorMode The new color mode.
    */
-  void SetColorMode(ColorMode colorMode)
+  void SetColorMode( ColorMode colorMode )
   {
     mColorMode = colorMode;
 
-    SetDirtyFlag(ColorFlag);
+    SetDirtyFlag( NodePropertyFlags::COLOR );
   }
 
   /**
@@ -722,13 +709,19 @@ public:
    * @brief Sets the sibling order of the node
    * @param[in] order The new order
    */
-  void SetDepthIndex( unsigned int depthIndex ){ mDepthIndex = depthIndex; }
+  void SetDepthIndex( uint32_t depthIndex )
+  {
+    mDepthIndex = depthIndex;
+  }
 
   /**
    * @brief Get the depth index of the node
    * @return Current depth index
    */
-  unsigned int GetDepthIndex(){ return mDepthIndex; }
+  uint32_t GetDepthIndex()
+  {
+    return mDepthIndex;
+  }
 
   /**
    * @brief Sets the boolean which states whether the position should use the anchor-point.
@@ -808,7 +801,7 @@ protected:
    * Protected constructor; See also Node::New()
    * @param[in] id The Unique ID of the actor creating the node
    */
-  Node( unsigned int id );
+  Node( uint32_t id );
 
   /**
    * Protected virtual destructor; See also Node::Delete( Node* )
@@ -821,17 +814,17 @@ private: // from NodeDataProvider
   /**
    * @copydoc NodeDataProvider::GetModelMatrix
    */
-  virtual const Matrix& GetModelMatrix( unsigned int bufferId ) const
+  virtual const Matrix& GetModelMatrix( BufferIndex bufferIndex ) const
   {
-    return GetWorldMatrix( bufferId );
+    return GetWorldMatrix( bufferIndex );
   }
 
   /**
    * @copydoc NodeDataProvider::GetRenderColor
    */
-  virtual const Vector4& GetRenderColor( unsigned int bufferId ) const
+  virtual const Vector4& GetRenderColor( BufferIndex bufferIndex ) const
   {
-    return GetWorldColor( bufferId );
+    return GetWorldColor( bufferIndex );
   }
 
 public: // From UniformMapDataProvider
@@ -870,8 +863,8 @@ public: // Default properties
 
   TransformManager*                  mTransformManager;
   TransformId                        mTransformId;
-  TransformManagerPropertyVector3    mParentOrigin;           ///< Local transform; the position is relative to this. Sets the TransformFlag dirty when changed
-  TransformManagerPropertyVector3    mAnchorPoint;            ///< Local transform; local center of rotation. Sets the TransformFlag dirty when changed
+  TransformManagerPropertyVector3    mParentOrigin;           ///< Local transform; the position is relative to this. Sets the Transform flag dirty when changed
+  TransformManagerPropertyVector3    mAnchorPoint;            ///< Local transform; local center of rotation. Sets the Transform flag dirty when changed
   TransformManagerPropertyVector3    mSize;                   ///< Size is provided for layouting
   TransformManagerPropertyVector3    mPosition;               ///< Local transform; distance between parent-origin & anchor-point
   TransformManagerPropertyQuaternion mOrientation;            ///< Local transform; rotation relative to parent node
@@ -890,7 +883,7 @@ public: // Default properties
   InheritedColor                     mWorldColor;             ///< Full inherited color
 
   uint32_t                           mClippingSortModifier;   ///< Contains bit-packed clipping information for quick access when sorting
-  const unsigned int                 mId;                     ///< The Unique ID of the node.
+  const uint32_t                     mId;                     ///< The Unique ID of the node.
 
 protected:
 
@@ -902,15 +895,15 @@ protected:
   NodeContainer                      mChildren;               ///< Container of children; not owned
 
   CollectedUniformMap                mCollectedUniformMap[2]; ///< Uniform maps of the node
-  unsigned int                       mUniformMapChanged[2];   ///< Records if the uniform map has been altered this frame
+  uint32_t                           mUniformMapChanged[2];   ///< Records if the uniform map has been altered this frame
   uint32_t                           mClippingDepth;          ///< The number of stencil clipping nodes deep this node is
   uint32_t                           mScissorDepth;           ///< The number of scissor clipping nodes deep this node is
 
   uint32_t                           mDepthIndex;             ///< Depth index of the node
 
   // flags, compressed to bitfield
-  unsigned int                       mRegenerateUniformMap:2; ///< Indicate if the uniform map has to be regenerated this frame
-  int                                mDirtyFlags:8;           ///< A composite set of flags for each of the Node properties
+  NodePropertyFlags                  mDirtyFlags;             ///< Dirty flags for each of the Node properties
+  uint32_t                           mRegenerateUniformMap:2; ///< Indicate if the uniform map has to be regenerated this frame
   DrawMode::Type                     mDrawMode:3;             ///< How the Node and its children should be drawn
   ColorMode                          mColorMode:3;            ///< Determines whether mWorldColor is inherited, 2 bits is enough
   ClippingMode::Type                 mClippingMode:3;         ///< The clipping mode of this node
@@ -928,7 +921,7 @@ inline void SetInheritOrientationMessage( EventThreadServices& eventThreadServic
   typedef MessageValue1< Node, bool > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetInheritOrientation, inherit );
@@ -939,7 +932,7 @@ inline void SetParentOriginMessage( EventThreadServices& eventThreadServices, co
   typedef MessageValue1< Node, Vector3 > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetParentOrigin, origin );
@@ -950,7 +943,7 @@ inline void SetAnchorPointMessage( EventThreadServices& eventThreadServices, con
   typedef MessageValue1< Node, Vector3 > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetAnchorPoint, anchor );
@@ -961,7 +954,7 @@ inline void SetInheritPositionMessage( EventThreadServices& eventThreadServices,
   typedef MessageValue1< Node, bool > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetInheritPosition, inherit );
@@ -972,7 +965,7 @@ inline void SetInheritScaleMessage( EventThreadServices& eventThreadServices, co
   typedef MessageValue1< Node, bool > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetInheritScale, inherit );
@@ -983,7 +976,7 @@ inline void SetColorModeMessage( EventThreadServices& eventThreadServices, const
   typedef MessageValue1< Node, ColorMode > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetColorMode, colorMode );
@@ -994,7 +987,7 @@ inline void SetDrawModeMessage( EventThreadServices& eventThreadServices, const
   typedef MessageValue1< Node, DrawMode::Type > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetDrawMode, drawMode );
@@ -1005,7 +998,7 @@ inline void AddRendererMessage( EventThreadServices& eventThreadServices, const
   typedef MessageValue1< Node, Renderer* > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::AddRenderer, renderer );
@@ -1016,18 +1009,18 @@ inline void RemoveRendererMessage( EventThreadServices& eventThreadServices, con
   typedef MessageValue1< Node, Renderer* > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::RemoveRenderer, renderer );
 }
 
-inline void SetDepthIndexMessage( EventThreadServices& eventThreadServices, const Node& node, unsigned int depthIndex )
+inline void SetDepthIndexMessage( EventThreadServices& eventThreadServices, const Node& node, uint32_t depthIndex )
 {
-  typedef MessageValue1< Node, unsigned int > LocalType;
+  typedef MessageValue1< Node, uint32_t > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetDepthIndex, depthIndex );
@@ -1038,7 +1031,7 @@ inline void SetClippingModeMessage( EventThreadServices& eventThreadServices, co
   typedef MessageValue1< Node, ClippingMode::Type > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetClippingMode, clippingMode );
@@ -1049,7 +1042,7 @@ inline void SetPositionUsesAnchorPointMessage( EventThreadServices& eventThreadS
   typedef MessageValue1< Node, bool > LocalType;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &node, &Node::SetPositionUsesAnchorPoint, positionUsesAnchorPoint );
index 56e6b9e..ad2df4b 100644 (file)
@@ -297,7 +297,7 @@ void Camera::Update( BufferIndex updateBufferIndex )
   {
     mUpdateViewFlag = UPDATE_COUNT;
   }
-  if( mNode->GetDirtyFlags() & VisibleFlag )
+  if( mNode->GetDirtyFlags() & NodePropertyFlags::VISIBLE )
   {
     // If the visibility changes, the projection matrix needs to be re-calculated.
     // It may happen the first time an actor is rendered it's rendered only once and becomes invisible,