Reset node animatable properties for two frames after removing the frame callback
[platform/core/uifw/dali-core.git] / dali / internal / update / common / node-resetter.h
1 #ifndef DALI_INTERNAL_SCENEGRAPH_NODE_RESETTER_H
2 #define DALI_INTERNAL_SCENEGRAPH_NODE_RESETTER_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLDUES
21 #include <cstdint> // int8_t
22
23 #include <dali/internal/update/animation/property-accessor.h>
24 #include <dali/internal/update/animation/property-component-accessor.h>
25 #include <dali/internal/update/common/property-owner.h>
26 #include <dali/internal/update/nodes/node.h>
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 namespace SceneGraph
33 {
34 /**
35  * Class to reset the node's properties to their base values. Used by UpdateManager
36  * to reset the node properties after the node is connected to the scene graph.
37  */
38 class NodeResetter : public PropertyOwner::Observer
39 {
40 public:
41   /**
42    * New method.
43    * @param[in] node  The node
44    * @return the new node resetter
45    */
46   static NodeResetter* New(const Node& node)
47   {
48     return new NodeResetter(const_cast<Node*>(&node));
49   }
50
51   /**
52    * Virtual Destructor
53    */
54   ~NodeResetter() override
55   {
56     if(mNode != nullptr)
57     {
58       mNode->RemoveObserver(*this);
59     }
60   }
61
62   /**
63    * Initialize.
64    *
65    * Watches the node to track if it's disconnected or not.
66    */
67   void Initialize()
68   {
69     mNode->AddObserver(*this);
70   }
71
72   /**
73    * Reset the node properties to their base values if the node is still alive and on stage
74    * @param[in] updateBufferIndex the current buffer index
75    */
76   void ResetToBaseValue(BufferIndex updateBufferIndex)
77   {
78     if(mNode != nullptr && mActive)
79     {
80       // Start aging the node properties.
81       // We need to reset the node properties for two frames to ensure both
82       // property values are set appropriately.
83       --mActive;
84
85       mNode->mVisible.ResetToBaseValue(updateBufferIndex);
86       mNode->mColor.ResetToBaseValue(updateBufferIndex);
87     }
88   };
89
90   /**
91    * Called when the node is connected to the scene graph.
92    *
93    * Note, this resetter object may be created after the node has been connected
94    * to the scene graph, so we track disconnection and re-connection instead of connection
95    *
96    * @param[in] owner The property owner
97    */
98   void PropertyOwnerConnected(PropertyOwner& owner) override
99   {
100     mDisconnected = false;
101     mActive       = ACTIVE;
102
103     mNode->mVisible.MarkAsDirty();
104     mNode->mColor.MarkAsDirty();
105   }
106
107   /**
108    * Called when mPropertyOwner is disconnected from the scene graph.
109    * @param[in] bufferIndex the current buffer index
110    * @param[in] owner The property owner
111    */
112   void PropertyOwnerDisconnected(BufferIndex bufferIndex, PropertyOwner& owner) override
113   {
114     mDisconnected = true;
115   }
116
117   /**
118    * Called shortly before the propertyOwner is destroyed
119    * @param[in] owner The property owner
120    */
121   void PropertyOwnerDestroyed(PropertyOwner& owner) override
122   {
123     mDisconnected = true;
124     mNode         = nullptr;
125
126     // Don't need to wait another frame as the properties are being destroyed
127     mActive = STOPPED;
128   }
129
130   /**
131    * Determine if the node resetter has finished.
132    *
133    * @return true if the node resetter has finished.
134    */
135   virtual bool IsFinished()
136   {
137     return mActive <= STOPPED;
138   }
139
140 protected:
141   enum
142   {
143     STOPPED = 0,
144     AGING   = 1,
145     ACTIVE  = 2,
146   };
147
148   /**
149    * Constructor
150    *
151    * @param[in] node The node storing the base properties
152    */
153   NodeResetter(Node* node)
154   : mNode(node),
155     mActive(ACTIVE),
156     mDisconnected(false)
157   {
158     mNode->mVisible.MarkAsDirty();
159     mNode->mColor.MarkAsDirty();
160   }
161
162   Node*  mNode;         ///< The node that owns the properties
163   int8_t mActive;       ///< 2 if active, 1 if aging, 0 if stopped
164   bool   mDisconnected; ///< True if the node has been disconnected
165 };
166
167 } // namespace SceneGraph
168
169 } // namespace Internal
170
171 } // namespace Dali
172
173 #endif //DALI_INTERNAL_SCENEGRAPH_NODE_RESETTER_H