diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj
index dad9cfe7..55aa2264 100644
--- a/projects/kiwano/kiwano.vcxproj
+++ b/projects/kiwano/kiwano.vcxproj
@@ -61,7 +61,6 @@
-
@@ -137,7 +136,6 @@
-
diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters
index 9e3b3736..5eeb04db 100644
--- a/projects/kiwano/kiwano.vcxproj.filters
+++ b/projects/kiwano/kiwano.vcxproj.filters
@@ -165,9 +165,6 @@
platform\win32
-
- platform\win32
-
core\event
@@ -416,9 +413,6 @@
platform\win32
-
- platform\win32
-
core\event
diff --git a/src/kiwano-audio/AudioEngine.cpp b/src/kiwano-audio/AudioEngine.cpp
index c6ada268..146b3f32 100644
--- a/src/kiwano-audio/AudioEngine.cpp
+++ b/src/kiwano-audio/AudioEngine.cpp
@@ -21,7 +21,7 @@
#include
#include
#include
-#include // win32::ThrowIfFailed
+#include
namespace kiwano
{
@@ -51,7 +51,7 @@ void AudioEngine::SetupComponent()
hr = x_audio2_->CreateMasteringVoice(&mastering_voice_);
}
- win32::ThrowIfFailed(hr, "Create audio resources failed");
+ ThrowIfFailed(hr, "Create audio resources failed");
}
void AudioEngine::DestroyComponent()
@@ -85,7 +85,8 @@ bool AudioEngine::CreateSound(Sound& sound, const Transcoder::Buffer& buffer)
if (SUCCEEDED(hr))
{
IXAudio2SourceVoice* voice = nullptr;
- hr = x_audio2_->CreateSourceVoice(&voice, buffer.format, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
+
+ hr = x_audio2_->CreateSourceVoice(&voice, buffer.format, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
if (SUCCEEDED(hr))
{
@@ -100,8 +101,12 @@ bool AudioEngine::CreateSound(Sound& sound, const Transcoder::Buffer& buffer)
}
}
- win32::WarnIfFailed(hr, "Create sound failed");
- return SUCCEEDED(hr);
+ if (FAILED(hr))
+ {
+ KGE_ERROR("Create IXAudio2SourceVoice failed with HRESULT of %08X", hr);
+ return false;
+ }
+ return true;
}
void AudioEngine::Open()
diff --git a/src/kiwano-audio/libraries.cpp b/src/kiwano-audio/libraries.cpp
index 01be1d47..9c124cd9 100644
--- a/src/kiwano-audio/libraries.cpp
+++ b/src/kiwano-audio/libraries.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
namespace kiwano
{
@@ -51,8 +52,7 @@ XAudio2::XAudio2()
}
else
{
- KGE_ERROR("Load xaudio2.dll failed");
- throw std::runtime_error("Load xaudio2.dll failed");
+ KGE_THROW_SYSTEM_ERROR(HRESULT_FROM_WIN32(GetLastError()), "Load xaudio2.dll failed");
}
}
@@ -79,8 +79,7 @@ MediaFoundation::MediaFoundation()
}
else
{
- KGE_ERROR("Load Mfplat.dll failed");
- throw std::runtime_error("Load Mfplat.dll failed");
+ KGE_THROW_SYSTEM_ERROR(HRESULT_FROM_WIN32(GetLastError()), "Load Mfplat.dll failed");
}
if (mfreadwrite.Load("Mfreadwrite.dll"))
@@ -92,8 +91,7 @@ MediaFoundation::MediaFoundation()
}
else
{
- KGE_ERROR("Load Mfreadwrite.dll failed");
- throw std::runtime_error("Load Mfreadwrite.dll failed");
+ KGE_THROW_SYSTEM_ERROR(HRESULT_FROM_WIN32(GetLastError()), "Load Mfreadwrite.dll failed");
}
}
} // namespace dlls
diff --git a/src/kiwano/core/Exception.cpp b/src/kiwano/core/Exception.cpp
index a8418437..81876f92 100644
--- a/src/kiwano/core/Exception.cpp
+++ b/src/kiwano/core/Exception.cpp
@@ -19,42 +19,275 @@
// THE SOFTWARE.
#include
+#include
+#include
+
+#if defined(KGE_WIN32)
+#include
namespace kiwano
{
-Exception::Exception()
+class com_error_category : public std::error_category
{
-}
+public:
+ using error_category::error_category;
-Exception::Exception(String const& message)
- : message_(message)
-{
-}
+ const char* name() const noexcept override
+ {
+ return "com";
+ }
-Exception::~Exception()
-{
-}
+ // @note If _UNICODE is defined the error description gets
+ // converted to an ANSI string using the CP_ACP codepage.
+ std::string message(int hr) const override
+ {
+#ifdef _UNICODE
+ auto message = WideToMultiByte(_com_error{ hr }.ErrorMessage());
+ return message.c_str();
+#else
+ return _com_error{ hr }.ErrorMessage();
+#endif
+ }
-const String& Exception::ToString() const
-{
- return message_;
-}
+ // Make error_condition for error code (generic if possible)
+ // @return system's default error condition if error value can be mapped to a Windows error, error condition with
+ // com category otherwise
+ std::error_condition default_error_condition(int hr) const noexcept override
+ {
+ if (HRESULT_CODE(hr) || hr == 0)
+ // system error condition
+ return std::system_category().default_error_condition(HRESULT_CODE(hr));
+ else
+ // special error condition
+ return { hr, com_category() };
+ }
+};
-const char* Exception::what() const
-{
- return message_.c_str();
-}
+static kiwano::com_error_category com_ecat;
-SystemException::SystemException()
- : code_(0)
-{
-}
-
-SystemException::SystemException(ErrorCodeType code, String const& message)
- : Exception(message)
- , code_(code)
+const std::error_category& com_category() noexcept
{
+ return com_ecat;
}
} // namespace kiwano
+
+
+KGE_SUPPRESS_WARNING_PUSH
+KGE_SUPPRESS_WARNING(4091)
+#include // ignored on left of 'type' when no variable is declared
+KGE_SUPPRESS_WARNING_POP
+
+namespace kiwano
+{
+
+namespace
+{
+
+// SymInitialize()
+typedef BOOL(__stdcall* PFN_SymInitialize)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess);
+
+// SymCleanup()
+typedef BOOL(__stdcall* PFN_SymCleanup)(IN HANDLE hProcess);
+
+// SymGetLineFromAddr64()
+typedef BOOL(__stdcall* PFN_SymGetLineFromAddr64)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT PDWORD pdwDisplacement,
+ OUT PIMAGEHLP_LINE64 Line);
+
+// SymGetSymFromAddr64()
+typedef BOOL(__stdcall* PFN_SymGetSymFromAddr64)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT PDWORD64 pdwDisplacement,
+ OUT PIMAGEHLP_SYMBOL64 Symbol);
+
+// StackWalk64()
+typedef BOOL(__stdcall* PFN_StackWalk64)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame,
+ PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
+ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
+ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
+
+// SymFunctionTableAccess64()
+typedef PVOID(__stdcall* PFN_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase);
+
+// SymGetModuleBase64()
+typedef DWORD64(__stdcall* PFN_SymGetModuleBase64)(IN HANDLE hProcess, IN DWORD64 dwAddr);
+
+struct DbgHelp
+{
+ Library dbgLib;
+ PFN_SymInitialize SymInitialize;
+ PFN_SymCleanup SymCleanup;
+ PFN_SymGetLineFromAddr64 SymGetLineFromAddr64;
+ PFN_SymGetSymFromAddr64 SymGetSymFromAddr64;
+ PFN_StackWalk64 StackWalk64;
+ PFN_SymFunctionTableAccess64 SymFunctionTableAccess64;
+ PFN_SymGetModuleBase64 SymGetModuleBase64;
+
+ DbgHelp()
+ : SymInitialize(nullptr)
+ , SymCleanup(nullptr)
+ , SymGetLineFromAddr64(nullptr)
+ , SymGetSymFromAddr64(nullptr)
+ , StackWalk64(nullptr)
+ , SymFunctionTableAccess64(nullptr)
+ , SymGetModuleBase64(nullptr)
+ {
+ }
+
+ bool Load()
+ {
+ if (IsValid())
+ return true;
+
+ if (!dbgLib.Load("dbghelp.dll"))
+ return false;
+
+ SymInitialize = dbgLib.GetProcess("SymInitialize");
+ SymCleanup = dbgLib.GetProcess("SymCleanup");
+ SymGetLineFromAddr64 = dbgLib.GetProcess("SymGetLineFromAddr64");
+ SymGetSymFromAddr64 = dbgLib.GetProcess("SymGetSymFromAddr64");
+ StackWalk64 = dbgLib.GetProcess("StackWalk64");
+ SymFunctionTableAccess64 = dbgLib.GetProcess("SymFunctionTableAccess64");
+ SymGetModuleBase64 = dbgLib.GetProcess("SymGetModuleBase64");
+
+ if (!IsValid())
+ {
+ dbgLib.Free();
+ return false;
+ }
+ return true;
+ }
+
+ bool IsValid() const
+ {
+ return SymInitialize && SymCleanup && SymGetLineFromAddr64 && SymGetSymFromAddr64 && StackWalk64
+ && SymFunctionTableAccess64 && SymGetModuleBase64;
+ }
+};
+
+DbgHelp g_DbgHelp;
+
+} // namespace
+
+void PrintErrorCode(LPCSTR lpszFunction)
+{
+ KGE_ERROR("%s failed with HRESULT of %08X", lpszFunction, HRESULT_FROM_WIN32(GetLastError()));
+}
+
+void PrintCallStackOnContext(PCONTEXT pContext)
+{
+ if (!g_DbgHelp.Load())
+ return;
+
+ if (pContext == nullptr)
+ return;
+
+ DWORD dwMachineType;
+ STACKFRAME64 sf;
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hThread = GetCurrentThread();
+
+ ZeroMemory(&sf, sizeof(sf));
+
+ sf.AddrPC.Mode = AddrModeFlat;
+ sf.AddrFrame.Mode = AddrModeFlat;
+ sf.AddrStack.Mode = AddrModeFlat;
+ sf.AddrBStore.Mode = AddrModeFlat;
+
+#ifdef _M_IX86
+ dwMachineType = IMAGE_FILE_MACHINE_I386;
+ sf.AddrPC.Offset = pContext->Eip;
+ sf.AddrFrame.Offset = pContext->Ebp;
+ sf.AddrStack.Offset = pContext->Esp;
+#elif _M_X64
+ dwMachineType = IMAGE_FILE_MACHINE_AMD64;
+ sf.AddrPC.Offset = pContext->Rip;
+ sf.AddrFrame.Offset = pContext->Rsp;
+ sf.AddrStack.Offset = pContext->Rsp;
+#elif _M_IA64
+ dwMachineType = IMAGE_FILE_MACHINE_IA64;
+ sf.AddrPC.Offset = pContext->StIIP;
+ sf.AddrFrame.Offset = pContext->IntSp;
+ sf.AddrBStore.Offset = pContext->RsBSP;
+ sf.AddrStack.Offset = pContext->IntSp;
+#else
+#error "Platform not supported!"
+#endif
+
+ constexpr int STACKWALK_MAX_NAMELEN = 1024;
+ BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN];
+
+ KGE_ERROR("========== Stack trace ==========");
+
+ while (true)
+ {
+ if (!g_DbgHelp.StackWalk64(dwMachineType, hProcess, hThread, &sf, pContext, NULL,
+ g_DbgHelp.SymFunctionTableAccess64, g_DbgHelp.SymGetModuleBase64, NULL))
+ {
+ PrintErrorCode("StackWalk64");
+ break;
+ }
+
+ if (sf.AddrFrame.Offset == 0)
+ {
+ break;
+ }
+
+ ZeroMemory(symbolBuffer, sizeof(symbolBuffer));
+
+ IMAGEHLP_SYMBOL64* pSymbol = reinterpret_cast(symbolBuffer);
+ pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+ pSymbol->MaxNameLength = STACKWALK_MAX_NAMELEN;
+
+ DWORD64 dwDisplacement;
+ if (!g_DbgHelp.SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, &dwDisplacement, pSymbol))
+ {
+ PrintErrorCode("SymGetSymFromAddr64");
+ break;
+ }
+
+ IMAGEHLP_LINE64 lineInfo;
+ ZeroMemory(&lineInfo, sizeof(IMAGEHLP_LINE64));
+ lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+
+ DWORD dwLineDisplacement;
+ if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
+ {
+ KGE_ERROR("%s (%d): %s", lineInfo.FileName, lineInfo.LineNumber, pSymbol->Name);
+ }
+ else
+ {
+ KGE_ERROR("(filename not available): %s", pSymbol->Name);
+ }
+
+ if (sf.AddrReturn.Offset == 0)
+ {
+ SetLastError(ERROR_SUCCESS);
+ break;
+ }
+ }
+}
+
+StackTracer::StackTracer() {}
+
+void StackTracer::Print() const
+{
+ CONTEXT ctx;
+ HANDLE hProcess = GetCurrentProcess();
+
+ if (!g_DbgHelp.Load())
+ return;
+
+ if (!g_DbgHelp.SymInitialize(hProcess, NULL, TRUE))
+ return;
+
+ RtlCaptureContext(&ctx);
+
+ PrintCallStackOnContext(&ctx);
+
+ g_DbgHelp.SymCleanup(hProcess);
+}
+
+#endif
+
+} // namespace kiwano
diff --git a/src/kiwano/core/Exception.h b/src/kiwano/core/Exception.h
index 9d147adc..22149590 100644
--- a/src/kiwano/core/Exception.h
+++ b/src/kiwano/core/Exception.h
@@ -20,72 +20,83 @@
#pragma once
#include
-#include
#include
+#include
+
+#define KGE_THROW(MESSAGE) \
+ do \
+ { \
+ kiwano::StackTracer().Print(); \
+ throw std::runtime_error(MESSAGE); \
+ } while (0)
+
+#define KGE_THROW_SYSTEM_ERROR(ERRCODE, MESSAGE) \
+ do \
+ { \
+ kiwano::StackTracer().Print(); \
+ throw std::system_error(std::error_code(kiwano::error_enum(ERRCODE)), MESSAGE); \
+ } while (0)
namespace kiwano
{
-/**
- * \~chinese
- * @brief 异常
- */
-class KGE_API Exception : public std::exception
+class StackTracer
{
public:
- Exception();
+ StackTracer();
- /// \~chinese
- /// @brief 构造异常
- /// @param message 描述异常的信息
- explicit Exception(String const& message);
-
- virtual ~Exception();
-
- /// \~chinese
- /// @brief 转为解释性字符串
- const String& ToString() const;
-
- /// \~chinese
- /// @brief 转为解释性字符串
- virtual const char* what() const override;
-
-protected:
- String message_;
+ void Print() const;
};
-/**
- * \~chinese
- * @brief 系统异常
- */
-class SystemException : public Exception
+#ifdef KGE_WIN32
+
+// Enables classifying error codes
+// @note We don't bother listing all possible values
+enum class error_enum
{
-public:
-#if defined(KGE_WIN32)
- /// \~chinese
- /// @brief 错误代码类型
- typedef HRESULT ErrorCodeType;
+};
+
+#else
+
+typedef std::errc error_enum;
+
#endif
- SystemException();
+} // namespace kiwano
- /// \~chinese
- /// @brief 构造系统异常
- /// @param code 错误代码
- /// @param message 描述异常的信息
- SystemException(ErrorCodeType code, String const& message);
+#ifdef KGE_WIN32
- /// \~chinese
- /// @brief 获取错误代码
- ErrorCodeType GetErrorCode() const;
-
-private:
- ErrorCodeType code_;
-};
-
-inline SystemException::ErrorCodeType SystemException::GetErrorCode() const
+namespace std
{
- return code_;
+template <>
+struct is_error_code_enum : true_type
+{
+};
+} // namespace std
+
+namespace kiwano
+{
+
+const std::error_category& com_category() noexcept;
+
+inline std::error_code make_error_code(kiwano::error_enum errc) noexcept
+{
+ return std::error_code(static_cast(errc), kiwano::com_category());
+}
+
+inline std::error_condition make_error_condition(kiwano::error_enum errc) noexcept
+{
+ return std::error_condition(static_cast(errc), kiwano::com_category());
+}
+
+inline void ThrowIfFailed(HRESULT hr, const String& message)
+{
+ if (FAILED(hr))
+ {
+ KGE_THROW_SYSTEM_ERROR(hr, message.c_str());
+ }
}
} // namespace kiwano
+
+#endif // KGE_WIN32
diff --git a/src/kiwano/core/Time.cpp b/src/kiwano/core/Time.cpp
index 520192e4..82d6908a 100644
--- a/src/kiwano/core/Time.cpp
+++ b/src/kiwano/core/Time.cpp
@@ -358,7 +358,7 @@ Duration Duration::Parse(const String& format)
if (!std::regex_match(format.c_str(), duration_regex))
{
- throw Exception("Duration::Parse failed, invalid duration");
+ KGE_THROW("Duration::Parse failed, invalid duration");
}
if (format.empty() || format == "0")
@@ -391,7 +391,7 @@ Duration Duration::Parse(const String& format)
pos = i;
if (num_str.empty() || num_str == ".")
- throw Exception("Duration::Parse failed, invalid duration");
+ KGE_THROW("Duration::Parse failed, invalid duration");
// 单位
for (; i < len; ++i)
@@ -408,7 +408,7 @@ Duration Duration::Parse(const String& format)
pos = i;
if (unit_map.find(unit_str) == unit_map.end())
- throw Exception("Duration::Parse failed, invalid duration");
+ KGE_THROW("Duration::Parse failed, invalid duration");
double num = std::stod(num_str.c_str());
Duration unit = unit_map.at(unit_str);
diff --git a/src/kiwano/core/Time.h b/src/kiwano/core/Time.h
index 920c9617..3a9bde50 100644
--- a/src/kiwano/core/Time.h
+++ b/src/kiwano/core/Time.h
@@ -107,7 +107,7 @@ struct KGE_API Duration
/// 例如: "300ms", "-1.5h", "2h45m"
/// 允许的时间单位有 "ms", "s", "m", "h"
/// @return 解析出的时间段
- /// @throw kiwano::Exception 传入一个不合法的格式时抛出
+ /// @throw std::runtime_error 传入一个不合法的格式时抛出
static Duration Parse(const String& str);
static const Duration Ms; ///< 毫秒
diff --git a/src/kiwano/platform/Window.h b/src/kiwano/platform/Window.h
index 95ca8e64..e0365967 100644
--- a/src/kiwano/platform/Window.h
+++ b/src/kiwano/platform/Window.h
@@ -66,7 +66,7 @@ public:
* @param icon 图标资源ID
* @param resizable 窗口大小可拉伸
* @param fullscreen 全屏模式
- * @throw kiwano::SystemException 窗口创建失败时抛出
+ * @throw std::system_error 窗口创建失败时抛出
*/
virtual void Create(String const& title, uint32_t width, uint32_t height, uint32_t icon = 0, bool resizable = false,
bool fullscreen = false) = 0;
diff --git a/src/kiwano/platform/win32/StackWalker.cpp b/src/kiwano/platform/win32/StackWalker.cpp
deleted file mode 100644
index 410e8a4d..00000000
--- a/src/kiwano/platform/win32/StackWalker.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright (c) 2016-2018 Kiwano - Nomango
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include
-#include
-#include
-
-KGE_SUPPRESS_WARNING_PUSH
-KGE_SUPPRESS_WARNING(4091)
-#include // ignored on left of 'type' when no variable is declared
-KGE_SUPPRESS_WARNING_POP
-
-namespace kiwano
-{
-namespace win32
-{
-namespace
-{
-
-// SymInitialize()
-typedef BOOL(__stdcall* PFN_SymInitialize)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess);
-
-// SymCleanup()
-typedef BOOL(__stdcall* PFN_SymCleanup)(IN HANDLE hProcess);
-
-// SymGetLineFromAddr64()
-typedef BOOL(__stdcall* PFN_SymGetLineFromAddr64)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT PDWORD pdwDisplacement,
- OUT PIMAGEHLP_LINE64 Line);
-
-// SymGetSymFromAddr64()
-typedef BOOL(__stdcall* PFN_SymGetSymFromAddr64)(IN HANDLE hProcess, IN DWORD64 dwAddr, OUT PDWORD64 pdwDisplacement,
- OUT PIMAGEHLP_SYMBOL64 Symbol);
-
-// StackWalk64()
-typedef BOOL(__stdcall* PFN_StackWalk64)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame,
- PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
- PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
- PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
- PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
-
-// SymFunctionTableAccess64()
-typedef PVOID(__stdcall* PFN_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase);
-
-// SymGetModuleBase64()
-typedef DWORD64(__stdcall* PFN_SymGetModuleBase64)(IN HANDLE hProcess, IN DWORD64 dwAddr);
-
-struct DbgHelp
-{
- Library dbgLib;
- PFN_SymInitialize SymInitialize;
- PFN_SymCleanup SymCleanup;
- PFN_SymGetLineFromAddr64 SymGetLineFromAddr64;
- PFN_SymGetSymFromAddr64 SymGetSymFromAddr64;
- PFN_StackWalk64 StackWalk64;
- PFN_SymFunctionTableAccess64 SymFunctionTableAccess64;
- PFN_SymGetModuleBase64 SymGetModuleBase64;
-
- DbgHelp()
- : SymInitialize(nullptr)
- , SymCleanup(nullptr)
- , SymGetLineFromAddr64(nullptr)
- , SymGetSymFromAddr64(nullptr)
- , StackWalk64(nullptr)
- , SymFunctionTableAccess64(nullptr)
- , SymGetModuleBase64(nullptr)
- {
- }
-
- bool Load()
- {
- if (IsValid())
- return true;
-
- if (!dbgLib.Load("dbghelp.dll"))
- return false;
-
- SymInitialize = dbgLib.GetProcess("SymInitialize");
- SymCleanup = dbgLib.GetProcess("SymCleanup");
- SymGetLineFromAddr64 = dbgLib.GetProcess("SymGetLineFromAddr64");
- SymGetSymFromAddr64 = dbgLib.GetProcess("SymGetSymFromAddr64");
- StackWalk64 = dbgLib.GetProcess("StackWalk64");
- SymFunctionTableAccess64 = dbgLib.GetProcess("SymFunctionTableAccess64");
- SymGetModuleBase64 = dbgLib.GetProcess("SymGetModuleBase64");
-
- if (!IsValid())
- {
- dbgLib.Free();
- return false;
- }
- return true;
- }
-
- bool IsValid() const
- {
- return SymInitialize && SymCleanup && SymGetLineFromAddr64 && SymGetSymFromAddr64 && StackWalk64
- && SymFunctionTableAccess64 && SymGetModuleBase64;
- }
-};
-
-DbgHelp g_DbgHelp;
-} // namespace
-
-void PrintErrorCode(LPCSTR lpszFunction)
-{
- KGE_ERROR("%s failed with HRESULT of %08X", lpszFunction, HRESULT_FROM_WIN32(GetLastError()));
-}
-
-void PrintCallStackOnContext(PCONTEXT pContext)
-{
- if (!g_DbgHelp.Load())
- return;
-
- if (pContext == nullptr)
- return;
-
- DWORD dwMachineType;
- STACKFRAME64 sf;
- HANDLE hProcess = GetCurrentProcess();
- HANDLE hThread = GetCurrentThread();
-
- ZeroMemory(&sf, sizeof(sf));
-
- sf.AddrPC.Mode = AddrModeFlat;
- sf.AddrFrame.Mode = AddrModeFlat;
- sf.AddrStack.Mode = AddrModeFlat;
- sf.AddrBStore.Mode = AddrModeFlat;
-
-#ifdef _M_IX86
- dwMachineType = IMAGE_FILE_MACHINE_I386;
- sf.AddrPC.Offset = pContext->Eip;
- sf.AddrFrame.Offset = pContext->Ebp;
- sf.AddrStack.Offset = pContext->Esp;
-#elif _M_X64
- dwMachineType = IMAGE_FILE_MACHINE_AMD64;
- sf.AddrPC.Offset = pContext->Rip;
- sf.AddrFrame.Offset = pContext->Rsp;
- sf.AddrStack.Offset = pContext->Rsp;
-#elif _M_IA64
- dwMachineType = IMAGE_FILE_MACHINE_IA64;
- sf.AddrPC.Offset = pContext->StIIP;
- sf.AddrFrame.Offset = pContext->IntSp;
- sf.AddrBStore.Offset = pContext->RsBSP;
- sf.AddrStack.Offset = pContext->IntSp;
-#else
-#error "Platform not supported!"
-#endif
-
- constexpr int STACKWALK_MAX_NAMELEN = 1024;
- BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN];
-
- KGE_ERROR("========== Stack trace ==========");
-
- while (true)
- {
- if (!g_DbgHelp.StackWalk64(dwMachineType, hProcess, hThread, &sf, pContext, NULL,
- g_DbgHelp.SymFunctionTableAccess64, g_DbgHelp.SymGetModuleBase64, NULL))
- {
- PrintErrorCode("StackWalk64");
- break;
- }
-
- if (sf.AddrFrame.Offset == 0)
- {
- break;
- }
-
- ZeroMemory(symbolBuffer, sizeof(symbolBuffer));
-
- IMAGEHLP_SYMBOL64* pSymbol = reinterpret_cast(symbolBuffer);
- pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
- pSymbol->MaxNameLength = STACKWALK_MAX_NAMELEN;
-
- DWORD64 dwDisplacement;
- if (!g_DbgHelp.SymGetSymFromAddr64(hProcess, sf.AddrPC.Offset, &dwDisplacement, pSymbol))
- {
- PrintErrorCode("SymGetSymFromAddr64");
- break;
- }
-
- IMAGEHLP_LINE64 lineInfo;
- ZeroMemory(&lineInfo, sizeof(IMAGEHLP_LINE64));
- lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
-
- DWORD dwLineDisplacement;
- if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
- {
- KGE_ERROR("%s (%d): %s", lineInfo.FileName, lineInfo.LineNumber, pSymbol->Name);
- }
- else
- {
- KGE_ERROR("(filename not available): %s", pSymbol->Name);
- }
-
- if (sf.AddrReturn.Offset == 0)
- {
- SetLastError(ERROR_SUCCESS);
- break;
- }
- }
-}
-
-void PrintCallStack()
-{
- CONTEXT ctx;
- HANDLE hProcess = GetCurrentProcess();
-
- if (!g_DbgHelp.Load())
- return;
-
- if (!g_DbgHelp.SymInitialize(hProcess, NULL, TRUE))
- return;
-
- RtlCaptureContext(&ctx);
-
- PrintCallStackOnContext(&ctx);
-
- g_DbgHelp.SymCleanup(hProcess);
-}
-
-} // namespace win32
-} // namespace kiwano
diff --git a/src/kiwano/platform/win32/WindowImpl.cpp b/src/kiwano/platform/win32/WindowImpl.cpp
index 0ce597ef..9fb74a68 100644
--- a/src/kiwano/platform/win32/WindowImpl.cpp
+++ b/src/kiwano/platform/win32/WindowImpl.cpp
@@ -236,9 +236,7 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui
if (handle_ == nullptr)
{
::UnregisterClassW(L"KiwanoAppWnd", hinst);
-
- KGE_ERROR("Failed with HRESULT of %08X", HRESULT_FROM_WIN32(GetLastError()));
- throw SystemException(HRESULT_FROM_WIN32(GetLastError()), "Create window failed");
+ KGE_THROW_SYSTEM_ERROR(HRESULT_FROM_WIN32(GetLastError()), "Create window failed");
}
width_ = width;
diff --git a/src/kiwano/platform/win32/helper.h b/src/kiwano/platform/win32/helper.h
deleted file mode 100644
index 13a73723..00000000
--- a/src/kiwano/platform/win32/helper.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2016-2018 Kiwano - Nomango
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#pragma once
-#include
-#include
-
-namespace kiwano
-{
-namespace win32
-{
-void PrintCallStack();
-
-void PrintCallStackOnContext(PCONTEXT pContext);
-
-inline void ThrowIfFailed(HRESULT hr, const String& message)
-{
- if (FAILED(hr))
- {
- PrintCallStack();
-
- throw SystemException(hr, message);
- }
-}
-
-inline void WarnIfFailed(HRESULT hr, const String& message)
-{
- if (FAILED(hr))
- {
- PrintCallStack();
-
- KGE_WARN("Failed with HRESULT of %08X: ", hr, message.c_str());
- }
-}
-
-} // namespace win32
-} // namespace kiwano
diff --git a/src/kiwano/platform/win32/libraries.cpp b/src/kiwano/platform/win32/libraries.cpp
index c7221175..ac0f6bbb 100644
--- a/src/kiwano/platform/win32/libraries.cpp
+++ b/src/kiwano/platform/win32/libraries.cpp
@@ -41,8 +41,7 @@ Shlwapi::Shlwapi()
}
else
{
- KGE_ERROR("Load shlapi.dll failed");
- throw SystemException(HRESULT_FROM_WIN32(GetLastError()), "Load shlapi.dll failed");
+ KGE_THROW_SYSTEM_ERROR(HRESULT_FROM_WIN32(GetLastError()), "Load shlapi.dll failed");
}
}
diff --git a/src/kiwano/render/DirectX/RenderContextImpl.cpp b/src/kiwano/render/DirectX/RenderContextImpl.cpp
index a12794b5..75a1692a 100644
--- a/src/kiwano/render/DirectX/RenderContextImpl.cpp
+++ b/src/kiwano/render/DirectX/RenderContextImpl.cpp
@@ -86,7 +86,7 @@ void RenderContextImpl::BeginDraw()
void RenderContextImpl::EndDraw()
{
- win32::ThrowIfFailed(render_target_->EndDraw(), "ID2D1RenderTarget EndDraw failed");
+ ThrowIfFailed(render_target_->EndDraw(), "ID2D1RenderTarget EndDraw failed");
RenderContext::EndDraw();
@@ -271,7 +271,7 @@ void RenderContextImpl::CreateTexture(Texture& texture, math::Vec2T si
texture.SetBitmap(saved_bitmap);
}
- win32::ThrowIfFailed(hr, "Create texture failed");
+ ThrowIfFailed(hr, "Create texture failed");
}
void RenderContextImpl::PushClipRect(Rect const& clip_rect)
@@ -302,7 +302,7 @@ void RenderContextImpl::PushLayer(Layer& layer)
}
else
{
- win32::ThrowIfFailed(hr, "Create ID2D1Layer failed");
+ ThrowIfFailed(hr, "Create ID2D1Layer failed");
}
}
diff --git a/src/kiwano/render/DirectX/RendererImpl.cpp b/src/kiwano/render/DirectX/RendererImpl.cpp
index 24ffbb31..90b2c40b 100644
--- a/src/kiwano/render/DirectX/RendererImpl.cpp
+++ b/src/kiwano/render/DirectX/RendererImpl.cpp
@@ -50,7 +50,7 @@ void RendererImpl::SetupComponent()
{
KGE_SYS_LOG("Creating device resources");
- win32::ThrowIfFailed(::CoInitialize(nullptr), "CoInitialize failed");
+ ThrowIfFailed(::CoInitialize(nullptr), "CoInitialize failed");
HWND target_window = WindowImpl::GetInstance().GetHandle();
output_size_ = Window::GetInstance().GetSize();
@@ -112,7 +112,7 @@ void RendererImpl::SetupComponent()
}
}
- win32::ThrowIfFailed(hr, "Create render resources failed");
+ ThrowIfFailed(hr, "Create render resources failed");
}
void RendererImpl::DestroyComponent()
@@ -165,7 +165,7 @@ void RendererImpl::Present()
hr = HandleDeviceLost();
}
- win32::ThrowIfFailed(hr, "Unexpected DXGI exception");
+ ThrowIfFailed(hr, "Unexpected DXGI exception");
}
void RendererImpl::HandleEvent(Event* evt)
@@ -206,7 +206,7 @@ void RendererImpl::CreateTexture(Texture& texture, String const& file_path)
if (!FileSystem::GetInstance().IsFileExists(file_path))
{
KGE_WARN("Texture file '%s' not found!", file_path.c_str());
- hr = E_FAIL;
+ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
if (SUCCEEDED(hr))
@@ -244,7 +244,7 @@ void RendererImpl::CreateTexture(Texture& texture, String const& file_path)
if (FAILED(hr))
{
- win32::ThrowIfFailed(hr, "Load texture failed");
+ ThrowIfFailed(hr, "Load texture failed");
}
}
@@ -311,7 +311,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, String const& file_path)
if (!FileSystem::GetInstance().IsFileExists(file_path))
{
KGE_WARN("Gif texture file '%s' not found!", file_path.c_str());
- hr = E_FAIL;
+ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
if (SUCCEEDED(hr))
@@ -537,7 +537,7 @@ void RendererImpl::CreateFontCollection(Font& font, String const& file_path)
if (!FileSystem::GetInstance().IsFileExists(file_path))
{
KGE_WARN("Font file '%s' not found!", file_path.c_str());
- hr = E_FAIL;
+ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
}
@@ -562,7 +562,7 @@ void RendererImpl::CreateFontCollection(Font& font, String const& file_path)
}
}
- win32::ThrowIfFailed(hr, "Create font collection failed");
+ ThrowIfFailed(hr, "Create font collection failed");
}
void RendererImpl::CreateFontCollection(Font& font, Resource const& res)
@@ -593,7 +593,7 @@ void RendererImpl::CreateFontCollection(Font& font, Resource const& res)
}
}
- win32::ThrowIfFailed(hr, "Create font collection failed");
+ ThrowIfFailed(hr, "Create font collection failed");
}
void RendererImpl::CreateTextFormat(TextLayout& layout)
@@ -620,7 +620,7 @@ void RendererImpl::CreateTextFormat(TextLayout& layout)
layout.SetTextFormat(output);
}
- win32::ThrowIfFailed(hr, "Create text format failed");
+ ThrowIfFailed(hr, "Create text format failed");
}
void RendererImpl::CreateTextLayout(TextLayout& layout)
@@ -644,7 +644,7 @@ void RendererImpl::CreateTextLayout(TextLayout& layout)
layout.SetTextLayout(output);
}
- win32::ThrowIfFailed(hr, "Create text layout failed");
+ ThrowIfFailed(hr, "Create text layout failed");
}
void RendererImpl::CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos)
@@ -680,7 +680,7 @@ void RendererImpl::CreateLineShape(Shape& shape, Point const& begin_pos, Point c
shape.SetGeometry(path_geo);
}
- win32::ThrowIfFailed(hr, "Create ID2D1PathGeometry failed");
+ ThrowIfFailed(hr, "Create ID2D1PathGeometry failed");
}
void RendererImpl::CreateRectShape(Shape& shape, Rect const& rect)
@@ -702,7 +702,7 @@ void RendererImpl::CreateRectShape(Shape& shape, Rect const& rect)
shape.SetGeometry(output);
}
- win32::ThrowIfFailed(hr, "Create ID2D1RectangleGeometry failed");
+ ThrowIfFailed(hr, "Create ID2D1RectangleGeometry failed");
}
void RendererImpl::CreateRoundedRectShape(Shape& shape, Rect const& rect, Vec2 const& radius)
@@ -725,7 +725,7 @@ void RendererImpl::CreateRoundedRectShape(Shape& shape, Rect const& rect, Vec2 c
shape.SetGeometry(output);
}
- win32::ThrowIfFailed(hr, "Create ID2D1RoundedRectangleGeometry failed");
+ ThrowIfFailed(hr, "Create ID2D1RoundedRectangleGeometry failed");
}
void RendererImpl::CreateEllipseShape(Shape& shape, Point const& center, Vec2 const& radius)
@@ -748,7 +748,7 @@ void RendererImpl::CreateEllipseShape(Shape& shape, Point const& center, Vec2 co
shape.SetGeometry(output);
}
- win32::ThrowIfFailed(hr, "Create ID2D1EllipseGeometry failed");
+ ThrowIfFailed(hr, "Create ID2D1EllipseGeometry failed");
}
void RendererImpl::CreateShapeSink(ShapeSink& sink)
@@ -770,7 +770,7 @@ void RendererImpl::CreateShapeSink(ShapeSink& sink)
sink.SetPathGeometry(output);
}
- win32::ThrowIfFailed(hr, "Create ID2D1PathGeometry failed");
+ ThrowIfFailed(hr, "Create ID2D1PathGeometry failed");
}
void RendererImpl::CreateBrush(Brush& brush, Color const& color)
@@ -804,7 +804,7 @@ void RendererImpl::CreateBrush(Brush& brush, Color const& color)
}
}
- win32::ThrowIfFailed(hr, "Create ID2D1SolidBrush failed");
+ ThrowIfFailed(hr, "Create ID2D1SolidBrush failed");
}
void RendererImpl::CreateBrush(Brush& brush, LinearGradientStyle const& style)
@@ -836,7 +836,7 @@ void RendererImpl::CreateBrush(Brush& brush, LinearGradientStyle const& style)
}
}
- win32::ThrowIfFailed(hr, "Create ID2D1LinearGradientBrush failed");
+ ThrowIfFailed(hr, "Create ID2D1LinearGradientBrush failed");
}
void RendererImpl::CreateBrush(Brush& brush, RadialGradientStyle const& style)
@@ -869,7 +869,7 @@ void RendererImpl::CreateBrush(Brush& brush, RadialGradientStyle const& style)
}
}
- win32::ThrowIfFailed(hr, "Create ID2D1RadialGradientBrush failed");
+ ThrowIfFailed(hr, "Create ID2D1RadialGradientBrush failed");
}
void RendererImpl::CreateStrokeStyle(StrokeStyle& stroke_style, CapStyle cap, LineJoinStyle line_join,
@@ -896,7 +896,7 @@ void RendererImpl::CreateStrokeStyle(StrokeStyle& stroke_style, CapStyle cap, Li
}
}
- win32::ThrowIfFailed(hr, "Create ID2D1StrokeStyle failed");
+ ThrowIfFailed(hr, "Create ID2D1StrokeStyle failed");
}
TextureRenderContextPtr RendererImpl::CreateTextureRenderContext(const Size* desired_size)
@@ -965,7 +965,7 @@ void RendererImpl::Resize(uint32_t width, uint32_t height)
render_ctx_->Resize(output_size_);
}
- win32::ThrowIfFailed(hr, "Resize render target failed");
+ ThrowIfFailed(hr, "Resize render target failed");
}
} // namespace kiwano
diff --git a/src/kiwano/render/DirectX/helper.h b/src/kiwano/render/DirectX/helper.h
index f9bb36d6..42032991 100644
--- a/src/kiwano/render/DirectX/helper.h
+++ b/src/kiwano/render/DirectX/helper.h
@@ -20,9 +20,9 @@
#pragma once
#include
+#include
#include
#include
-#include
#include
namespace kiwano
diff --git a/src/kiwano/render/Renderer.h b/src/kiwano/render/Renderer.h
index 7ca73cc1..5e921baa 100644
--- a/src/kiwano/render/Renderer.h
+++ b/src/kiwano/render/Renderer.h
@@ -66,28 +66,28 @@ public:
/// @brief 创建纹理内部资源
/// @param[out] texture 纹理
/// @param[in] file_path 图片路径
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateTexture(Texture& texture, String const& file_path) = 0;
/// \~chinese
/// @brief 创建纹理内部资源
/// @param[out] texture 纹理
/// @param[in] resource 图片资源
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateTexture(Texture& texture, Resource const& resource) = 0;
/// \~chinese
/// @brief 创建GIF图像内部资源
/// @param[out] gif GIF图像
/// @param[in] file_path 图片路径
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateGifImage(GifImage& gif, String const& file_path) = 0;
/// \~chinese
/// @brief 创建GIF图像内部资源
/// @param[out] gif GIF图像
/// @param[in] resource 图片资源
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateGifImage(GifImage& gif, Resource const& resource) = 0;
/// \~chinese
@@ -95,33 +95,33 @@ public:
/// @param[out] frame GIF图像帧
/// @param[in] gif GIF图像
/// @param[in] frame_index 帧下标
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateGifImageFrame(GifImage::Frame& frame, GifImage const& gif, size_t frame_index) = 0;
/// \~chinese
/// @brief 创建字体集内部资源
/// @param[out] font 字体
/// @param[in] file_paths 字体文件路径
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateFontCollection(Font& font, String const& file_path) = 0;
/// \~chinese
/// @brief 创建字体集内部资源
/// @param[out] font 字体
/// @param[in] res_arr 字体资源
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateFontCollection(Font& font, Resource const& res) = 0;
/// \~chinese
/// @brief 创建文字格式内部资源
/// @param[out] layout 字体布局
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateTextFormat(TextLayout& layout) = 0;
/// \~chinese
/// @brief 创建文字布局内部资源
/// @param[out] layout 字体布局
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateTextLayout(TextLayout& layout) = 0;
/// \~chinese
@@ -129,14 +129,14 @@ public:
/// @param[out] shape 形状
/// @param[in] begin_pos 线段起点
/// @param[in] end_pos 线段终点
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos) = 0;
/// \~chinese
/// @brief 创建矩形形状内部资源
/// @param[out] shape 形状
/// @param[in] rect 矩形大小
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateRectShape(Shape& shape, Rect const& rect) = 0;
/// \~chinese
@@ -144,7 +144,7 @@ public:
/// @param[out] shape 形状
/// @param[in] rect 矩形大小
/// @param[in] radius 圆角半径
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateRoundedRectShape(Shape& shape, Rect const& rect, Vec2 const& radius) = 0;
/// \~chinese
@@ -152,34 +152,34 @@ public:
/// @param[out] shape 形状
/// @param[in] center 椭圆圆心
/// @param[in] radius 椭圆半径
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateEllipseShape(Shape& shape, Point const& center, Vec2 const& radius) = 0;
/// \~chinese
/// @brief 创建几何图形生成器内部资源
/// @param[out] sink 形状生成器
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateShapeSink(ShapeSink& sink) = 0;
/// \~chinese
/// @brief 创建纯色画刷内部资源
/// @param[out] brush 画刷
/// @param[in] color 颜色
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateBrush(Brush& brush, Color const& color) = 0;
/// \~chinese
/// @brief 创建线性渐变画刷内部资源
/// @param[out] brush 画刷
/// @param[in] style 线性渐变样式
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateBrush(Brush& brush, LinearGradientStyle const& style) = 0;
/// \~chinese
/// @brief 创建径向渐变画刷内部资源
/// @param[out] brush 画刷
/// @param[in] style 径向渐变样式
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateBrush(Brush& brush, RadialGradientStyle const& style) = 0;
/// \~chinese
@@ -190,7 +190,7 @@ public:
/// @param[in] dash_array 虚线长度与间隙数组
/// @param[in] dash_size 虚线数组大小
/// @param[in] dash_offset 虚线偏移量
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual void CreateStrokeStyle(StrokeStyle& stroke_style, CapStyle cap, LineJoinStyle line_join,
const float* dash_array, size_t dash_size, float dash_offset) = 0;
@@ -198,7 +198,7 @@ public:
/// @brief 创建纹理渲染上下文
/// @param[in] desired_size 期望的输出大小
/// @return 纹理渲染上下文
- /// @throw kiwano::SystemException 创建失败时抛出
+ /// @throw std::system_error 创建失败时抛出
virtual TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) = 0;
public:
@@ -216,7 +216,7 @@ public:
/// \~chinese
/// @brief 将绘制内容呈现至窗口
- /// @throw kiwano::SystemException 呈现失败时抛出
+ /// @throw std::system_error 呈现失败时抛出
virtual void Present() = 0;
/// \~chinese
diff --git a/src/kiwano/render/ShapeSink.cpp b/src/kiwano/render/ShapeSink.cpp
index 7ddabaea..91281e1e 100644
--- a/src/kiwano/render/ShapeSink.cpp
+++ b/src/kiwano/render/ShapeSink.cpp
@@ -38,7 +38,7 @@ void ShapeSink::Open()
path_geo_.reset();
Renderer::GetInstance().CreateShapeSink(*this);
- win32::ThrowIfFailed(path_geo_->Open(&sink_), "Open ID2D1GeometrySink failed");
+ ThrowIfFailed(path_geo_->Open(&sink_), "Open ID2D1GeometrySink failed");
}
}
@@ -46,7 +46,7 @@ void ShapeSink::Close()
{
if (IsOpened())
{
- win32::ThrowIfFailed(sink_->Close(), "Close ID2D1GeometrySink failed");
+ ThrowIfFailed(sink_->Close(), "Close ID2D1GeometrySink failed");
sink_.reset();
}
@@ -78,7 +78,7 @@ ShapeSink& ShapeSink::AddShape(ShapePtr input, const Matrix3x2* input_matrix)
HRESULT hr =
geo->Outline(DX::ConvertToMatrix3x2F(input_matrix), D2D1_DEFAULT_FLATTENING_TOLERANCE, sink_.get());
- win32::ThrowIfFailed(hr, "Get outline of ID2D1Geometry failed");
+ ThrowIfFailed(hr, "Get outline of ID2D1Geometry failed");
}
return (*this);
}
@@ -153,7 +153,7 @@ ShapeSink& ShapeSink::Combine(ShapePtr shape_a, ShapePtr shape_b, CombineMode mo
HRESULT hr = geo_a_raw->CombineWithGeometry(geo_b_raw.get(), D2D1_COMBINE_MODE(mode),
DX::ConvertToMatrix3x2F(matrix), sink_.get());
- win32::ThrowIfFailed(hr, "Combine ID2D1Geometry failed");
+ ThrowIfFailed(hr, "Combine ID2D1Geometry failed");
}
return (*this);
}
diff --git a/src/kiwano/render/TextLayout.cpp b/src/kiwano/render/TextLayout.cpp
index 55462960..cfcf4ef4 100644
--- a/src/kiwano/render/TextLayout.cpp
+++ b/src/kiwano/render/TextLayout.cpp
@@ -183,7 +183,7 @@ void TextLayout::SetWrapWidth(float wrap_width)
}
}
}
- win32::ThrowIfFailed(hr, "Apply word wrapping to text layout failed");
+ ThrowIfFailed(hr, "Apply word wrapping to text layout failed");
}
}
@@ -202,7 +202,7 @@ void TextLayout::SetLineSpacing(float line_spacing)
{
hr = text_layout_->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_UNIFORM, line_spacing, line_spacing * 0.8f);
}
- win32::ThrowIfFailed(hr, "Apply line spacing to text layout failed");
+ ThrowIfFailed(hr, "Apply line spacing to text layout failed");
}
}
@@ -213,7 +213,7 @@ void TextLayout::SetAlignment(TextAlign align)
if (text_layout_)
{
HRESULT hr = text_layout_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(align));
- win32::ThrowIfFailed(hr, "Apply alignment style to text layout failed");
+ ThrowIfFailed(hr, "Apply alignment style to text layout failed");
}
}
@@ -228,7 +228,7 @@ void TextLayout::SetUnderline(bool enable, uint32_t start, uint32_t length)
{
hr = text_layout_->SetUnderline(enable, { start, length });
}
- win32::ThrowIfFailed(hr, "Apply underline style to text layout failed");
+ ThrowIfFailed(hr, "Apply underline style to text layout failed");
}
void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length)
@@ -242,7 +242,7 @@ void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length)
{
hr = text_layout_->SetStrikethrough(enable, { start, length });
}
- win32::ThrowIfFailed(hr, "Apply strikethrough style to text layout failed");
+ ThrowIfFailed(hr, "Apply strikethrough style to text layout failed");
}
} // namespace kiwano
diff --git a/src/kiwano/render/Texture.cpp b/src/kiwano/render/Texture.cpp
index cdbfdd73..4e44ed2f 100644
--- a/src/kiwano/render/Texture.cpp
+++ b/src/kiwano/render/Texture.cpp
@@ -139,7 +139,7 @@ void Texture::CopyFrom(TexturePtr copy_from)
{
HRESULT hr = bitmap_->CopyFromBitmap(nullptr, copy_from->GetBitmap().get(), nullptr);
- win32::ThrowIfFailed(hr, "Copy texture data failed");
+ ThrowIfFailed(hr, "Copy texture data failed");
}
}
@@ -152,7 +152,7 @@ void Texture::CopyFrom(TexturePtr copy_from, Rect const& src_rect, Point const&
&D2D1::RectU(uint32_t(src_rect.GetLeft()), uint32_t(src_rect.GetTop()), uint32_t(src_rect.GetRight()),
uint32_t(src_rect.GetBottom())));
- win32::ThrowIfFailed(hr, "Copy texture data failed");
+ ThrowIfFailed(hr, "Copy texture data failed");
}
}