[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / tree-node-manipulator.h
1 #ifndef DALI_SCRIPT_TREE_NODE_MANIPULATOR_H
2 #define DALI_SCRIPT_TREE_NODE_MANIPULATOR_H
3
4 /*
5  * Copyright (c) 2024 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 // EXTERNAL INCLUDES
22 #include <cstring>
23 #include <iterator>
24 #include <utility> // pair
25
26 #include <dali-toolkit/public-api/dali-toolkit-common.h>
27 #include <dali/public-api/common/vector-wrapper.h>
28
29 // INTERNAL INCLUDES
30 #include <dali-toolkit/devel-api/builder/tree-node.h>
31
32 namespace Dali
33 {
34 namespace Toolkit
35 {
36 namespace Internal
37 {
38 typedef std::vector<char>    VectorChar;
39 typedef VectorChar::iterator VectorCharIter;
40
41 /*
42  * TreeNodeManipulator performs modification operations on a TreeNode which are
43  * otherwise prohibited on the TreeNode public interface.
44  */
45 class TreeNodeManipulator
46 {
47 public:
48   /*
49    * Constructor
50    * @param node The TreeNode to modify
51    */
52   explicit TreeNodeManipulator(TreeNode* node);
53
54   /*
55    * Create a new TreeNode instance
56    * @return new TreeNode
57    */
58   static TreeNode* NewTreeNode();
59
60   /*
61    * Shallow copy node data
62    * Shallow copy the data but doesnt parent or copy children
63    * @param from Node to copy from
64    * @param to Node to copy to
65    */
66   static void ShallowCopy(const TreeNode* from, TreeNode* to);
67
68   /*
69    * Moves all string data to a new buffer. There must be enough space for all string data.
70    * @param start The buffer start
71    * @param sentinel The end of the buffer
72    */
73   void MoveStrings(VectorCharIter& start, const VectorCharIter& sentinel);
74
75   /*
76    * Remove all children from the node
77    */
78   void RemoveChildren();
79
80   /*
81    * Make a deep copy of the tree.
82    * @param tree The tree to copy
83    * @param numberOfNodes The number of nodes that were copied
84    * @param numberOfChars The size of string data.
85    */
86   static TreeNode* Copy(const TreeNode& tree, int& numberOfNodes, int& numberOfChars);
87
88   /*
89    * Add child to the node
90    * @param child The child to add
91    * @return the added child
92    */
93   TreeNode* AddChild(TreeNode* child);
94
95   /*
96    * Change the type of the Node
97    * NB: If the type changes from a type with children to a value type without children then
98    *     the children are removed
99    * @param type The new type
100    */
101   void SetType(TreeNode::NodeType type);
102
103   /*
104    * Set the name of the node
105    * @param name The name to set
106    */
107   void SetName(const char* name);
108
109   /*
110    * Set the substituion flag
111    * The substitution flag indicates this nodes string value contains a reference to another node
112    * in the tree.
113    * @param on The state
114    */
115   void SetSubstitution(bool on);
116
117   /*
118    * Get the nodes type
119    * @return The nodes type
120    */
121   TreeNode::NodeType GetType() const;
122
123   /*
124    * Get the number of children of the node
125    * @return The number of children
126    */
127   size_t Size() const;
128
129   /*
130    * Set the node as a string value
131    * @param string The string value
132    */
133   void SetString(const char* string);
134
135   /*
136    * Set the node as an integer value
137    * @param i The integer
138    */
139   void SetInteger(int i);
140
141   /*
142    * Set the node as an float value
143    * @param f The float
144    */
145   void SetFloat(float f);
146
147   /*
148    * Set the node as an boolean value
149    * @param b The boolean
150    */
151   void SetBoolean(bool b);
152
153   /*
154    * Get the nodes parent
155    * @return The nodes parent
156    */
157   TreeNode* GetParent() const;
158
159   /*
160    * Get the nodes child by name
161    * @param name The childs name
162    * @return The nodes if found, else NULL
163    */
164   const TreeNode* GetChild(const std::string& name) const;
165
166   /*
167    * @copydoc Dali::Scripting::JsonParser::Write()
168    */
169   void Write(std::ostream& output, int indent) const;
170
171 private:
172   TreeNode* mNode;
173
174   /*
175    * Move the nodes strings to the buffer
176    */
177   void MoveNodeStrings(VectorCharIter& start, const VectorCharIter& sentinel);
178
179   /*
180    * Recursively move child strings to the buffer
181    */
182   void RecurseMoveChildStrings(VectorCharIter& start, const VectorCharIter& sentinel);
183
184   /*
185    * Recursively copy children
186    */
187   static void CopyChildren(const TreeNode* from, TreeNode* to, int& numberNodes, int& numberChars);
188
189   /*
190    * Do write to string stream
191    */
192   void DoWrite(const TreeNode* value, std::ostream& output, int level, int ident, bool groupChildren) const;
193 };
194
195 /*
196  * Collect nodes
197  */
198 struct CollectNodes
199 {
200   CollectNodes(){};
201
202   /*
203    * Call operator to add nodes to the list
204    */
205   void operator()(TreeNode*& n)
206   {
207     DALI_ASSERT_DEBUG(n && "Operation on NULL JSON node");
208     nodes.push_back(n);
209   }
210
211   typedef std::vector<const TreeNode*> VectorNodes;
212   typedef VectorNodes::iterator        iterator;
213
214   VectorNodes nodes; ///< List of collected nodes
215 };
216
217 /*
218  * Delete nodes immediately, instead of self
219  */
220 struct DeleteNodesWithoutSelf
221 {
222   DeleteNodesWithoutSelf(TreeNode* self)
223   : mSelf(self){};
224
225   /*
226    * Call operator to delete object if given node is not self
227    */
228   void operator()(TreeNode*& n)
229   {
230     DALI_ASSERT_DEBUG(n && "Operation on NULL JSON node");
231     if(mSelf != n)
232     {
233       delete n;
234     }
235   }
236
237   const TreeNode* mSelf; ///< self node what we should not remove.
238 };
239
240 /*
241  * Depth first walk of nodes applying given operation (unary_function)
242  */
243 template<typename Operation>
244 void DepthFirst(TreeNode* node, Operation& operation)
245 {
246   DALI_ASSERT_DEBUG(node && "Operation on NULL JSON node");
247
248   for(TreeNode::ConstIterator iter = node->CBegin(); iter != node->CEnd(); ++iter)
249   {
250     // iterator access is const for external api but were modifying
251     DepthFirst(const_cast<TreeNode*>(&((*iter).second)), operation);
252   }
253
254   operation(node);
255 }
256
257 /*
258  * Recursive search on the tree for the child with the given name
259  * @param childName The name to find
260  * @param tree The tree to search
261  * @return the TreeNode if found, else NULL
262  */
263 const TreeNode* FindIt(std::string_view childName, const TreeNode* tree);
264
265 /*
266  * Copy string to a buffer
267  * Raises if there is not enough space in the buffer
268  * @param fromString The string
269  * @param iter The start of the buffer
270  * @param sentinel The buffer sentinel
271  * @return The start of the given buffer
272  */
273 char* CopyString(const char* fromString, VectorCharIter& iter, const VectorCharIter& sentinel);
274
275 } // namespace Internal
276
277 } // namespace Toolkit
278
279 } // namespace Dali
280
281 #endif // DALI_SCRIPT_TREE_NODE_MANIPULATOR_H