Update Logger & Timer

This commit is contained in:
Nomango 2019-12-25 18:07:57 +08:00
parent 5ba5e4525c
commit 11c43a0731
32 changed files with 725 additions and 498 deletions

View File

@ -38,7 +38,7 @@
<ClInclude Include="..\..\src\kiwano\core\keys.h" />
<ClInclude Include="..\..\src\kiwano\core\Logger.h" />
<ClInclude Include="..\..\src\kiwano\core\ObjectBase.h" />
<ClInclude Include="..\..\src\kiwano\core\RefCounter.hpp" />
<ClInclude Include="..\..\src\kiwano\core\RefCounter.h" />
<ClInclude Include="..\..\src\kiwano\core\Resource.h" />
<ClInclude Include="..\..\src\kiwano\core\SmartPtr.hpp" />
<ClInclude Include="..\..\src\kiwano\core\Timer.h" />
@ -112,6 +112,7 @@
<ClCompile Include="..\..\src\kiwano\core\Library.cpp" />
<ClCompile Include="..\..\src\kiwano\core\Logger.cpp" />
<ClCompile Include="..\..\src\kiwano\core\ObjectBase.cpp" />
<ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp" />
<ClCompile Include="..\..\src\kiwano\core\Resource.cpp" />
<ClCompile Include="..\..\src\kiwano\core\Timer.cpp" />
<ClCompile Include="..\..\src\kiwano\core\TimerManager.cpp" />

View File

@ -63,9 +63,6 @@
<ClInclude Include="..\..\src\kiwano\core\EventListener.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\RefCounter.hpp">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Resource.h">
<Filter>core</Filter>
</ClInclude>
@ -270,6 +267,9 @@
<ClInclude Include="..\..\src\kiwano\core\common.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\RefCounter.h">
<Filter>core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp">
@ -452,5 +452,8 @@
<ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp">
<Filter>2d</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\RefCounter.cpp">
<Filter>core</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -38,7 +38,7 @@ namespace kiwano
void AudioEngine::SetupComponent()
{
// KGE_LOG(L"Creating audio resources");
// KGE_SYS_LOG(L"Creating audio resources");
HRESULT hr = modules::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
@ -57,7 +57,7 @@ namespace kiwano
void AudioEngine::DestroyComponent()
{
// KGE_LOG(L"Destroying audio resources");
// KGE_SYS_LOG(L"Destroying audio resources");
if (mastering_voice_)
{

View File

@ -78,7 +78,7 @@ namespace kiwano
}
else
{
KGE_LOG(L"Load Mfplat.dll failed");
KGE_SYS_LOG(L"Load Mfplat.dll failed");
throw std::runtime_error("Load Mfplat.dll failed");
}
@ -89,7 +89,7 @@ namespace kiwano
}
else
{
KGE_LOG(L"Load Mfreadwrite.dll failed");
KGE_SYS_LOG(L"Load Mfreadwrite.dll failed");
throw std::runtime_error("Load Mfreadwrite.dll failed");
}
}

View File

@ -103,7 +103,7 @@ namespace kiwano
#if defined(KGE_DEBUG)
if (ObjectBase::IsTracingLeaks())
{
ss << "Objects: " << ObjectBase::__GetTracingObjects().size() << std::endl;
ss << "Objects: " << ObjectBase::GetTracingObjects().size() << std::endl;
}
#endif

View File

@ -43,7 +43,7 @@ namespace kiwano
public:
/// \~chinese
/// @brief GIF²¥·ÅÑ­»·½áÊø»Øµ÷
using LoopDoneCallback = Function<void(int)>;
using LoopDoneCallback = Function<void(int /* times */)>;
/// \~chinese
/// @brief GIF²¥·Å½áÊø»Øµ÷

View File

@ -38,12 +38,12 @@ namespace kiwano
void Stage::OnEnter()
{
// KGE_LOG(L"Stage entered");
// KGE_SYS_LOG(L"Stage entered");
}
void Stage::OnExit()
{
// KGE_LOG(L"Stage exited");
// KGE_SYS_LOG(L"Stage exited");
}
}

View File

