commit
						daf063dcb1
					
				|  | @ -26,7 +26,7 @@ | |||
| 
 | ||||
| //---- 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.
 | ||||
| //#define IMGUI_DISABLE_DEMO_WINDOWS
 | ||||
| #define IMGUI_DISABLE_DEMO_WINDOWS | ||||
| 
 | ||||
| //---- 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.
 | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| 
 | ||||
| #pragma once | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
|  | @ -27,23 +28,6 @@ namespace kiwano | |||
| template <typename _Ty> | ||||
| 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: | ||||
|     using object_type = _Ty; | ||||
| 
 | ||||
|  | @ -56,11 +40,7 @@ public: | |||
| 
 | ||||
|     static inline object_type* GetInstancePtr() | ||||
|     { | ||||
|         creator_.Dummy(); | ||||
|         if (!instance_ptr_) | ||||
|         { | ||||
|             instance_ptr_.reset(new object_type); | ||||
|         } | ||||
|         std::call_once(once_, Singleton::Init); | ||||
|         return instance_ptr_.get(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -68,10 +48,26 @@ public: | |||
|     { | ||||
|         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> | ||||
| typename Singleton<_Ty>::InstanceCreator Singleton<_Ty>::creator_; | ||||
| std::once_flag Singleton<_Ty>::once_; | ||||
| 
 | ||||
| template <typename _Ty> | ||||
| typename std::unique_ptr<_Ty> Singleton<_Ty>::instance_ptr_; | ||||
|  |  | |||
|  | @ -52,19 +52,80 @@ String LogFormater::GetLevelLabel(LogLevel level) const | |||
| 
 | ||||
| class TextFormater : public LogFormater | ||||
| { | ||||
| public: | ||||
|     void FormatHeader(std::ostream& out, LogLevel level, Time time) override | ||||
| private: | ||||
|     struct TimeFormater | ||||
|     { | ||||
|         // get timestamp
 | ||||
|         time_t  unix = std::time(nullptr); | ||||
|         std::tm tmbuf; | ||||
|         localtime_s(&tmbuf, &unix); | ||||
|         TimeFormater() | ||||
|         { | ||||
|             time_t ctime = std::time(nullptr); | ||||
|             prev_sec_    = ctime; | ||||
|             prev_min_    = ctime / 60; | ||||
| 
 | ||||
|         // build message
 | ||||
|         out << GetLevelLabel(level) << std::put_time(&tmbuf, " %H:%M:%S "); | ||||
|             RefreshLocalTime(&ctime); | ||||
|             ResetFormat(); | ||||
|         } | ||||
| 
 | ||||
|     void FormatFooter(std::ostream& out, LogLevel level, Time time) override | ||||
|         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
 | ||||
|         out << GetLevelLabel(level) << ' ' << tf_.Format(&time); | ||||
|     } | ||||
| 
 | ||||
|     void FormatFooter(std::ostream& out, LogLevel level) override | ||||
|     { | ||||
|         out << "\n"; | ||||
|     } | ||||
|  | @ -510,7 +571,7 @@ std::iostream& Logger::GetFormatedStream(LogLevel level, LogBuffer* buffer) | |||
| 
 | ||||
|     if (formater_) | ||||
|     { | ||||
|         formater_->FormatHeader(stream_, level, Time::Now()); | ||||
|         formater_->FormatHeader(stream_, level, ClockTime::Now()); | ||||
|     } | ||||
|     return stream_; | ||||
| } | ||||
|  | @ -534,7 +595,7 @@ void Logger::Logf(LogLevel level, const char* format, ...) | |||
| 
 | ||||
|     // build message
 | ||||
|     auto& stream = this->GetFormatedStream(level, &buffer_); | ||||
|     stream << strings::FormatArgs(format, args); | ||||
|     stream << ' ' << strings::FormatArgs(format, args); | ||||
| 
 | ||||
|     va_end(args); | ||||
| 
 | ||||
|  | @ -582,7 +643,7 @@ void Logger::WriteToProviders(LogLevel level, LogBuffer* buffer) | |||
|     // format footer
 | ||||
|     if (formater_) | ||||
|     { | ||||
|         formater_->FormatFooter(stream_, level, Time::Now()); | ||||
|         formater_->FormatFooter(stream_, level); | ||||
|     } | ||||
| 
 | ||||
|     // write message
 | ||||
|  |  | |||
|  | @ -132,9 +132,9 @@ enum class LogLevel | |||
| class KGE_API LogFormater : public ObjectBase | ||||
| { | ||||
| 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; | ||||
| }; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue