Merge "Add tc log to check a failure" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / control / control-debug.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <dali/integration-api/debug.h>
18 #include <dali/public-api/object/property.h>
19 #include <dali/public-api/object/property-index-ranges.h>
20 #include <dali-toolkit/public-api/controls/control-impl.h>
21 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
22 #include <dali-toolkit/internal/controls/control/control-debug.h>
23 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
24 #include <iostream>
25 #include <algorithm>
26 #include <functional>
27
28 #if defined(DEBUG_ENABLED)
29
30 namespace Dali
31 {
32 namespace Toolkit
33 {
34 namespace Internal
35 {
36
37 class JsonWriter
38 {
39 public:
40   JsonWriter( Property::Value& value )
41   : mValue(value)
42   {
43   }
44
45   std::string ToString()
46   {
47     std::ostringstream stream;
48     ToStream( stream );
49     return stream.str();
50   }
51
52   void ToStream( std::ostream& stream )
53   {
54     switch( mValue.GetType() )
55     {
56       case Dali::Property::BOOLEAN:
57       {
58         auto value = mValue.Get<bool>();
59         stream << ((value)?"true":"false");
60         break;
61       }
62       case Dali::Property::FLOAT:
63       {
64         stream << mValue.Get<float>();
65         break;
66       }
67       case Dali::Property::INTEGER:
68       {
69         stream << mValue.Get<int>();
70         break;
71       }
72       case Dali::Property::VECTOR2:
73       {
74         auto vector = mValue.Get<Vector2>();
75         stream << "[" << vector.x << ", " << vector.y << "]";
76         break;
77       }
78       case Dali::Property::VECTOR3:
79       {
80         auto vector = mValue.Get<Vector3>();
81         stream << "[" << vector.x << ", " << vector.y << ", " << vector.z << "]";
82         break;
83       }
84       case Dali::Property::VECTOR4:
85       {
86         auto vector = mValue.Get<Vector4>();
87         stream << "[" << vector.x << ", " << vector.y << ", " << vector.z << ", " << vector.w << "]";
88         break;
89       }
90       case Dali::Property::MATRIX3:
91       {
92         auto matrix = mValue.Get<Matrix3>();
93         stream << "[";
94         for( int i=0; i<9; ++i )
95         {
96           if( i>0)
97             stream << ",";
98           stream << matrix.AsFloat()[i];
99         }
100         stream << "]";
101         break;
102       }
103       case Dali::Property::MATRIX:
104       {
105         auto matrix = mValue.Get<Matrix>();
106         stream << "[";
107         for( int i=0; i<16; ++i )
108         {
109           if( i>0)
110             stream << ",";
111           stream << matrix.AsFloat()[i];
112         }
113         stream << "]";
114         break;
115       }
116       case Dali::Property::RECTANGLE:
117       {
118         auto vector = mValue.Get<Rect<int> >();
119         stream << "[" << vector.x << ", " << vector.y << ", " << vector.width << ", " << vector.height << "]";
120         break;
121       }
122       case Dali::Property::ROTATION:
123       {
124         auto angleAxis = mValue.Get<AngleAxis>();
125         stream << "[ [ " << angleAxis.axis.x << ", " << angleAxis.axis.y << ", " << angleAxis.axis.z << "], "
126                << angleAxis.angle.radian << "]";
127         break;
128       }
129       case Dali::Property::STRING:
130       {
131         stream << '"' << mValue.Get<std::string>() << '"';
132         break;
133       }
134       case Dali::Property::ARRAY:
135       {
136         auto array = mValue.GetArray();
137         stream << "[ ";
138         if( array )
139         {
140           for( Property::Array::SizeType i=0; i<array->Size(); ++i)
141           {
142             if( i>0)
143               stream << ", ";
144             auto outValue = JsonWriter( array->GetElementAt(i) );
145             stream << outValue.ToString();
146           }
147         }
148         stream << "]";
149         break;
150       }
151       case Dali::Property::MAP:
152       {
153         auto map = mValue.GetMap();
154         stream << "{ ";
155         if( map )
156         {
157           for( Property::Map::SizeType i=0; i<map->Count(); ++i)
158           {
159             if( i>0)
160               stream << ", ";
161             auto key = map->GetKeyAt( i );
162             auto outValue = JsonWriter( map->GetValue(i) );
163             stream << '\"' << key << "\":";
164             stream << outValue.ToString();
165           }
166         }
167         stream << "}";
168         break;
169       }
170       case Dali::Property::EXTENTS:
171       {
172         stream << mValue.Get<Extents>();
173         break;
174       }
175       case Dali::Property::NONE:
176       {
177         stream << "undefined type";
178         break;
179       }
180     }
181   }
182
183   Property::Value& mValue;
184 };
185
186 static std::ostream& operator<<( std::ostream& o, JsonWriter& value )
187 {
188   value.ToStream(o);
189   return o;
190 }
191
192
193 std::ostream& operator<<( std::ostream& o, const RegisteredVisual& registeredVisual )
194 {
195   o << "{\n" << "\"index\":" << registeredVisual.index << ",\n";
196   o << "\"enabled\":" << (registeredVisual.enabled?"true":"false") << ",\n";
197   o << "\"pending\":" << (registeredVisual.pending?"true":"false") << ",\n";
198
199   Property::Map map;
200   registeredVisual.visual.CreatePropertyMap( map );
201   o << "\"visual\": {\n\"name\":\"" << registeredVisual.visual.GetName() << "\",\n";
202   o << map << "}\n" << "\n}\n";
203   return o;
204 }
205
206 std::ostream& operator<<( std::ostream& o, const RegisteredVisualContainer& visualContainer )
207 {
208   o<<"[\n";
209
210   bool first=true;
211   for( auto&& elem : visualContainer )
212   {
213     if(!first)
214     {
215       o << ",";
216     }
217     first = false;
218
219     o<<*elem<<"\n";
220   }
221   o<<"]\n";
222   return o;
223 }
224
225 std::ostream& DumpProperty( std::ostream& o, Property::Index index, Handle handle )
226 {
227   auto propertyValue = handle.GetProperty( index );
228   auto jsonPropertyValue = JsonWriter(propertyValue);
229
230   o << "{\n";
231   o << "\"index\":" << index << ",\n";
232   o << "\"name\":\"" << handle.GetPropertyName( index ) << "\",\n";
233   o << "\"value\":" << jsonPropertyValue << "\n";
234   o << "}";
235   return o;
236 }
237
238
239 std::ostream& DumpPropertiesWithPredicate( std::ostream& o, Dali::Handle handle,
240                                            Property::IndexContainer& indices, std::function<bool(int)> predicate)
241 {
242   bool first = true;
243   for( auto index : indices )
244   {
245     if( predicate( index ) )
246     {
247       if( !first )
248       {
249         o << ",";
250       }
251       o << std::endl;
252       first = false;
253       DumpProperty( o, index, handle );
254     }
255   }
256   return o;
257 }
258
259 std::ostream& DumpProperties( std::ostream& o, Handle handle )
260 {
261   Property::IndexContainer indices;
262   handle.GetPropertyIndices( indices );
263
264   auto childPropertiesP = [](int index) -> bool
265     {
266       return CHILD_PROPERTY_REGISTRATION_START_INDEX <= index && index <= CHILD_PROPERTY_REGISTRATION_MAX_INDEX;
267     };
268   auto propertiesP = [](int index) -> bool
269     {
270       return !(CHILD_PROPERTY_REGISTRATION_START_INDEX <= index && index <= CHILD_PROPERTY_REGISTRATION_MAX_INDEX);
271     };
272
273   o << "\"childProperties\":[\n" ;
274   DumpPropertiesWithPredicate( o, handle, indices, childPropertiesP );
275   o << std::endl << "]," << std::endl;
276
277   o << "\"Properties\":[\n" ;
278   DumpPropertiesWithPredicate( o, handle, indices, propertiesP );
279   o << std::endl << "]" << std::endl;
280
281   return o;
282 }
283
284 std::string DumpControl( const Internal::Control& control )
285 {
286   auto& controlData = Internal::Control::Impl::Get( control );
287
288   std::ostringstream oss;
289   oss << "{\n  ";
290   const std::string& name = control.Self().GetProperty< std::string >( Dali::Actor::Property::NAME );
291   if( ! name.empty() )
292   {
293     oss << "\"name\":\"" << name << "\",\n";
294   }
295   oss << "\"id\":\"" << control.Self().GetProperty< int >( Actor::Property::ID ) << "\",\n";
296   oss << "\"registeredVisuals\":\n" << controlData.mVisuals << ",\n";
297   oss << "\"removeVisuals\":\n" << controlData.mRemoveVisuals << ",\n";
298   oss << "\"rendererCount\":" << control.Self().GetRendererCount() << ",\n";
299   oss << "\"properties\":\n{\n";
300   DumpProperties( oss, control.Self() ) << "}\n";
301   oss << "}\n";
302   return oss.str();
303 }
304
305 std::string DumpActor( Actor actor )
306 {
307   std::ostringstream oss;
308   oss << "{\n  ";
309   const std::string& name = actor.GetProperty< std::string >( Dali::Actor::Property::NAME );
310   if( ! name.empty() )
311   {
312     oss << "\"name\":\"" << name << "\",\n";
313   }
314   oss << "\"id\":\"" << actor.GetProperty< int >( Actor::Property::ID ) << "\",\n";
315   oss << "\"rendererCount\":" << actor.GetRendererCount() << ",\n";
316   oss << "\"properties\":\n{\n";
317   Toolkit::Internal::DumpProperties( oss, actor ) << "}\n";
318   oss << "}\n";
319   return oss.str();
320 }
321
322 void DumpControlHierarchy( std::ostream& o, Actor actor )
323 {
324   auto control = Toolkit::Control::DownCast( actor );
325   o << "{\n";
326   if( control )
327   {
328     o << "\"Control\":" << DumpControl( Toolkit::Internal::GetImplementation( control ) );
329   }
330   else
331   {
332     o << "\"Actor\":" << DumpActor( actor );
333   }
334   o << ",\n\"children\":[\n";
335   bool first=true;
336   for( auto count=actor.GetChildCount(), i=0u; i<count; ++i )
337   {
338     if( !first )
339     {
340       o << ",";
341     }
342     first = false;
343     o << "\n";
344     DumpControlHierarchy( o, actor.GetChildAt( i ) );
345   }
346   o << "]}\n";
347 }
348
349 } // namespace Internal
350 } // namespace Toolkit
351 } // namespace Dali
352
353 #endif