commit
d1c90ed4b0
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -263,12 +263,20 @@ public:
|
||||||
void SetPositionY(float y);
|
void SetPositionY(float y);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 移动坐标
|
/// @brief 移动至坐标
|
||||||
void Move(const Vec2& v);
|
void MoveTo(const Point& p);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 移动坐标
|
/// @brief 移动至坐标
|
||||||
void Move(float vx, float vy);
|
void MoveTo(float x, float y);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 移动相对坐标
|
||||||
|
void MoveBy(const Vec2& trans);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 移动相对坐标
|
||||||
|
void MoveBy(float trans_x, float trans_y);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 设置缩放比例,默认为 (1.0, 1.0)
|
/// @brief 设置缩放比例,默认为 (1.0, 1.0)
|
||||||
|
|
@ -725,14 +733,24 @@ inline void Actor::SetPositionY(float y)
|
||||||
this->SetPosition(Point(transform_.position.x, y));
|
this->SetPosition(Point(transform_.position.x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Actor::Move(const Vec2& v)
|
inline void Actor::MoveTo(const Point& p)
|
||||||
{
|
{
|
||||||
this->SetPosition(transform_.position.x + v.x, transform_.position.y + v.y);
|
this->SetPosition(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Actor::Move(float vx, float vy)
|
inline void Actor::MoveTo(float x, float y)
|
||||||
{
|
{
|
||||||
this->Move(Vec2(vx, vy));
|
this->SetPosition(Point(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Actor::MoveBy(const Vec2& trans)
|
||||||
|
{
|
||||||
|
this->SetPosition(transform_.position.x + trans.x, transform_.position.y + trans.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Actor::MoveBy(float trans_x, float trans_y)
|
||||||
|
{
|
||||||
|
this->MoveBy(Vec2(trans_x, trans_y));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Actor::SetScale(float scalex, float scaley)
|
inline void Actor::SetScale(float scalex, float scaley)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -25,24 +25,24 @@
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
|
|
||||||
ActionGroupPtr ActionGroup::Create(const Vector<ActionPtr>& actions, bool sync)
|
ActionGroupPtr ActionGroup::Create(const Vector<ActionPtr>& actions, bool parallel)
|
||||||
{
|
{
|
||||||
ActionGroupPtr ptr = memory::New<ActionGroup>();
|
ActionGroupPtr ptr = memory::New<ActionGroup>();
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
ptr->sync_ = sync;
|
ptr->parallel_ = parallel;
|
||||||
ptr->AddActions(actions);
|
ptr->AddActions(actions);
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionGroup::ActionGroup()
|
ActionGroup::ActionGroup()
|
||||||
: sync_(false)
|
: parallel_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionGroup::ActionGroup(bool sync)
|
ActionGroup::ActionGroup(bool parallel)
|
||||||
: sync_(sync)
|
: parallel_(parallel)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ void ActionGroup::Init(Actor* target)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sync_)
|
if (parallel_)
|
||||||
{
|
{
|
||||||
// init all actions
|
// init all actions
|
||||||
for (current_ = actions_.GetFirst(); current_; current_ = current_->GetNext())
|
for (current_ = actions_.GetFirst(); current_; current_ = current_->GetNext())
|
||||||
|
|
@ -73,7 +73,7 @@ void ActionGroup::Init(Actor* target)
|
||||||
|
|
||||||
void ActionGroup::Update(Actor* target, Duration dt)
|
void ActionGroup::Update(Actor* target, Duration dt)
|
||||||
{
|
{
|
||||||
if (!sync_)
|
if (!parallel_)
|
||||||
{
|
{
|
||||||
if (current_)
|
if (current_)
|
||||||
{
|
{
|
||||||
|
|
@ -133,7 +133,7 @@ ActionPtr ActionGroup::Clone() const
|
||||||
actions.push_back(action->Clone());
|
actions.push_back(action->Clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DoClone(ActionGroup::Create(actions, sync_));
|
return DoClone(ActionGroup::Create(actions, parallel_));
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionPtr ActionGroup::Reverse() const
|
ActionPtr ActionGroup::Reverse() const
|
||||||
|
|
@ -146,7 +146,7 @@ ActionPtr ActionGroup::Reverse() const
|
||||||
actions.push_back(action->Reverse());
|
actions.push_back(action->Reverse());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DoClone(ActionGroup::Create(actions, sync_));
|
return DoClone(ActionGroup::Create(actions, parallel_));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,12 @@ public:
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 创建动画组合
|
/// @brief 创建动画组合
|
||||||
/// @param actions 动画集合
|
/// @param actions 动画集合
|
||||||
/// @param sync 同步执行
|
/// @param parallel 同步执行
|
||||||
static ActionGroupPtr Create(const Vector<ActionPtr>& actions, bool sync = false);
|
static ActionGroupPtr Create(const Vector<ActionPtr>& actions, bool parallel = false);
|
||||||
|
|
||||||
ActionGroup();
|
ActionGroup();
|
||||||
|
|
||||||
ActionGroup(bool sync);
|
ActionGroup(bool parallel);
|
||||||
|
|
||||||
virtual ~ActionGroup();
|
virtual ~ActionGroup();
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ protected:
|
||||||
void Update(Actor* target, Duration dt) override;
|
void Update(Actor* target, Duration dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool sync_;
|
bool parallel_;
|
||||||
ActionPtr current_;
|
ActionPtr current_;
|
||||||
ActionList actions_;
|
ActionList actions_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -359,10 +359,10 @@ public:
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 动画组合
|
/// @brief 动画组合
|
||||||
/// @param actions 动画集合
|
/// @param actions 动画集合
|
||||||
/// @param sync 同步执行
|
/// @param parallel 同步执行
|
||||||
static inline ActionHelper Group(const Vector<ActionPtr>& actions, bool sync = false)
|
static inline ActionHelper Group(const Vector<ActionPtr>& actions, bool parallel = false)
|
||||||
{
|
{
|
||||||
return ActionHelper(ActionGroup::Create(actions, sync));
|
return ActionHelper(ActionGroup::Create(actions, parallel));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,38 +31,52 @@ namespace strings
|
||||||
|
|
||||||
String Format(const char* format, ...)
|
String Format(const char* format, ...)
|
||||||
{
|
{
|
||||||
String result;
|
|
||||||
if (format)
|
|
||||||
{
|
|
||||||
va_list args = nullptr;
|
va_list args = nullptr;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
|
||||||
|
String result = FormatArgs(format, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WideString Format(const wchar_t* format, ...)
|
||||||
|
{
|
||||||
|
va_list args = nullptr;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
WideString result = FormatArgs(format, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String FormatArgs(const char* format, va_list args)
|
||||||
|
{
|
||||||
|
String result;
|
||||||
|
if (format)
|
||||||
|
{
|
||||||
const auto len = static_cast<size_t>(::_vscprintf(format, args) + 1);
|
const auto len = static_cast<size_t>(::_vscprintf(format, args) + 1);
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
result.resize(len - 1);
|
result.resize(len - 1);
|
||||||
::_vsnprintf_s(&result[0], len, len, format, args);
|
::_vsnprintf_s(&result[0], len, len, format, args);
|
||||||
}
|
}
|
||||||
va_end(args);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
WideString Format(const wchar_t* format, ...)
|
WideString FormatArgs(const wchar_t* format, va_list args)
|
||||||
{
|
{
|
||||||
WideString result;
|
WideString result;
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
va_list args = nullptr;
|
|
||||||
va_start(args, format);
|
|
||||||
|
|
||||||
const auto len = static_cast<size_t>(::_vscwprintf(format, args) + 1);
|
const auto len = static_cast<size_t>(::_vscwprintf(format, args) + 1);
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
result.resize(len - 1);
|
result.resize(len - 1);
|
||||||
::_vsnwprintf_s(&result[0], len, len, format, args);
|
::_vsnwprintf_s(&result[0], len, len, format, args);
|
||||||
}
|
}
|
||||||
va_end(args);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,14 @@ String Format(const char* format, ...);
|
||||||
/// @brief ¸ñʽ»¯×Ö·û´®
|
/// @brief ¸ñʽ»¯×Ö·û´®
|
||||||
WideString Format(const wchar_t* format, ...);
|
WideString Format(const wchar_t* format, ...);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief ¸ñʽ»¯×Ö·û´®
|
||||||
|
String FormatArgs(const char* format, va_list args);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief ¸ñʽ»¯×Ö·û´®
|
||||||
|
WideString FormatArgs(const wchar_t* format, va_list args);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief ¿í×Ö·û´®×ªÕ×Ö·û´®
|
/// @brief ¿í×Ö·û´®×ªÕ×Ö·û´®
|
||||||
String WideToNarrow(const WideString& str);
|
String WideToNarrow(const WideString& str);
|
||||||
|
|
|
||||||
|
|
@ -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,563 @@
|
||||||
// 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
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// LogFormater
|
||||||
|
//
|
||||||
|
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::~LogProvider() {}
|
||||||
|
|
||||||
|
#if defined(KGE_PLATFORM_WINDOWS)
|
||||||
|
void SetWindowConsoleColor(std::ostream& os, int foreground, int background)
|
||||||
|
{
|
||||||
|
static WORD defaultAttributes = 0;
|
||||||
|
|
||||||
|
// get terminal handle
|
||||||
|
HANDLE hTerminal = INVALID_HANDLE_VALUE;
|
||||||
|
if (&os == &std::cout)
|
||||||
|
hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
else if (&os == &std::cerr)
|
||||||
|
hTerminal = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
|
||||||
|
if (hTerminal == INVALID_HANDLE_VALUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// save default terminal attributes if it unsaved
|
||||||
|
if (!defaultAttributes)
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
||||||
|
return;
|
||||||
|
defaultAttributes = info.wAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore all default settings
|
||||||
|
if (foreground == -1 && background == -1)
|
||||||
|
{
|
||||||
|
SetConsoleTextAttribute(hTerminal, defaultAttributes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get current settings
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (foreground != -1)
|
||||||
|
{
|
||||||
|
info.wAttributes &= ~(info.wAttributes & 0x0F);
|
||||||
|
info.wAttributes |= static_cast<WORD>(foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (background != -1)
|
||||||
|
{
|
||||||
|
info.wAttributes &= ~(info.wAttributes & 0xF0);
|
||||||
|
info.wAttributes |= static_cast<WORD>(background);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hTerminal, info.wAttributes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <int color>
|
||||||
|
std::ostream& ConsoleColorBrush(std::ostream& os)
|
||||||
|
{
|
||||||
|
#if defined(KGE_PLATFORM_WINDOWS)
|
||||||
|
if (color > 0)
|
||||||
|
{
|
||||||
|
switch (color)
|
||||||
|
{
|
||||||
|
case 31: // red
|
||||||
|
SetWindowConsoleColor(os, FOREGROUND_RED | FOREGROUND_INTENSITY, -1);
|
||||||
|
break;
|
||||||
|
case 32: // green
|
||||||
|
SetWindowConsoleColor(os, FOREGROUND_GREEN | FOREGROUND_INTENSITY, -1);
|
||||||
|
break;
|
||||||
|
case 33: // yellow
|
||||||
|
SetWindowConsoleColor(os, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, -1);
|
||||||
|
break;
|
||||||
|
case 34: // blue
|
||||||
|
SetWindowConsoleColor(os, FOREGROUND_BLUE | FOREGROUND_INTENSITY, -1);
|
||||||
|
break;
|
||||||
|
case 36: // cyan
|
||||||
|
SetWindowConsoleColor(os, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY, -1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (color < 0)
|
||||||
|
{
|
||||||
|
SetWindowConsoleColor(os, -1, -1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (color > 0)
|
||||||
|
{
|
||||||
|
os << "\033[1;" << color << "m";
|
||||||
|
}
|
||||||
|
else if (color < 0)
|
||||||
|
{
|
||||||
|
os << "\033[0m";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 << GetColor(level) << msg << std::flush << ConsoleColorBrush<-1>;
|
||||||
|
else
|
||||||
|
std::cerr << GetColor(level) << msg << ConsoleColorBrush<-1>;
|
||||||
|
|
||||||
|
#if defined(KGE_PLATFORM_WINDOWS)
|
||||||
|
::OutputDebugStringA(msg->GetRaw());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleLogProvider::Flush()
|
||||||
|
{
|
||||||
|
std::cout.flush();
|
||||||
|
std::cout.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleLogProvider::ConsoleColor ConsoleLogProvider::GetColor(LogLevel level)
|
||||||
|
{
|
||||||
|
std::initializer_list<ConsoleColor> colors = {
|
||||||
|
ConsoleColorBrush<34>, // Debug Blue
|
||||||
|
ConsoleColorBrush<0>, // Info Default
|
||||||
|
ConsoleColorBrush<32>, // Notice Green
|
||||||
|
ConsoleColorBrush<33>, // Warn Yellow
|
||||||
|
ConsoleColorBrush<31>, // Error Red
|
||||||
|
};
|
||||||
|
|
||||||
|
if (size_t(level) < colors.size())
|
||||||
|
return *std::next(colors.begin(), ptrdiff_t(level));
|
||||||
|
return ConsoleColorBrush<0>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
ofs_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// LogBuffer
|
||||||
|
//
|
||||||
|
LogBuffer::LogBuffer(size_t buffer_size)
|
||||||
|
: buf_(buffer_size)
|
||||||
|
, seek_high_(nullptr)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogBuffer::Resize(size_t size)
|
||||||
|
{
|
||||||
|
if (buf_.size() < size)
|
||||||
|
{
|
||||||
|
buf_.resize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogBuffer::Reset()
|
||||||
|
{
|
||||||
|
const auto begin = buf_.data();
|
||||||
|
const auto size = buf_.size();
|
||||||
|
this->setp(begin, begin + size);
|
||||||
|
this->setg(begin, begin, begin);
|
||||||
|
seek_high_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 pos, std::ios_base::openmode mode)
|
||||||
|
{
|
||||||
|
const auto offset = static_cast<std::streamoff>(pos);
|
||||||
|
const auto old_gptr = this->gptr();
|
||||||
|
const auto olg_pptr = this->pptr();
|
||||||
|
if (olg_pptr && seek_high_ < olg_pptr)
|
||||||
|
{
|
||||||
|
seek_high_ = olg_pptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto seek_low = this->eback();
|
||||||
|
const auto seek_dist = seek_high_ - seek_low;
|
||||||
|
if (static_cast<unsigned long long>(offset) > static_cast<unsigned long long>(seek_dist))
|
||||||
|
{
|
||||||
|
return pos_type(off_type(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset != 0 && (((mode & std::ios_base::in) && !old_gptr) || ((mode & std::ios_base::out) && !olg_pptr)))
|
||||||
|
{
|
||||||
|
return pos_type(off_type(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto new_ptr = seek_low + offset;
|
||||||
|
if ((mode & std::ios_base::in) && old_gptr)
|
||||||
|
{
|
||||||
|
this->setg(seek_low, new_ptr, seek_high_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode & std::ios_base::out) && olg_pptr)
|
||||||
|
{
|
||||||
|
this->setp(seek_low, new_ptr, this->epptr());
|
||||||
|
}
|
||||||
|
return pos_type(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogBuffer::pos_type LogBuffer::seekoff(off_type offset, std::ios_base::seekdir way, std::ios_base::openmode mode)
|
||||||
|
{
|
||||||
|
const auto old_gptr = this->gptr();
|
||||||
|
const auto old_pptr = this->pptr();
|
||||||
|
if (old_pptr && seek_high_ < old_pptr)
|
||||||
|
{
|
||||||
|
seek_high_ = old_pptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto seek_low = this->eback();
|
||||||
|
const auto seek_dist = seek_high_ - seek_low;
|
||||||
|
off_type new_offset;
|
||||||
|
switch (way)
|
||||||
|
{
|
||||||
|
case std::ios_base::beg:
|
||||||
|
new_offset = 0;
|
||||||
|
break;
|
||||||
|
case std::ios_base::end:
|
||||||
|
new_offset = seek_dist;
|
||||||
|
break;
|
||||||
|
case std::ios_base::cur:
|
||||||
|
{
|
||||||
|
constexpr auto both = std::ios_base::in | std::ios_base::out;
|
||||||
|
if ((mode & both) != both)
|
||||||
|
{
|
||||||
|
if (mode & std::ios_base::in)
|
||||||
|
{
|
||||||
|
if (old_gptr || !seek_low)
|
||||||
|
{
|
||||||
|
new_offset = old_gptr - seek_low;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((mode & std::ios_base::out) && (old_pptr || !seek_low))
|
||||||
|
{
|
||||||
|
new_offset = old_pptr - seek_low;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallthrough
|
||||||
|
default:
|
||||||
|
return pos_type(off_type(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::streamsize(offset) + new_offset > std::streamsize(seek_dist))
|
||||||
|
{
|
||||||
|
return pos_type(off_type(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += new_offset;
|
||||||
|
if (offset != 0 && (((mode & std::ios_base::in) && !old_gptr) || ((mode & std::ios_base::out) && !old_pptr)))
|
||||||
|
{
|
||||||
|
return pos_type(off_type(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto new_ptr = seek_low + offset;
|
||||||
|
if ((mode & std::ios_base::in) && old_gptr)
|
||||||
|
{
|
||||||
|
this->setg(seek_low, new_ptr, seek_high_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode & std::ios_base::out) && old_pptr)
|
||||||
|
{
|
||||||
|
this->setp(seek_low, new_ptr, this->epptr());
|
||||||
|
}
|
||||||
|
return pos_type(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Logger
|
||||||
|
//
|
||||||
|
Logger::Logger()
|
||||||
|
: enabled_(true)
|
||||||
|
, level_(LogLevel::Debug)
|
||||||
|
, buffer_(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_);
|
||||||
|
|
||||||
|
// reset buffer
|
||||||
|
buffer_.Reset();
|
||||||
|
|
||||||
|
// format message
|
||||||
|
std::iostream stream(&buffer_);
|
||||||
|
if (formater_)
|
||||||
|
{
|
||||||
|
formater_->Format(stream, level, Time::Now(), raw_msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream << raw_msg << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// write message
|
||||||
|
for (auto provider : providers_)
|
||||||
|
{
|
||||||
|
buffer_.pubseekpos(0, std::ios_base::in);
|
||||||
|
provider->WriteMessage(level, &buffer_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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,204 +674,11 @@ HWND GetAllocatedConsole()
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace kiwano
|
#endif
|
||||||
{
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
#if defined(KGE_PLATFORM_WINDOWS)
|
||||||
HWND current_console = ::GetConsoleWindow();
|
HWND current_console = ::GetConsoleWindow();
|
||||||
if (show)
|
if (show)
|
||||||
{
|
{
|
||||||
|
|
@ -328,14 +688,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);
|
||||||
|
|
@ -357,6 +716,10 @@ void Logger::ShowConsole(bool show)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// NOT IMPLEMENT
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -19,83 +19,212 @@
|
||||||
// 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(size_t buffer_size);
|
||||||
|
|
||||||
|
void Resize(size_t size);
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
const char* GetRaw() const;
|
||||||
|
|
||||||
|
LogBuffer(const LogBuffer&) = delete;
|
||||||
|
|
||||||
|
LogBuffer& operator=(const LogBuffer&) = delete;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::ostream&(*ConsoleColor)(std::ostream&);
|
||||||
|
|
||||||
|
ConsoleColor GetColor(LogLevel level);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~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 +235,51 @@ 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);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 显示或关闭控制台
|
/// @brief 显示或关闭控制台
|
||||||
/// @note 此操作会重定向输出流到标准输出流
|
|
||||||
void ShowConsole(bool show);
|
void ShowConsole(bool show);
|
||||||
|
|
||||||
~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_;
|
||||||
|
LogBuffer buffer_;
|
||||||
OutputStream output_stream_;
|
Vector<LogProviderPtr> providers_;
|
||||||
OutputStream error_stream_;
|
std::mutex mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void Logger::Enable()
|
inline void Logger::Enable()
|
||||||
|
|
@ -160,57 +292,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