@ -47,6 +47,8 @@ namespace kiwano
void Action::UpdateStep(Actor* target, Duration dt)
{
KGE_ASSERT(target != nullptr && "Action target should NOT be nullptr!");
elapsed_ += dt;
if (status_ == Status::NotStarted)
@ -72,7 +74,7 @@ namespace kiwano
if (status_ == Status::Done)
{
if (cb_done_)
cb_done_();
cb_done_(target);
if (detach_target_)
target->RemoveFromParent();
@ -84,7 +86,7 @@ namespace kiwano
void Action::Complete(Actor* target)
{
if (cb_loop_done_)
cb_loop_done_();
cb_loop_done_(target);
if (loops_ >= 0
&& loops_done_ >= loops_)

View File

@ -55,7 +55,7 @@ namespace kiwano
public:
/// \~chinese
/// @brief 动画结束时的回调函数
using DoneCallback = Function<void()>;
using DoneCallback = Function<void(Actor* /* target */)>;
Action();

View File

@ -28,39 +28,47 @@ namespace kiwano
* @{
*/
/**
* \~chinese
* @brief
*/
class KGE_API ActionManager
{
public:
using Actions = IntrusiveList<ActionPtr>;
public:
// 添加动画
Action* AddAction(
ActionPtr action
);
/// \~chinese
/// @brief 添加动画
Action* AddAction(ActionPtr action);
// 添加动画
Action* AddAction(
Action* action
);
/// \~chinese
/// @brief 添加动画
Action* AddAction(Action* action);
// 获取动画
Action* GetAction(
String const& name
);
/// \~chinese
/// @brief 获取指定名称的动画
/// @param name 动画名称
Action* GetAction(String const& name);
// 继续所有暂停动画
/// \~chinese
/// @brief 继续所有暂停动画
void ResumeAllActions();
// 暂停所有动画
/// \~chinese
/// @brief 暂停所有动画
void PauseAllActions();
// 停止所有动画
/// \~chinese
/// @brief 停止所有动画
void StopAllActions();
// 获取所有动画
/// \~chinese
/// @brief 获取所有动画
Actions const& GetAllActions() const;
protected:
/// \~chinese
/// @brief 更新动画
void UpdateActions(Actor* target, Duration dt);
private:

View File

@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <functional>
#include <kiwano/2d/action/ActionTween.h>
#include <kiwano/2d/Actor.h>

View File

@ -475,7 +475,7 @@ namespace kiwano
/// \~chinese
/// @brief 动画回调函数
/// @details 在动画更新时回调该函数第一个参数是执行动画的目标第二个参数是动画进度0.0 - 1.0
using TweenFunc = Function<void(Actor*, float)>;
using TweenFunc = Function<void(Actor* /* target */, float /* percent */)>;
/// \~chinese
/// @brief 构造自定义动画

View File

@ -9,7 +9,7 @@
//#define KGE_ASSERT(EXPR) __noop // Disable asserts
//---- Define debug-output handler. Defaults to calling kiwano::logs::Messageln()/Warningln()/Errorln()
//#define KGE_LOG(FORMAT, ...) wprintf(FORMAT L"\n", __VA_ARGS__)
//#define KGE_SYS_LOG(FORMAT, ...) wprintf(FORMAT L"\n", __VA_ARGS__)
//#define KGE_WARN(FORMAT, ...) wprintf(FORMAT L"\n", __VA_ARGS__)
//#define KGE_ERROR(FORMAT, ...) wprintf(FORMAT L"\n", __VA_ARGS__)

View File

@ -122,7 +122,7 @@ namespace kiwano
virtual void HandleEvent(Event& evt) {}
/// \~chinese
/// @brief Windows 消息处理
/// @brief 处理 Windows 消息
virtual void HandleMessage(HWND, UINT32, WPARAM, LPARAM) {}
public:

View File

@ -104,7 +104,7 @@ namespace kiwano
>
inline const _Ty& Cast() const
{
return *dynamic_cast<const _Ty*>(this);
return dynamic_cast<const _Ty&>(*this);
}
/// \~chinese
@ -116,7 +116,7 @@ namespace kiwano
>
inline _Ty& Cast()
{
return *dynamic_cast<_Ty*>(this);
return dynamic_cast<_Ty&>(*this);
}
/// \~chinese

View File

@ -20,6 +20,7 @@
#include <iostream>
#include <fstream>
#include <ctime>
#include <kiwano/core/Logger.h>
@ -109,25 +110,29 @@ namespace
namespace kiwano
{
namespace __console_colors
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 = 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 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;
const WORD reset = white;
}
#define DECLARE_HANDLE_COLOR(NAME, HANDLE_NAME, COLOR)\
inline std::wostream& (NAME)(std::wostream& _out)\
{ ::SetConsoleTextAttribute(::GetStdHandle(HANDLE_NAME), _##COLOR); return _out; }
{\
::SetConsoleTextAttribute(::GetStdHandle(HANDLE_NAME), console_colors::##COLOR);\
return _out;\
}
#define DECLARE_COLOR(COLOR) \
DECLARE_HANDLE_COLOR(stdout_##COLOR, STD_OUTPUT_HANDLE, COLOR)\
@ -137,6 +142,8 @@ namespace kiwano
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);
@ -149,9 +156,6 @@ namespace kiwano
DECLARE_BG_COLOR(yellow);
DECLARE_BG_COLOR(blue);
DECLARE_BG_COLOR(white);
#undef DECLARE_COLOR
#undef DECLARE_BG_COLOR
}
Logger::Logger()
@ -169,6 +173,98 @@ namespace kiwano
FreeAllocatedConsole();
}
void Logger::Printf(Level level, const wchar_t* format, ...)
{
if (!enabled_)
return;
StringStream sstream;
Prepare(level, sstream);
// Format message
if (format)
{
va_list args = nullptr;
va_start(args, format);
static wchar_t temp_buffer[1024 * 3 + 1];
const auto len = ::_vscwprintf(format, args) + 1;
::_vsnwprintf_s(temp_buffer, len, len, format, args);
sstream << ' ' << temp_buffer << L"\r\n";
va_end(args);
}
Output(level, sstream);
}
void Logger::Prepare(Level level, StringStream& sstream)
{
String prompt;
switch (level)
{
case Level::Info:
prompt = L"[INFO] ";
break;
case Level::System:
prompt = L"[SYSTEM] ";
break;
case Level::Warning:
prompt = L"[WARNING] ";
break;
case Level::Error:
prompt = L"[ERROR] ";
break;
}
// Prefix
sstream << L"[KIWANO] " << prompt;
// Timestamp
time_t unix = std::time(nullptr);
std::tm tmbuf;
localtime_s(&tmbuf, &unix);
sstream << std::put_time(&tmbuf, L"%H:%M:%S ");
}
void Logger::Output(Level level, StringStream& sstream)
{
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;
::OutputDebugStringW(output.c_str());
ResetConsoleColor();
}
}
void Logger::ResetOutputStream()
{
bool has_console = ::GetConsoleWindow() != nullptr;
@ -208,96 +304,6 @@ namespace kiwano
return error_stream_.rdbuf(buf);
}
void Logger::Printf(const wchar_t* format, ...)
{
va_list args = nullptr;
va_start(args, format);
Outputf(output_stream_, Logger::DefaultOutputColor, nullptr, format, args);
va_end(args);
}
void Logger::Messagef(const wchar_t* format, ...)
{
using namespace __console_colors;
va_list args = nullptr;
va_start(args, format);
Outputf(output_stream_, stdout_blue, nullptr, format, args);
va_end(args);
}
void Logger::Warningf(const wchar_t* format, ...)
{
using namespace __console_colors;
va_list args = nullptr;
va_start(args, format);
Outputf(output_stream_, stdout_yellow_bg, L" Warning:", format, args);
va_end(args);
}
void Logger::Errorf(const wchar_t* format, ...)
{
using namespace __console_colors;
va_list args = nullptr;
va_start(args, format);
Outputf(error_stream_, stderr_red_bg, L" Error:", format, args);
va_end(args);
}
void Logger::Outputf(std::wostream& os, std::wostream& (*color)(std::wostream&), const wchar_t* prompt, const wchar_t* format, va_list args) const
{
if (enabled_)
{
std::wstring output = MakeOutputStringf(prompt, format, args);
os << color << output << std::flush;
::OutputDebugStringW(output.c_str());
ResetConsoleColor();
}
}
std::wstring Logger::MakeOutputStringf(const wchar_t* prompt, const wchar_t* format, va_list args) const
{
static wchar_t temp_buffer[1024 * 3 + 1];
StringStream ss;
ss << Logger::OutPrefix;
if (prompt)
ss << prompt;
if (format)
{
const auto len = ::_vscwprintf(format, args) + 1;
::_vsnwprintf_s(temp_buffer, len, len, format, args);
ss << ' ' << temp_buffer;
}
return ss.str();
}
std::wostream& Logger::OutPrefix(std::wostream& out)
{
out << L"[KIWANO] ";
time_t unix = std::time(nullptr);
std::tm tmbuf;
localtime_s(&tmbuf, &unix);
out << std::put_time(&tmbuf, L"%H:%M:%S");
return out;
}
void Logger::ShowConsole(bool show)
{
HWND current_console = ::GetConsoleWindow();

View File

@ -19,94 +19,115 @@
// THE SOFTWARE.
#pragma once
#include <ctime>
#include <iomanip>
#include <sstream>
#include <kiwano/macros.h>
#include <kiwano/core/common.h>
#ifndef KGE_LOG
#ifndef KGE_SYS_LOG
# ifdef KGE_DEBUG
# define KGE_LOG(FORMAT, ...) ::kiwano::Logger::instance().Messagef((FORMAT ## "\n"), __VA_ARGS__)
# define KGE_SYS_LOG(FORMAT, ...) ::kiwano::Logger::instance().Printf(::kiwano::Logger::Level::System, FORMAT, __VA_ARGS__)
# else
# define KGE_LOG __noop
# define KGE_SYS_LOG __noop
# endif
#endif
#ifndef KGE_WARN
# define KGE_WARN(FORMAT, ...) ::kiwano::Logger::instance().Warningf((FORMAT ## "\n"), __VA_ARGS__)
# define KGE_WARN(FORMAT, ...) ::kiwano::Logger::instance().Printf(::kiwano::Logger::Level::Warning, FORMAT, __VA_ARGS__)
#endif
#ifndef KGE_ERROR
# define KGE_ERROR(FORMAT, ...) ::kiwano::Logger::instance().Errorf((FORMAT ## "\n"), __VA_ARGS__)
# define KGE_ERROR(FORMAT, ...) ::kiwano::Logger::instance().Printf(::kiwano::Logger::Level::Error, FORMAT, __VA_ARGS__)
#endif
#ifndef KGE_PRINT
# define KGE_PRINT(...) ::kiwano::Logger::instance().Println(__VA_ARGS__)
#ifndef KGE_LOG
# define KGE_LOG(...) ::kiwano::Logger::instance().Println(::kiwano::Logger::Level::Info, __VA_ARGS__)
#endif
#ifndef KGE_PRINTF
# define KGE_PRINTF(FORMAT, ...) ::kiwano::Logger::instance().Printf((FORMAT), __VA_ARGS__)
#ifndef KGE_LOGF
# define KGE_LOGF(FORMAT, ...) ::kiwano::Logger::instance().Printf(::kiwano::Logger::Level::Info, FORMAT, __VA_ARGS__)
#endif
namespace kiwano
{
/**
* \~chinese
* @brief
*/
class KGE_API Logger
: public Singleton<Logger>
{
friend Singleton<Logger>;
public:
// 显示或关闭控制台
/// \~chinese
/// @brief 日志级别
enum class Level
{
Info, ///< 信息
System, ///< 系统
Warning, ///< 警告
Error ///< 错误
};
/// \~chinese
/// @brief 输出流
using OutputStream = std::wostream;
/// \~chinese
/// @brief 控制台颜色
using ConsoleColor = Function<OutputStream& (OutputStream&)>;
/// \~chinese
/// @brief 显示或关闭控制台
void ShowConsole(bool show);
// 启用 Logger
/// \~chinese
/// @brief 启用日志
void Enable();
// 禁用 Logger
/// \~chinese
/// @brief 禁用日志
void Disable();
void Printf(const wchar_t* format, ...);
void Messagef(const wchar_t * format, ...);
void Warningf(const wchar_t* format, ...);
void Errorf(const wchar_t* format, ...);
/// \~chinese
/// @brief 打印日志
/// @param level 日志级别
/// @param format 格式字符串
void Printf(Level level, const wchar_t* format, ...);
/// \~chinese
/// @brief 打印日志
/// @param level 日志级别
/// @param args 参数
template <typename ..._Args>
void Print(_Args&& ... args);
void Print(Level level, _Args&& ... args);
/// \~chinese
/// @brief 打印一行日志
/// @param level 日志级别
/// @param args 参数
template <typename ..._Args>
void Println(_Args&& ... args);
template <typename ..._Args>
void Message(_Args&& ... args);
template <typename ..._Args>
void Messageln(_Args&& ... args);
template <typename ..._Args>
void Warning(_Args&& ... args);
template <typename ..._Args>
void Warningln(_Args&& ... args);
template <typename ..._Args>
void Error(_Args&& ... args);
template <typename ..._Args>
void Errorln(_Args&& ... args);
void Println(Level level, _Args&& ... args);
/// \~chinese
/// @brief 获取输出流
std::wostream& GetOutputStream();
/// \~chinese
/// @brief 获取错误流
std::wostream& GetErrorStream();
/// \~chinese
/// @brief 重定向输出流
std::wstreambuf* RedirectOutputStreamBuffer(std::wstreambuf* buf);
/// \~chinese
/// @brief 重定向错误流
std::wstreambuf* RedirectErrorStreamBuffer(std::wstreambuf* buf);
/// \~chinese
/// @brief 重置输出流
void ResetOutputStream();
private:
@ -114,76 +135,24 @@ namespace kiwano
~Logger();
//
// output functions
//
void Outputf(std::wostream& os, std::wostream&(*color)(std::wostream&), const wchar_t* prompt, const wchar_t* format, va_list args) const;
void Prepare(Level level, StringStream& sstream);
template <typename ..._Args>
void OutputLine(std::wostream& os, std::wostream& (*color)(std::wostream&), const wchar_t* prompt, _Args&& ... args) const;
void Output(Level level, StringStream& sstream);
template <typename ..._Args>
void Output(std::wostream& os, std::wostream& (*color)(std::wostream&), const wchar_t* prompt, _Args&& ... args) const;
static std::wostream& OutPrefix(std::wostream& out);
//
// make string
//
std::wstring MakeOutputStringf(const wchar_t* prompt, const wchar_t* format, va_list args) const;
template <typename ..._Args>
std::wstring MakeOutputString(const wchar_t* prompt, _Args&& ... args) const;
//
// reset functions
//
void ResetConsoleColor() const;
static std::wostream& DefaultOutputColor(std::wostream& out);
OutputStream& DefaultOutputColor(OutputStream& out);
private:
bool enabled_;
WORD default_stdout_color_;
WORD default_stderr_color_;
std::wostream output_stream_;
std::wostream error_stream_;
OutputStream output_stream_;
OutputStream error_stream_;
};
//
// details of Logger
//
namespace __console_colors
{
#define DECLARE_COLOR(COLOR)\
extern std::wostream&(stdout_##COLOR)(std::wostream&);\
extern std::wostream&(stderr_##COLOR)(std::wostream&);
#define DECLARE_BG_COLOR(COLOR)\
extern std::wostream&(stdout_##COLOR##_bg)(std::wostream&);\
extern std::wostream&(stderr_##COLOR##_bg)(std::wostream&);
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);
#undef DECLARE_COLOR
#undef DECLARE_BG_COLOR
}
inline void Logger::Enable()
{
enabled_ = true;
@ -195,97 +164,35 @@ namespace kiwano
}
template <typename ..._Args>
inline void Logger::Print(_Args&& ... args)
void Logger::Print(Level level, _Args&& ... args)
{
Output(output_stream_, Logger::DefaultOutputColor, nullptr, std::forward<_Args>(args)...);
if (!enabled_)
return;
StringStream sstream;
Prepare(level, sstream);
// Format message
(void)std::initializer_list<int>{((sstream << ' ' << args), 0)...};
Output(level, sstream);
}
template <typename ..._Args>
inline void Logger::Println(_Args&& ... args)
void Logger::Println(Level level, _Args&& ... args)
{
OutputLine(output_stream_, Logger::DefaultOutputColor, nullptr, std::forward<_Args>(args)...);
}
if (!enabled_)
return;
template <typename ..._Args>
inline void Logger::Message(_Args&& ... args)
{
using namespace __console_colors;
Output(output_stream_, stdout_blue, nullptr, std::forward<_Args>(args)...);
}
StringStream sstream;
Prepare(level, sstream);
template <typename ..._Args>
inline void Logger::Messageln(_Args&& ... args)
{
using namespace __console_colors;
OutputLine(output_stream_, stdout_blue, nullptr, std::forward<_Args>(args)...);
}
// Format message
(void)std::initializer_list<int>{((sstream << ' ' << args), 0)...};
template <typename ..._Args>
inline void Logger::Warning(_Args&& ... args)
{
using namespace __console_colors;
Output(output_stream_, stdout_yellow_bg, L"Warning:", std::forward<_Args>(args)...);
}
sstream << L"\r\n";
template <typename ..._Args>
inline void Logger::Warningln(_Args&& ... args)
{
using namespace __console_colors;
OutputLine(output_stream_, stdout_yellow_bg, L"Warning:", std::forward<_Args>(args)...);
}
template <typename ..._Args>
inline void Logger::Error(_Args&& ... args)
{
using namespace __console_colors;
Output(error_stream_, stderr_red_bg, L"Error:", std::forward<_Args>(args)...);
}
template <typename ..._Args>
inline void Logger::Errorln(_Args&& ... args)
{
using namespace __console_colors;
OutputLine(error_stream_, stderr_red_bg, L"Error:", std::forward<_Args>(args)...);
}
template <typename ..._Args>
void Logger::OutputLine(std::wostream& os, std::wostream& (*color)(std::wostream&), const wchar_t* prompt, _Args&& ... args) const
{
if (enabled_)
{
Output(os, color, prompt, std::forward<_Args>(args)...);
os << std::endl;
::OutputDebugStringW(L"\r\n");
}
}
template <typename ..._Args>
void Logger::Output(std::wostream& os, std::wostream& (*color)(std::wostream&), const wchar_t* prompt, _Args&& ... args) const
{
if (enabled_)
{
std::wstring output = MakeOutputString(prompt, std::forward<_Args>(args)...);
os << color << output << std::flush;
::OutputDebugStringW(output.c_str());
ResetConsoleColor();
}
}
template <typename ..._Args>
std::wstring Logger::MakeOutputString(const wchar_t* prompt, _Args&& ... args) const
{
StringStream ss;
ss << Logger::OutPrefix;
if (prompt)
ss << prompt;
(void)std::initializer_list<int>{((ss << ' ' << args), 0)...};
return ss.str();
Output(level, sstream);
}
inline void Logger::ResetConsoleColor() const
@ -294,9 +201,9 @@ namespace kiwano
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), default_stderr_color_);
}
inline std::wostream& Logger::DefaultOutputColor(std::wostream& out)
inline Logger::OutputStream& Logger::DefaultOutputColor(OutputStream& out)
{
::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::instance().default_stdout_color_);
::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), default_stdout_color_);
return out;
}

View File

@ -28,32 +28,30 @@ namespace kiwano
{
bool tracing_leaks = false;
Vector<ObjectBase*> tracing_objects;
uint32_t last_object_id = 0;
}
uint32_t ObjectBase::last_object_id = 0;
ObjectBase::ObjectBase()
: tracing_leak_(false)
, user_data_(nullptr)
, user_data_()
, name_(nullptr)
, id_(++last_object_id)
{
#ifdef KGE_DEBUG
ObjectBase::__AddObjectToTracingList(this);
ObjectBase::AddObjectToTracingList(this);
#endif
}
ObjectBase::~ObjectBase()
{
if (name_)
{
delete name_;
name_ = nullptr;
}
#ifdef KGE_DEBUG
ObjectBase::__RemoveObjectFromTracingList(this);
ObjectBase::RemoveObjectFromTracingList(this);
#endif
}
@ -112,36 +110,33 @@ namespace kiwano
void ObjectBase::DumpTracingObjects()
{
KGE_LOG(L"-------------------------- All Objects --------------------------");
KGE_SYS_LOG(L"-------------------------- All Objects --------------------------");
for (const auto object : tracing_objects)
{
KGE_LOG(L"%s", object->DumpObject().c_str());
KGE_SYS_LOG(L"%s", object->DumpObject().c_str());
}
KGE_LOG(L"------------------------- Total size: %d -------------------------", tracing_objects.size());
KGE_SYS_LOG(L"------------------------- Total size: %d -------------------------", tracing_objects.size());
}
Vector<ObjectBase*>& kiwano::ObjectBase::__GetTracingObjects()
Vector<ObjectBase*>& ObjectBase::GetTracingObjects()
{
return tracing_objects;
}
void ObjectBase::__AddObjectToTracingList(ObjectBase * obj)
void ObjectBase::AddObjectToTracingList(ObjectBase * obj)
{
#ifdef KGE_DEBUG
if (tracing_leaks && !obj->tracing_leak_)
{
obj->tracing_leak_ = true;
tracing_objects.push_back(obj);
}
#endif
}
void ObjectBase::__RemoveObjectFromTracingList(ObjectBase * obj)
void ObjectBase::RemoveObjectFromTracingList(ObjectBase * obj)
{
#ifdef KGE_DEBUG
if (tracing_leaks && obj->tracing_leak_)
{
obj->tracing_leak_ = false;
@ -152,7 +147,6 @@ namespace kiwano
tracing_objects.erase(iter);
}
}
#endif
}

View File

@ -21,34 +21,55 @@
#pragma once
#include <kiwano/macros.h>
#include <kiwano/core/common.h>
#include <kiwano/core/RefCounter.hpp>
#include <kiwano/core/RefCounter.h>
#include <kiwano/core/SmartPtr.hpp>
namespace kiwano
{
KGE_DECLARE_SMART_PTR(ObjectBase);
/**
* \~chinese
* @brief
*/
class KGE_API ObjectBase
: public virtual RefCounter
{
public:
/// \~chinese
/// @brief 构造基础对象
ObjectBase();
virtual ~ObjectBase();
const Any& GetUserData() const;
/// \~chinese
/// @brief 设置对象名
void SetName(String const& name);
void SetUserData(Any const& data);
/// \~chinese
/// @brief 获取对象名
String GetName() const;
void SetName(String const& name);
/// \~chinese
/// @brief 判断对象的名称是否相同
/// @param name 需要判断的名称
bool IsName(String const& name) const;
String DumpObject();
/// \~chinese
/// @brief 获取用户数据
const Any& GetUserData() const;
inline String GetName() const { if (name_) return *name_; return String(); }
/// \~chinese
/// @brief 设置用户数据
void SetUserData(Any const& data);
inline bool IsName(String const& name) const { return name_ ? (*name_ == name) : name.empty(); }
/// \~chinese
/// @brief 获取对象ID
uint32_t GetObjectID() const;
inline uint32_t GetObjectID() const { return id_; }
/// \~chinese
/// @brief 序列化对象
String DumpObject();
public:
static bool IsTracingLeaks();
@ -59,12 +80,12 @@ namespace kiwano
static void DumpTracingObjects();
public:
static Vector<ObjectBase*>& __GetTracingObjects();
static Vector<ObjectBase*>& GetTracingObjects();
static void __AddObjectToTracingList(ObjectBase*);
private:
static void AddObjectToTracingList(ObjectBase*);
static void __RemoveObjectFromTracingList(ObjectBase*);
static void RemoveObjectFromTracingList(ObjectBase*);
private:
bool tracing_leak_;
@ -72,6 +93,11 @@ namespace kiwano
String* name_;
const uint32_t id_;
static uint32_t last_object_id;
};
inline String ObjectBase::GetName() const { if (name_) return *name_; return String(); }
inline bool ObjectBase::IsName(String const& name) const { return name_ ? (*name_ == name) : name.empty(); }
inline uint32_t ObjectBase::GetObjectID() const { return id_; }
}

View File

@ -0,0 +1,46 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/core/RefCounter.h>
namespace kiwano
{
RefCounter::RefCounter()
: ref_count_(0)
{
}
RefCounter::~RefCounter()
{
}
void RefCounter::Retain()
{
++ref_count_;
}
void RefCounter::Release()
{
--ref_count_;
if (ref_count_ <= 0)
delete this;
}
}

View File

@ -24,29 +24,37 @@
namespace kiwano
{
/**
* \~chinese
* @brief
*/
class KGE_API RefCounter
: protected Noncopyable
{
public:
// 增加引用计数
inline void Retain() { ++ref_count_; }
/// \~chinese
/// @brief 增加引用计数
void Retain();
// 减少引用计数
inline void Release()
{
if (--ref_count_ <= 0)
delete this;
}
/// \~chinese
/// @brief 减少引用计数
void Release();
// 获取引用计数
inline long GetRefCount() const { return ref_count_; }
/// \~chinese
/// @brief 获取引用计数
long GetRefCount() const;
protected:
RefCounter() : ref_count_(0) {}
RefCounter();
virtual ~RefCounter() {}
virtual ~RefCounter();
private:
long ref_count_;
};
inline long RefCounter::GetRefCount() const
{
return ref_count_;
}
}

View File

@ -29,7 +29,6 @@ namespace kiwano
: id_(0)
, type_(nullptr)
{
}
Resource::Resource(uint32_t id, const wchar_t* type)

View File

@ -24,41 +24,54 @@
namespace kiwano
{
// 资源
//
// 资源是保存在 exe 中的二进制数据
// 例如, 一份音频资源的类型为 L"WAVE", 名称标识符为 IDR_WAVE_1,
// 那么可以这样指定该资源: Resource(IDR_WAVE_1, L"WAVE");
//
// 了解资源的更多信息: https://docs.microsoft.com/en-us/windows/desktop/menurc/resources
//
/**
* \~chinese
* @brief
* @details
* exe
* L"WAVE" IDR_WAVE_1:
* @code
* Resource(IDR_WAVE_1, L"WAVE");
* @endcode
* : https://docs.microsoft.com/en-us/windows/desktop/menurc/resources
*/
class KGE_API Resource
{
public:
// 二进制数据
/// \~chinese
/// @brief 资源的二进制数据
struct Data
{
void* buffer;
uint32_t size;
void* buffer; ///< 资源数据
uint32_t size; ///< 资源数据大小
inline Data() : buffer(nullptr), size(0) {}
Data();
inline operator bool() const { return buffer && size; }
operator bool() const;
};
/// \~chinese
/// @brief 构造资源
Resource();
Resource(
uint32_t id, /* 资源 ID */
const wchar_t* type /* 资源类型 */
);
/// \~chinese
/// @brief 构造资源
/// @param id 资源 ID
/// @param type 资源类型
Resource(uint32_t id, const wchar_t* type);
// 获取二进制数据
Resource::Data GetData() const;
/// \~chinese
/// @brief 获取资源的二进制数据
/// @return 资源数据
Resource::Data GetData() const;
inline uint32_t GetId() const { return id_; }
/// \~chinese
/// @brief 获取资源 ID
uint32_t GetId() const;
inline const wchar_t* GetType() const { return type_; }
/// \~chinese
/// @brief 获取资源类型
const wchar_t* GetType() const;
private:
uint32_t id_;
@ -66,4 +79,25 @@ namespace kiwano
mutable Resource::Data data_;
};
inline Resource::Data::Data()
: buffer(nullptr)
, size(0)
{
}
inline Resource::Data::operator bool() const
{
return buffer != nullptr && size;
}
inline uint32_t Resource::GetId() const
{
return id_;
}
inline const wchar_t* Resource::GetType() const
{
return type_;
}
}

View File

@ -20,11 +20,15 @@
#pragma once
#include <kiwano/core/common.h>
#include <kiwano/core/RefCounter.hpp>
#include <kiwano/core/RefCounter.h>
namespace kiwano
{
struct DefaultIntrusivePtrProxy
/**
* \~chinese
* @brief
*/
struct DefaultSmartPtrRefProxy
{
static inline void add_ref(RefCounter* ptr)
{
@ -37,13 +41,17 @@ namespace kiwano
}
};
/**
* \~chinese
* @brief
*/
template <typename _Ty>
using SmartPtr = IntrusivePtr<_Ty, DefaultIntrusivePtrProxy>;
using SmartPtr = IntrusivePtr<_Ty, DefaultSmartPtrRefProxy>;
}
#ifndef KGE_DECLARE_SMART_PTR
#define KGE_DECLARE_SMART_PTR(CLASS)\
class CLASS;\
using CLASS##Ptr = ::kiwano::SmartPtr< CLASS >
typedef ::kiwano::SmartPtr< CLASS > CLASS##Ptr;
#endif

View File

@ -22,68 +22,64 @@
namespace kiwano
{
Timer::Timer(Callback const& func, Duration delay, int times, String const& name)
Timer::Timer()
: running_(true)
, removeable_(false)
, run_times_(0)
, total_times_(times)
, delay_(delay)
, callback_(func)
, delta_()
, total_times_(0)
, interval_(0)
, elapsed_(0)
, callback_()
{
}
Timer::Timer(Callback const& cb, Duration interval, int times)
: Timer(String(), cb, interval, times)
{
}
Timer::Timer(String const& name, Callback const& cb, Duration interval, int times)
: Timer()
{
SetName(name);
SetCallback(cb);
SetInterval(interval);
SetTotalRunTimes(times);
}
void Timer::Start()
void Timer::Update(Duration dt)
{
running_ = true;
}
void Timer::Stop()
{
running_ = false;
}
void Timer::Update(Duration dt, bool& remove_after_update)
{
if (!running_)
return;
if (total_times_ == 0)
{
remove_after_update = true;
Remove();
return;
}
if (!delay_.IsZero())
if (IsRunning())
{
delta_ += dt;
if (delta_ < delay_)
return;
}
if (!interval_.IsZero())
{
elapsed_ += dt;
if (elapsed_ < interval_)
return;
}
++run_times_;
if (callback_)
callback_(this, elapsed_);
if (callback_)
{
callback_();
}
++run_times_;
elapsed_ = 0;
if (run_times_ == total_times_)
{
remove_after_update = true;
return;
if (run_times_ == total_times_)
Remove();
}
}
void Timer::Reset()
{
delta_ = Duration{};
elapsed_ = 0;
run_times_ = 0;
}
bool Timer::IsRunning() const
{
return running_;
}
}

View File

@ -19,8 +19,6 @@
// THE SOFTWARE.
#pragma once
#include <functional>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/time.h>
@ -30,7 +28,9 @@ namespace kiwano
KGE_DECLARE_SMART_PTR(Timer);
// 定时任务
/// \~chinese
/// @brief 定时器
/// @details 定时器用于每隔一段时间执行一次回调函数,且可以指定执行总次数
class KGE_API Timer
: public ObjectBase
, protected IntrusiveListItem<TimerPtr>
@ -38,36 +38,155 @@ namespace kiwano
friend class TimerManager;
friend IntrusiveList<TimerPtr>;
using Callback = Function<void()>;
public:
Timer(
Callback const& func, /* 执行函数 */
Duration delay, /* 时间间隔(秒) */
int times = -1, /* 执行次数(设 -1 为永久执行) */
String const& name = L"" /* 任务名称 */
);
/// \~chinese
/// @brief 定时器回调函数
/// @details 回调函数第一个参数是定时器自身,第二个参数是距离上次更新的时间间隔
using Callback = Function<void(Timer* /* self */, Duration /* dt */)>;
// 启动任务
/// \~chinese
/// @brief 构造空定时器
Timer();
/// \~chinese
/// @brief 构造定时器
/// @param cb 回调函数
/// @param interval 时间间隔
/// @param times 执行次数(设 -1 为永久执行)
Timer(Callback const& cb, Duration interval, int times = -1);
/// \~chinese
/// @brief 构造定时器
/// @param name 名称
/// @param cb 回调函数
/// @param interval 时间间隔
/// @param times 执行次数(设 -1 为永久执行)
Timer(String const& name, Callback const& cb, Duration interval, int times = -1);
/// \~chinese
/// @brief 启动定时器
void Start();
// 停止任务
/// \~chinese
/// @brief 停止定时器
void Stop();
// 任务是否正在执行
/// \~chinese
/// @brief 移除定时器
void Remove();
/// \~chinese
/// @brief 定时器是否在运行
bool IsRunning() const;
private:
void Update(Duration dt, bool& remove_after_update);
/// \~chinese
/// @brief 定时器是否可移除
bool IsRemoveable() const;
/// \~chinese
/// @brief 获取定时器执行过回调函数的次数
int GetRunTimes() const;
/// \~chinese
/// @brief 获取定时器执行回调函数的总次数
int GetTotalRunTimes() const;
/// \~chinese
/// @brief 设置定时器执行回调函数的总次数
void SetTotalRunTimes(int times);
/// \~chinese
/// @brief 获取定时器执行时间间隔
Duration GetInterval() const;
/// \~chinese
/// @brief 设置定时器执行时间间隔
void SetInterval(Duration interval);
/// \~chinese
/// @brief 获取定时器回调函数
Callback GetCallback() const;
/// \~chinese
/// @brief 设置定时器回调函数
void SetCallback(const Callback& callback);
private:
/// \~chinese
/// @brief 更新定时器
void Update(Duration dt);
/// \~chinese
/// @brief 重置定时器
void Reset();
private:
bool running_;
int run_times_;
int total_times_;
Duration delay_;
Duration delta_;
bool removeable_;
int run_times_;
int total_times_;
Duration interval_;
Duration elapsed_;
Callback callback_;
};
inline void Timer::Start()
{
running_ = true;
}
inline void Timer::Stop()
{
running_ = false;
}
inline void Timer::Remove()
{
removeable_ = true;
}
inline bool Timer::IsRunning() const
{
return running_;
}
inline bool Timer::IsRemoveable() const
{
return removeable_;
}
inline int Timer::GetRunTimes() const
{
return run_times_;
}
inline int Timer::GetTotalRunTimes() const
{
return total_times_;
}
inline void Timer::SetTotalRunTimes(int times)
{
total_times_ = times;
}
inline Duration Timer::GetInterval() const
{
return interval_;
}
inline void Timer::SetInterval(Duration interval)
{
interval_ = interval;
}
inline Timer::Callback Timer::GetCallback() const
{
return callback_;
}
inline void Timer::SetCallback(const Timer::Callback& callback)
{
callback_ = callback;
}
}

View File

@ -33,17 +33,21 @@ namespace kiwano
{
next = timer->next_item();
bool remove_after_update = false;
timer->Update(dt, remove_after_update);
timer->Update(dt);
if (remove_after_update)
if (timer->IsRemoveable())
timers_.remove(timer);
}
}
Timer* TimerManager::AddTimer(Timer::Callback const& func, Duration delay, int times, String const& name)
Timer* TimerManager::AddTimer(Timer::Callback const& cb, Duration interval, int times)
{
TimerPtr timer = new Timer(func, delay, times, name);
return AddTimer(String(), cb, interval, times);
}
Timer* TimerManager::AddTimer(String const& name, Timer::Callback const& cb, Duration interval, int times)
{
TimerPtr timer = new Timer(name, cb, interval, times);
return AddTimer(timer);
}
@ -99,7 +103,7 @@ namespace kiwano
next = timer->next_item();
if (timer->IsName(name))
{
timers_.remove(timer);
timer->Remove();
}
}
}

