Merge "use modern construct 'nullptr' instead of 'NULL' or '0'" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / common / double-buffered.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_DOUBLE_BUFFERED_H
2 #define DALI_INTERNAL_SCENE_GRAPH_DOUBLE_BUFFERED_H
3
4 /*
5  * Copyright (c) 2020 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
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/owner-pointer.h>
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29
30 // The number of buffers per scene-graph property
31 static const unsigned int NUM_SCENE_GRAPH_BUFFERS = 2;
32
33 namespace SceneGraph
34 {
35
36 /**
37  * Templated class for a double-buffered value.
38  */
39 template <typename T>
40 class DoubleBuffered
41 {
42 public:
43
44   DoubleBuffered()
45   : mValue1(),
46     mValue2()
47   {
48   }
49
50   DoubleBuffered(const T& val)
51   : mValue1(val),
52     mValue2(val)
53   {
54   }
55
56   inline T& operator[](const BufferIndex i)
57   {
58     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
59
60     return *(&mValue1+i);
61   }
62
63   inline const T& operator[](const BufferIndex i) const
64   {
65     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
66
67     return *(&mValue1+i);
68   }
69
70 private:
71
72   // Undefined
73   DoubleBuffered<T>(const DoubleBuffered<T>&);
74
75   // Undefined
76   DoubleBuffered<T>& operator=(const DoubleBuffered<T>& rhs);
77
78 private:
79
80   T mValue1;
81   T mValue2;
82 };
83
84 /**
85  * @brief Specialization for owner-pointer
86  *
87  * This class takes ownership of the pointers and releases the memory when the pointer
88  * is no longer used by either buffer
89  */
90 template <typename T>
91 class DoubleBuffered< OwnerPointer< T > >
92 {
93 public:
94
95   /**
96    * Class that deals with setting a value
97    */
98   class Setter
99   {
100   public:
101     /**
102      * @brief Assignment operator to that a value that will later
103      * be set in the correct buffer index of the object referenced by the setter.
104      */
105     Setter& operator=( T* value )
106     {
107       mValue = value;
108       return *this;
109     }
110
111     ~Setter()
112     {
113       mObject.Set( mIndex, mValue );
114     }
115
116   private:
117     Setter( DoubleBuffered& object,
118             BufferIndex i,
119             T* value )
120     : mObject( object ),
121       mIndex( i ),
122       mValue( value )
123     {
124     }
125
126     Setter( const Setter& rhs )
127     : mObject( rhs.mObject ),
128       mIndex( rhs.mIndex ),
129       mValue( rhs.mValue )
130     {
131     }
132
133     DoubleBuffered& mObject;  ///< Double-buffered object that will be changed
134     const BufferIndex mIndex; ///< Buffer index that will be changed
135     T* mValue;                ///< Value of the pointer
136
137     friend class DoubleBuffered;
138   };
139
140   DoubleBuffered()
141   : mValue1( NULL ),
142     mValue2( NULL )
143   {
144   }
145
146   DoubleBuffered(T* val)
147   : mValue1( val ),
148     mValue2( val )
149   {
150   }
151
152   ~DoubleBuffered()
153   {
154     if( mValue2 != mValue1 )
155     {
156       delete mValue2;
157     }
158     delete mValue1;
159   }
160
161   void Set( BufferIndex i, T* value )
162   {
163     T*& current = *(&mValue1 + i);
164     T*& previous = *(&mValue1 + 1u-i);
165
166     if( current != value && current != previous )
167     {
168       delete current;
169     }
170     current = value;
171   }
172
173   Setter operator[]( BufferIndex i )
174   {
175     return Setter( *this, i, *(&mValue1+i) );
176   }
177
178   const T* operator[]( BufferIndex i ) const
179   {
180     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
181
182     return *(&mValue1+i);
183   }
184
185   /**
186    * Auto-age the property: if it was set the previous frame,
187    * then copy the value into the current frame's buffer.
188    */
189   void CopyPrevious( BufferIndex i )
190   {
191     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
192
193     T*& current = *(&mValue1 + i);
194     T*& previous = *(&mValue1 + 1u-i);
195
196     if( current != previous )
197     {
198       delete current;
199     }
200
201     current = previous;
202   }
203
204 private:
205
206   // Undefined
207   DoubleBuffered(const DoubleBuffered&);
208
209   // Undefined
210   DoubleBuffered& operator=(const DoubleBuffered& rhs);
211
212 private:
213
214   T* mValue1;
215   T* mValue2;
216
217 };
218
219
220 } // namespace SceneGraph
221
222 } // namespace Internal
223
224 } // namespace Dali
225
226 #endif // DALI_INTERNAL_SCENE_GRAPH_DOUBLE_BUFFERED_H