add LogFormater & LogProvider & LogBuffer
This commit is contained in:
parent
83b8e9013d
commit
c19b5e224f
|
|
@ -37,7 +37,7 @@ AudioModule::~AudioModule() {}
|
||||||
|
|
||||||
void AudioModule::SetupModule()
|
void AudioModule::SetupModule()
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Creating audio resources");
|
KGE_DEBUG_LOGF("Creating audio resources");
|
||||||
|
|
||||||
HRESULT hr = dlls::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
HRESULT hr = dlls::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ void AudioModule::SetupModule()
|
||||||
|
|
||||||
void AudioModule::DestroyModule()
|
void AudioModule::DestroyModule()
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Destroying audio resources");
|
KGE_DEBUG_LOGF("Destroying audio resources");
|
||||||
|
|
||||||
if (mastering_voice_)
|
if (mastering_voice_)
|
||||||
{
|
{
|
||||||
|
|
@ -103,7 +103,7 @@ bool AudioModule::CreateSound(Sound& sound, const Transcoder::Buffer& buffer)
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_ERROR("Create IXAudio2SourceVoice failed with HRESULT of %08X", hr);
|
KGE_ERRORF("Create IXAudio2SourceVoice failed with HRESULT of %08X", hr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ bool Sound::Load(const String& file_path)
|
||||||
{
|
{
|
||||||
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
||||||
{
|
{
|
||||||
KGE_WARN("Media file '%s' not found", file_path.c_str());
|
KGE_WARNF("Media file '%s' not found", file_path.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ bool Sound::Load(const String& file_path)
|
||||||
HRESULT hr = transcoder_.LoadMediaFile(full_path);
|
HRESULT hr = transcoder_.LoadMediaFile(full_path);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_ERROR("Load media file failed with HRESULT of %08X", hr);
|
KGE_ERRORF("Load media file failed with HRESULT of %08X", hr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ bool Sound::Load(const Resource& res)
|
||||||
HRESULT hr = transcoder_.LoadMediaResource(res);
|
HRESULT hr = transcoder_.LoadMediaResource(res);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_ERROR("Load media resource failed with HRESULT of %08X", hr);
|
KGE_ERRORF("Load media resource failed with HRESULT of %08X", hr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ void Sound::Play(int loop_count)
|
||||||
{
|
{
|
||||||
if (!opened_)
|
if (!opened_)
|
||||||
{
|
{
|
||||||
KGE_ERROR("Sound must be opened first!");
|
KGE_ERRORF("Sound must be opened first!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +157,7 @@ void Sound::Play(int loop_count)
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_ERROR("Submitting source buffer failed with HRESULT of %08X", hr);
|
KGE_ERRORF("Submitting source buffer failed with HRESULT of %08X", hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
playing_ = SUCCEEDED(hr);
|
playing_ = SUCCEEDED(hr);
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ HRESULT Transcoder::LoadMediaResource(const Resource& res)
|
||||||
|
|
||||||
if (stream == nullptr)
|
if (stream == nullptr)
|
||||||
{
|
{
|
||||||
KGE_ERROR("SHCreateMemStream failed");
|
KGE_ERRORF("SHCreateMemStream failed");
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,7 +198,7 @@ HRESULT Transcoder::ReadSource(IMFSourceReader* reader)
|
||||||
|
|
||||||
if (data == nullptr)
|
if (data == nullptr)
|
||||||
{
|
{
|
||||||
KGE_ERROR("Low memory");
|
KGE_ERRORF("Low memory");
|
||||||
hr = E_OUTOFMEMORY;
|
hr = E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -298,7 +298,7 @@ void HttpModule::Perform(HttpRequestPtr request, HttpResponsePtr response)
|
||||||
ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message);
|
ok = Curl::DeleteRequest(this, headers, url, &response_code, &response_data, &response_header, error_message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
KGE_ERROR("HttpModule: unknown request type, only GET, POST, PUT or DELETE is supported");
|
KGE_ERRORF("HttpModule: unknown request type, only GET, POST, PUT or DELETE is supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -535,7 +535,7 @@ void Actor::AddChild(ActorPtr child, int zorder)
|
||||||
{
|
{
|
||||||
if (parent == child)
|
if (parent == child)
|
||||||
{
|
{
|
||||||
KGE_ERROR("A actor cannot be its own parent");
|
KGE_ERRORF("A actor cannot be its own parent");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,12 @@ Stage::~Stage() {}
|
||||||
|
|
||||||
void Stage::OnEnter()
|
void Stage::OnEnter()
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Stage entered");
|
KGE_DEBUG_LOGF("Stage entered");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stage::OnExit()
|
void Stage::OnExit()
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Stage exited");
|
KGE_DEBUG_LOGF("Stage exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stage::RenderBorder(RenderContext& ctx)
|
void Stage::RenderBorder(RenderContext& ctx)
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ public:
|
||||||
/// @brief 获取该动画的倒转
|
/// @brief 获取该动画的倒转
|
||||||
virtual ActionPtr Reverse() const override
|
virtual ActionPtr Reverse() const override
|
||||||
{
|
{
|
||||||
KGE_ERROR("Reverse() not supported in ActionMoveTo");
|
KGE_ERRORF("Reverse() not supported in ActionMoveTo");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,7 +299,7 @@ public:
|
||||||
/// @brief 获取该动画的倒转
|
/// @brief 获取该动画的倒转
|
||||||
virtual ActionPtr Reverse() const override
|
virtual ActionPtr Reverse() const override
|
||||||
{
|
{
|
||||||
KGE_ERROR("Reverse() not supported in ActionJumpTo");
|
KGE_ERRORF("Reverse() not supported in ActionJumpTo");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -398,7 +398,7 @@ public:
|
||||||
/// @brief 获取该动画的倒转
|
/// @brief 获取该动画的倒转
|
||||||
virtual ActionPtr Reverse() const override
|
virtual ActionPtr Reverse() const override
|
||||||
{
|
{
|
||||||
KGE_ERROR("Reverse() not supported in ActionScaleTo");
|
KGE_ERRORF("Reverse() not supported in ActionScaleTo");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,7 +439,7 @@ public:
|
||||||
/// @brief 获取该动画的倒转
|
/// @brief 获取该动画的倒转
|
||||||
virtual ActionPtr Reverse() const override
|
virtual ActionPtr Reverse() const override
|
||||||
{
|
{
|
||||||
KGE_ERROR("Reverse() not supported in ActionFadeTo");
|
KGE_ERRORF("Reverse() not supported in ActionFadeTo");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -544,7 +544,7 @@ public:
|
||||||
/// @brief 获取该动画的倒转
|
/// @brief 获取该动画的倒转
|
||||||
virtual ActionPtr Reverse() const override
|
virtual ActionPtr Reverse() const override
|
||||||
{
|
{
|
||||||
KGE_ERROR("Reverse() not supported in ActionRotateTo");
|
KGE_ERRORF("Reverse() not supported in ActionRotateTo");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -589,7 +589,7 @@ public:
|
||||||
/// @brief 获取该动画的倒转
|
/// @brief 获取该动画的倒转
|
||||||
ActionPtr Reverse() const override
|
ActionPtr Reverse() const override
|
||||||
{
|
{
|
||||||
KGE_ERROR("Reverse() not supported in ActionCustom");
|
KGE_ERRORF("Reverse() not supported in ActionCustom");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,13 +122,13 @@ void ObjectBase::StopTracingLeaks()
|
||||||
|
|
||||||
void ObjectBase::DumpTracingObjects()
|
void ObjectBase::DumpTracingObjects()
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("-------------------------- All Objects --------------------------");
|
KGE_DEBUG_LOGF("-------------------------- All Objects --------------------------");
|
||||||
for (const auto object : tracing_objects)
|
for (const auto object : tracing_objects)
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("{ class=\"%s\" id=%d refcount=%d name=\"%s\" }", typeid(*object).name(), object->GetObjectID(),
|
KGE_DEBUG_LOGF("{ class=\"%s\" id=%d refcount=%d name=\"%s\" }", typeid(*object).name(), object->GetObjectID(),
|
||||||
object->GetRefCount(), object->GetName().c_str());
|
object->GetRefCount(), object->GetName().c_str());
|
||||||
}
|
}
|
||||||
KGE_SYS_LOG("------------------------- Total size: %d -------------------------", tracing_objects.size());
|
KGE_DEBUG_LOGF("------------------------- Total size: %d -------------------------", tracing_objects.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<ObjectBase*>& ObjectBase::GetTracingObjects()
|
Vector<ObjectBase*>& ObjectBase::GetTracingObjects()
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@
|
||||||
//#define KGE_ASSERT(EXPR) __noop // Disable asserts
|
//#define KGE_ASSERT(EXPR) __noop // Disable asserts
|
||||||
|
|
||||||
//---- Define debug-output handler. Defaults to calling kiwano::logs::Messageln()/Warningln()/Errorln()
|
//---- Define debug-output handler. Defaults to calling kiwano::logs::Messageln()/Warningln()/Errorln()
|
||||||
//#define KGE_SYS_LOG(FORMAT, ...) wprintf(FORMAT "\n", __VA_ARGS__)
|
//#define KGE_LOGF(FORMAT, ...) printf(FORMAT "\n", __VA_ARGS__)
|
||||||
//#define KGE_WARN(FORMAT, ...) wprintf(FORMAT "\n", __VA_ARGS__)
|
//#define KGE_WARNF(FORMAT, ...) printf(FORMAT "\n", __VA_ARGS__)
|
||||||
//#define KGE_ERROR(FORMAT, ...) wprintf(FORMAT "\n", __VA_ARGS__)
|
//#define KGE_ERRORF(FORMAT, ...) printf(FORMAT "\n", __VA_ARGS__)
|
||||||
|
|
||||||
//---- Define attributes of all API symbols declarations for DLL
|
//---- Define attributes of all API symbols declarations for DLL
|
||||||
//#define KGE_USE_DLL
|
//#define KGE_USE_DLL
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ DbgHelp g_DbgHelp;
|
||||||
|
|
||||||
void PrintErrorCode(LPCSTR lpszFunction)
|
void PrintErrorCode(LPCSTR lpszFunction)
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed with HRESULT of %08X", lpszFunction, HRESULT_FROM_WIN32(GetLastError()));
|
KGE_ERRORF("%s failed with HRESULT of %08X", lpszFunction, HRESULT_FROM_WIN32(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintCallStackOnContext(PCONTEXT pContext)
|
void PrintCallStackOnContext(PCONTEXT pContext)
|
||||||
|
|
@ -227,7 +227,7 @@ void PrintCallStackOnContext(PCONTEXT pContext)
|
||||||
constexpr int STACKWALK_MAX_NAMELEN = 1024;
|
constexpr int STACKWALK_MAX_NAMELEN = 1024;
|
||||||
BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN];
|
BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN];
|
||||||
|
|
||||||
KGE_ERROR("========== Stack trace ==========");
|
KGE_ERRORF("========== Stack trace ==========");
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
@ -263,11 +263,11 @@ void PrintCallStackOnContext(PCONTEXT pContext)
|
||||||
DWORD dwLineDisplacement;
|
DWORD dwLineDisplacement;
|
||||||
if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
|
if (g_DbgHelp.SymGetLineFromAddr64(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s (%d): %s", lineInfo.FileName, lineInfo.LineNumber, pSymbol->Name);
|
KGE_ERRORF("%s (%d): %s", lineInfo.FileName, lineInfo.LineNumber, pSymbol->Name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KGE_ERROR("(filename not available): %s", pSymbol->Name);
|
KGE_ERRORF("(filename not available): %s", pSymbol->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sf.AddrReturn.Offset == 0)
|
if (sf.AddrReturn.Offset == 0)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#define KGE_THROW(MESSAGE) \
|
#define KGE_THROW(MESSAGE) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
KGE_ERROR("An exception occurred: %s", MESSAGE); \
|
KGE_ERRORF("An exception occurred: %s", MESSAGE); \
|
||||||
kiwano::StackTracer().Print(); \
|
kiwano::StackTracer().Print(); \
|
||||||
throw kiwano::RuntimeError(MESSAGE); \
|
throw kiwano::RuntimeError(MESSAGE); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
#define KGE_THROW_SYSTEM_ERROR(ERRCODE, MESSAGE) \
|
#define KGE_THROW_SYSTEM_ERROR(ERRCODE, MESSAGE) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
KGE_ERROR("An exception occurred (%#x): %s", ERRCODE, MESSAGE); \
|
KGE_ERRORF("An exception occurred (%#x): %s", ERRCODE, MESSAGE); \
|
||||||
kiwano::StackTracer().Print(); \
|
kiwano::StackTracer().Print(); \
|
||||||
throw kiwano::SystemError(std::error_code(kiwano::error_enum(ERRCODE)), MESSAGE); \
|
throw kiwano::SystemError(std::error_code(kiwano::error_enum(ERRCODE)), MESSAGE); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
|
||||||
|
|
@ -48,28 +48,28 @@ Resource::Data Resource::GetData() const
|
||||||
HRSRC res_info = FindResourceA(nullptr, MAKEINTRESOURCEA(id_), type_.data());
|
HRSRC res_info = FindResourceA(nullptr, MAKEINTRESOURCEA(id_), type_.data());
|
||||||
if (res_info == nullptr)
|
if (res_info == nullptr)
|
||||||
{
|
{
|
||||||
KGE_ERROR("FindResource failed");
|
KGE_ERRORF("FindResource failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
HGLOBAL res_data = LoadResource(nullptr, res_info);
|
HGLOBAL res_data = LoadResource(nullptr, res_info);
|
||||||
if (res_data == nullptr)
|
if (res_data == nullptr)
|
||||||
{
|
{
|
||||||
KGE_ERROR("LoadResource failed");
|
KGE_ERRORF("LoadResource failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD size = SizeofResource(nullptr, res_info);
|
DWORD size = SizeofResource(nullptr, res_info);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
KGE_ERROR("SizeofResource failed");
|
KGE_ERRORF("SizeofResource failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPVOID buffer = LockResource(res_data);
|
LPVOID buffer = LockResource(res_data);
|
||||||
if (buffer == nullptr)
|
if (buffer == nullptr)
|
||||||
{
|
{
|
||||||
KGE_ERROR("LockResource failed");
|
KGE_ERRORF("LockResource failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -606,7 +606,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
{
|
{
|
||||||
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
|
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window minimized");
|
KGE_DEBUG_LOGF("Window minimized");
|
||||||
|
|
||||||
is_minimized_ = true;
|
is_minimized_ = true;
|
||||||
// Pause game when window is minimized
|
// Pause game when window is minimized
|
||||||
|
|
@ -614,7 +614,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
}
|
}
|
||||||
else if (SIZE_MAXIMIZED == wparam)
|
else if (SIZE_MAXIMIZED == wparam)
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window maximized");
|
KGE_DEBUG_LOGF("Window maximized");
|
||||||
|
|
||||||
if (is_minimized_)
|
if (is_minimized_)
|
||||||
{
|
{
|
||||||
|
|
@ -626,7 +626,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
{
|
{
|
||||||
if (is_minimized_)
|
if (is_minimized_)
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window restored");
|
KGE_DEBUG_LOGF("Window restored");
|
||||||
|
|
||||||
// the window was restored and was previously minimized
|
// the window was restored and was previously minimized
|
||||||
is_minimized_ = false;
|
is_minimized_ = false;
|
||||||
|
|
@ -646,7 +646,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
evt->height = this->GetHeight();
|
evt->height = this->GetHeight();
|
||||||
this->PushEvent(evt);
|
this->PushEvent(evt);
|
||||||
|
|
||||||
KGE_SYS_LOG("Window resized to (%d, %d)", this->width_, this->height_);
|
KGE_DEBUG_LOGF("Window resized to (%d, %d)", this->width_, this->height_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -672,7 +672,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
uint32_t client_height = uint32_t(client_rect.bottom - client_rect.top);
|
uint32_t client_height = uint32_t(client_rect.bottom - client_rect.top);
|
||||||
if (client_width != this->GetWidth() || client_height != this->GetHeight())
|
if (client_width != this->GetWidth() || client_height != this->GetHeight())
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window resized to (%d, %d)", client_width, client_height);
|
KGE_DEBUG_LOGF("Window resized to (%d, %d)", client_width, client_height);
|
||||||
|
|
||||||
this->width_ = client_width;
|
this->width_ = client_width;
|
||||||
this->height_ = client_height;
|
this->height_ = client_height;
|
||||||
|
|
@ -744,7 +744,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
|
|
||||||
case WM_SETTEXT:
|
case WM_SETTEXT:
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window title changed");
|
KGE_DEBUG_LOGF("Window title changed");
|
||||||
|
|
||||||
this->title_ = strings::WideToNarrow(reinterpret_cast<LPCWSTR>(lparam));
|
this->title_ = strings::WideToNarrow(reinterpret_cast<LPCWSTR>(lparam));
|
||||||
|
|
||||||
|
|
@ -756,13 +756,13 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
|
|
||||||
case WM_SETICON:
|
case WM_SETICON:
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window icon changed");
|
KGE_DEBUG_LOGF("Window icon changed");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_DISPLAYCHANGE:
|
case WM_DISPLAYCHANGE:
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("The display resolution has changed");
|
KGE_DEBUG_LOGF("The display resolution has changed");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -774,7 +774,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
|
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window is closing");
|
KGE_DEBUG_LOGF("Window is closing");
|
||||||
|
|
||||||
WindowClosedEventPtr evt = new WindowClosedEvent;
|
WindowClosedEventPtr evt = new WindowClosedEvent;
|
||||||
this->PushEvent(evt);
|
this->PushEvent(evt);
|
||||||
|
|
@ -785,7 +785,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Window was destroyed");
|
KGE_DEBUG_LOGF("Window was destroyed");
|
||||||
|
|
||||||
::PostQuitMessage(0);
|
::PostQuitMessage(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KGE_ERROR("Failed to draw text layout with HRESULT of %08X", hr);
|
KGE_ERRORF("Failed to draw text layout with HRESULT of %08X", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ RendererImpl::RendererImpl()
|
||||||
|
|
||||||
void RendererImpl::MakeContextForWindow(WindowPtr window)
|
void RendererImpl::MakeContextForWindow(WindowPtr window)
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Creating device resources");
|
KGE_DEBUG_LOGF("Creating device resources");
|
||||||
|
|
||||||
KGE_THROW_IF_FAILED(::CoInitialize(nullptr), "CoInitialize failed");
|
KGE_THROW_IF_FAILED(::CoInitialize(nullptr), "CoInitialize failed");
|
||||||
|
|
||||||
|
|
@ -143,7 +143,7 @@ void RendererImpl::MakeContextForWindow(WindowPtr window)
|
||||||
|
|
||||||
void RendererImpl::Destroy()
|
void RendererImpl::Destroy()
|
||||||
{
|
{
|
||||||
KGE_SYS_LOG("Destroying device resources");
|
KGE_DEBUG_LOGF("Destroying device resources");
|
||||||
|
|
||||||
if (d2d_res_)
|
if (d2d_res_)
|
||||||
{
|
{
|
||||||
|
|
@ -194,7 +194,7 @@ void RendererImpl::CreateTexture(Texture& texture, const String& file_path)
|
||||||
|
|
||||||
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
||||||
{
|
{
|
||||||
KGE_WARN("Texture file '%s' not found!", file_path.c_str());
|
KGE_WARNF("Texture file '%s' not found!", file_path.c_str());
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -291,7 +291,7 @@ void RendererImpl::CreateTexture(Texture& texture, const Resource& resource)
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_WARN("Load texture failed with HRESULT of %08X!", hr);
|
KGE_WARNF("Load texture failed with HRESULT of %08X!", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -305,7 +305,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path)
|
||||||
|
|
||||||
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
||||||
{
|
{
|
||||||
KGE_WARN("Gif texture file '%s' not found!", file_path.c_str());
|
KGE_WARNF("Gif texture file '%s' not found!", file_path.c_str());
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,7 +324,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path)
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_WARN("Load GIF texture failed with HRESULT of %08X!", hr);
|
KGE_WARNF("Load GIF texture failed with HRESULT of %08X!", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -356,7 +356,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const Resource& resource)
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_WARN("Load GIF texture failed with HRESULT of %08X!", hr);
|
KGE_WARNF("Load GIF texture failed with HRESULT of %08X!", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -520,7 +520,7 @@ void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, const GifImage& g
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
KGE_WARN("Load GIF frame failed with HRESULT of %08X!", hr);
|
KGE_WARNF("Load GIF frame failed with HRESULT of %08X!", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -536,7 +536,7 @@ void RendererImpl::CreateFontCollection(Font& font, const String& file_path)
|
||||||
{
|
{
|
||||||
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
||||||
{
|
{
|
||||||
KGE_WARN("Font file '%s' not found!", file_path.c_str());
|
KGE_WARNF("Font file '%s' not found!", file_path.c_str());
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,222 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <ios>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <kiwano/utils/Logger.h>
|
#include <kiwano/utils/Logger.h>
|
||||||
|
|
||||||
|
namespace kiwano
|
||||||
|
{
|
||||||
|
|
||||||
|
String LogFormater::GetLevelLabel(LogLevel level) const
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case kiwano::LogLevel::Debug:
|
||||||
|
return "[Debug]";
|
||||||
|
case kiwano::LogLevel::Info:
|
||||||
|
return "[Info]";
|
||||||
|
case kiwano::LogLevel::Notice:
|
||||||
|
return "[Notice]";
|
||||||
|
case kiwano::LogLevel::Warning:
|
||||||
|
return "[Warning]";
|
||||||
|
case kiwano::LogLevel::Error:
|
||||||
|
return "[Error]";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextFormater : public LogFormater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Format(std::iostream& out, LogLevel level, Time time, std::streambuf* raw_msg) override
|
||||||
|
{
|
||||||
|
// get timestamp
|
||||||
|
time_t unix = std::time(nullptr);
|
||||||
|
std::tm tmbuf;
|
||||||
|
localtime_s(&tmbuf, &unix);
|
||||||
|
|
||||||
|
// build message
|
||||||
|
out << GetLevelLabel(level) << std::put_time(&tmbuf, " %H:%M:%S ");
|
||||||
|
|
||||||
|
if (raw_msg->sgetc() != std::char_traits<char>::eof())
|
||||||
|
out << raw_msg;
|
||||||
|
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
LogProvider::~LogProvider() {}
|
||||||
|
|
||||||
|
LogProviderPtr ConsoleLogProvider::Create()
|
||||||
|
{
|
||||||
|
LogProviderPtr ptr = new ConsoleLogProvider;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleLogProvider::~ConsoleLogProvider()
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleLogProvider::Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleLogProvider::WriteMessage(LogLevel level, LogBuffer* msg)
|
||||||
|
{
|
||||||
|
if (level != LogLevel::Error)
|
||||||
|
std::cout << msg << std::flush;
|
||||||
|
else
|
||||||
|
std::cerr << msg;
|
||||||
|
|
||||||
|
#if defined(KGE_PLATFORM_WINDOWS)
|
||||||
|
::OutputDebugStringA(msg->GetRaw());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleLogProvider::Flush()
|
||||||
|
{
|
||||||
|
std::cout.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogProviderPtr FileLogProvider::Create(const String& filepath, std::ios_base::openmode mode)
|
||||||
|
{
|
||||||
|
SmartPtr<FileLogProvider> ptr = new FileLogProvider;
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
ptr->ofs_.open(filepath, mode);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileLogProvider::~FileLogProvider()
|
||||||
|
{
|
||||||
|
if (ofs_.is_open())
|
||||||
|
ofs_.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileLogProvider::Init() {}
|
||||||
|
|
||||||
|
void FileLogProvider::WriteMessage(LogLevel level, LogBuffer* msg)
|
||||||
|
{
|
||||||
|
if (ofs_)
|
||||||
|
ofs_ << msg << std::flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileLogProvider::Flush()
|
||||||
|
{
|
||||||
|
if (ofs_)
|
||||||
|
ofs_.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Logger::Logger()
|
||||||
|
: enabled_(true)
|
||||||
|
, level_(LogLevel::Debug)
|
||||||
|
{
|
||||||
|
ResizeBuffer(1024);
|
||||||
|
|
||||||
|
LogFormaterPtr formater = new TextFormater;
|
||||||
|
SetFormater(formater);
|
||||||
|
|
||||||
|
LogProviderPtr provider = ConsoleLogProvider::Create();
|
||||||
|
AddProvider(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::~Logger()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::Logf(LogLevel level, const char* format, ...)
|
||||||
|
{
|
||||||
|
if (!enabled_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (level < level_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// build message
|
||||||
|
va_list args = nullptr;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
StringStream sstream;
|
||||||
|
sstream << strings::FormatArgs(format, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// write message
|
||||||
|
Write(level, sstream.rdbuf());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::Flush()
|
||||||
|
{
|
||||||
|
if (!enabled_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto provider : providers_)
|
||||||
|
{
|
||||||
|
provider->Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::SetLevel(LogLevel level)
|
||||||
|
{
|
||||||
|
level_ = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::AddProvider(LogProviderPtr provider)
|
||||||
|
{
|
||||||
|
if (provider)
|
||||||
|
{
|
||||||
|
provider->Init();
|
||||||
|
providers_.push_back(provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogFormaterPtr Logger::GetFormater()
|
||||||
|
{
|
||||||
|
return formater_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::ResizeBuffer(size_t buffer_size)
|
||||||
|
{
|
||||||
|
buffer_.resize(buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::Write(LogLevel level, std::streambuf* raw_msg)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
LogBuffer buf(buffer_);
|
||||||
|
std::iostream stream(&buf);
|
||||||
|
|
||||||
|
if (formater_)
|
||||||
|
{
|
||||||
|
formater_->Format(stream, level, Time::Now(), raw_msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream << raw_msg << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto provider : providers_)
|
||||||
|
{
|
||||||
|
buf.pubseekpos(0, std::ios_base::out);
|
||||||
|
provider->WriteMessage(level, &buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(KGE_PLATFORM_WINDOWS)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Console log
|
||||||
|
//
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::streambuf *cin_buffer, *cout_buffer, *cerr_buffer;
|
std::streambuf *cin_buffer, *cout_buffer, *cerr_buffer;
|
||||||
|
|
@ -121,202 +333,6 @@ HWND GetAllocatedConsole()
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace kiwano
|
|
||||||
{
|
|
||||||
namespace console_colors
|
|
||||||
{
|
|
||||||
const WORD blue = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
|
||||||
const WORD green = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
|
||||||
const WORD red = FOREGROUND_RED | FOREGROUND_INTENSITY;
|
|
||||||
const WORD yellow = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
|
||||||
const WORD white = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
|
||||||
|
|
||||||
const WORD blue_bg = white | BACKGROUND_BLUE | BACKGROUND_INTENSITY;
|
|
||||||
const WORD green_bg = white | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
|
||||||
const WORD red_bg = white | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
|
||||||
const WORD yellow_bg = BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
|
||||||
const WORD white_bg = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
|
||||||
|
|
||||||
const WORD Reset = white;
|
|
||||||
} // namespace console_colors
|
|
||||||
|
|
||||||
#define DECLARE_HANDLE_COLOR(NAME, HANDLE_NAME, COLOR) \
|
|
||||||
inline OutputStream&(NAME)(OutputStream & _out) \
|
|
||||||
{ \
|
|
||||||
::SetConsoleTextAttribute(::GetStdHandle(HANDLE_NAME), console_colors::##COLOR); \
|
|
||||||
return _out; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DECLARE_COLOR(COLOR) \
|
|
||||||
DECLARE_HANDLE_COLOR(stdout_##COLOR, STD_OUTPUT_HANDLE, COLOR) \
|
|
||||||
DECLARE_HANDLE_COLOR(stderr_##COLOR, STD_ERROR_HANDLE, COLOR)
|
|
||||||
|
|
||||||
#define DECLARE_BG_COLOR(COLOR) \
|
|
||||||
DECLARE_HANDLE_COLOR(stdout_##COLOR##_bg, STD_OUTPUT_HANDLE, COLOR##_bg) \
|
|
||||||
DECLARE_HANDLE_COLOR(stderr_##COLOR##_bg, STD_ERROR_HANDLE, COLOR##_bg)
|
|
||||||
|
|
||||||
namespace console_colors
|
|
||||||
{
|
|
||||||
DECLARE_COLOR(red);
|
|
||||||
DECLARE_COLOR(green);
|
|
||||||
DECLARE_COLOR(yellow);
|
|
||||||
DECLARE_COLOR(blue);
|
|
||||||
DECLARE_COLOR(white);
|
|
||||||
DECLARE_COLOR(Reset);
|
|
||||||
|
|
||||||
DECLARE_BG_COLOR(red);
|
|
||||||
DECLARE_BG_COLOR(green);
|
|
||||||
DECLARE_BG_COLOR(yellow);
|
|
||||||
DECLARE_BG_COLOR(blue);
|
|
||||||
DECLARE_BG_COLOR(white);
|
|
||||||
} // namespace console_colors
|
|
||||||
|
|
||||||
Logger::Logger()
|
|
||||||
: enabled_(true)
|
|
||||||
, default_stdout_color_(0)
|
|
||||||
, default_stderr_color_(0)
|
|
||||||
, output_stream_(std::cout.rdbuf())
|
|
||||||
, error_stream_(std::cerr.rdbuf())
|
|
||||||
{
|
|
||||||
ResetStreamToStdStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::~Logger()
|
|
||||||
{
|
|
||||||
FreeAllocatedConsole();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::Printf(Level level, const char* format, ...)
|
|
||||||
{
|
|
||||||
if (!enabled_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
StringStream sstream;
|
|
||||||
Prepare(level, sstream);
|
|
||||||
|
|
||||||
// Format message
|
|
||||||
if (format)
|
|
||||||
{
|
|
||||||
va_list args = nullptr;
|
|
||||||
va_start(args, format);
|
|
||||||
|
|
||||||
static char temp_buffer[1024 * 3 + 1];
|
|
||||||
const auto len = ::_vscprintf(format, args) + 1;
|
|
||||||
::_vsnprintf_s(temp_buffer, len, len, format, args);
|
|
||||||
|
|
||||||
sstream << ' ' << temp_buffer << "\n";
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
Output(level, sstream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::Prepare(Level level, StringStream& sstream)
|
|
||||||
{
|
|
||||||
String prefix;
|
|
||||||
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case Level::Info:
|
|
||||||
prefix = "[INFO] ";
|
|
||||||
break;
|
|
||||||
case Level::System:
|
|
||||||
prefix = "[SYSTEM] ";
|
|
||||||
break;
|
|
||||||
case Level::Warning:
|
|
||||||
prefix = "[WARN] ";
|
|
||||||
break;
|
|
||||||
case Level::Error:
|
|
||||||
prefix = "[ERROR] ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timestamp
|
|
||||||
time_t unix = std::time(nullptr);
|
|
||||||
std::tm tmbuf;
|
|
||||||
localtime_s(&tmbuf, &unix);
|
|
||||||
sstream << prefix << std::put_time(&tmbuf, "%H:%M:%S ");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::Output(Level level, StringStream& sstream)
|
|
||||||
{
|
|
||||||
using ConsoleColor = Function<OutputStream&(OutputStream&)>;
|
|
||||||
|
|
||||||
OutputStream* ostream = nullptr;
|
|
||||||
ConsoleColor color = nullptr;
|
|
||||||
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case Level::Info:
|
|
||||||
ostream = &output_stream_;
|
|
||||||
color = Closure(this, &Logger::DefaultOutputColor);
|
|
||||||
break;
|
|
||||||
case Level::System:
|
|
||||||
ostream = &output_stream_;
|
|
||||||
color = console_colors::stdout_blue;
|
|
||||||
break;
|
|
||||||
case Level::Warning:
|
|
||||||
ostream = &output_stream_;
|
|
||||||
color = console_colors::stdout_yellow_bg;
|
|
||||||
break;
|
|
||||||
case Level::Error:
|
|
||||||
ostream = &error_stream_;
|
|
||||||
color = console_colors::stderr_red_bg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Printing
|
|
||||||
if (ostream)
|
|
||||||
{
|
|
||||||
auto output = sstream.str();
|
|
||||||
color(*ostream) << output << std::flush;
|
|
||||||
::OutputDebugStringA(output.c_str());
|
|
||||||
|
|
||||||
ResetConsoleColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::ResetStreamToStdStream()
|
|
||||||
{
|
|
||||||
bool has_console = ::GetConsoleWindow() != nullptr;
|
|
||||||
if (has_console)
|
|
||||||
{
|
|
||||||
default_stdout_color_ = default_stderr_color_ =
|
|
||||||
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
|
||||||
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO stdout_info;
|
|
||||||
if (::GetConsoleScreenBufferInfo(::GetStdHandle(STD_OUTPUT_HANDLE), &stdout_info))
|
|
||||||
{
|
|
||||||
default_stdout_color_ = stdout_info.wAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO stderr_info;
|
|
||||||
if (::GetConsoleScreenBufferInfo(::GetStdHandle(STD_ERROR_HANDLE), &stderr_info))
|
|
||||||
{
|
|
||||||
default_stderr_color_ = stderr_info.wAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace the C++ global locale with the user-preferred locale
|
|
||||||
(void)std::locale::global(std::locale());
|
|
||||||
(void)std::cout.imbue(std::locale());
|
|
||||||
(void)std::cerr.imbue(std::locale());
|
|
||||||
|
|
||||||
RedirectOutputStream(std::cout.rdbuf());
|
|
||||||
RedirectErrorStream(std::cerr.rdbuf());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::streambuf* Logger::RedirectOutputStream(std::streambuf* buf)
|
|
||||||
{
|
|
||||||
return output_stream_.rdbuf(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::streambuf* Logger::RedirectErrorStream(std::streambuf* buf)
|
|
||||||
{
|
|
||||||
return error_stream_.rdbuf(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::ShowConsole(bool show)
|
void Logger::ShowConsole(bool show)
|
||||||
{
|
{
|
||||||
HWND current_console = ::GetConsoleWindow();
|
HWND current_console = ::GetConsoleWindow();
|
||||||
|
|
@ -328,14 +344,13 @@ void Logger::ShowConsole(bool show)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HWND console = ::AllocateConsole();
|
HWND console = AllocateConsole();
|
||||||
if (!console)
|
if (console)
|
||||||
{
|
{
|
||||||
KGE_WARN("AllocConsole failed");
|
// replace the C++ global locale with the user-preferred locale
|
||||||
}
|
(void)std::locale::global(std::locale());
|
||||||
else
|
(void)std::cout.imbue(std::locale());
|
||||||
{
|
(void)std::cerr.imbue(std::locale());
|
||||||
ResetStreamToStdStream();
|
|
||||||
|
|
||||||
// disable the close button of console
|
// disable the close button of console
|
||||||
HMENU hmenu = ::GetSystemMenu(console, FALSE);
|
HMENU hmenu = ::GetSystemMenu(console, FALSE);
|
||||||
|
|
@ -359,4 +374,117 @@ void Logger::ShowConsole(bool show)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LogBuffer::LogBuffer(Vector<char_type>& buf)
|
||||||
|
: buf_(buf)
|
||||||
|
, seek_high_(nullptr)
|
||||||
|
{
|
||||||
|
this->setbuf(buf.data(), buf.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LogBuffer::GetRaw() const
|
||||||
|
{
|
||||||
|
const auto pptr = this->pptr();
|
||||||
|
if (!pptr)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
const auto data = buf_.data();
|
||||||
|
const auto size = buf_.size();
|
||||||
|
if (pptr == data)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
if (pptr > data && pptr < data + size)
|
||||||
|
{
|
||||||
|
*pptr = '\0';
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
LogBuffer::int_type LogBuffer::overflow(int_type ch)
|
||||||
|
{
|
||||||
|
if (traits_type::eq_int_type(ch, traits_type::eof()))
|
||||||
|
return traits_type::not_eof(ch); // EOF, return success
|
||||||
|
|
||||||
|
const auto pptr = this->pptr();
|
||||||
|
if (pptr)
|
||||||
|
return traits_type::eof();
|
||||||
|
|
||||||
|
const auto epptr = this->epptr();
|
||||||
|
if (pptr < epptr)
|
||||||
|
{
|
||||||
|
seek_high_ = pptr + 1;
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto old_ptr = buf_.data();
|
||||||
|
const auto old_size = pptr - old_ptr;
|
||||||
|
|
||||||
|
size_t new_size = 0;
|
||||||
|
if (old_size < INT_MAX / 2)
|
||||||
|
new_size = old_size << 1;
|
||||||
|
else if (old_size < INT_MAX)
|
||||||
|
new_size = INT_MAX;
|
||||||
|
else
|
||||||
|
return traits_type::eof(); // buffer can't grow, fail
|
||||||
|
|
||||||
|
// grow
|
||||||
|
buf_.resize(new_size);
|
||||||
|
|
||||||
|
const auto new_ptr = buf_.data();
|
||||||
|
const auto new_pnext = new_ptr + old_size;
|
||||||
|
|
||||||
|
seek_high_ = new_pnext + 1;
|
||||||
|
|
||||||
|
this->setp(new_ptr, new_pnext, new_ptr + new_size);
|
||||||
|
this->setg(new_ptr, new_ptr + (this->gptr() - old_ptr), seek_high_);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogBuffer::int_type LogBuffer::underflow()
|
||||||
|
{
|
||||||
|
const auto gptr = this->gptr();
|
||||||
|
if (!gptr)
|
||||||
|
return traits_type::eof();
|
||||||
|
|
||||||
|
if (gptr < this->egptr())
|
||||||
|
return traits_type::to_int_type(*gptr);
|
||||||
|
|
||||||
|
const auto pptr = this->pptr();
|
||||||
|
if (!pptr)
|
||||||
|
return traits_type::eof();
|
||||||
|
|
||||||
|
const auto high = std::max(seek_high_, pptr);
|
||||||
|
if (high <= gptr)
|
||||||
|
return traits_type::eof();
|
||||||
|
|
||||||
|
seek_high_ = high;
|
||||||
|
this->setg(this->eback(), gptr, high);
|
||||||
|
return traits_type::to_int_type(*gptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogBuffer::pos_type LogBuffer::seekpos(pos_type sp, std::ios_base::openmode which)
|
||||||
|
{
|
||||||
|
return this->seekoff(sp - pos_type(off_type(0)), std::ios_base::beg, which);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogBuffer::pos_type LogBuffer::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which)
|
||||||
|
{
|
||||||
|
if (dir == std::ios_base::cur)
|
||||||
|
gbump(int(off));
|
||||||
|
else if (dir == std::ios_base::end)
|
||||||
|
setg(eback(), egptr() + off, egptr());
|
||||||
|
else if (dir == std::ios_base::beg)
|
||||||
|
setg(eback(), eback() + off, egptr());
|
||||||
|
return gptr() - eback();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::streambuf* LogBuffer::setbuf(char_type* s, std::streamsize n)
|
||||||
|
{
|
||||||
|
this->setp(s, s + n);
|
||||||
|
this->setg(s, s, s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -19,83 +19,201 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <kiwano/core/Common.h>
|
#include <kiwano/core/Time.h>
|
||||||
|
#include <kiwano/base/ObjectBase.h>
|
||||||
|
#include <mutex>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#ifndef KGE_SYS_LOG
|
#ifndef KGE_DEBUG_LOG
|
||||||
#ifdef KGE_DEBUG
|
#ifdef KGE_DEBUG
|
||||||
#define KGE_SYS_LOG(FORMAT, ...) \
|
#define KGE_DEBUG_LOG(...) ::kiwano::Logger::GetInstance().Log(::kiwano::LogLevel::Debug, __VA_ARGS__)
|
||||||
::kiwano::Logger::GetInstance().Printf(::kiwano::Logger::Level::System, FORMAT, __VA_ARGS__)
|
|
||||||
#else
|
#else
|
||||||
#define KGE_SYS_LOG __noop
|
#define KGE_DEBUG_LOG __noop
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef KGE_WARN
|
|
||||||
#define KGE_WARN(FORMAT, ...) ::kiwano::Logger::GetInstance().Printf(::kiwano::Logger::Level::Warning, FORMAT, __VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KGE_ERROR
|
|
||||||
#define KGE_ERROR(FORMAT, ...) ::kiwano::Logger::GetInstance().Printf(::kiwano::Logger::Level::Error, FORMAT, __VA_ARGS__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KGE_LOG
|
#ifndef KGE_LOG
|
||||||
#define KGE_LOG(...) ::kiwano::Logger::GetInstance().Println(::kiwano::Logger::Level::Info, __VA_ARGS__)
|
#define KGE_LOG(...) ::kiwano::Logger::GetInstance().Log(::kiwano::LogLevel::Info, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KGE_NOTICE
|
||||||
|
#define KGE_NOTICE(...) ::kiwano::Logger::GetInstance().Log(::kiwano::LogLevel::Notice, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KGE_WARN
|
||||||
|
#define KGE_WARN(...) ::kiwano::Logger::GetInstance().Log(::kiwano::LogLevel::Warning, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KGE_ERROR
|
||||||
|
#define KGE_ERROR(...) ::kiwano::Logger::GetInstance().Log(::kiwano::LogLevel::Error, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KGE_DEBUG_LOGF
|
||||||
|
#ifdef KGE_DEBUG
|
||||||
|
#define KGE_DEBUG_LOGF(FORMAT, ...) ::kiwano::Logger::GetInstance().Logf(::kiwano::LogLevel::Debug, FORMAT, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define KGE_DEBUG_LOGF __noop
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef KGE_LOGF
|
#ifndef KGE_LOGF
|
||||||
#define KGE_LOGF(FORMAT, ...) ::kiwano::Logger::GetInstance().Printf(::kiwano::Logger::Level::Info, FORMAT, __VA_ARGS__)
|
#define KGE_LOGF(FORMAT, ...) ::kiwano::Logger::GetInstance().Logf(::kiwano::LogLevel::Info, FORMAT, __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef KGE_LOG_STREAM
|
#ifndef KGE_NOTICEF
|
||||||
#define KGE_LOG_STREAM() ::kiwano::Logger::GetInstance().GetOutputStream()
|
#define KGE_NOTICEF(FORMAT, ...) ::kiwano::Logger::GetInstance().Logf(::kiwano::LogLevel::Notice, FORMAT, __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef KGE_ERROR_STREAM
|
#ifndef KGE_WARNF
|
||||||
#define KGE_ERROR_STREAM() ::kiwano::Logger::GetInstance().GetErrorStream()
|
#define KGE_WARNF(FORMAT, ...) ::kiwano::Logger::GetInstance().Logf(::kiwano::LogLevel::Warning, FORMAT, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KGE_ERRORF
|
||||||
|
#define KGE_ERRORF(FORMAT, ...) ::kiwano::Logger::GetInstance().Logf(::kiwano::LogLevel::Error, FORMAT, __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
|
|
||||||
|
KGE_DECLARE_SMART_PTR(LogFormater);
|
||||||
|
KGE_DECLARE_SMART_PTR(LogProvider);
|
||||||
|
KGE_DECLARE_SMART_PTR(Logger);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \~chinese
|
* \~chinese
|
||||||
* @brief 日志
|
* @brief 日志等级
|
||||||
|
*/
|
||||||
|
enum class LogLevel
|
||||||
|
{
|
||||||
|
Debug, ///< 调试
|
||||||
|
Info, ///< 信息
|
||||||
|
Notice, ///< 注意
|
||||||
|
Warning, ///< 警告
|
||||||
|
Error, ///< 错误
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 日志格式化
|
||||||
|
*/
|
||||||
|
class KGE_API LogFormater : public ObjectBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Format(std::iostream& out, LogLevel level, Time time, std::streambuf* raw_msg) = 0;
|
||||||
|
|
||||||
|
String GetLevelLabel(LogLevel level) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 日志流缓冲
|
||||||
|
*/
|
||||||
|
class LogBuffer : public std::streambuf
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LogBuffer(Vector<char_type>& buf);
|
||||||
|
|
||||||
|
const char* GetRaw() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int_type overflow(int_type ch) override;
|
||||||
|
|
||||||
|
int_type underflow() override;
|
||||||
|
|
||||||
|
pos_type seekpos(pos_type sp, std::ios_base::openmode which) override;
|
||||||
|
|
||||||
|
pos_type seekoff(off_type off, std::ios_base::seekdir dir,
|
||||||
|
std::ios_base::openmode which = std::ios_base::in) override;
|
||||||
|
|
||||||
|
std::streambuf* setbuf(char_type* s, std::streamsize n) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<char_type>& buf_;
|
||||||
|
char_type* seek_high_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 日志提供者
|
||||||
|
*/
|
||||||
|
class KGE_API LogProvider : public ObjectBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~LogProvider();
|
||||||
|
|
||||||
|
virtual void Init() = 0;
|
||||||
|
|
||||||
|
virtual void WriteMessage(LogLevel level, LogBuffer* msg) = 0;
|
||||||
|
|
||||||
|
virtual void Flush() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 控制台日志提供者
|
||||||
|
*/
|
||||||
|
class KGE_API ConsoleLogProvider : public LogProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static LogProviderPtr Create();
|
||||||
|
|
||||||
|
virtual ~ConsoleLogProvider();
|
||||||
|
|
||||||
|
void Init() override;
|
||||||
|
|
||||||
|
void WriteMessage(LogLevel level, LogBuffer* msg) override;
|
||||||
|
|
||||||
|
void Flush() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 文件日志提供者
|
||||||
|
*/
|
||||||
|
class KGE_API FileLogProvider : public LogProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static LogProviderPtr Create(const String& filepath, std::ios_base::openmode mode = std::ios_base::out);
|
||||||
|
|
||||||
|
virtual ~FileLogProvider();
|
||||||
|
|
||||||
|
void Init() override;
|
||||||
|
|
||||||
|
void WriteMessage(LogLevel level, LogBuffer* msg) override;
|
||||||
|
|
||||||
|
void Flush() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ofstream ofs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 日志记录器
|
||||||
*/
|
*/
|
||||||
class KGE_API Logger : public Singleton<Logger>
|
class KGE_API Logger : public Singleton<Logger>
|
||||||
{
|
{
|
||||||
friend Singleton<Logger>;
|
friend Singleton<Logger>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \~chinese
|
|
||||||
/// @brief 日志级别
|
|
||||||
enum class Level
|
|
||||||
{
|
|
||||||
Info, ///< 信息
|
|
||||||
System, ///< 系统
|
|
||||||
Warning, ///< 警告
|
|
||||||
Error ///< 错误
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 打印日志
|
/// @brief 打印日志
|
||||||
/// @param level 日志级别
|
/// @param level 日志级别
|
||||||
/// @param format 格式字符串
|
/// @param format 格式字符串
|
||||||
void Printf(Level level, const char* format, ...);
|
void Logf(LogLevel level, const char* format, ...);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 打印日志
|
/// @brief 打印日志
|
||||||
/// @param level 日志级别
|
/// @param level 日志级别
|
||||||
/// @param args 参数
|
/// @param args 参数
|
||||||
template <typename... _Args>
|
template <typename... _Args>
|
||||||
void Print(Level level, _Args&&... args);
|
void Log(LogLevel level, _Args&&... args);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 打印一行日志
|
/// @brief 刷新日志缓冲
|
||||||
/// @param level 日志级别
|
void Flush();
|
||||||
/// @param args 参数
|
|
||||||
template <typename... _Args>
|
|
||||||
void Println(Level level, _Args&&... args);
|
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 启用日志
|
/// @brief 启用日志
|
||||||
|
|
@ -106,48 +224,53 @@ public:
|
||||||
void Disable();
|
void Disable();
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 获取输出流
|
/// @brief 设置日志等级
|
||||||
OutputStream& GetOutputStream();
|
void SetLevel(LogLevel level);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 获取错误输出流
|
/// @brief 添加日志提供者
|
||||||
OutputStream& GetErrorStream();
|
/// @param provider 日志提供者
|
||||||
|
void AddProvider(LogProviderPtr provider);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 重定向输出流
|
/// @brief 设置日志格式
|
||||||
std::streambuf* RedirectOutputStream(std::streambuf* buf);
|
/// @param formater 日志格式化
|
||||||
|
void SetFormater(LogFormaterPtr formater);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 重定向错误输出流
|
/// @brief 获取日志格式
|
||||||
std::streambuf* RedirectErrorStream(std::streambuf* buf);
|
/// @return 日志格式
|
||||||
|
LogFormaterPtr GetFormater();
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 重设缓冲区大小
|
||||||
|
/// @param buffer_size 缓冲区大小
|
||||||
|
void ResizeBuffer(size_t buffer_size);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 写入缓冲区
|
||||||
|
/// @param level 日志等级
|
||||||
|
/// @param raw_msg 日志内容
|
||||||
|
void Write(LogLevel level, std::streambuf* raw_msg);
|
||||||
|
|
||||||
|
#if defined(KGE_PLATFORM_WINDOWS)
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 显示或关闭控制台
|
/// @brief 显示或关闭控制台
|
||||||
/// @note 此操作会重定向输出流到标准输出流
|
|
||||||
void ShowConsole(bool show);
|
void ShowConsole(bool show);
|
||||||
|
#endif
|
||||||
|
|
||||||
~Logger();
|
virtual ~Logger();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logger();
|
Logger();
|
||||||
|
|
||||||
void Prepare(Level level, StringStream& sstream);
|
|
||||||
|
|
||||||
void Output(Level level, StringStream& sstream);
|
|
||||||
|
|
||||||
void ResetStreamToStdStream();
|
|
||||||
|
|
||||||
void ResetConsoleColor() const;
|
|
||||||
|
|
||||||
OutputStream& DefaultOutputColor(OutputStream& out);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool enabled_;
|
bool enabled_;
|
||||||
WORD default_stdout_color_;
|
LogLevel level_;
|
||||||
WORD default_stderr_color_;
|
LogFormaterPtr formater_;
|
||||||
|
Vector<LogProviderPtr> providers_;
|
||||||
OutputStream output_stream_;
|
Vector<char> buffer_;
|
||||||
OutputStream error_stream_;
|
std::mutex mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void Logger::Enable()
|
inline void Logger::Enable()
|
||||||
|
|
@ -160,57 +283,26 @@ inline void Logger::Disable()
|
||||||
enabled_ = false;
|
enabled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Logger::SetFormater(LogFormaterPtr formater)
|
||||||
|
{
|
||||||
|
formater_ = formater;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... _Args>
|
template <typename... _Args>
|
||||||
void Logger::Print(Level level, _Args&&... args)
|
inline void Logger::Log(LogLevel level, _Args&&... args)
|
||||||
{
|
{
|
||||||
if (!enabled_)
|
if (!enabled_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
StringStream sstream;
|
if (level < level_)
|
||||||
Prepare(level, sstream);
|
|
||||||
|
|
||||||
// Format message
|
|
||||||
(void)std::initializer_list<int>{ ((sstream << ' ' << args), 0)... };
|
|
||||||
|
|
||||||
Output(level, sstream);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... _Args>
|
|
||||||
void Logger::Println(Level level, _Args&&... args)
|
|
||||||
{
|
|
||||||
if (!enabled_)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// build message
|
||||||
StringStream sstream;
|
StringStream sstream;
|
||||||
Prepare(level, sstream);
|
|
||||||
|
|
||||||
// Format message
|
|
||||||
(void)std::initializer_list<int>{ ((sstream << ' ' << args), 0)... };
|
(void)std::initializer_list<int>{ ((sstream << ' ' << args), 0)... };
|
||||||
|
|
||||||
sstream << "\r\n";
|
// write message
|
||||||
|
this->Write(level, sstream.rdbuf());
|
||||||
Output(level, sstream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Logger::ResetConsoleColor() const
|
|
||||||
{
|
|
||||||
::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), default_stdout_color_);
|
|
||||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), default_stderr_color_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline OutputStream& Logger::DefaultOutputColor(OutputStream& out)
|
|
||||||
{
|
|
||||||
::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), default_stdout_color_);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline OutputStream& Logger::GetOutputStream()
|
|
||||||
{
|
|
||||||
return output_stream_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline OutputStream& Logger::GetErrorStream()
|
|
||||||
{
|
|
||||||
return error_stream_;
|
|
||||||
}
|
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ bool ResourceCache::LoadFromJsonFile(const String& file_path)
|
||||||
{
|
{
|
||||||
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: File not found.", __FUNCTION__);
|
KGE_ERRORF("%s failed: File not found.", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,12 +78,12 @@ bool ResourceCache::LoadFromJsonFile(const String& file_path)
|
||||||
}
|
}
|
||||||
catch (std::wifstream::failure& e)
|
catch (std::wifstream::failure& e)
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: Cannot open file. (%s)", __FUNCTION__, e.what());
|
KGE_ERRORF("%s failed: Cannot open file. (%s)", __FUNCTION__, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (Json::exception& e)
|
catch (Json::exception& e)
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: Cannot parse to JSON. (%s)", __FUNCTION__, e.what());
|
KGE_ERRORF("%s failed: Cannot parse to JSON. (%s)", __FUNCTION__, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return LoadFromJson(json_data);
|
return LoadFromJson(json_data);
|
||||||
|
|
@ -106,12 +106,12 @@ bool ResourceCache::LoadFromJson(const Json& json_data)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: unknown resource data version", __FUNCTION__);
|
KGE_ERRORF("%s failed: unknown resource data version", __FUNCTION__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Json::exception& e)
|
catch (Json::exception& e)
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: JSON data is invalid. (%s)", __FUNCTION__, e.what());
|
KGE_ERRORF("%s failed: JSON data is invalid. (%s)", __FUNCTION__, e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -121,7 +121,7 @@ bool ResourceCache::LoadFromXmlFile(const String& file_path)
|
||||||
{
|
{
|
||||||
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
if (!FileSystem::GetInstance().IsFileExists(file_path))
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: File not found.", __FUNCTION__);
|
KGE_ERRORF("%s failed: File not found.", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,7 +136,7 @@ bool ResourceCache::LoadFromXmlFile(const String& file_path)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: XML [%s] parsed with errors: %s", __FUNCTION__, full_path.c_str(), result.description());
|
KGE_ERRORF("%s failed: XML [%s] parsed with errors: %s", __FUNCTION__, full_path.c_str(), result.description());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +160,7 @@ bool ResourceCache::LoadFromXml(const XmlDocument& doc)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KGE_ERROR("%s failed: unknown resource data version", __FUNCTION__);
|
KGE_ERRORF("%s failed: unknown resource data version", __FUNCTION__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue