/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
// INTERNAL INCLUDES
#include <dali/devel-api/update/frame-callback-interface.h>
#include <dali/devel-api/update/update-proxy.h>
+#include <dali/integration-api/trace.h>
-namespace Dali
+namespace
{
+DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
+} // namespace
+namespace Dali
+{
namespace Internal
{
-
namespace SceneGraph
{
-
-namespace
-{
-
-/**
- * Given a node, it matches all update-proxies using that node as their root-node.
- */
-template< typename FrameCallbackInfoT >
-class MatchRootNode
-{
-public:
-
- MatchRootNode( PropertyOwner& rootNode )
- : mRootNode( rootNode )
- {
- }
-
- bool operator() ( const FrameCallbackInfoT& info )
- {
- return &info.updateProxyImpl->GetRootNode() == &mRootNode;
- }
-
-private:
-
- const PropertyOwner& mRootNode;
-};
-
-} // unnamed namespace
-
-FrameCallbackProcessor::FrameCallbackProcessor( TransformManager& transformManager, Node& rootNode )
+FrameCallbackProcessor::FrameCallbackProcessor(UpdateManager& updateManager, TransformManager& transformManager)
: mFrameCallbacks(),
- mTransformManager( transformManager ),
- mRootNode( rootNode ),
- mNodeHierarchyChanged( true )
+ mUpdateManager(updateManager),
+ mTransformManager(transformManager),
+ mNodeHierarchyChanged(true)
{
}
-FrameCallbackProcessor::~FrameCallbackProcessor()
-{
-}
+FrameCallbackProcessor::~FrameCallbackProcessor() = default;
-void FrameCallbackProcessor::AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode )
+void FrameCallbackProcessor::AddFrameCallback(OwnerPointer<FrameCallback>& frameCallback, const Node* rootNode)
{
- Node& node = const_cast< Node& >( *rootNode ); // Was sent as const from event thread, we need to be able to use non-const version here.
+ Node& node = const_cast<Node&>(*rootNode); // Was sent as const from event thread, we need to be able to use non-const version here.
- // We want to be notified when the node is destroyed (if we're not observing it already)
- auto iter = std::find_if( mFrameCallbacks.begin(), mFrameCallbacks.end(), MatchRootNode< FrameCallbackInfo >( node ) );
- if( iter == mFrameCallbacks.end() )
- {
- node.AddObserver( *this );
- }
+ frameCallback->ConnectToSceneGraph(mUpdateManager, mTransformManager, node);
- mFrameCallbacks.emplace_back( FrameCallbackInfo( frameCallback , new UpdateProxy( mTransformManager, node ) ) );
+ mFrameCallbacks.emplace_back(frameCallback);
}
-void FrameCallbackProcessor::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
+void FrameCallbackProcessor::RemoveFrameCallback(FrameCallbackInterface* frameCallback)
{
- std::vector< SceneGraph::Node* > nodesToStopObserving;
-
- // Find and remove all matching frame-callbacks
- auto iter =
- std::remove_if( mFrameCallbacks.begin(), mFrameCallbacks.end(),
- [ frameCallback, &nodesToStopObserving ] ( FrameCallbackInfo& info )
- {
- bool match = false;
- if( info.frameCallback == frameCallback )
- {
- nodesToStopObserving.push_back( &info.updateProxyImpl->GetRootNode() );
- match = true;
- }
- return match;
- } );
- mFrameCallbacks.erase( iter, mFrameCallbacks.end() );
-
- // Only stop observing the removed frame-callback nodes if none of the other frame-callbacks use them as root nodes
- for( auto&& node : nodesToStopObserving )
- {
- auto nodeMatchingIter = std::find_if( mFrameCallbacks.begin(), mFrameCallbacks.end(), MatchRootNode< FrameCallbackInfo >( *node ) );
- if( nodeMatchingIter == mFrameCallbacks.end() )
- {
- node->RemoveObserver( *this );
- }
- }
+ // Find and remove all frame-callbacks that use the given frame-callback-interface
+ auto iter = std::remove(mFrameCallbacks.begin(), mFrameCallbacks.end(), frameCallback);
+ mFrameCallbacks.erase(iter, mFrameCallbacks.end());
}
-void FrameCallbackProcessor::Update( BufferIndex bufferIndex, float elapsedSeconds )
+void FrameCallbackProcessor::Update(BufferIndex bufferIndex, float elapsedSeconds)
{
- for( auto&& iter : mFrameCallbacks )
+ if(!mFrameCallbacks.empty())
{
- UpdateProxy& updateProxyImpl = *iter.updateProxyImpl;
- updateProxyImpl.SetCurrentBufferIndex( bufferIndex );
+ DALI_TRACE_BEGIN(gTraceFilter, "DALI_FRAME_CALLBACK_UPDATE");
- if( mNodeHierarchyChanged )
- {
- updateProxyImpl.NodeHierarchyChanged();
- }
+ // If any of the FrameCallback::Update calls returns false, then they are no longer required & can be removed.
+ auto iter = std::remove_if(
+ mFrameCallbacks.begin(), mFrameCallbacks.end(), [&](OwnerPointer<FrameCallback>& frameCallback) {
+ return !frameCallback->Update(bufferIndex, elapsedSeconds, mNodeHierarchyChanged);
+ });
+ mFrameCallbacks.erase(iter, mFrameCallbacks.end());
- Dali::UpdateProxy updateProxy( updateProxyImpl );
- iter.frameCallback->Update( updateProxy, elapsedSeconds );
+ DALI_TRACE_END(gTraceFilter, "DALI_FRAME_CALLBACK_UPDATE");
}
- mNodeHierarchyChanged = false;
-}
-void FrameCallbackProcessor::PropertyOwnerDestroyed( PropertyOwner& owner )
-{
- auto iter = std::remove_if( mFrameCallbacks.begin(), mFrameCallbacks.end(), MatchRootNode< FrameCallbackInfo >( owner ) );
- mFrameCallbacks.erase( iter, mFrameCallbacks.end() );
+ mNodeHierarchyChanged = false;
}
} // namespace SceneGraph