-#ifndef __DALI_INTEGRATION_DEBUG_H__
-#define __DALI_INTEGRATION_DEBUG_H__
+#ifndef DALI_INTEGRATION_DEBUG_H
+#define DALI_INTEGRATION_DEBUG_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
// EXTERNAL INCLUDES
-#include <string>
-#include <sstream>
-#include <list>
#include <stdint.h>
+#include <cstring>
+#include <iostream>
+#include <list>
+#include <sstream>
+#include <string>
+
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/property-map.h>
#include <dali/public-api/common/dali-common.h>
// Using Debug namespace alias shortens the log usage significantly
-namespace Dali{namespace Integration{namespace Log{}}}
+namespace Dali
+{
+namespace Integration
+{
+namespace Log
+{
+}
+} // namespace Integration
+} // namespace Dali
namespace Debug = Dali::Integration::Log;
namespace Dali
{
-
struct Vector2;
struct Vector3;
struct Vector4;
// Less opaque types for debugger
typedef std::vector<Dali::Property::Value> DebugPropertyValueArray;
-typedef std::pair< Property::Index, Property::Value > DebugIndexValuePair;
-typedef std::vector<Dali::StringValuePair> DebugStringValueContainer;
-typedef std::vector< DebugIndexValuePair > DebugIndexValueContainer;
+using DebugIndexValuePair = std::pair<Property::Index, Property::Value>;
+using DebugStringValueContainer = std::vector<Dali::StringValuePair>;
+using DebugIndexValueContainer = std::vector<DebugIndexValuePair>;
struct DebugPropertyValueMap
{
{
namespace Log
{
-
enum DebugPriority
{
- DebugInfo,
- DebugWarning,
- DebugError
+ DEBUG,
+ INFO,
+ WARNING,
+ ERROR
};
/**
- * Used by logging macros to log a message along with function/class name
+ * Used by logging macros to log a message
+ * @param level debug level
+ * @param format string format
+ */
+DALI_CORE_API void LogMessage(enum DebugPriority level, const char* format, ...);
+
+/**
+ * Prefix macros to sync with dlog logger format
+ * __MODULE__ macro also defined at dlog-internal.h
+ */
+#ifndef DALI_LOG_FORMAT_PREFIX
+#ifndef __MODULE__
+#define __MODULE__ (std::strrchr(__FILE__, '/') ? std::strrchr(__FILE__, '/') + 1 : __FILE__)
+#endif
+#define DALI_LOG_FORMAT_PREFIX "%s: %s(%d) > "
+#define DALI_LOG_FORMAT_PREFIX_ARGS __MODULE__, __func__, __LINE__
+#endif
+
+/**
+ * Global logging macros to log a message along with function/class name and line
* @param level debug level
* @param format string format
*/
-DALI_IMPORT_API void LogMessage(enum DebugPriority level,const char *format, ...);
+#define LogMessageWithFunctionLine(level, format, ...) \
+ LogMessage(level, \
+ (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \
+ DALI_LOG_FORMAT_PREFIX_ARGS, \
+ ##__VA_ARGS__)
/**
* typedef for the logging function.
*/
-typedef void (*LogFunction)(DebugPriority priority, std::string& message);
+using LogFunction = void (*)(DebugPriority, std::string&);
/**
* A log function has to be installed for every thread that wants to use logging.
* @param logFunction the log function to install
* @param logOpts the log options to save in thread
*/
-DALI_IMPORT_API void InstallLogFunction(const LogFunction& logFunction);
+DALI_CORE_API void InstallLogFunction(const LogFunction& logFunction);
/**
* A log function has to be uninstalled for every thread that wants to use logging.
* The log function can be different for each thread.
*/
-DALI_IMPORT_API void UninstallLogFunction();
+DALI_CORE_API void UninstallLogFunction();
/********************************************************************************
* Error/Warning macros. *
/**
* Provides unfiltered logging for global error level messages
*/
-#define DALI_LOG_ERROR(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, "%s " format, __PRETTY_FUNCTION__, ## args)
+#define DALI_LOG_ERROR(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::ERROR, format, ##__VA_ARGS__)
-#define DALI_LOG_ERROR_NOFN(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ## args)
+#define DALI_LOG_ERROR_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::ERROR, format, ##__VA_ARGS__)
-#define DALI_LOG_WARNING_NOFN(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, format, ## args)
+#define DALI_LOG_WARNING_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::WARNING, format, ##__VA_ARGS__)
/**
* Provides unfiltered logging for fps monitor
*/
-#define DALI_LOG_FPS(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
+#define DALI_LOG_FPS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
/**
* Provides unfiltered logging for update status
*/
-#define DALI_LOG_UPDATE_STATUS(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
+#define DALI_LOG_UPDATE_STATUS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
/**
* Provides unfiltered logging for render information
*/
-#define DALI_LOG_RENDER_INFO(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
+#define DALI_LOG_RENDER_INFO(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
/**
* Provides unfiltered logging for release
*/
-#define DALI_LOG_RELEASE_INFO(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ## args)
+#define DALI_LOG_RELEASE_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::INFO, format, ##__VA_ARGS__)
+
+/**
+ * Provides unfiltered logging for debuf information
+ */
+#define DALI_LOG_DEBUG_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DEBUG, format, ##__VA_ARGS__)
#ifdef DEBUG_ENABLED
/**
* Provides unfiltered logging for global warning level messages
*/
-#define DALI_LOG_WARNING(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, "%s " format, __PRETTY_FUNCTION__, ## args)
-
+#define DALI_LOG_WARNING(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::WARNING, "%s " format, ASSERT_LOCATION, ##__VA_ARGS__)
#else // DEBUG_ENABLED
// Don't warn on release build
-#define DALI_LOG_WARNING(format, args...)
+#define DALI_LOG_WARNING(format, ...)
#endif
*/
enum LogLevel
{
- NoLogging = 0,
- Concise = 1,
- General = 2,
- Verbose = 3
+ NoLogging = 0,
+ Concise = 1,
+ General = 2,
+ Verbose = 3
};
-
/**
* The Filter object is used by the DALI_LOG_INFO macro and others to determine if the logging
* should take place, and routes the logging via the platform abstraction's LogMessage.
* It provides the ability to turn tracing on or off.
*
*/
-class DALI_IMPORT_API Filter
+class DALI_CORE_API Filter
{
public:
- typedef std::list<Filter*> FilterList;
- typedef std::list<Filter*>::iterator FilterIter;
+ using FilterList = std::list<Filter*>;
+ using FilterIter = std::list<Filter*>::iterator;
public:
-
/**
* Test if the filter is enabled for the given logging level
* @param[in] level - the level to test.
* @return true if this level of logging is enabled.
*/
- bool IsEnabledFor(LogLevel level) { return level != Debug::NoLogging && level <= mLoggingLevel;}
+ bool IsEnabledFor(LogLevel level)
+ {
+ return level != Debug::NoLogging && level <= mLoggingLevel;
+ }
/**
* Test if trace is enabled for this filter.
* @return true if trace is enabled;
*/
- bool IsTraceEnabled() { return mTraceEnabled; }
+ bool IsTraceEnabled()
+ {
+ return mTraceEnabled;
+ }
/**
* Enable tracing on this filter.
*/
- void EnableTrace() { mTraceEnabled = true; }
+ void EnableTrace()
+ {
+ mTraceEnabled = true;
+ }
/**
* Disable tracing on this filter.
*/
- void DisableTrace() { mTraceEnabled = false; }
+ void DisableTrace()
+ {
+ mTraceEnabled = false;
+ }
/**
* Set the log level for this filter. Setting to a higher value than Debug::General also
* enables General;
*/
- void SetLogLevel(LogLevel level) { mLoggingLevel = level; }
+ void SetLogLevel(LogLevel level)
+ {
+ mLoggingLevel = level;
+ }
/**
* Perform the logging for this filter.
* FILTER_ENV=0,true dali-demo // LogLevel NoLogging, Trace ON
* @endcode
*/
- static Filter* New(LogLevel level, bool trace, const char * environmentVariableName );
+ static Filter* New(LogLevel level, bool trace, const char* environmentVariableName);
/**
* Enable trace on all filters.
*/
- void EnableGlobalTrace();
+ static void EnableGlobalTrace();
/**
* Disable trace on all filters.
*/
- void DisableGlobalTrace();
+ static void DisableGlobalTrace();
-private:
+ /**
+ * Set log level for all filters.
+ *
+ * @param[in] level The log level
+ */
+ static void SetGlobalLogLevel(LogLevel level);
+private:
/**
* Constructor.
* @param[in] level - the highest log level.
* @param[in] trace - whether this filter allows tracing.
*/
- Filter(LogLevel level, bool trace) : mLoggingLevel(level), mTraceEnabled(trace), mNesting(0) {}
+ Filter(LogLevel level, bool trace)
+ : mLoggingLevel(level),
+ mTraceEnabled(trace),
+ mNesting(0)
+ {
+ }
static FilterList* GetActiveFilters();
// you can add a filter to your own class or source file. If you do, use Filter::New()
// to tell this class about it.
- static Filter *gRender;
- static Filter *gResource;
- static Filter *gGLResource;
- static Filter *gObject;
- static Filter *gImage;
- static Filter *gModel;
- static Filter *gNode;
- static Filter *gElement;
- static Filter *gActor;
- static Filter *gShader;
+ static Filter* gRender;
+ static Filter* gResource;
+ static Filter* gGLResource;
+ static Filter* gObject;
+ static Filter* gImage;
+ static Filter* gModel;
+ static Filter* gNode;
+ static Filter* gElement;
+ static Filter* gActor;
+ static Filter* gShader;
private:
LogLevel mLoggingLevel;
bool mTraceEnabled;
-public:
- int mNesting;
+public:
+ int mNesting;
};
-
-#define DALI_LOG_FILTER_SET_LEVEL(filter, level) filter->SetLogLevel(level)
-#define DALI_LOG_FILTER_ENABLE_TRACE(filter) filter->EnableTrace()
-#define DALI_LOG_FILTER_DISABLE_TRACE(filter) filter->DisableTrace()
+#define DALI_LOG_FILTER_SET_LEVEL(filter, level) filter->SetLogLevel(level)
+#define DALI_LOG_FILTER_ENABLE_TRACE(filter) filter->EnableTrace()
+#define DALI_LOG_FILTER_DISABLE_TRACE(filter) filter->DisableTrace()
#else
-#define DALI_LOG_FILTER_SET_LEVEL(filter, level)
-#define DALI_LOG_FILTER_ENABLE_TRACE(filter)
-#define DALI_LOG_FILTER_DISABLE_TRACE(filter)
+#define DALI_LOG_FILTER_SET_LEVEL(filter, level)
+#define DALI_LOG_FILTER_ENABLE_TRACE(filter)
+#define DALI_LOG_FILTER_DISABLE_TRACE(filter)
#endif
#ifdef DEBUG_ENABLED
-#define DALI_LOG_INFO(filter, level, format, args...) \
- if(filter && filter->IsEnabledFor(level)) { filter->Log(level, format, ## args); }
+#define DALI_LOG_INFO(filter, level, format, ...) \
+ if(filter && filter->IsEnabledFor(level)) \
+ { \
+ filter->Log(level, \
+ (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \
+ DALI_LOG_FORMAT_PREFIX_ARGS, \
+ ##__VA_ARGS__); \
+ }
+
+#define DALI_LOG_STREAM(filter, level, stream) \
+ if(filter && filter->IsEnabledFor(level)) \
+ { \
+ std::ostringstream o; \
+ o << stream << std::endl; \
+ filter->Log(level, "%s", o.str().c_str()); \
+ }
#else // DEBUG_ENABLED
-#define DALI_LOG_INFO(filter, level, format, args...)
+#define DALI_LOG_INFO(filter, level, format, ...)
+#define DALI_LOG_STREAM(filter, level, stream)
#endif // DEBUG_ENABLED
-
/********************************************************************************
* Trace Macros *
********************************************************************************/
/*
* These macros allow the instrumentation of methods. These translate into calls
- * to LogMessage(DebugInfo).
+ * to LogMessage(INFO).
*/
#ifdef DEBUG_ENABLED
-class DALI_IMPORT_API TraceObj
+class DALI_CORE_API TraceObj
{
public:
TraceObj(Filter* filter, const char* fmt, ...);
public:
std::string mMessage;
- Filter* mFilter;
+ Filter* mFilter;
};
+#define DALI_LOG_TRACE_METHOD_FMT(filter, format, ...) \
+ Dali::Integration::Log::TraceObj debugTraceObj(filter, "%s: " format, ASSERT_LOCATION, ##__VA_ARGS__)
-#define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...) \
- Dali::Integration::Log::TraceObj debugTraceObj(filter, "%s: " format, __PRETTY_FUNCTION__, ## args)
-
-#define DALI_LOG_TRACE_METHOD(filter) \
- Dali::Integration::Log::TraceObj debugTraceObj(filter, __PRETTY_FUNCTION__)
-
+#define DALI_LOG_TRACE_METHOD(filter) \
+ Dali::Integration::Log::TraceObj debugTraceObj(filter, ASSERT_LOCATION)
#else // DEBUG_ENABLED
-#define DALI_LOG_TRACE_METHOD_FMT(filter, format, args...)
+#define DALI_LOG_TRACE_METHOD_FMT(filter, format, ...)
#define DALI_LOG_TRACE_METHOD(filter)
-
#endif
/********************************************************************************
* Warning - this will increase the size of the object for a debug build.
*/
#define DALI_LOG_OBJECT_STRING_DECLARATION \
-public: \
+public: \
std::string mDebugString;
/**
* Print all the actor tree names
**/
-#define DALI_LOG_ACTOR_TREE( node ) { \
- std::stringstream branch; \
- Node* tempNode = node; \
- while( tempNode ) { \
- branch << "<" << tempNode->mDebugString << ">::"; \
- tempNode = tempNode->GetParent(); \
- } \
- DALI_LOG_ERROR_NOFN("Actor tree: %s\n", branch.str().c_str()); \
-}
+#define DALI_LOG_ACTOR_TREE(node) \
+ { \
+ std::stringstream branch; \
+ Node* tempNode = node; \
+ while(tempNode) \
+ { \
+ branch << "<" << tempNode->mDebugString << ">::"; \
+ tempNode = tempNode->GetParent(); \
+ } \
+ DALI_LOG_ERROR_NOFN("Actor tree: %s\n", branch.str().c_str()); \
+ }
/**
* Allows one object to set another object's debug string
/**
* Allows one object to set another object's std::string easily
*/
-#define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...) (object->mDebugString = FormatToString(fmt, ## args))
+#define DALI_LOG_FMT_OBJECT_STRING(object, fmt, ...) (object->mDebugString = FormatToString(fmt, ##__VA_ARGS__))
/**
* Allows one object to get another object's debug string
/**
* Filtered logging of the object's debug string
*/
-#define DALI_LOG_OBJECT(filter, object) DALI_LOG_INFO(filter, Debug::General, object->mDebugString)
-
+#define DALI_LOG_OBJECT(filter, object) DALI_LOG_INFO(filter, Debug::General, object->mDebugString)
#else // DEBUG_ENABLED
#define DALI_LOG_OBJECT_STRING_DECLARATION
#define DALI_LOG_ACTOR_TREE(node)
#define DALI_LOG_SET_OBJECT_STRING(object, string)
-#define DALI_LOG_FMT_OBJECT_STRING(object, fmt, args...)
+#define DALI_LOG_FMT_OBJECT_STRING(object, fmt, ...)
#define DALI_LOG_GET_OBJECT_STRING(object)
#define DALI_LOG_GET_OBJECT_C_STR(object) ""
#define DALI_LOG_OBJECT(filter, object)
#endif
/********************************************************************************
- * Helper writers *
- ********************************************************************************/
-
-/**
- * Helper method to translate a color to a string.
- * @param[in] color - the color to translate
- * @return string - the text representation of the color.
- */
-DALI_IMPORT_API std::string ColorToString(const Vector4& color);
-
-/**
- * Helper method to translate a vector4 to a string.
- * @param[in] v - the vector
- * @param[in] precision - the precision to write the float data.
- * @param[in] indent - the indent level to use.
- * @return string - the text representation of the vector.
- */
-DALI_IMPORT_API std::string Vector4ToString(const Vector4& v, size_t precision=3, size_t indent=0);
-
-/**
- * Helper method to translate a vector4 to a string.
- * @param[in] v - the vector
- * @param[in] precision - the precision to write the float data.
- * @param[in] indent - the indent level to use.
- * @return string - the text representation of the vector.
- */
-DALI_IMPORT_API std::string Vector3ToString(const Vector3& v, size_t precision=3, size_t indent=0);
-
-/**
- * Helper method to translate a quaternion to a string.
- * @param[in] q the quaternion
- * @param[in] precision - the precision to write the float data.
- * @param[in] indent - the indent level to use.
- * @return string - the text representation of the quaternion.
- */
-DALI_IMPORT_API std::string QuaternionToString(const Quaternion& q, size_t precision=3, size_t indent=0);
-
-/**
- * Helper method to translate a 3x3 matrix to a string.
- * @param[in] m - the matrix
- * @param[in] precision - the precision to write the float data.
- * @param[in] indent - the indent level to use.
- * @return string - the text representation of the vector.
- */
-DALI_IMPORT_API std::string Matrix3ToString(const Matrix3& m, size_t precision=3, size_t indent=0);
-
-/**
- * Helper method to translate a 4x4 matrix to a string.
- * @param[in] m - the matrix
- * @param[in] precision - the precision to write the float data.
- * @param[in] indent - the indent level to use.
- * @return string - the text representation of the vector.
- */
-DALI_IMPORT_API std::string MatrixToString(const Matrix& m, size_t precision=3, size_t indent=0);
-
-#ifdef DEBUG_ENABLED
-
-
-/**
- * Filtered write of a matrix
- */
-#define DALI_LOG_MATRIX(filter, matrix) DALI_LOG_INFO(filter, Debug::General, MatrixToString(matrix))
-
-/**
- * Filtered write of a vector
- */
-#define DALI_LOG_VECTOR4(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector4ToString(vector))
-
-/**
- * Filtered write of a vector
- */
-#define DALI_LOG_VECTOR3(filter, vector) DALI_LOG_INFO(filter, Debug::General, Vector3ToString(vector))
-
-/**
- * Filtered write of a color
- */
-#define DALI_LOG_COLOR(filter, color) DALI_LOG_INFO(filter, Debug::General, ColorToString(color))
-
-#else
-
-#define DALI_LOG_MATRIX(filter, matrix)
-#define DALI_LOG_VECTOR4(filter,vector)
-#define DALI_LOG_VECTOR3(filter,vector)
-#define DALI_LOG_COLOR(filter, color)
-
-#endif
-
-/********************************************************************************
* Time instrumentation *
********************************************************************************/
-
#if defined(DEBUG_ENABLED)
-void GetNanoseconds( uint64_t& timeInNanoseconds );
-
-#define DALI_LOG_TIMER_START( timeVariable ) \
- uint64_t timeVariable##1; \
- Debug::GetNanoseconds( timeVariable##1 );
-
-#define DALI_LOG_TIMER_END( timeVariable, filter, level, preString) \
- uint64_t timeVariable##2; \
- Debug::GetNanoseconds( timeVariable##2 ); \
- DALI_LOG_INFO( filter, level, preString " %ld uSec\n", ((timeVariable##2-timeVariable##1)/1000));
+/**
+ * @brief Get the monotonic time since the clock's epoch.
+ *
+ * @param[out] timeInNanoseconds The time in nanoseconds since the reference point.
+ *
+ * @note The maximum value timeInNanoseconds can hold is 0xFFFFFFFFFFFFFFFF which is 1.844674407e+19. Therefore, this can overflow after approximately 584 years.
+ */
+void GetNanoseconds(uint64_t& timeInNanoseconds);
+
+#define DALI_LOG_TIMER_START(timeVariable) \
+ uint64_t timeVariable##1; \
+ Debug::GetNanoseconds(timeVariable##1);
+
+#define DALI_LOG_TIMER_END(timeVariable, filter, level, preString) \
+ uint64_t timeVariable##2; \
+ Debug::GetNanoseconds(timeVariable##2); \
+ DALI_LOG_INFO(filter, level, preString " %ld uSec\n", ((timeVariable##2 - timeVariable##1) / 1000));
#else // DEBUG_ENABLED
-#define DALI_LOG_TIMER_START( timeVariable )
-#define DALI_LOG_TIMER_END( timeVariable, filter, level, preString)
+#define DALI_LOG_TIMER_START(timeVariable)
+#define DALI_LOG_TIMER_END(timeVariable, filter, level, preString)
#endif
-} // Debug
-} // Integration
-} // Dali
-
+} // namespace Log
+} // namespace Integration
+} // namespace Dali
-#endif // __DALI_INTEGRATION_DEBUG_H__
+#endif // DALI_INTEGRATION_DEBUG_H