diff options
author | 杨宇千 <crupest@outlook.com> | 2019-09-08 22:24:28 +0800 |
---|---|---|
committer | 杨宇千 <crupest@outlook.com> | 2019-09-08 22:24:28 +0800 |
commit | a8ba16ddab3291e59a33b36405462094f8cdf5bc (patch) | |
tree | aa849cdc1f9b4f7a0aa150f562b2e618c63ecceb | |
parent | 8b9a306d6f24dbc08aeee16b115260406e79126d (diff) | |
download | cru-a8ba16ddab3291e59a33b36405462094f8cdf5bc.tar.gz cru-a8ba16ddab3291e59a33b36405462094f8cdf5bc.tar.bz2 cru-a8ba16ddab3291e59a33b36405462094f8cdf5bc.zip |
...
-rw-r--r-- | include/cru/common/logger.hpp | 104 | ||||
-rw-r--r-- | include/cru/common/pre_config.hpp | 2 | ||||
-rw-r--r-- | include/cru/platform/debug.hpp | 8 | ||||
-rw-r--r-- | include/cru/win/win_pre_config.hpp | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 12 | ||||
-rw-r--r-- | src/common/CMakeLists.txt | 13 | ||||
-rw-r--r-- | src/common/logger.cpp | 61 | ||||
-rw-r--r-- | src/ui/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/ui/render/border_render_object.cpp | 10 | ||||
-rw-r--r-- | src/ui/render/flex_layout_render_object.cpp | 1 | ||||
-rw-r--r-- | src/ui/render/render_object.cpp | 10 | ||||
-rw-r--r-- | src/win/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/win/debug.cpp | 9 | ||||
-rw-r--r-- | src/win/debug_logger.hpp | 20 | ||||
-rw-r--r-- | src/win/native/cursor.cpp | 12 | ||||
-rw-r--r-- | src/win/native/native_window.cpp | 7 | ||||
-rw-r--r-- | src/win/native/ui_application.cpp | 5 |
17 files changed, 230 insertions, 51 deletions
diff --git a/include/cru/common/logger.hpp b/include/cru/common/logger.hpp new file mode 100644 index 00000000..4da81eb1 --- /dev/null +++ b/include/cru/common/logger.hpp @@ -0,0 +1,104 @@ +#pragma once + +#include "cru/common/base.hpp" +#include "cru/common/format.hpp" + +#include <iostream> +#include <list> +#include <string_view> + +namespace cru::log { + +enum class LogLevel { Debug, Info, Warn, Error }; + +struct ILoggerSource : Interface { + // Write the s. LogLevel is just a helper. It has no effect on the content to + // write. + virtual void Write(LogLevel level, const std::wstring_view& s) = 0; +}; + +class StdioLoggerSource : public ILoggerSource { + public: + StdioLoggerSource() = default; + + CRU_DELETE_COPY(StdioLoggerSource) + CRU_DELETE_MOVE(StdioLoggerSource) + + ~StdioLoggerSource() = default; + + void Write(LogLevel level, const std::wstring_view& s) override { + if (level == LogLevel::Error) { + std::wcerr << s; + } else { + std::wcout << s; + } + } +}; + +class Logger : public Object { + public: + static Logger* GetInstance(); + + public: + Logger() = default; + + CRU_DELETE_COPY(Logger) + CRU_DELETE_MOVE(Logger) + + ~Logger() override; + + public: + void AddSource(ILoggerSource* source); + void RemoveSource(ILoggerSource* source); + + public: + void Log(LogLevel level, const std::wstring_view& s); + + template <typename... TArgs> + void Debug(const std::wstring_view& format, TArgs&&... args) { + Log(LogLevel::Debug, util::Format(format, std::forward<TArgs>(args)...)); + } + + template <typename... TArgs> + void Info(const std::wstring_view& format, TArgs&&... args) { + Log(LogLevel::Info, util::Format(format, std::forward<TArgs>(args)...)); + } + + template <typename... TArgs> + void Warn(const std::wstring_view& format, TArgs&&... args) { + Log(LogLevel::Warn, util::Format(format, std::forward<TArgs>(args)...)); + } + + template <typename... TArgs> + void Error(const std::wstring_view& format, TArgs&&... args) { + Log(LogLevel::Error, util::Format(format, std::forward<TArgs>(args)...)); + } + + public: + std::list<ILoggerSource*> sources_; +}; + +template <typename... TArgs> +void Debug(const std::wstring_view& format, TArgs&&... args) { + Logger::GetInstance()->Log( + LogLevel::Debug, util::Format(format, std::forward<TArgs>(args)...)); +} + +template <typename... TArgs> +void Info(const std::wstring_view& format, TArgs&&... args) { + Logger::GetInstance()->Log( + LogLevel::Info, util::Format(format, std::forward<TArgs>(args)...)); +} + +template <typename... TArgs> +void Warn(const std::wstring_view& format, TArgs&&... args) { + Logger::GetInstance()->Log( + LogLevel::Warn, util::Format(format, std::forward<TArgs>(args)...)); +} + +template <typename... TArgs> +void Error(const std::wstring_view& format, TArgs&&... args) { + Logger::GetInstance()->Log( + LogLevel::Error, util::Format(format, std::forward<TArgs>(args)...)); +} +} // namespace cru::logger diff --git a/include/cru/common/pre_config.hpp b/include/cru/common/pre_config.hpp index aa4d680b..96b1bab5 100644 --- a/include/cru/common/pre_config.hpp +++ b/include/cru/common/pre_config.hpp @@ -3,3 +3,5 @@ #ifdef _DEBUG #define CRU_DEBUG #endif + +#define _CRT_SECURE_NO_WARNINGS diff --git a/include/cru/platform/debug.hpp b/include/cru/platform/debug.hpp deleted file mode 100644 index 18472201..00000000 --- a/include/cru/platform/debug.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "cru/common/pre_config.hpp" - -#include <string_view> - -namespace cru::platform { -void DebugMessage(const std::wstring_view& message); -} diff --git a/include/cru/win/win_pre_config.hpp b/include/cru/win/win_pre_config.hpp index 7466a62c..a7dc72f3 100644 --- a/include/cru/win/win_pre_config.hpp +++ b/include/cru/win/win_pre_config.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "cru/common/pre_config.hpp" #define NOMINMAX diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ece4ca7e..3cff8a24 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,18 +1,8 @@ -set(CRU_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/common) -add_library(cru_base INTERFACE) -target_sources(cru_base INTERFACE - ${CRU_BASE_INCLUDE_DIR}/base.hpp - ${CRU_BASE_INCLUDE_DIR}/event.hpp - ${CRU_BASE_INCLUDE_DIR}/format.hpp - ${CRU_BASE_INCLUDE_DIR}/pre_config.hpp - ${CRU_BASE_INCLUDE_DIR}/self_resolvable.hpp -) -target_include_directories(cru_base INTERFACE ${CRU_INCLUDE_DIR}) +add_subdirectory(common) set(CRU_PLATFORM_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform) add_library(cru_platform_base INTERFACE) target_sources(cru_platform_base INTERFACE - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/debug.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/exception.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/graphic_base.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/heap_debug.hpp diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt new file mode 100644 index 00000000..afbbc139 --- /dev/null +++ b/src/common/CMakeLists.txt @@ -0,0 +1,13 @@ +set(CRU_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/common) +add_library(cru_base STATIC + logger.cpp +) +target_sources(cru_base INTERFACE + ${CRU_BASE_INCLUDE_DIR}/base.hpp + ${CRU_BASE_INCLUDE_DIR}/event.hpp + ${CRU_BASE_INCLUDE_DIR}/format.hpp + ${CRU_BASE_INCLUDE_DIR}/logger.hpp + ${CRU_BASE_INCLUDE_DIR}/pre_config.hpp + ${CRU_BASE_INCLUDE_DIR}/self_resolvable.hpp +) +target_include_directories(cru_base PUBLIC ${CRU_INCLUDE_DIR}) diff --git a/src/common/logger.cpp b/src/common/logger.cpp new file mode 100644 index 00000000..11446f24 --- /dev/null +++ b/src/common/logger.cpp @@ -0,0 +1,61 @@ +#include "cru/common/logger.hpp" + +#include "cru/common/format.hpp" + +#include <cstdlib> +#include <ctime> +#include <memory> +#include <string_view> + +namespace cru::log { +namespace { +Logger *CreateLogger() { + const auto logger = new Logger(); + logger->AddSource(new StdioLoggerSource()); + return logger; +} +} // namespace + +Logger *Logger::GetInstance() { + static std::unique_ptr<Logger> logger{CreateLogger()}; + return logger.get(); +} + +Logger::~Logger() { + for (const auto i : sources_) { + delete i; + } +} + +void Logger::AddSource(ILoggerSource *source) { sources_.push_back(source); } + +void Logger::RemoveSource(ILoggerSource *source) { sources_.remove(source); } + +namespace { +std::wstring_view LogLevelToString(LogLevel level) { + switch (level) { + case LogLevel::Debug: + return L"DEBUG"; + case LogLevel::Info: + return L"INFO"; + case LogLevel::Warn: + return L"WARN"; + case LogLevel::Error: + return L"ERROR"; + default: + std::abort(); + } +} +} // namespace + +void Logger::Log(LogLevel level, const std::wstring_view &s) { + for (const auto source : sources_) { + auto now = std::time(nullptr); + wchar_t buffer[50]; + std::wcsftime(buffer, 50, L"%c", std::localtime(&now)); + + source->Write(level, util::Format(L"[{}] {}: {}\n", buffer, + LogLevelToString(level), s)); + } +} +} // namespace cru::log diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 3186b0f5..ac69c644 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -1,4 +1,4 @@ -file(GLOB CRU_UI_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/ui) +set(CRU_UI_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/ui) add_library(cru_ui STATIC routed_event_dispatch.hpp diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp index 4b61e511..20bc2a50 100644 --- a/src/ui/render/border_render_object.cpp +++ b/src/ui/render/border_render_object.cpp @@ -1,6 +1,6 @@ #include "cru/ui/render/border_render_object.hpp" -#include "cru/platform/debug.hpp" +#include "cru/common/logger.hpp" #include "cru/platform/graph/geometry.hpp" #include "cru/platform/graph/graph_factory.hpp" #include "cru/platform/graph/util/painter_util.hpp" @@ -75,13 +75,13 @@ void BorderRenderObject::OnMeasureCore(const Size& available_size) { auto coerced_margin_border_padding_size = margin_border_padding_size; if (coerced_margin_border_padding_size.width > available_size.width) { - platform::DebugMessage( + log::Warn( L"Measure: horizontal length of padding, border and margin is bigger " L"than available length."); coerced_margin_border_padding_size.width = available_size.width; } if (coerced_margin_border_padding_size.height > available_size.height) { - platform::DebugMessage( + log::Warn( L"Measure: vertical length of padding, border and margin is bigger " L"than available length."); coerced_margin_border_padding_size.height = available_size.height; @@ -113,13 +113,13 @@ void BorderRenderObject::OnLayoutCore(const Rect& rect) { auto coerced_content_available_size = content_available_size; if (coerced_content_available_size.width < 0) { - platform::DebugMessage( + log::Warn( L"Layout: horizontal length of padding, border and margin is bigger " L"than available length."); coerced_content_available_size.width = 0; } if (coerced_content_available_size.height < 0) { - platform::DebugMessage( + log::Warn( L"Layout: vertical length of padding, border and margin is bigger " L"than available length."); coerced_content_available_size.height = 0; diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp index 5e313e49..c4bdd874 100644 --- a/src/ui/render/flex_layout_render_object.cpp +++ b/src/ui/render/flex_layout_render_object.cpp @@ -1,6 +1,5 @@ #include "cru/ui/render/flex_layout_render_object.hpp" -#include "cru/platform/debug.hpp" #include "cru/platform/graph/util/painter_util.hpp" #include <algorithm> diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp index 3cb7e4df..a083403b 100644 --- a/src/ui/render/render_object.cpp +++ b/src/ui/render/render_object.cpp @@ -1,6 +1,6 @@ #include "cru/ui/render/render_object.hpp" -#include "cru/platform/debug.hpp" +#include "cru/common/logger.hpp" #include <algorithm> #include <cassert> @@ -54,13 +54,13 @@ void RenderObject::OnMeasureCore(const Size& available_size) { auto coerced_margin_padding_size = margin_padding_size; if (coerced_margin_padding_size.width > available_size.width) { - platform::DebugMessage( + log::Warn( L"Measure: horizontal length of padding and margin is bigger than " L"available length."); coerced_margin_padding_size.width = available_size.width; } if (coerced_margin_padding_size.height > available_size.height) { - platform::DebugMessage( + log::Warn( L"Measure: vertical length of padding and margin is bigger than " L"available length."); coerced_margin_padding_size.height = available_size.height; @@ -82,13 +82,13 @@ void RenderObject::OnLayoutCore(const Rect& rect) { auto coerced_content_available_size = content_available_size; if (coerced_content_available_size.width < 0) { - platform::DebugMessage( + log::Warn( L"Layout: horizontal length of padding and margin is bigger than " L"available length."); coerced_content_available_size.width = 0; } if (coerced_content_available_size.height < 0) { - platform::DebugMessage( + log::Warn( L"Layout: vertical length of padding and margin is bigger than " L"available length."); coerced_content_available_size.height = 0; diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index d7d4ba96..8c58954d 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -1,7 +1,8 @@ set(CRU_WIN_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/win/) add_library(cru_win_base STATIC - debug.cpp + debug_logger.hpp + exception.cpp heap_debug.cpp string_util.cpp diff --git a/src/win/debug.cpp b/src/win/debug.cpp deleted file mode 100644 index e15b1f6c..00000000 --- a/src/win/debug.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "cru/win/win_pre_config.hpp" - -#include "cru/platform/debug.hpp" - -namespace cru::platform { -void DebugMessage(const std::wstring_view& message) { - ::OutputDebugStringW(message.data()); -} -} // namespace cru::platform diff --git a/src/win/debug_logger.hpp b/src/win/debug_logger.hpp new file mode 100644 index 00000000..ab6a2266 --- /dev/null +++ b/src/win/debug_logger.hpp @@ -0,0 +1,20 @@ +#include "cru/win/win_pre_config.hpp" + +#include "cru/common/logger.hpp" + +namespace cru::platform::win { + +class WinDebugLoggerSource : public ::cru::log::ILoggerSource { + public: + WinDebugLoggerSource() = default; + + CRU_DELETE_COPY(WinDebugLoggerSource) + CRU_DELETE_MOVE(WinDebugLoggerSource) + + ~WinDebugLoggerSource() = default; + + void Write(::cru::log::LogLevel level, const std::wstring_view& s) override { + ::OutputDebugStringW(s.data()); + } +}; +} // namespace cru::platform::win diff --git a/src/win/native/cursor.cpp b/src/win/native/cursor.cpp index 8c0e393b..a0f9dd6c 100644 --- a/src/win/native/cursor.cpp +++ b/src/win/native/cursor.cpp @@ -1,7 +1,7 @@ #include "cru/win/native/cursor.hpp" #include "cru/common/format.hpp" -#include "cru/platform/debug.hpp" +#include "cru/common/logger.hpp" #include "cru/win/native/exception.hpp" #include <stdexcept> @@ -15,17 +15,17 @@ WinCursor::WinCursor(HCURSOR handle, bool auto_delete) { WinCursor::~WinCursor() { if (auto_delete_) { if (!::DestroyCursor(handle_)) { - DebugMessage( - util::Format(L"Failed to destroy a cursor. Last error code: {}", - ::GetLastError())); // This is not a fetal error but - // might still need notice. + // This is not a fetal error but might still need notice. + log::Warn(L"Failed to destroy a cursor. Last error code: {}", + ::GetLastError()); } } } namespace { WinCursor* LoadWinCursor(const wchar_t* name) { - const auto handle = static_cast<HCURSOR>(::LoadImageW(NULL, name, IMAGE_CURSOR, SM_CYCURSOR, SM_CYCURSOR, LR_SHARED)); + const auto handle = static_cast<HCURSOR>(::LoadImageW( + NULL, name, IMAGE_CURSOR, SM_CYCURSOR, SM_CYCURSOR, LR_SHARED)); if (handle == NULL) { throw Win32Error(::GetLastError(), "Failed to get system cursor."); } diff --git a/src/win/native/native_window.cpp b/src/win/native/native_window.cpp index 6a02c2fc..149d9158 100644 --- a/src/win/native/native_window.cpp +++ b/src/win/native/native_window.cpp @@ -1,7 +1,7 @@ #include "cru/win/native/native_window.hpp" #include "cru/common/format.hpp" -#include "cru/platform/debug.hpp" +#include "cru/common/logger.hpp" #include "cru/win/graph/direct/graph_factory.hpp" #include "cru/win/native/cursor.hpp" #include "cru/win/native/exception.hpp" @@ -169,12 +169,11 @@ void WinNativeWindow::SetCursor(std::shared_ptr<Cursor> cursor) { WinCursor* c = static_cast<WinCursor*>(cursor.get()); auto outputError = [] { - DebugMessage(util::Format(util::Format( - L"Failed to set cursor. Last error code: {}.", ::GetLastError()))); + log::Debug(L"Failed to set cursor. Last error code: {}.", ::GetLastError()); }; if (!::SetClassLongPtrW(hwnd_, GCLP_HCURSOR, - reinterpret_cast<LONG_PTR>(c->GetHandle()))) { + reinterpret_cast<LONG_PTR>(c->GetHandle()))) { outputError(); return; } diff --git a/src/win/native/ui_application.cpp b/src/win/native/ui_application.cpp index fdc0aace..c2d3ac2c 100644 --- a/src/win/native/ui_application.cpp +++ b/src/win/native/ui_application.cpp @@ -1,5 +1,7 @@ #include "cru/win/native/ui_application.hpp" +#include "../debug_logger.hpp" +#include "cru/common/logger.hpp" #include "cru/win/graph/direct/graph_factory.hpp" #include "cru/win/native/exception.hpp" #include "cru/win/native/god_window.hpp" @@ -38,6 +40,9 @@ WinUiApplication::WinUiApplication(HINSTANCE h_instance) : h_instance_(h_instance) { assert(instance == nullptr); + log::Logger::GetInstance()->AddSource( + new ::cru::platform::win::WinDebugLoggerSource()); + if (!::IsWindows8OrGreater()) throw std::runtime_error("Must run on Windows 8 or later."); |