View File

@ -23,52 +23,67 @@
namespace kiwano
{
/**
* \~chinese
* @brief
*/
class KGE_API TimerManager
{
public:
using Timers = IntrusiveList<TimerPtr>;
public:
// 添加定时器
Timer* AddTimer(
Timer::Callback const& func, /* 执行函数 */
Duration delay, /* 时间间隔(秒) */
int times = -1, /* 执行次数(设 -1 为永久执行) */
String const& name = L"" /* 任务名称 */
);
/// \~chinese
/// @brief 添加定时器
/// @param cb 回调函数
/// @param interval 时间间隔
/// @param times 执行次数(设 -1 为永久执行)
Timer* AddTimer(Timer::Callback const& cb, Duration interval, int times = -1);
// 添加定时器
Timer* AddTimer(
TimerPtr timer
);
/// \~chinese
/// @brief 添加定时器
/// @param name 定时器名称
/// @param cb 回调函数
/// @param interval 时间间隔
/// @param times 执行次数(设 -1 为永久执行)
Timer* AddTimer(String const& name, Timer::Callback const& cb, Duration interval, int times = -1);
// 启动任务
void StartTimers(
String const& timer_name
);
/// \~chinese
/// @brief 添加定时器
Timer* AddTimer(TimerPtr timer);
// 停止任务
void StopTimers(
String const& timer_name
);
/// \~chinese
/// @brief 启动定时器
void StartTimers(String const& timer_name);
// 移除任务
/// \~chinese
/// @brief 停止定时器
void StopTimers(String const& timer_name);
/// \~chinese
/// @brief 移除定时器
void RemoveTimers(
String const& timer_name
);
// 启动所有任务
/// \~chinese
/// @brief 启动所有定时器
void StartAllTimers();
// 停止所有任务
/// \~chinese
/// @brief 停止所有定时器
void StopAllTimers();
// 移除所有任务
/// \~chinese
/// @brief 移除所有定时器
void RemoveAllTimers();
// 获取所有任务
/// \~chinese
/// @brief 获取所有定时器
const Timers& GetAllTimers() const;
protected:
/// \~chinese
/// @brief 更新定时器
void UpdateTimers(Duration dt);
private:

View File

@ -33,67 +33,117 @@
namespace kiwano
{
/// \~chinese
/// @brief 字符串容器
using String = oc::wstring;
/// \~chinese
/// @brief 字符串流
using StringStream = std::wstringstream;
/// \~chinese
/// @brief 线性数组容器
template <typename _Ty, typename... _Args>
using Vector = oc::vector<_Ty, _Args...>;
/// \~chinese
/// @brief 链表容器
template <typename _Ty, typename... _Args>
using List = std::list<_Ty, _Args...>;
/// \~chinese
/// @brief 队列容器
template <typename _Ty, typename... _Args>
using Queue = std::queue<_Ty, _Args...>;
/// \~chinese
/// @brief 集合容器
template <typename _Ty, typename... _Args>
using Set = std::set<_Ty, _Args...>;
/// \~chinese
/// @brief 对容器
template <typename _Ty1, typename _Ty2>
using Pair = std::pair<_Ty1, _Ty2>;
/// \~chinese
/// @brief 无序集合容器
template <typename _Ty, typename... _Args>
using UnorderedSet = std::unordered_set<_Ty, _Args...>;
/// \~chinese
/// @brief 栈容器
template <typename _Ty, typename... _Args>
using Stack = std::stack<_Ty, _Args...>;
/// \~chinese
/// @brief 字符串容器
template <typename _Kty, typename _Ty, typename... _Args>
using Map = std::map<_Kty, _Ty, _Args...>;
/// \~chinese
/// @brief 字符串容器
template <typename _Kty, typename _Ty, typename... _Args>
using UnorderedMap = std::unordered_map<_Kty, _Ty, _Args...>;
/// \~chinese
/// @brief 函数封装器
/// @par
/// 使用函数封装器可以储存、复制和调用任何可调用目标,示例代码如下:
/// @code
/// Function<bool(int)> func1 = StaticFunc; // bool StaticFunc(int x);
/// Function<bool(int)> func2 = Closure(&t, &T::Func); // bool T::Func(int x);
/// Function<bool(int)> func3 = T::StaticFunc; // static bool T::StaticFunc(int x);
/// Function<bool(int)> func4 = [](int x) -> bool {}; // Lambda function
/// Function<bool(int)> func5 = std::bind(&T::Func, &t); // std::bind
/// Function<bool(int)> func5 = Callable(); // Callable objects: struct Callable { bool operator()(int x) {} };
/// @endcode
template <typename _FuncTy>
using Function = oc::function<_FuncTy>;
/// \~chinese
/// @brief 单值容器
using Any = oc::any;
/// \~chinese
/// @brief JSON对象容器
using Json = oc::basic_json<Map, Vector, String, int, double, bool, std::allocator>;
/// \~chinese
/// @brief 单例模板
template <typename _Ty>
using Singleton = oc::singleton<_Ty>;
/// \~chinese
/// @brief 侵入式链表容器
template <typename _Ty>
using IntrusiveList = oc::intrusive_list<_Ty>;
/// \~chinese
/// @brief 侵入式链表元素
template <typename _Ty>
using IntrusiveListItem = oc::intrusive_list_item<_Ty>;
/// \~chinese
/// @brief 侵入式智能指针
template <typename _Ty, typename _RefProxyTy>
using IntrusivePtr = oc::intrusive_ptr<_Ty, _RefProxyTy>;
/// \~chinese
/// @brief 不可拷贝对象
using Noncopyable = oc::noncopyable;
// Closure
/// \~chinese
/// @brief 闭包函数
template<typename _Ty, typename _Uty, typename _Ret, typename... _Args>
inline Function<_Ret(_Args...)> Closure(_Uty* ptr, _Ret(_Ty::* func)(_Args...))
{
return oc::closure(ptr, func);
}
/// \~chinese
/// @brief 闭包函数
template<typename _Ty, typename _Uty, typename _Ret, typename... _Args>
inline Function<_Ret(_Args...)> Closure(_Uty* ptr, _Ret(_Ty::* func)(_Args...) const)
{

View File

@ -27,7 +27,7 @@ namespace kiwano
/**
* \~chinese
* @brief
* @details
* @par
* :
* @code
* time::Second * 5 // 5 秒

View File

@ -383,11 +383,11 @@ namespace kiwano
{
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
{
// KGE_LOG(L"Window minimized");
// KGE_SYS_LOG(L"Window minimized");
}
else
{
// KGE_LOG(L"Window resized");
// KGE_SYS_LOG(L"Window resized");
Window::instance().UpdateWindowRect();
@ -425,7 +425,7 @@ namespace kiwano
case WM_SETTEXT:
{
// KGE_LOG(L"Window title changed");
// KGE_SYS_LOG(L"Window title changed");
WindowTitleChangedEvent evt;
evt.title = reinterpret_cast<const wchar_t*>(lparam);
@ -435,13 +435,13 @@ namespace kiwano
case WM_SETICON:
{
// KGE_LOG(L"Window icon changed");
// KGE_SYS_LOG(L"Window icon changed");
}
break;
case WM_DISPLAYCHANGE:
{
// KGE_LOG(L"The display resolution has changed");
// KGE_SYS_LOG(L"The display resolution has changed");
::InvalidateRect(hwnd, nullptr, FALSE);
}
@ -455,7 +455,7 @@ namespace kiwano
case WM_CLOSE:
{
// KGE_LOG(L"Window is closing");
// KGE_SYS_LOG(L"Window is closing");
if (!app->OnClosing())
{
@ -468,7 +468,7 @@ namespace kiwano
case WM_DESTROY:
{
KGE_LOG(L"Window was destroyed");
KGE_SYS_LOG(L"Window was destroyed");
app->Quit();
app->OnDestroy();

View File

@ -50,7 +50,7 @@ namespace kiwano
void Renderer::SetupComponent()
{
KGE_LOG(L"Creating device resources");
KGE_SYS_LOG(L"Creating device resources");
hwnd_ = Window::instance().GetHandle();
output_size_ = Window::instance().GetSize();
@ -128,7 +128,7 @@ namespace kiwano
void Renderer::DestroyComponent()
{
KGE_LOG(L"Destroying device resources");
KGE_SYS_LOG(L"Destroying device resources");
RenderTarget::DiscardDeviceResources();