aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author杨宇千 <crupest@outlook.com>2019-09-08 22:24:28 +0800
committer杨宇千 <crupest@outlook.com>2019-09-08 22:24:28 +0800
commita8ba16ddab3291e59a33b36405462094f8cdf5bc (patch)
treeaa849cdc1f9b4f7a0aa150f562b2e618c63ecceb
parent8b9a306d6f24dbc08aeee16b115260406e79126d (diff)
downloadcru-a8ba16ddab3291e59a33b36405462094f8cdf5bc.tar.gz
cru-a8ba16ddab3291e59a33b36405462094f8cdf5bc.tar.bz2
cru-a8ba16ddab3291e59a33b36405462094f8cdf5bc.zip
...
-rw-r--r--include/cru/common/logger.hpp104
-rw-r--r--include/cru/common/pre_config.hpp2
-rw-r--r--include/cru/platform/debug.hpp8
-rw-r--r--include/cru/win/win_pre_config.hpp2
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/common/CMakeLists.txt13
-rw-r--r--src/common/logger.cpp61
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/render/border_render_object.cpp10
-rw-r--r--src/ui/render/flex_layout_render_object.cpp1
-rw-r--r--src/ui/render/render_object.cpp10
-rw-r--r--src/win/CMakeLists.txt3
-rw-r--r--src/win/debug.cpp9
-rw-r--r--src/win/debug_logger.hpp20
-rw-r--r--src/win/native/cursor.cpp12
-rw-r--r--src/win/native/native_window.cpp7
-rw-r--r--src/win/native/ui_application.cpp5
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.");