Remove the dependency between update manager and event side rendertasklist, generalize notification mechanism
[Problem] cyclic dependencies, heap allocations potentially on a frame by frame basis
[Cause] update manager needed to call API in event side to get the message to sent
[Solution] pass the interface pointer to notification manager
Change-Id: If29f3fd9fe5c972cbf19fcb34a3adf800374b33a
mStage->Initialize();
- mUpdateManager->SetRenderTaskList( &mStage->GetRenderTaskList() );
-
mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
*/
void MoveFrom( OwnerContainer& source )
{
- // Optimisation for the case that this is empty
- if( IsEmpty() )
+ typename Vector< T >::SizeType sourceCount = source.Count();
+ // if source is empty, nothing to move
+ if( sourceCount > 0u )
{
- VectorBase::Swap( source );
- }
- else
- {
- // make space for new items
- Vector< T >::Reserve( VectorBase::Count() + source.Count() );
- Iterator iter = source.Begin();
- ConstIterator end = source.End();
- for( ; iter != end; ++iter )
+ // Optimisation for the case that this is empty
+ if( IsEmpty() )
+ {
+ VectorBase::Swap( source );
+ }
+ else
{
- T pointer = *iter;
- Vector< T >::PushBack( pointer );
+ // make space for new items
+ Vector< T >::Reserve( VectorBase::Count() + sourceCount );
+ Iterator iter = source.Begin();
+ ConstIterator end = source.End();
+ for( ; iter != end; ++iter )
+ {
+ T pointer = *iter;
+ Vector< T >::PushBack( pointer );
+ }
+ // cannot call Clear on OwnerContainer as that deletes the elements
+ source.Vector< T >::Clear();
}
- // cannot call Clear on OwnerContainer as that deletes the elements
- source.Vector< T >::Clear();
}
}
+++ /dev/null
-#ifndef __DALI_INTERNAL_ANIMATION_FINISHED_NOTIFIER_H__
-#define __DALI_INTERNAL_ANIMATION_FINISHED_NOTIFIER_H__
-
-/*
- * Copyright (c) 2014 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.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/internal/common/message.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-/**
- * Interface used by the update-thread to trigger animation "Finished" signals.
- */
-class AnimationFinishedNotifier
-{
-public:
-
- /**
- * Virtual destructor.
- */
- virtual ~AnimationFinishedNotifier()
- {
- }
-
- /**
- * Provide notification signals for any "Finished" animations.
- * This method should be called in the event-thread; the update-thread must use AnimationFinishedMessage.
- */
- virtual void NotifyFinishedAnimations() = 0;
-};
-
-/**
- * Notification message for when 1+ animations have finished
- * @param[in] notifier This will provide the notification signals.
- */
-inline MessageBase* AnimationFinishedMessage( AnimationFinishedNotifier& notifier )
-{
- return new Message< AnimationFinishedNotifier >( ¬ifier, &AnimationFinishedNotifier::NotifyFinishedAnimations );
-}
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_ANIMATION_FINISHED_NOTIFIER_H__
-
mPlaylist.erase( Dali::Animation(&animation) );
}
-void AnimationPlaylist::NotifyFinishedAnimations()
+void AnimationPlaylist::NotifyCompleted()
{
std::vector< Dali::Animation > finishedAnimations;
// INTERNAL INCLUDES
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/common/set-wrapper.h>
-#include <dali/internal/common/message.h>
-#include <dali/internal/event/animation/animation-finished-notifier.h>
+#include <dali/internal/event/common/complete-notification-interface.h>
namespace Dali
{
* AnimationPlaylist provides notifications to applications when animations are finished.
* It reference-counts playing animations, to allow "fire and forget" behaviour.
*/
-class AnimationPlaylist : public AnimationFinishedNotifier
+class AnimationPlaylist : public CompleteNotificationInterface
{
public:
*/
void OnClear( Animation& animation );
- /**
- * From AnimationFinishedNotifier; emit "Finished" signal on any animations that have finished.
- * This method should be called in the event-thread; the update-thread must use AnimationFinishedMessage.
- * @post The "Finished" animations will no longer be referenced by AnimationPlaylist.
- */
- void NotifyFinishedAnimations();
-
private:
/**
// Undefined
AnimationPlaylist& operator=(const AnimationPlaylist& rhs);
+private: // from CompleteNotificationInterface
+
+ /**
+ * @copydoc CompleteNotificationInterface::NotifyCompleted()
+ */
+ virtual void NotifyCompleted();
+
private:
std::set< Animation* > mAnimations; ///< All existing animations (not referenced)
-
std::set< Dali::Animation > mPlaylist; ///< The currently playing animations (reference counted)
+
};
} // namespace Internal
--- /dev/null
+#ifndef __DALI_INTERNAL_COMPLETE_NOTIFICATION_INTERFACE_H__
+#define __DALI_INTERNAL_COMPLETE_NOTIFICATION_INTERFACE_H__
+
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+/**
+ * Provides notifications to the event-thread regarding the changes in previous update(s).
+ * For example after an animation finished, or after resources were loaded.
+ */
+class CompleteNotificationInterface
+{
+protected:
+
+ /**
+ * Constructor, not to be directly instantiated.
+ */
+ CompleteNotificationInterface()
+ {}
+
+ /**
+ * Virtual destructor as this is an interface, no deletion through this interface though.
+ */
+ virtual ~CompleteNotificationInterface()
+ {}
+
+public:
+
+ /**
+ * This method is called by Notification Manager
+ */
+ virtual void NotifyCompleted() = 0;
+
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_COMPLETE_NOTIFICATION_INTERFACE_H__
+
// CLASS HEADER
#include <dali/internal/event/common/notification-manager.h>
-#include <dali/internal/common/owner-container.h>
-#include <dali/internal/common/message.h>
// EXTERNAL INCLUDES
#ifdef __clang__
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
+#include <dali/internal/common/owner-container.h>
+#include <dali/internal/common/message.h>
#include <dali/internal/event/common/property-notification-impl.h>
+#include <dali/internal/event/common/complete-notification-interface.h>
namespace Dali
{
namespace Internal
{
+namespace
+{
+typedef Dali::Vector< CompleteNotificationInterface* > InterfaceContainer;
+
+/**
+ * helper to move elements from one container to another
+ * @param from where to move
+ * @param to move target
+ */
+void MoveElements( InterfaceContainer& from, InterfaceContainer& to )
+{
+ // check if there's something in from
+ const InterfaceContainer::SizeType fromCount = from.Count();
+ if( fromCount > 0u )
+ {
+ // check if to has some elements
+ const InterfaceContainer::SizeType toCount = to.Count();
+ if( toCount == 0u )
+ {
+ // to is empty so we can swap with from
+ to.Swap( from );
+ }
+ else
+ {
+ to.Reserve( toCount + fromCount );
+ for( InterfaceContainer::SizeType i = 0; i < fromCount; ++i )
+ {
+ to.PushBack( from[ i ] );
+ }
+ from.Clear();
+ }
+ }
+}
+}
+
typedef boost::mutex MessageQueueMutex;
typedef OwnerContainer< MessageBase* > MessageContainer;
struct NotificationManager::Impl
{
Impl()
- : notificationCount(0)
{
// reserve space on the vectors to avoid reallocs
- // applications typically have upto 20-30 notifications at startup
- updateCompletedQueue.Reserve( 32 );
- updateWorkingQueue.Reserve( 32 );
- eventQueue.Reserve( 32 );
+ // applications typically have up-to 20-30 notifications at startup
+ updateCompletedMessageQueue.Reserve( 32 );
+ updateWorkingMessageQueue.Reserve( 32 );
+ eventMessageQueue.Reserve( 32 );
+
+ // only a few manager objects get complete notifications (animation, render list, property notifications, ...)
+ updateCompletedInterfaceQueue.Reserve( 4 );
+ updateWorkingInterfaceQueue.Reserve( 4 );
+ eventInterfaceQueue.Reserve( 4 );
}
~Impl()
{
}
- // Used to skip duplicate operations during Notify()
- unsigned int notificationCount;
-
// queueMutex must be locked whilst accessing queue
MessageQueueMutex queueMutex;
- MessageContainer updateCompletedQueue;
- MessageContainer updateWorkingQueue;
- MessageContainer eventQueue;
+ // three queues for objects owned by notification manager
+ MessageContainer updateCompletedMessageQueue;
+ MessageContainer updateWorkingMessageQueue;
+ MessageContainer eventMessageQueue;
+ // three queues for objects referenced by notification manager
+ InterfaceContainer updateCompletedInterfaceQueue;
+ InterfaceContainer updateWorkingInterfaceQueue;
+ InterfaceContainer eventInterfaceQueue;
};
NotificationManager::NotificationManager()
delete mImpl;
}
+void NotificationManager::QueueCompleteNotification( CompleteNotificationInterface* instance )
+{
+ // queueMutex must be locked whilst accessing queues
+ MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+
+ mImpl->updateWorkingInterfaceQueue.PushBack( instance );
+}
+
void NotificationManager::QueueMessage( MessageBase* message )
{
DALI_ASSERT_DEBUG( NULL != message );
// queueMutex must be locked whilst accessing queues
MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
- mImpl->updateWorkingQueue.PushBack( message );
+ mImpl->updateWorkingMessageQueue.PushBack( message );
}
void NotificationManager::UpdateCompleted()
// Move messages from update working queue to completed queue
// note that in theory its possible for update completed to have last frames
// events as well still hanging around. we need to keep them as well
- mImpl->updateCompletedQueue.MoveFrom( mImpl->updateWorkingQueue );
+ mImpl->updateCompletedMessageQueue.MoveFrom( mImpl->updateWorkingMessageQueue );
+ // move pointers from interface queue
+ MoveElements( mImpl->updateWorkingInterfaceQueue, mImpl->updateCompletedInterfaceQueue );
// finally the lock is released
}
// queueMutex must be locked whilst accessing queues
MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
- return ( false == mImpl->updateCompletedQueue.IsEmpty() );
+ return ( 0u < mImpl->updateCompletedMessageQueue.Count() ||
+ ( 0u < mImpl->updateCompletedInterfaceQueue.Count() ) );
}
void NotificationManager::ProcessMessages()
{
- // Done before messages are processed, for notification count comparisons
- ++mImpl->notificationCount;
-
// queueMutex must be locked whilst accessing queues
{
MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
// Move messages from update completed queue to event queue
// note that in theory its possible for event queue to have
// last frames events as well still hanging around so need to keep them
- mImpl->eventQueue.MoveFrom( mImpl->updateCompletedQueue );
+ mImpl->eventMessageQueue.MoveFrom( mImpl->updateCompletedMessageQueue );
+ MoveElements( mImpl->updateCompletedInterfaceQueue, mImpl->eventInterfaceQueue );
}
// end of scope, lock is released
- MessageContainer::Iterator iter = mImpl->eventQueue.Begin();
- MessageContainer::Iterator end = mImpl->eventQueue.End();
+ MessageContainer::Iterator iter = mImpl->eventMessageQueue.Begin();
+ const MessageContainer::Iterator end = mImpl->eventMessageQueue.End();
for( ; iter != end; ++iter )
{
(*iter)->Process( 0u/*ignored*/ );
}
-
// release the processed messages from event side queue
- mImpl->eventQueue.Clear();
-}
+ mImpl->eventMessageQueue.Clear();
-unsigned int NotificationManager::GetNotificationCount() const
-{
- return mImpl->notificationCount;
+ InterfaceContainer::Iterator iter2 = mImpl->eventInterfaceQueue.Begin();
+ const InterfaceContainer::Iterator end2 = mImpl->eventInterfaceQueue.End();
+ for( ; iter2 != end2; ++iter2 )
+ {
+ CompleteNotificationInterface* interface = *iter2;
+ if( interface )
+ {
+ interface->NotifyCompleted();
+ }
+ }
+ // just clear the container, we dont own the objects
+ mImpl->eventInterfaceQueue.Clear();
}
} // namespace Internal
namespace Internal
{
-class PropertyNotification;
+class CompleteNotificationInterface;
class MessageBase;
/**
/// Update side interface, can only be called from Update-thread
/**
+ * Queue a scene message to an interface. This method is thread-safe.
+ * @param[in] instance to be notified about completion of the Update side event.
+ */
+ void QueueCompleteNotification( CompleteNotificationInterface* instance );
+
+ /**
* Queue a scene message. This method is thread-safe.
* @param[in] message A newly allocated message; NotificationManager takes ownership.
*/
*/
void ProcessMessages();
- /**
- * Retrieve the notification count; this is incremented when Notify() is called.
- */
- unsigned int GetNotificationCount() const;
-
private:
struct Impl;
Impl* mImpl;
-};
-
-/**
- * A functor for querying the notification count.
- * This is useful for skipping duplicate operations during NotificationManager::Notify()
- */
-struct NotificationCountQuery
-{
- NotificationCountQuery(const NotificationManager& manager)
- : mNotificationManager(manager)
- {
- }
-
- unsigned int operator()() const
- {
- return mNotificationManager.GetNotificationCount();
- }
-
-private:
- const NotificationManager& mNotificationManager;
};
} // namespace Internal
return mTasks[index];
}
-void RenderTaskList::NotifyFinished()
+RenderTaskList::RenderTaskList( EventToUpdate& eventToUpdate, RenderTaskDefaults& defaults, bool systemLevel )
+: mEventToUpdate( eventToUpdate ),
+ mDefaults( defaults ),
+ mIsSystemLevel( systemLevel ),
+ mSceneObject( NULL )
+{
+}
+
+RenderTaskList::~RenderTaskList()
+{
+}
+
+void RenderTaskList::Initialize( UpdateManager& updateManager )
+{
+ // This should only be called once, with no existing scene-object
+ DALI_ASSERT_DEBUG( NULL == mSceneObject );
+
+ // Get raw-pointer to render task list
+ mSceneObject = updateManager.GetRenderTaskList( mIsSystemLevel );
+ // set the callback to call us back when tasks are completed
+ mSceneObject->SetCompleteNotificationInterface( this );
+}
+
+void RenderTaskList::NotifyCompleted()
{
DALI_LOG_TRACE_METHOD(gLogRenderList);
}
}
-RenderTaskList::RenderTaskList( EventToUpdate& eventToUpdate, RenderTaskDefaults& defaults, bool systemLevel )
-: mEventToUpdate( eventToUpdate ),
- mDefaults( defaults ),
- mIsSystemLevel( systemLevel ),
- mSceneObject( NULL )
-{
-}
-
-RenderTaskList::~RenderTaskList()
-{
-}
-
-void RenderTaskList::Initialize( UpdateManager& updateManager )
-{
- // This should only be called once, with no existing scene-object
- DALI_ASSERT_DEBUG( NULL == mSceneObject );
-
- // Get raw-pointer to render task list
- mSceneObject = updateManager.GetRenderTaskList( mIsSystemLevel );
-}
-
} // namespace Internal
} // namespace Dali
#include <dali/public-api/object/base-object.h>
#include <dali/public-api/render-tasks/render-task.h>
#include <dali/public-api/render-tasks/render-task-list.h>
-#include <dali/internal/common/message.h>
+#include <dali/internal/event/common/complete-notification-interface.h>
namespace Dali
{
* A proxy for the scene-graph RenderTaskList.
* A separate LayerList is maintained for actors added via the SystemLevel::Add().
*/
-class RenderTaskList : public BaseObject
+class RenderTaskList : public BaseObject, public CompleteNotificationInterface
{
public:
* Provide notification signals for a "Finished" render task.
* This method should be called in the event-thread
* Queue NotifyFinishedMessage() from update-thread
+ * @param object pointer to this class instance
*/
- void NotifyFinished();
+ static void NotifyFinished( void* object );
protected:
*/
void Initialize( SceneGraph::UpdateManager& updateManager );
+private: // from CompleteNotificationInterface
+
+ /**
+ * @copydoc CompleteNotificationInterface::NotifyCompleted()
+ */
+ virtual void NotifyCompleted();
+
private:
EventToUpdate& mEventToUpdate;
RenderTaskContainer mTasks; ///< Reference counted render-tasks
};
-/**
- * Notification message for when 1+ render tasks have finished
- * @param[in] renderTaskList This will provide the notification signals.
- */
-inline MessageBase* NotifyFinishedMessage( RenderTaskList& renderTaskList )
-{
- return new Message< RenderTaskList >( &renderTaskList, &RenderTaskList::NotifyFinished );
-}
-
} // namespace Internal
// Helpers for public-api forwarding methods
#include <dali/internal/event/common/notification-manager.h>
#include <dali/internal/event/common/property-notification-impl.h>
#include <dali/internal/event/common/property-notifier.h>
-#include <dali/internal/event/animation/animation-finished-notifier.h>
-#include <dali/internal/event/render-tasks/render-task-list-impl.h>
#include <dali/internal/update/animation/scene-graph-animator.h>
#include <dali/internal/update/animation/scene-graph-animation.h>
{
Impl( NotificationManager& notificationManager,
GlSyncAbstraction& glSyncAbstraction,
- AnimationFinishedNotifier& animationFinishedNotifier,
+ CompleteNotificationInterface& animationFinishedNotifier,
PropertyNotifier& propertyNotifier,
ResourceManager& resourceManager,
DiscardQueue& discardQueue,
previousUpdateScene( false ),
frameCounter( 0 ),
renderSortingHelper(),
- renderTaskList( NULL ),
renderTaskWaiting( false )
{
sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager, defaultShader );
SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
- AnimationFinishedNotifier& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
+ CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
ResourceManager& resourceManager; ///< resource manager
DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
- Internal::RenderTaskList* renderTaskList; ///< Stores a pointer to the internal implementation to the render task list.
GestureContainer gestures; ///< A container of owned gesture detectors
bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
};
UpdateManager::UpdateManager( NotificationManager& notificationManager,
GlSyncAbstraction& glSyncAbstraction,
- AnimationFinishedNotifier& animationFinishedNotifier,
+ CompleteNotificationInterface& animationFinishedNotifier,
PropertyNotifier& propertyNotifier,
ResourceManager& resourceManager,
DiscardQueue& discardQueue,
delete mImpl;
}
-void UpdateManager::SetRenderTaskList( Internal::RenderTaskList* renderTaskList )
-{
- mImpl->renderTaskList = renderTaskList;
-}
-
EventToUpdate& UpdateManager::GetEventToUpdate()
{
return mImpl->messageQueue;
if ( mImpl->animationFinishedDuringUpdate )
{
// The application should be notified by NotificationManager, in another thread
- mImpl->notificationManager.QueueMessage( AnimationFinishedMessage( mImpl->animationFinishedNotifier ) );
+ mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
}
PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
}
}
- // check the countdown and notify
+ // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
bool doRenderOnceNotify = false;
mImpl->renderTaskWaiting = false;
const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
if( doRenderOnceNotify )
{
DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
- mImpl->notificationManager.QueueMessage( NotifyFinishedMessage( *mImpl->renderTaskList ) );
+ mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
}
PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
namespace Internal
{
-class AnimationFinishedNotifier;
class PropertyNotifier;
class EventToUpdate;
struct DynamicsWorldSettings;
class NotificationManager;
+class CompleteNotificationInterface;
class ResourceManager;
-class RenderTaskList;
class TouchResampler;
// value types used by messages
* Construct a new UpdateManager.
* @param[in] notificationManager This should be notified when animations have finished.
* @param[in] glSyncAbstraction Used to determine when framebuffers are ready
- * @param[in] animationFinishedNotifier The AnimationFinishedNotifier
+ * @param[in] animationFinishedNotifier The CompleteNotificationInterface that handles animation completions
* @param[in] propertyNotifier The PropertyNotifier
* @param[in] resourceManager The resource manager used to load textures etc.
* @param[in] discardQueue Nodes are added here when disconnected from the scene-graph.
*/
UpdateManager( NotificationManager& notificationManager,
Integration::GlSyncAbstraction& glSyncAbstraction,
- AnimationFinishedNotifier& animationFinishedNotifier,
+ CompleteNotificationInterface& animationFinishedNotifier,
PropertyNotifier& propertyNotifier,
ResourceManager& resourceManager,
DiscardQueue& discardQueue,
~UpdateManager();
/**
- * Sets a pointer to the internal render task list.
- *
- * The render task list is used to notify which render tasks with refresh rate REFRESH_ONCE have finished.
- *
- * @param[in] renderTaskList A pointer to the internal render task list.
- */
- void SetRenderTaskList( Internal::RenderTaskList* renderTaskList );
-
- /**
* The event-thread uses this interface to queue messages for the next update.
* @return The event-to-update interface.
*/
return mRenderTasks;
}
+void RenderTaskList::SetCompleteNotificationInterface( CompleteNotificationInterface* object )
+{
+
+ mNotificationObject = object;
+}
+
+CompleteNotificationInterface* RenderTaskList::GetCompleteNotificationInterface()
+{
+
+ return mNotificationObject;
+}
+
} // namespace SceneGraph
} // namespace Internal
namespace Internal
{
class CompleteStatusManager;
+class CompleteNotificationInterface;
namespace SceneGraph
{
*/
const RenderTaskContainer& GetTasks() const;
+ /**
+ * Set the notification method to package in the NotifyFinishedMessage
+ * @param object to store in notification managers queue
+ */
+ void SetCompleteNotificationInterface( CompleteNotificationInterface* object );
+
+ /**
+ * Get the Notification interface for when 1+ render tasks have finished
+ */
+ CompleteNotificationInterface* GetCompleteNotificationInterface();
+
private:
// Undefined
RenderTaskList& operator=(const RenderTaskList&);
private:
+
+ CompleteNotificationInterface* mNotificationObject; ///< object to pass in to the complete notification
RenderTaskContainer mRenderTasks; ///< A container of owned RenderTasks
CompleteStatusManager& mCompleteStatusManager; ///< The complete status tracker (render tasks need this)
+
};
// Messages for RenderTaskList