Apply deprecate macro and LOG
[platform/core/uifw/dali-core.git] / dali / integration-api / debug.h
1 #ifndef __DALI_INTEGRATION_DEBUG_H__
2 #define __DALI_INTEGRATION_DEBUG_H__
3
4 /*
5  * Copyright (c) 2014 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 <string>
23 #include <sstream>
24 #include <list>
25
26 // INTERNAL INCLUDES
27 #include <dali/public-api/common/dali-common.h>
28
29 // Using Debug namespace alias shortens the log usage significantly
30 namespace Dali{namespace Integration{namespace Log{}}}
31 namespace Debug = Dali::Integration::Log;
32
33 namespace Dali
34 {
35
36 struct Vector2;
37 struct Vector3;
38 struct Vector4;
39 class Matrix3;
40 class Matrix;
41 class Quaternion;
42
43 namespace Integration
44 {
45 namespace Log
46 {
47
48 enum DebugPriority
49 {
50   DebugInfo,
51   DebugWarning,
52   DebugError
53 };
54
55 /**
56  * Used by logging macros to log a message along with function/class name
57  * @param level debug level
58  * @param format string format
59  */
60 DALI_IMPORT_API void LogMessage(enum DebugPriority level,const char *format, ...);
61
62 /**
63  * typedef for the logging function.
64  */
65 typedef void (*LogFunction)(DebugPriority priority, std::string& message);
66
67 /**
68  * A log function has to be installed for every thread that wants to use logging.
69  * This should be done by the adaptor.
70  * The log function can be different for each thread.
71  * @param logFunction the log function to install
72  * @param logOpts the log options to save in thread
73  */
74 DALI_IMPORT_API void InstallLogFunction(const LogFunction& logFunction);
75
76 /**
77  * A log function has to be uninstalled for every thread that wants to use logging.
78  * The log function can be different for each thread.
79  */
80 DALI_IMPORT_API void UninstallLogFunction();
81
82 /********************************************************************************
83  *                            Error/Warning  macros.                            *
84  ********************************************************************************/
85
86 /**
87  * Provides unfiltered logging for global error level messages
88  */
89 #define DALI_LOG_ERROR(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError,   "%s " format, __PRETTY_FUNCTION__, ## args)
90
91 #define DALI_LOG_ERROR_NOFN(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ## args)
92
93 #define DALI_LOG_WARNING_NOFN(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, format, ## args)
94
95 /**
96  * Provides unfiltered logging for fps monitor
97  */
98 #define DALI_LOG_FPS(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
99
100 /**
101  * Provides unfiltered logging for update status
102  */
103 #define DALI_LOG_UPDATE_STATUS(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
104
105 /**
106  * Provides unfiltered logging for render information
107  */
108 #define DALI_LOG_RENDER_INFO(format, args...)     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
109
110 #ifdef DEBUG_ENABLED
111
112 /**
113  * Provides unfiltered logging for global warning level messages
114  */
115 #define DALI_LOG_WARNING(format, args...)   Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, "%s " format, __PRETTY_FUNCTION__, ## args)
116
117
118 #else // DEBUG_ENABLED
119
120 // Don't warn on release build
121 #define DALI_LOG_WARNING(format, args...)
122
123 #endif
124
125 /********************************************************************************
126  *                                    Filter                                    *
127  ********************************************************************************/
128
129 #ifdef DEBUG_ENABLED
130
131 /**
132  * Enumeration of logging levels.
133  * Used by the filters to provide multiple log levels.
134  * In general, the higher the value, the more debug is available for that filter.
135  */
136 enum LogLevel
137 {
138   NoLogging   = 0,
139   Concise     = 1,
140   General     = 2,
141   Verbose     = 3
142 };
143
144
145 /**
146  * The Filter object is used by the DALI_LOG_INFO macro and others to determine if the logging
147  * should take place, and routes the logging via the platform abstraction's LogMessage.
148  *
149  * It provides a logging level. If this is set to zero, then DALI_LOG_INFO won't log anything.
150  * It provides the ability to turn tracing on or off.
151  *
152  */
153 class DALI_IMPORT_API Filter
154 {
155 public:
156   typedef std::list<Filter*>           FilterList;
157   typedef std::list<Filter*>::iterator FilterIter;
158
159 public:
160
161   /**
162    * Test if the filter is enabled for the given logging level
163    * @param[in] level - the level to test.
164    * @return true if this level of logging is enabled.
165    */
166   bool IsEnabledFor(LogLevel level) { return level != Debug::NoLogging && level <= mLoggingLevel;}
167
168   /**
169    * Test if trace is enabled for this filter.
170    * @return true if trace is enabled;
171    */
172   bool IsTraceEnabled() { return mTraceEnabled; }
173
174   /**
175    * Enable tracing on this filter.
176    */
177   void EnableTrace() { mTraceEnabled = true; }
178
179   /**
180    * Disable tracing on this filter.
181    */
182   void DisableTrace() { mTraceEnabled = false; }
183
184   /**
185    * Set the log level for this filter. Setting to a higher value than Debug::General also
186    * enables General;
187    */
188   void SetLogLevel(LogLevel level) { mLoggingLevel = level; }
189
190   /**
191    * Perform the logging for this filter.
192    */
193   void Log(LogLevel level, const char* format, ...);
194
195   /**
196    * Create a new filter whose debug level and trace can be modified through the use of an
197    * environment variable.
198    *
199    * @param[in] level The default log level
200    * @param[in] trace The default trace level. If true, function tracing is on.
201    * @param[in] environmentVariableName The environment variable name used in order to change the
202    *                                    log level or trace.
203    *
204    * @info To modify logg level/trace at runtime, you can should define your filter as shown below:
205    *
206    * @code
207    * Debug::Filter* filter = Debug::Filter::New( Debug::NoLogging, false, "FILTER_ENV" );
208    * @endcode
209    *
210    * And to use it when running an executable:
211    * @code
212    * FILTER_ENV=3 dali-demo        // LogLevel Verbose,   Trace using default
213    * FILTER_ENV=1,true dali-demo   // LogLevel Concise,   Trace ON
214    * FILTER_ENV=2,false dali-demo  // LogLevel General,   Trace OFF
215    * FILTER_ENV=0,true dali-demo   // LogLevel NoLogging, Trace ON
216    * @endcode
217    */
218   static Filter* New(LogLevel level, bool trace, const char * environmentVariableName );
219
220   /**
221    * Enable trace on all filters.
222    */
223   void EnableGlobalTrace();
224
225   /**
226    * Disable trace on all filters.
227    */
228   void DisableGlobalTrace();
229
230 private:
231
232   /**
233    * Constructor.
234    * @param[in] level - the highest log level.
235    * @param[in] trace - whether this filter allows tracing.
236    */
237   Filter(LogLevel level, bool trace) : mLoggingLevel(level), mTraceEnabled(trace), mNesting(0) {}
238
239   static FilterList* GetActiveFilters();
240
241 public:
242   // High level filters. If these filters are too broad for your current requirement, then
243   // you can add a filter to your own class or source file. If you do, use Filter::New()
244   // to tell this class about it.
245
246   static Filter *gRender;
247   static Filter *gResource;
248   static Filter *gGLResource;
249   static Filter *gObject;
250   static Filter *gImage;
251   static Filter *gModel;
252   static Filter *gNode;
253   static Filter *gElement;
254   static Filter *gActor;
255   static Filter *gShader;
256
257 private:
258   LogLevel mLoggingLevel;
259   bool     mTraceEnabled;
260 public:
261   int      mNesting;
262
263 };
264
265
266 #define  DALI_LOG_FILTER_SET_LEVEL(filter, level) filter->SetLogLevel(level)
267 #define  DALI_LOG_FILTER_ENABLE_TRACE(filter)     filter->EnableTrace()
268 #define  DALI_LOG_FILTER_DISABLE_TRACE(filter)    filter->DisableTrace()
269
270 #else
271
272 #define  DALI_LOG_FILTER_SET_LEVEL(filter, level)
273 #define  DALI_LOG_FILTER_ENABLE_TRACE(filter)
274 #define  DALI_LOG_FILTER_DISABLE_TRACE(filter)
275
276 #endif
277
278 /********************************************************************************
279  *                            General Logging macros                            *
280  ********************************************************************************/
281
282 #ifdef DEBUG_ENABLED
283
284 #define DALI_LOG_INFO(filter, level, format, args...)                        \
285   if(filter && filter->IsEnabledFor(level)) { filter->Log(level, format,  ## args); }
286
287 #else // DEBUG_ENABLED
288
289 #define DALI_LOG_INFO(filter, level, format, args...)
290
291 #endif // DEBUG_ENABLED
292
293
294 /********************************************************************************
295  *                                  Trace Macros                                *
296  ********************************************************************************/
297
298 /*
299  * These macros allow the instrumentation of methods. These translate into calls
300  * to LogMessage(DebugInfo).
301  */
302
303 #ifdef DEBUG_ENABLED
304
305 class DALI_IMPORT_API TraceObj
306 {
307 public:
308   TraceObj(Filter* filter, const char* fmt, ...);
309   ~TraceObj();
310
311 public:
312   std::string mMessage;
313   Filter* mFilter;
314 };
315
316
317 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...)                 \
318   Dali::Integration::Log::TraceObj debugTraceObj(filter, "%s: " format, __PRETTY_FUNCTION__, ## args)
319
320 #define DALI_LOG_TRACE_METHOD(filter)                                      \
321   Dali::Integration::Log::TraceObj debugTraceObj(filter, __PRETTY_FUNCTION__)
322
323
324 #else // DEBUG_ENABLED
325
326 #define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...)
327 #define DALI_LOG_TRACE_METHOD(filter)
328
329
330 #endif
331
332 /********************************************************************************
333  *                              Extra object debug                              *
334  ********************************************************************************/
335
336 #ifdef DEBUG_ENABLED
337
338 /**
339  * Warning, this macro changes the current scope, so should usually be put at the
340  * end of the class definition.
341  *
342  * Suggest that the value is usually set to the object's name.
343  * Warning - this will increase the size of the object for a debug build.
344  */
345 #define DALI_LOG_OBJECT_STRING_DECLARATION \
346 public: \
347   std::string mDebugString;
348
349 /**
350  * Print all the actor tree names
351  **/
352 #define DALI_LOG_ACTOR_TREE( node ) { \
353   std::stringstream branch; \
354   Node* tempNode = node; \
355   while( tempNode ) { \
356     branch << "<" << tempNode->mDebugString << ">::"; \
357     tempNode = tempNode->GetParent(); \
358   } \
359   DALI_LOG_ERROR_NOFN("Actor tree: %s\n", branch.str().c_str()); \
360 }
361
362 /**
363  * Allows one object to set another object's debug string
364  */
365 #define DALI_LOG_SET_OBJECT_STRING(object, string) (object->mDebugString = string)
366
367 /**
368  * Allows one object to set another object's std::string easily
369  */
370 #define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...) (object->mDebugString = FormatToString(fmt, ## args))
371
372 /**
373  * Allows one object to get another object's debug string
374  */
375 #define DALI_LOG_GET_OBJECT_STRING(object) (object->mDebugString)
376
377 /**
378  * Get the C string (for use in formatted logging)
379  */
380 #define DALI_LOG_GET_OBJECT_C_STR(object) (object->mDebugString.c_str())
381
382 /**
383  * Filtered logging of the object's debug string
384  */
385 #define DALI_LOG_OBJECT(filter, object)  DALI_LOG_INFO(filter, Debug::General, object->mDebugString)
386
387
388 #else // DEBUG_ENABLED
389
390 #define DALI_LOG_OBJECT_STRING_DECLARATION
391 #define DALI_LOG_ACTOR_TREE(node)
392 #define DALI_LOG_SET_OBJECT_STRING(object, string)
393 #define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...)
394 #define DALI_LOG_GET_OBJECT_STRING(object)
395 #define DALI_LOG_GET_OBJECT_C_STR(object) ""
396 #define DALI_LOG_OBJECT(filter, object)
397
398 #endif
399
400 /********************************************************************************
401  *                                Helper writers                                *
402  ********************************************************************************/
403
404 /**
405  * Helper method to translate a color to a string.
406  * @param[in] color - the color to translate
407  * @return string - the text representation of the color.
408  */
409 DALI_IMPORT_API std::string ColorToString(const Vector4& color);
410
411 /**
412  * Helper method to translate a vector4 to a string.
413  * @param[in] v - the vector
414  * @param[in] precision - the precision to write the float data.
415  * @param[in] indent - the indent level to use.
416  * @return string - the text representation of the vector.
417  */
418 DALI_IMPORT_API std::string Vector4ToString(const Vector4& v, size_t precision=3, size_t indent=0);
419
420 /**
421  * Helper method to translate a vector4 to a string.
422  * @param[in] v - the vector
423  * @param[in] precision - the precision to write the float data.
424  * @param[in] indent - the indent level to use.
425  * @return string - the text representation of the vector.
426  */
427 DALI_IMPORT_API std::string Vector3ToString(const Vector3& v, size_t precision=3, size_t indent=0);
428
429 /**
430  * Helper method to translate a quaternion to a string.
431  * @param[in] q the quaternion
432  * @param[in] precision - the precision to write the float data.
433  * @param[in] indent - the indent level to use.
434  * @return string - the text representation of the quaternion.
435  */
436 DALI_IMPORT_API std::string QuaternionToString(const Quaternion& q, size_t precision=3, size_t indent=0);
437
438 /**
439  * Helper method to translate a 3x3 matrix to a string.
440  * @param[in] m - the matrix
441  * @param[in] precision - the precision to write the float data.
442  * @param[in] indent - the indent level to use.
443  * @return string - the text representation of the vector.
444  */
445 DALI_IMPORT_API std::string Matrix3ToString(const Matrix3& m, size_t precision=3, size_t indent=0);
446
447 /**
448  * Helper method to translate a 4x4 matrix to a string.
449  * @param[in] m - the matrix
450  * @param[in] precision - the precision to write the float data.
451  * @param[in] indent - the indent level to use.
452  * @return string - the text representation of the vector.
453  */
454 DALI_IMPORT_API std::string MatrixToString(const Matrix& m, size_t precision=3, size_t indent=0);
455
456 #ifdef DEBUG_ENABLED
457
458
459 /**
460  * Filtered write of a matrix
461  */
462 #define DALI_LOG_MATRIX(filter, matrix)  DALI_LOG_INFO(filter, Debug::General, MatrixToString(matrix))
463
464 /**
465  * Filtered write of a vector
466  */
467 #define DALI_LOG_VECTOR4(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector4ToString(vector))
468
469 /**
470  * Filtered write of a vector
471  */
472 #define DALI_LOG_VECTOR3(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector3ToString(vector))
473
474 /**
475  * Filtered write of a color
476  */
477 #define DALI_LOG_COLOR(filter, color)    DALI_LOG_INFO(filter, Debug::General, ColorToString(color))
478
479 #else
480
481 #define DALI_LOG_MATRIX(filter, matrix)
482 #define DALI_LOG_VECTOR4(filter,vector)
483 #define DALI_LOG_VECTOR3(filter,vector)
484 #define DALI_LOG_COLOR(filter, color)
485
486 #endif
487
488 }}} // Dali/Integration/Debug namespaces
489
490
491 #endif // __DALI_INTEGRATION_DEBUG_H__