inline void InstallRootMessage( UpdateManager& manager, Layer& root, bool systemLevel )
{
- typedef MessageValue2< UpdateManager, Layer*, bool > LocalType;
+ // Message has ownership of Layer while in transit from event -> update
+ typedef MessageValue2< UpdateManager, OwnerPointer<Layer>, bool > LocalType;
// Reserve some memory inside the message queue
unsigned int* slot = manager.ReserveMessageSlot( sizeof( LocalType ) );
inline void AddNodeMessage( UpdateManager& manager, Node& node )
{
+ // Message has ownership of Node while in transit from event -> update
typedef MessageValue1< UpdateManager, OwnerPointer<Node> > LocalType;
// Reserve some memory inside the message queue
//Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
// or DALI library is unloaded
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;
+
+// Called when the process is about to exit, Node count should be zero at this point.
+void __attribute__ ((destructor)) ShutDown(void)
+{
+DALI_ASSERT_DEBUG( (gNodeCount == 0) && "Node memory leak");
+}
+#endif
}
namespace Dali
{
mUniformMapChanged[0] = 0u;
mUniformMapChanged[1] = 0u;
+
+#ifdef DEBUG_ENABLED
+ gNodeCount++;
+#endif
+
}
Node::~Node()
{
mTransformManager->RemoveTransform(mTransformId);
}
+
+#ifdef DEBUG_ENABLED
+ gNodeCount--;
+#endif
}
void Node::OnDestroy()
} // namespace SceneGraph
+template <>
+void OwnerPointer<Dali::Internal::SceneGraph::Layer>::Reset()
+{
+ if( mObject != NULL )
+ {
+ Dali::Internal::SceneGraph::Node::Delete( mObject );
+ mObject = NULL;
+ }
+}
} // namespace Internal
} // namespace Dali
} // namespace SceneGraph
+// Template specialisation for OwnerPointer<Layer>, because delete is protected
+template <>
+void OwnerPointer<Dali::Internal::SceneGraph::Layer>::Reset();
+
} // namespace Internal
} // namespace Dali
~Impl()
{
// Delete the current buffer
- delete currentMessageBuffer;
+ if( currentMessageBuffer )
+ {
+ DeleteBufferContents( currentMessageBuffer );
+ delete currentMessageBuffer;
+ }
// Delete the unprocessed buffers
const MessageBufferIter processQueueEndIter = processQueue.end();