From: Richard Huang Date: Tue, 12 Oct 2021 15:26:04 +0000 (+0100) Subject: Add a node resetter that resets the animatable properties for two frames after node... X-Git-Tag: dali_2.1.0~10 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=a2e592d0588a244ac62162bf6c91cd8d2d6863a6 Add a node resetter that resets the animatable properties for two frames after node connection Change-Id: I3a64c3719107c231085a524b05c1302977ccde10 --- diff --git a/dali/internal/update/common/node-resetter.h b/dali/internal/update/common/node-resetter.h new file mode 100644 index 0000000..7e73a6b --- /dev/null +++ b/dali/internal/update/common/node-resetter.h @@ -0,0 +1,173 @@ +#ifndef DALI_INTERNAL_SCENEGRAPH_NODE_RESETTER_H +#define DALI_INTERNAL_SCENEGRAPH_NODE_RESETTER_H + +/* + * Copyright (c) 2021 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. + */ + +// EXTERNAL INCLDUES +#include // int8_t + +#include +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ +/** + * Class to reset the node's properties to their base values. Used by UpdateManager + * to reset the node properties after the node is connected to the scene graph. + */ +class NodeResetter : public PropertyOwner::Observer +{ +public: + /** + * New method. + * @param[in] node The node + * @return the new node resetter + */ + static NodeResetter* New(const Node& node) + { + return new NodeResetter(const_cast(&node)); + } + + /** + * Virtual Destructor + */ + ~NodeResetter() override + { + if(mNode != nullptr) + { + mNode->RemoveObserver(*this); + } + } + + /** + * Initialize. + * + * Watches the node to track if it's disconnected or not. + */ + void Initialize() + { + mNode->AddObserver(*this); + } + + /** + * Reset the node properties to their base values if the node is still alive and on stage + * @param[in] updateBufferIndex the current buffer index + */ + void ResetToBaseValue(BufferIndex updateBufferIndex) + { + if(mNode != nullptr && mActive) + { + // Start aging the node properties. + // We need to reset the node properties for two frames to ensure both + // property values are set appropriately. + // if(mDisconnected) + { + --mActive; + } + + mNode->mVisible.ResetToBaseValue(updateBufferIndex); + mNode->mCulled.ResetToBaseValue(updateBufferIndex); + mNode->mColor.ResetToBaseValue(updateBufferIndex); + mNode->mUpdateSizeHint.ResetToBaseValue(updateBufferIndex); + } + }; + + /** + * Called when the node is connected to the scene graph. + * + * Note, this resetter object may be created after the node has been connected + * to the scene graph, so we track disconnection and re-connection instead of connection + * + * @param[in] owner The property owner + */ + void PropertyOwnerConnected(PropertyOwner& owner) override + { + mDisconnected = false; + mActive = ACTIVE; + } + + /** + * Called when mPropertyOwner is disconnected from the scene graph. + * @param[in] bufferIndex the current buffer index + * @param[in] owner The property owner + */ + void PropertyOwnerDisconnected(BufferIndex bufferIndex, PropertyOwner& owner) override + { + mDisconnected = true; + } + + /** + * Called shortly before the propertyOwner is destroyed + * @param[in] owner The property owner + */ + void PropertyOwnerDestroyed(PropertyOwner& owner) override + { + mDisconnected = true; + mNode = nullptr; + + // Don't need to wait another frame as the properties are being destroyed + mActive = STOPPED; + } + + /** + * Determine if the node resetter has finished. + * + * @return true if the node resetter has finished. + */ + virtual bool IsFinished() + { + return mActive <= STOPPED; + } + +protected: + enum + { + STOPPED = 0, + AGING = 1, + ACTIVE = 2, + }; + + /** + * Constructor + * + * @param[in] node The node storing the base properties + */ + NodeResetter(Node* node) + : mNode(node), + mActive(ACTIVE), + mDisconnected(false) + { + } + + Node* mNode; ///< The node that owns the properties + int8_t mActive; ///< 2 if active, 1 if aging, 0 if stopped + bool mDisconnected; ///< True if the node has been disconnected +}; + +} // namespace SceneGraph + +} // namespace Internal + +} // namespace Dali + +#endif //DALI_INTERNAL_SCENEGRAPH_NODE_RESETTER_H diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 7f8eca8..86db620 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -268,6 +268,7 @@ struct UpdateManager::Impl OwnerContainer customObjects; ///< A container of owned objects (with custom properties) OwnerContainer propertyResetters; ///< A container of property resetters + OwnerContainer nodeResetters; ///< A container of node resetters OwnerContainer animations; ///< A container of owned animations PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. OwnerContainer renderers; ///< A container of owned renderers @@ -340,6 +341,9 @@ void UpdateManager::InstallRoot(OwnerPointer& layer) rootLayer->CreateTransform(&mImpl->transformManager); rootLayer->SetRoot(true); + OwnerPointer nodeResetter = SceneGraph::NodeResetter::New(*rootLayer); + AddNodeResetter(nodeResetter); + mImpl->scenes.emplace_back(new Impl::SceneInfo(rootLayer)); } @@ -384,6 +388,9 @@ void UpdateManager::ConnectNode(Node* parent, Node* node) parent->ConnectChild(node); + OwnerPointer nodeResetter = SceneGraph::NodeResetter::New(*node); + AddNodeResetter(nodeResetter); + // Inform the frame-callback-processor, if set, about the node-hierarchy changing if(mImpl->frameCallbackProcessor) { @@ -555,6 +562,12 @@ void UpdateManager::AddPropertyResetter(OwnerPointer& prop mImpl->propertyResetters.PushBack(propertyResetter.Release()); } +void UpdateManager::AddNodeResetter(OwnerPointer& nodeResetter) +{ + nodeResetter->Initialize(); + mImpl->nodeResetters.PushBack(nodeResetter.Release()); +} + void UpdateManager::AddPropertyNotification(OwnerPointer& propertyNotification) { mImpl->propertyNotifications.PushBack(propertyNotification.Release()); @@ -659,19 +672,36 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex) // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped mImpl->animationFinishedDuringUpdate = false; + // Reset node properties + std::vector nodeResetterToDelete; + for(auto&& element : mImpl->nodeResetters) + { + element->ResetToBaseValue(bufferIndex); + if(element->IsFinished()) + { + nodeResetterToDelete.push_back(element); + } + } + + // If a node resetter is no longer required, delete it. + for(auto&& elementPtr : nodeResetterToDelete) + { + mImpl->nodeResetters.EraseObject(elementPtr); + } + // Reset all animating / constrained properties - std::vector toDelete; + std::vector propertyResettertoDelete; for(auto&& element : mImpl->propertyResetters) { element->ResetToBaseValue(bufferIndex); if(element->IsFinished()) { - toDelete.push_back(element); + propertyResettertoDelete.push_back(element); } } - // If a resetter is no longer required (the animator or constraint has been removed), delete it. - for(auto&& elementPtr : toDelete) + // If a property resetter is no longer required (the animator or constraint has been removed), delete it. + for(auto&& elementPtr : propertyResettertoDelete) { mImpl->propertyResetters.EraseObject(elementPtr); } diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 8a8b2b3..da66ea4 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -33,6 +33,7 @@ #include #include // for OwnerPointer< Shader > #include +#include #include #include #include @@ -259,6 +260,13 @@ public: */ void AddPropertyResetter(OwnerPointer& propertyResetter); + /** + * Add a node resetter. UpdateManager takes ownership of the object. + * It will be killed by UpdateManager when the node is disconnected from the scene graph; + * or when the node is destroyed. + */ + void AddNodeResetter(OwnerPointer& nodeResetter); + // Property Notification /**