commit
						daf063dcb1
					
				|  | @ -26,7 +26,7 @@ | ||||||
| 
 | 
 | ||||||
| //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
 | //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
 | ||||||
| //---- It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
 | //---- It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
 | ||||||
| //#define IMGUI_DISABLE_DEMO_WINDOWS
 | #define IMGUI_DISABLE_DEMO_WINDOWS | ||||||
| 
 | 
 | ||||||
| //---- Don't implement some functions to reduce linkage requirements.
 | //---- Don't implement some functions to reduce linkage requirements.
 | ||||||
| //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS   // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS   // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
 | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| #include <memory> | #include <memory> | ||||||
|  | #include <mutex> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -27,23 +28,6 @@ namespace kiwano | ||||||
| template <typename _Ty> | template <typename _Ty> | ||||||
| class Singleton | class Singleton | ||||||
| { | { | ||||||
| protected: |  | ||||||
|     Singleton()                 = default; |  | ||||||
|     Singleton(const Singleton&) = delete; |  | ||||||
|     Singleton& operator=(const Singleton&) = delete; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     struct InstanceCreator |  | ||||||
|     { |  | ||||||
|         InstanceCreator() |  | ||||||
|         { |  | ||||||
|             (void)Singleton<_Ty>::GetInstancePtr(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         inline void Dummy() const {} |  | ||||||
|     }; |  | ||||||
|     static InstanceCreator creator_; |  | ||||||
| 
 |  | ||||||
| public: | public: | ||||||
|     using object_type = _Ty; |     using object_type = _Ty; | ||||||
| 
 | 
 | ||||||
|  | @ -56,11 +40,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     static inline object_type* GetInstancePtr() |     static inline object_type* GetInstancePtr() | ||||||
|     { |     { | ||||||
|         creator_.Dummy(); |         std::call_once(once_, Singleton::Init); | ||||||
|         if (!instance_ptr_) |  | ||||||
|         { |  | ||||||
|             instance_ptr_.reset(new object_type); |  | ||||||
|         } |  | ||||||
|         return instance_ptr_.get(); |         return instance_ptr_.get(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -68,10 +48,26 @@ public: | ||||||
|     { |     { | ||||||
|         instance_ptr_.reset(); |         instance_ptr_.reset(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  |     Singleton()                 = default; | ||||||
|  |     Singleton(const Singleton&) = delete; | ||||||
|  |     Singleton& operator=(const Singleton&) = delete; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     static inline void Init() | ||||||
|  |     { | ||||||
|  |         if (!instance_ptr_) | ||||||
|  |         { | ||||||
|  |             instance_ptr_.reset(new object_type); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     static std::once_flag once_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <typename _Ty> | template <typename _Ty> | ||||||
| typename Singleton<_Ty>::InstanceCreator Singleton<_Ty>::creator_; | std::once_flag Singleton<_Ty>::once_; | ||||||
| 
 | 
 | ||||||
| template <typename _Ty> | template <typename _Ty> | ||||||
| typename std::unique_ptr<_Ty> Singleton<_Ty>::instance_ptr_; | typename std::unique_ptr<_Ty> Singleton<_Ty>::instance_ptr_; | ||||||
|  |  | ||||||
|  | @ -52,19 +52,80 @@ String LogFormater::GetLevelLabel(LogLevel level) const | ||||||
| 
 | 
 | ||||||
| class TextFormater : public LogFormater | class TextFormater : public LogFormater | ||||||
| { | { | ||||||
| public: | private: | ||||||
|     void FormatHeader(std::ostream& out, LogLevel level, Time time) override |     struct TimeFormater | ||||||
|     { |     { | ||||||
|         // get timestamp
 |         TimeFormater() | ||||||
|         time_t  unix = std::time(nullptr); |         { | ||||||
|         std::tm tmbuf; |             time_t ctime = std::time(nullptr); | ||||||
|         localtime_s(&tmbuf, &unix); |             prev_sec_    = ctime; | ||||||
|  |             prev_min_    = ctime / 60; | ||||||
| 
 | 
 | ||||||
|  |             RefreshLocalTime(&ctime); | ||||||
|  |             ResetFormat(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const char* Format(ClockTime* current_time) | ||||||
|  |         { | ||||||
|  |             time_t ctime = current_time->GetCTime(); | ||||||
|  |             if (ctime != prev_sec_) | ||||||
|  |             { | ||||||
|  |                 prev_sec_        = ctime; | ||||||
|  |                 tmbuf_.tm_sec    = static_cast<int>(ctime % 60); | ||||||
|  |                 time_t ctime_min = ctime / 60; | ||||||
|  |                 if (ctime_min != prev_min_) | ||||||
|  |                 { | ||||||
|  |                     prev_min_ = ctime_min; | ||||||
|  | 
 | ||||||
|  |                     RefreshLocalTime(&ctime); | ||||||
|  |                     ResetFormat(); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     ResetFormatSec(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return time_format_; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         void ResetFormat() | ||||||
|  |         { | ||||||
|  |             std::snprintf(time_format_, 20, "%d-%02d-%02d %02d:%02d:%02d", tmbuf_.tm_year + 1900, tmbuf_.tm_mon + 1, | ||||||
|  |                           tmbuf_.tm_mday, tmbuf_.tm_hour, tmbuf_.tm_min, tmbuf_.tm_sec); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         void ResetFormatSec() | ||||||
|  |         { | ||||||
|  |             std::snprintf(time_format_ + 17, 3, "%02d", tmbuf_.tm_sec); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         void RefreshLocalTime(const time_t* ptime) | ||||||
|  |         { | ||||||
|  | #if defined(KGE_PLATFORM_WINDOWS) | ||||||
|  |             ::localtime_s(&tmbuf_, ptime); | ||||||
|  | #else | ||||||
|  |             std::tm* ptm = std::localtime(ptime); | ||||||
|  |             ::memcpy(&tmbuf_, ptm, sizeof(std::tm)); | ||||||
|  | #endif | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         time_t  prev_sec_        = 0; | ||||||
|  |         time_t  prev_min_        = 0; | ||||||
|  |         std::tm tmbuf_           = {}; | ||||||
|  |         char    time_format_[20] = {}; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     TimeFormater tf_; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     void FormatHeader(std::ostream& out, LogLevel level, ClockTime time) override | ||||||
|  |     { | ||||||
|         // build message
 |         // build message
 | ||||||
|         out << GetLevelLabel(level) << std::put_time(&tmbuf, " %H:%M:%S "); |         out << GetLevelLabel(level) << ' ' << tf_.Format(&time); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void FormatFooter(std::ostream& out, LogLevel level, Time time) override |     void FormatFooter(std::ostream& out, LogLevel level) override | ||||||
|     { |     { | ||||||
|         out << "\n"; |         out << "\n"; | ||||||
|     } |     } | ||||||
|  | @ -510,7 +571,7 @@ std::iostream& Logger::GetFormatedStream(LogLevel level, LogBuffer* buffer) | ||||||
| 
 | 
 | ||||||
|     if (formater_) |     if (formater_) | ||||||
|     { |     { | ||||||
|         formater_->FormatHeader(stream_, level, Time::Now()); |         formater_->FormatHeader(stream_, level, ClockTime::Now()); | ||||||
|     } |     } | ||||||
|     return stream_; |     return stream_; | ||||||
| } | } | ||||||
|  | @ -534,7 +595,7 @@ void Logger::Logf(LogLevel level, const char* format, ...) | ||||||
| 
 | 
 | ||||||
|     // build message
 |     // build message
 | ||||||
|     auto& stream = this->GetFormatedStream(level, &buffer_); |     auto& stream = this->GetFormatedStream(level, &buffer_); | ||||||
|     stream << strings::FormatArgs(format, args); |     stream << ' ' << strings::FormatArgs(format, args); | ||||||
| 
 | 
 | ||||||
|     va_end(args); |     va_end(args); | ||||||
| 
 | 
 | ||||||
|  | @ -582,7 +643,7 @@ void Logger::WriteToProviders(LogLevel level, LogBuffer* buffer) | ||||||
|     // format footer
 |     // format footer
 | ||||||
|     if (formater_) |     if (formater_) | ||||||
|     { |     { | ||||||
|         formater_->FormatFooter(stream_, level, Time::Now()); |         formater_->FormatFooter(stream_, level); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // write message
 |     // write message
 | ||||||
|  |  | ||||||
|  | @ -132,9 +132,9 @@ enum class LogLevel | ||||||
| class KGE_API LogFormater : public ObjectBase | class KGE_API LogFormater : public ObjectBase | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     virtual void FormatHeader(std::ostream& out, LogLevel level, Time time) = 0; |     virtual void FormatHeader(std::ostream& out, LogLevel level, ClockTime time) = 0; | ||||||
| 
 | 
 | ||||||
|     virtual void FormatFooter(std::ostream& out, LogLevel level, Time time) = 0; |     virtual void FormatFooter(std::ostream& out, LogLevel level) = 0; | ||||||
| 
 | 
 | ||||||
|     String GetLevelLabel(LogLevel level) const; |     String GetLevelLabel(LogLevel level) const; | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue