update Duration
This commit is contained in:
parent
4be1d7eccb
commit
21c476c56f
|
|
@ -3,7 +3,8 @@
|
||||||
{
|
{
|
||||||
"name": "Mac",
|
"name": "Mac",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/src/**"
|
"${workspaceFolder}/src",
|
||||||
|
"${workspaceFolder}/src/3rd-party"
|
||||||
],
|
],
|
||||||
"defines": [
|
"defines": [
|
||||||
"TARGET_OS_MAC"
|
"TARGET_OS_MAC"
|
||||||
|
|
@ -19,7 +20,8 @@
|
||||||
{
|
{
|
||||||
"name": "Linux",
|
"name": "Linux",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/src/**"
|
"${workspaceFolder}/src",
|
||||||
|
"${workspaceFolder}/src/3rd-party"
|
||||||
],
|
],
|
||||||
"defines": [],
|
"defines": [],
|
||||||
"compilerPath": "/usr/bin/gcc",
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
<ClInclude Include="..\..\src\kiwano\core\Cloneable.h" />
|
<ClInclude Include="..\..\src\kiwano\core\Cloneable.h" />
|
||||||
<ClInclude Include="..\..\src\kiwano\core\Common.h" />
|
<ClInclude Include="..\..\src\kiwano\core\Common.h" />
|
||||||
<ClInclude Include="..\..\src\kiwano\core\Defer.h" />
|
<ClInclude Include="..\..\src\kiwano\core\Defer.h" />
|
||||||
|
<ClInclude Include="..\..\src\kiwano\core\Duration.h" />
|
||||||
<ClInclude Include="..\..\src\kiwano\core\Exception.h" />
|
<ClInclude Include="..\..\src\kiwano\core\Exception.h" />
|
||||||
<ClInclude Include="..\..\src\kiwano\core\Flag.h" />
|
<ClInclude Include="..\..\src\kiwano\core\Flag.h" />
|
||||||
<ClInclude Include="..\..\src\kiwano\core\Function.h" />
|
<ClInclude Include="..\..\src\kiwano\core\Function.h" />
|
||||||
|
|
@ -139,6 +140,7 @@
|
||||||
<ClCompile Include="..\..\src\kiwano\base\ObjectBase.cpp" />
|
<ClCompile Include="..\..\src\kiwano\base\ObjectBase.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\base\RefObject.cpp" />
|
<ClCompile Include="..\..\src\kiwano\base\RefObject.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\core\Allocator.cpp" />
|
<ClCompile Include="..\..\src\kiwano\core\Allocator.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\kiwano\core\Duration.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\core\Exception.cpp" />
|
<ClCompile Include="..\..\src\kiwano\core\Exception.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\core\Library.cpp" />
|
<ClCompile Include="..\..\src\kiwano\core\Library.cpp" />
|
||||||
<ClCompile Include="..\..\src\kiwano\core\Resource.cpp" />
|
<ClCompile Include="..\..\src\kiwano\core\Resource.cpp" />
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,9 @@
|
||||||
<ClInclude Include="..\..\src\kiwano\core\Time.h">
|
<ClInclude Include="..\..\src\kiwano\core\Time.h">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\kiwano\core\Duration.h">
|
||||||
|
<Filter>core</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\kiwano\render\Brush.h">
|
<ClInclude Include="..\..\src\kiwano\render\Brush.h">
|
||||||
<Filter>render</Filter>
|
<Filter>render</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
@ -599,6 +602,9 @@
|
||||||
<ClCompile Include="..\..\src\kiwano\render\NativeObject.cpp">
|
<ClCompile Include="..\..\src\kiwano\render\NativeObject.cpp">
|
||||||
<Filter>render</Filter>
|
<Filter>render</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\kiwano\core\Duration.cpp">
|
||||||
|
<Filter>core</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="suppress_warning.ruleset" />
|
<None Include="suppress_warning.ruleset" />
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ void DebugActor::OnRender(RenderContext& ctx)
|
||||||
ctx.DrawTextLayout(debug_text_, Point(10, 10));
|
ctx.DrawTextLayout(debug_text_, Point(10, 10));
|
||||||
|
|
||||||
frame_buffer_.PushBack(Time::Now());
|
frame_buffer_.PushBack(Time::Now());
|
||||||
while (frame_buffer_.Back() - frame_buffer_.Front() >= Duration::Second)
|
while (frame_buffer_.Back() - frame_buffer_.Front() >= time::Second)
|
||||||
{
|
{
|
||||||
frame_buffer_.PopFront();
|
frame_buffer_.PopFront();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
// 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 <regex> // std::regex
|
||||||
|
#include <unordered_map> // std::unordered_map
|
||||||
|
#include <chrono> // std::chrono::milliseconds
|
||||||
|
#include <thread> // std::this_thread::sleep_for
|
||||||
|
#include <kiwano/core/Duration.h>
|
||||||
|
#include <kiwano/utils/Logger.h> // KGE_THROW
|
||||||
|
|
||||||
|
namespace kiwano
|
||||||
|
{
|
||||||
|
|
||||||
|
const Duration time::Millisecond = 1L;
|
||||||
|
const Duration time::Second = 1000 * time::Millisecond;
|
||||||
|
const Duration time::Minute = 60 * time::Second;
|
||||||
|
const Duration time::Hour = 60 * time::Minute;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const auto duration_regex = std::regex(R"(^[-+]?([0-9]*(\.[0-9]*)?(h|m|s|ms)+)+$)");
|
||||||
|
|
||||||
|
typedef std::unordered_map<String, Duration> UnitMap;
|
||||||
|
|
||||||
|
const auto unit_map = UnitMap{ { "ms", time::Millisecond }, { "s", time::Second }, { "m", time::Minute }, { "h", time::Hour } };
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
float Duration::GetSeconds() const
|
||||||
|
{
|
||||||
|
auto sec = milliseconds_ / time::Second.milliseconds_;
|
||||||
|
auto ms = milliseconds_ % time::Second.milliseconds_;
|
||||||
|
return static_cast<float>(sec + ms) / 1000.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Duration::GetMinutes() const
|
||||||
|
{
|
||||||
|
auto min = milliseconds_ / time::Minute.milliseconds_;
|
||||||
|
auto ms = milliseconds_ % time::Minute.milliseconds_;
|
||||||
|
return static_cast<float>(min + ms) / (60 * 1000.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Duration::GetHours() const
|
||||||
|
{
|
||||||
|
auto hour = milliseconds_ / time::Hour.milliseconds_;
|
||||||
|
auto ms = milliseconds_ % time::Hour.milliseconds_;
|
||||||
|
return static_cast<float>(hour + ms) / (60 * 60 * 1000.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Duration::Sleep() const
|
||||||
|
{
|
||||||
|
using std::chrono::milliseconds;
|
||||||
|
using std::this_thread::sleep_for;
|
||||||
|
|
||||||
|
if (milliseconds_)
|
||||||
|
{
|
||||||
|
sleep_for(milliseconds(milliseconds_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String Duration::ToString() const
|
||||||
|
{
|
||||||
|
if (IsZero())
|
||||||
|
{
|
||||||
|
return String("0s");
|
||||||
|
}
|
||||||
|
|
||||||
|
StringStream stream;
|
||||||
|
|
||||||
|
int64_t total_ms = milliseconds_;
|
||||||
|
if (total_ms < 0)
|
||||||
|
{
|
||||||
|
stream << "-";
|
||||||
|
total_ms = -total_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t hour = total_ms / time::Hour.milliseconds_;
|
||||||
|
int64_t min = total_ms / time::Minute.milliseconds_ - hour * 60;
|
||||||
|
int64_t sec = total_ms / time::Second.milliseconds_ - (hour * 60 * 60 + min * 60);
|
||||||
|
int64_t ms = total_ms % time::Second.milliseconds_;
|
||||||
|
|
||||||
|
if (hour)
|
||||||
|
{
|
||||||
|
stream << hour << 'h' << min << 'm';
|
||||||
|
}
|
||||||
|
else if (min)
|
||||||
|
{
|
||||||
|
stream << min << 'm';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ms != 0)
|
||||||
|
{
|
||||||
|
stream << float(sec) + float(ms) / 1000.f << 's';
|
||||||
|
}
|
||||||
|
else if (sec != 0)
|
||||||
|
{
|
||||||
|
stream << sec << 's';
|
||||||
|
}
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Duration Duration::Parse(const String& format)
|
||||||
|
{
|
||||||
|
bool negative = false;
|
||||||
|
size_t len = format.length();
|
||||||
|
size_t pos = 0;
|
||||||
|
Duration ret;
|
||||||
|
|
||||||
|
if (!std::regex_match(format.c_str(), duration_regex))
|
||||||
|
{
|
||||||
|
KGE_THROW("Duration::Parse failed, invalid duration");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format.empty() || format == "0")
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ·ûºÅλ
|
||||||
|
if (format[0] == '-' || format[0] == '+')
|
||||||
|
{
|
||||||
|
negative = (format[0] == '-');
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pos < len)
|
||||||
|
{
|
||||||
|
// ÊýÖµ
|
||||||
|
size_t i = pos;
|
||||||
|
for (; i < len; ++i)
|
||||||
|
{
|
||||||
|
wchar_t ch = format[i];
|
||||||
|
if (!(ch == '.' || '0' <= ch && ch <= '9'))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String num_str = format.substr(pos, i - pos);
|
||||||
|
|
||||||
|
pos = i;
|
||||||
|
|
||||||
|
if (num_str.empty() || num_str == ".")
|
||||||
|
KGE_THROW("Duration::Parse failed, invalid duration");
|
||||||
|
|
||||||
|
// µ¥Î»
|
||||||
|
for (; i < len; ++i)
|
||||||
|
{
|
||||||
|
wchar_t ch = format[i];
|
||||||
|
if (ch == '.' || '0' <= ch && ch <= '9')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String unit_str = format.substr(pos, i - pos);
|
||||||
|
|
||||||
|
pos = i;
|
||||||
|
|
||||||
|
if (unit_map.find(unit_str) == unit_map.end())
|
||||||
|
KGE_THROW("Duration::Parse failed, invalid duration");
|
||||||
|
|
||||||
|
double num = std::stod(num_str.c_str());
|
||||||
|
Duration unit = unit_map.at(unit_str);
|
||||||
|
ret += unit * num;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negative)
|
||||||
|
{
|
||||||
|
ret = -ret;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace kiwano
|
||||||
|
|
@ -0,0 +1,433 @@
|
||||||
|
// Copyright (c) 2016-2018 Kiwano - Nomango
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <kiwano/core/Common.h>
|
||||||
|
|
||||||
|
namespace kiwano
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \~chinese
|
||||||
|
* @brief 时间段
|
||||||
|
* @par
|
||||||
|
* 时间段表示法:
|
||||||
|
* @code
|
||||||
|
* time::Millisecond * 50 // 50 毫秒
|
||||||
|
* time::Second * 5 // 5 秒
|
||||||
|
* time::Hour * 1.5 // 1.5 小时
|
||||||
|
* time::Hour * 3 + time::Minute * 45 + time::Second * 15 // 3 小时 45 分 15秒
|
||||||
|
* @endcode
|
||||||
|
* 在 VS2015 及更高版本可以使用 time literals:
|
||||||
|
* @code
|
||||||
|
* using namespace kiwano;
|
||||||
|
* 50_msec // 50 毫秒
|
||||||
|
* 5_sec // 5 秒
|
||||||
|
* 1.5_hour // 1.5 小时
|
||||||
|
* 3_hour + 45_min + 15_sec // 3 小时 45 分 15 秒
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
struct KGE_API Duration
|
||||||
|
{
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 构造时间段
|
||||||
|
Duration();
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 构造时间段
|
||||||
|
/// @param milliseconds 毫秒数
|
||||||
|
Duration(int64_t milliseconds);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取毫秒数
|
||||||
|
int64_t GetMilliseconds() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取秒数
|
||||||
|
float GetSeconds() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取分钟数
|
||||||
|
float GetMinutes() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取小时数
|
||||||
|
float GetHours() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 时长是否是零
|
||||||
|
/// @return 若时长是零,返回true
|
||||||
|
bool IsZero() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置毫秒数
|
||||||
|
/// @param ms 毫秒数
|
||||||
|
void SetMilliseconds(int64_t ms);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置秒数
|
||||||
|
/// @param seconds 秒数
|
||||||
|
void SetSeconds(float seconds);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置分钟数
|
||||||
|
/// @param minutes 分钟数
|
||||||
|
void SetMinutes(float minutes);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置小时数
|
||||||
|
/// @param hours 小时数
|
||||||
|
void SetHours(float hours);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 休眠
|
||||||
|
void Sleep() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 转为字符串
|
||||||
|
String ToString() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 解析时间段字符串
|
||||||
|
/// @param str 时间段字符串
|
||||||
|
/// @details
|
||||||
|
/// 时间段字符串允许是有符号的浮点数, 并且带有时间单位后缀
|
||||||
|
/// 例如: "300ms", "-1.5h", "2h45m"
|
||||||
|
/// 允许的时间单位有 "ms", "s", "m", "h"
|
||||||
|
/// @return 解析出的时间段
|
||||||
|
/// @throw kiwano::RuntimeError 传入一个不合法的格式时抛出
|
||||||
|
static Duration Parse(const String& str);
|
||||||
|
|
||||||
|
bool operator==(const Duration&) const;
|
||||||
|
bool operator!=(const Duration&) const;
|
||||||
|
bool operator>(const Duration&) const;
|
||||||
|
bool operator>=(const Duration&) const;
|
||||||
|
bool operator<(const Duration&) const;
|
||||||
|
bool operator<=(const Duration&) const;
|
||||||
|
|
||||||
|
float operator/(const Duration&) const;
|
||||||
|
|
||||||
|
const Duration operator+(const Duration&) const;
|
||||||
|
const Duration operator-(const Duration&) const;
|
||||||
|
const Duration operator-() const;
|
||||||
|
const Duration operator*(int)const;
|
||||||
|
const Duration operator*(unsigned long long)const;
|
||||||
|
const Duration operator*(float)const;
|
||||||
|
const Duration operator*(double)const;
|
||||||
|
const Duration operator*(long double)const;
|
||||||
|
const Duration operator/(int) const;
|
||||||
|
const Duration operator/(float) const;
|
||||||
|
const Duration operator/(double) const;
|
||||||
|
|
||||||
|
Duration& operator+=(const Duration&);
|
||||||
|
Duration& operator-=(const Duration&);
|
||||||
|
Duration& operator*=(int);
|
||||||
|
Duration& operator*=(float);
|
||||||
|
Duration& operator*=(double);
|
||||||
|
Duration& operator/=(int);
|
||||||
|
Duration& operator/=(float);
|
||||||
|
Duration& operator/=(double);
|
||||||
|
|
||||||
|
friend const Duration operator*(int, const Duration&);
|
||||||
|
friend const Duration operator*(float, const Duration&);
|
||||||
|
friend const Duration operator*(double, const Duration&);
|
||||||
|
friend const Duration operator*(long double, const Duration&);
|
||||||
|
friend const Duration operator/(int, const Duration&);
|
||||||
|
friend const Duration operator/(float, const Duration&);
|
||||||
|
friend const Duration operator/(double, const Duration&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int64_t milliseconds_;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace time
|
||||||
|
{
|
||||||
|
|
||||||
|
extern const Duration Millisecond; ///< 毫秒
|
||||||
|
extern const Duration Second; ///< 秒
|
||||||
|
extern const Duration Minute; ///< 分钟
|
||||||
|
extern const Duration Hour; ///< 小时
|
||||||
|
|
||||||
|
} // namespace time
|
||||||
|
|
||||||
|
inline Duration::Duration()
|
||||||
|
: milliseconds_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration::Duration(int64_t milliseconds)
|
||||||
|
: milliseconds_(milliseconds)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int64_t Duration::GetMilliseconds() const
|
||||||
|
{
|
||||||
|
return milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Duration::IsZero() const
|
||||||
|
{
|
||||||
|
return milliseconds_ == 0LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Duration::SetMilliseconds(int64_t ms)
|
||||||
|
{
|
||||||
|
milliseconds_ = ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Duration::SetSeconds(float seconds)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(seconds * 1000.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Duration::SetMinutes(float minutes)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(minutes * 60 * 1000.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Duration::SetHours(float hours)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(hours * 60 * 60 * 1000.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Duration::operator==(const Duration& other) const
|
||||||
|
{
|
||||||
|
return milliseconds_ == other.milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Duration::operator!=(const Duration& other) const
|
||||||
|
{
|
||||||
|
return milliseconds_ != other.milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Duration::operator>(const Duration& other) const
|
||||||
|
{
|
||||||
|
return milliseconds_ > other.milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Duration::operator>=(const Duration& other) const
|
||||||
|
{
|
||||||
|
return milliseconds_ >= other.milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Duration::operator<(const Duration& other) const
|
||||||
|
{
|
||||||
|
return milliseconds_ < other.milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Duration::operator<=(const Duration& other) const
|
||||||
|
{
|
||||||
|
return milliseconds_ <= other.milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float Duration::operator/(const Duration& other) const
|
||||||
|
{
|
||||||
|
return static_cast<float>(milliseconds_) / other.milliseconds_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator+(const Duration& other) const
|
||||||
|
{
|
||||||
|
return Duration(milliseconds_ + other.milliseconds_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator-(const Duration& other) const
|
||||||
|
{
|
||||||
|
return Duration(milliseconds_ - other.milliseconds_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator-() const
|
||||||
|
{
|
||||||
|
return Duration(-milliseconds_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator*(int val) const
|
||||||
|
{
|
||||||
|
return Duration(milliseconds_ * val);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator*(unsigned long long val) const
|
||||||
|
{
|
||||||
|
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator*(float val) const
|
||||||
|
{
|
||||||
|
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator*(double val) const
|
||||||
|
{
|
||||||
|
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator*(long double val) const
|
||||||
|
{
|
||||||
|
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator/(int val) const
|
||||||
|
{
|
||||||
|
return Duration(milliseconds_ / val);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator/(float val) const
|
||||||
|
{
|
||||||
|
return Duration(static_cast<int64_t>(milliseconds_ / val));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration Duration::operator/(double val) const
|
||||||
|
{
|
||||||
|
return Duration(static_cast<int64_t>(milliseconds_ / val));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator+=(const Duration& other)
|
||||||
|
{
|
||||||
|
milliseconds_ += other.milliseconds_;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator-=(const Duration& other)
|
||||||
|
{
|
||||||
|
milliseconds_ -= other.milliseconds_;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator*=(int val)
|
||||||
|
{
|
||||||
|
milliseconds_ *= val;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator/=(int val)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(milliseconds_ / val);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator*=(float val)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(milliseconds_ * val);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator/=(float val)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(milliseconds_ / val);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator*=(double val)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(milliseconds_ * val);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Duration& Duration::operator/=(double val)
|
||||||
|
{
|
||||||
|
milliseconds_ = static_cast<int64_t>(milliseconds_ / val);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration operator*(int val, const Duration& dur)
|
||||||
|
{
|
||||||
|
return dur * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration operator/(int val, const Duration& dur)
|
||||||
|
{
|
||||||
|
return dur / val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration operator*(float val, const Duration& dur)
|
||||||
|
{
|
||||||
|
return dur * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration operator/(float val, const Duration& dur)
|
||||||
|
{
|
||||||
|
return dur / val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration operator*(double val, const Duration& dur)
|
||||||
|
{
|
||||||
|
return dur * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration operator/(double val, const Duration& dur)
|
||||||
|
{
|
||||||
|
return dur / val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Duration operator*(long double val, const Duration& dur)
|
||||||
|
{
|
||||||
|
return dur * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace kiwano
|
||||||
|
|
||||||
|
#if defined(KGE_HAS_LITERALS)
|
||||||
|
|
||||||
|
namespace kiwano
|
||||||
|
{
|
||||||
|
inline namespace literals
|
||||||
|
{
|
||||||
|
inline const kiwano::Duration operator"" _msec(long double val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Millisecond * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const kiwano::Duration operator"" _msec(unsigned long long val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Millisecond * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const kiwano::Duration operator"" _sec(long double val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Second * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const kiwano::Duration operator"" _sec(unsigned long long val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Second * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const kiwano::Duration operator"" _min(long double val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Minute * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const kiwano::Duration operator"" _min(unsigned long long val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Minute * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const kiwano::Duration operator"" _hour(long double val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Hour * val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const kiwano::Duration operator"" _hour(unsigned long long val)
|
||||||
|
{
|
||||||
|
return kiwano::time::Hour * val;
|
||||||
|
}
|
||||||
|
} // namespace literals
|
||||||
|
} // namespace kiwano
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -18,12 +18,8 @@
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#include <regex>
|
#include <chrono> // std::chrono
|
||||||
#include <unordered_map>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
#include <kiwano/core/Time.h>
|
#include <kiwano/core/Time.h>
|
||||||
#include <kiwano/utils/Logger.h>
|
|
||||||
|
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
|
|
@ -180,353 +176,4 @@ ClockTime& ClockTime::operator-=(const Duration& other)
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------
|
|
||||||
// Duration
|
|
||||||
//-------------------------------------------------------
|
|
||||||
|
|
||||||
const Duration Duration::Ms = 1L;
|
|
||||||
const Duration Duration::Second = 1000 * Duration::Ms;
|
|
||||||
const Duration Duration::Minute = 60 * Duration::Second;
|
|
||||||
const Duration Duration::Hour = 60 * Duration::Minute;
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const auto duration_regex = std::regex(R"(^[-+]?([0-9]*(\.[0-9]*)?(h|m|s|ms)+)+$)");
|
|
||||||
|
|
||||||
typedef std::unordered_map<String, Duration> UnitMap;
|
|
||||||
|
|
||||||
const auto unit_map =
|
|
||||||
UnitMap{ { "ms", Duration::Ms }, { "s", Duration::Second }, { "m", Duration::Minute }, { "h", Duration::Hour } };
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
Duration::Duration()
|
|
||||||
: milliseconds_(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration::Duration(int64_t milliseconds)
|
|
||||||
: milliseconds_(milliseconds)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
float Duration::GetSeconds() const
|
|
||||||
{
|
|
||||||
auto sec = milliseconds_ / Second.milliseconds_;
|
|
||||||
auto ms = milliseconds_ % Second.milliseconds_;
|
|
||||||
return static_cast<float>(sec + ms) / 1000.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Duration::GetMinutes() const
|
|
||||||
{
|
|
||||||
auto min = milliseconds_ / Minute.milliseconds_;
|
|
||||||
auto ms = milliseconds_ % Minute.milliseconds_;
|
|
||||||
return static_cast<float>(min + ms) / (60 * 1000.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Duration::GetHours() const
|
|
||||||
{
|
|
||||||
auto hour = milliseconds_ / Hour.milliseconds_;
|
|
||||||
auto ms = milliseconds_ % Hour.milliseconds_;
|
|
||||||
return static_cast<float>(hour + ms) / (60 * 60 * 1000.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Duration::Sleep() const
|
|
||||||
{
|
|
||||||
using std::chrono::milliseconds;
|
|
||||||
using std::this_thread::sleep_for;
|
|
||||||
|
|
||||||
if (milliseconds_)
|
|
||||||
{
|
|
||||||
sleep_for(milliseconds(milliseconds_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String Duration::ToString() const
|
|
||||||
{
|
|
||||||
if (IsZero())
|
|
||||||
{
|
|
||||||
return String("0s");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringStream stream;
|
|
||||||
|
|
||||||
int64_t total_ms = milliseconds_;
|
|
||||||
if (total_ms < 0)
|
|
||||||
{
|
|
||||||
stream << "-";
|
|
||||||
total_ms = -total_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t hour = total_ms / Hour.milliseconds_;
|
|
||||||
int64_t min = total_ms / Minute.milliseconds_ - hour * 60;
|
|
||||||
int64_t sec = total_ms / Second.milliseconds_ - (hour * 60 * 60 + min * 60);
|
|
||||||
int64_t ms = total_ms % Second.milliseconds_;
|
|
||||||
|
|
||||||
if (hour)
|
|
||||||
{
|
|
||||||
stream << hour << 'h' << min << 'm';
|
|
||||||
}
|
|
||||||
else if (min)
|
|
||||||
{
|
|
||||||
stream << min << 'm';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ms != 0)
|
|
||||||
{
|
|
||||||
stream << float(sec) + float(ms) / 1000.f << 's';
|
|
||||||
}
|
|
||||||
else if (sec != 0)
|
|
||||||
{
|
|
||||||
stream << sec << 's';
|
|
||||||
}
|
|
||||||
return stream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Duration::operator==(const Duration& other) const
|
|
||||||
{
|
|
||||||
return milliseconds_ == other.milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Duration::operator!=(const Duration& other) const
|
|
||||||
{
|
|
||||||
return milliseconds_ != other.milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Duration::operator>(const Duration& other) const
|
|
||||||
{
|
|
||||||
return milliseconds_ > other.milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Duration::operator>=(const Duration& other) const
|
|
||||||
{
|
|
||||||
return milliseconds_ >= other.milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Duration::operator<(const Duration& other) const
|
|
||||||
{
|
|
||||||
return milliseconds_ < other.milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Duration::operator<=(const Duration& other) const
|
|
||||||
{
|
|
||||||
return milliseconds_ <= other.milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Duration::operator/(const Duration& other) const
|
|
||||||
{
|
|
||||||
return static_cast<float>(milliseconds_) / other.milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator+(const Duration& other) const
|
|
||||||
{
|
|
||||||
return Duration(milliseconds_ + other.milliseconds_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator-(const Duration& other) const
|
|
||||||
{
|
|
||||||
return Duration(milliseconds_ - other.milliseconds_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator-() const
|
|
||||||
{
|
|
||||||
return Duration(-milliseconds_);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator*(int val) const
|
|
||||||
{
|
|
||||||
return Duration(milliseconds_ * val);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator*(unsigned long long val) const
|
|
||||||
{
|
|
||||||
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator*(float val) const
|
|
||||||
{
|
|
||||||
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator*(double val) const
|
|
||||||
{
|
|
||||||
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator*(long double val) const
|
|
||||||
{
|
|
||||||
return Duration(static_cast<int64_t>(milliseconds_ * val));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator/(int val) const
|
|
||||||
{
|
|
||||||
return Duration(milliseconds_ / val);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator/(float val) const
|
|
||||||
{
|
|
||||||
return Duration(static_cast<int64_t>(milliseconds_ / val));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration Duration::operator/(double val) const
|
|
||||||
{
|
|
||||||
return Duration(static_cast<int64_t>(milliseconds_ / val));
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator+=(const Duration& other)
|
|
||||||
{
|
|
||||||
milliseconds_ += other.milliseconds_;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator-=(const Duration& other)
|
|
||||||
{
|
|
||||||
milliseconds_ -= other.milliseconds_;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator*=(int val)
|
|
||||||
{
|
|
||||||
milliseconds_ *= val;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator/=(int val)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(milliseconds_ / val);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator*=(float val)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(milliseconds_ * val);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator/=(float val)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(milliseconds_ / val);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator*=(double val)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(milliseconds_ * val);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration& Duration::operator/=(double val)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(milliseconds_ / val);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration operator*(int val, const Duration& dur)
|
|
||||||
{
|
|
||||||
return dur * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration operator/(int val, const Duration& dur)
|
|
||||||
{
|
|
||||||
return dur / val;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration operator*(float val, const Duration& dur)
|
|
||||||
{
|
|
||||||
return dur * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration operator/(float val, const Duration& dur)
|
|
||||||
{
|
|
||||||
return dur / val;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration operator*(double val, const Duration& dur)
|
|
||||||
{
|
|
||||||
return dur * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration operator/(double val, const Duration& dur)
|
|
||||||
{
|
|
||||||
return dur / val;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Duration operator*(long double val, const Duration& dur)
|
|
||||||
{
|
|
||||||
return dur * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration Duration::Parse(const String& format)
|
|
||||||
{
|
|
||||||
bool negative = false;
|
|
||||||
size_t len = format.length();
|
|
||||||
size_t pos = 0;
|
|
||||||
Duration ret;
|
|
||||||
|
|
||||||
if (!std::regex_match(format.c_str(), duration_regex))
|
|
||||||
{
|
|
||||||
KGE_THROW("Duration::Parse failed, invalid duration");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format.empty() || format == "0")
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ·ûºÅλ
|
|
||||||
if (format[0] == '-' || format[0] == '+')
|
|
||||||
{
|
|
||||||
negative = (format[0] == '-');
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (pos < len)
|
|
||||||
{
|
|
||||||
// ÊýÖµ
|
|
||||||
size_t i = pos;
|
|
||||||
for (; i < len; ++i)
|
|
||||||
{
|
|
||||||
wchar_t ch = format[i];
|
|
||||||
if (!(ch == '.' || '0' <= ch && ch <= '9'))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String num_str = format.substr(pos, i - pos);
|
|
||||||
|
|
||||||
pos = i;
|
|
||||||
|
|
||||||
if (num_str.empty() || num_str == ".")
|
|
||||||
KGE_THROW("Duration::Parse failed, invalid duration");
|
|
||||||
|
|
||||||
// µ¥Î»
|
|
||||||
for (; i < len; ++i)
|
|
||||||
{
|
|
||||||
wchar_t ch = format[i];
|
|
||||||
if (ch == '.' || '0' <= ch && ch <= '9')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String unit_str = format.substr(pos, i - pos);
|
|
||||||
|
|
||||||
pos = i;
|
|
||||||
|
|
||||||
if (unit_map.find(unit_str) == unit_map.end())
|
|
||||||
KGE_THROW("Duration::Parse failed, invalid duration");
|
|
||||||
|
|
||||||
double num = std::stod(num_str.c_str());
|
|
||||||
Duration unit = unit_map.at(unit_str);
|
|
||||||
ret += unit * num;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (negative)
|
|
||||||
{
|
|
||||||
ret = -ret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -19,150 +19,12 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <kiwano/core/Common.h>
|
#include <kiwano/core/Duration.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* \~chinese
|
|
||||||
* @brief 时间段
|
|
||||||
* @par
|
|
||||||
* 时间段表示法:
|
|
||||||
* @code
|
|
||||||
* Duration::Ms * 50 // 50 毫秒
|
|
||||||
* Duration::Second * 5 // 5 秒
|
|
||||||
* Duration::Hour * 1.5 // 1.5 小时
|
|
||||||
* Duration::Hour * 3 + Duration::Minute * 45 + Duration::Second * 15 // 3 小时 45 分 15秒
|
|
||||||
* @endcode
|
|
||||||
* 在 VS2015 及更高版本可以使用 time literals:
|
|
||||||
* @code
|
|
||||||
* using namespace kiwano;
|
|
||||||
* 50_msec // 50 毫秒
|
|
||||||
* 5_sec // 5 秒
|
|
||||||
* 1.5_hour // 1.5 小时
|
|
||||||
* 3_hour + 45_min + 15_sec // 3 小时 45 分 15 秒
|
|
||||||
* @endcode
|
|
||||||
*/
|
|
||||||
struct KGE_API Duration
|
|
||||||
{
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 构造时间段
|
|
||||||
Duration();
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 构造时间段
|
|
||||||
/// @param milliseconds 毫秒数
|
|
||||||
Duration(int64_t milliseconds);
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 获取毫秒数
|
|
||||||
int64_t GetMilliseconds() const;
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 获取秒数
|
|
||||||
float GetSeconds() const;
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 获取分钟数
|
|
||||||
float GetMinutes() const;
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 获取小时数
|
|
||||||
float GetHours() const;
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 时长是否是零
|
|
||||||
/// @return 若时长是零,返回true
|
|
||||||
bool IsZero() const;
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 设置毫秒数
|
|
||||||
/// @param ms 毫秒数
|
|
||||||
void SetMilliseconds(int64_t ms);
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 设置秒数
|
|
||||||
/// @param seconds 秒数
|
|
||||||
void SetSeconds(float seconds);
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 设置分钟数
|
|
||||||
/// @param minutes 分钟数
|
|
||||||
void SetMinutes(float minutes);
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 设置小时数
|
|
||||||
/// @param hours 小时数
|
|
||||||
void SetHours(float hours);
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 休眠
|
|
||||||
void Sleep() const;
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 转为字符串
|
|
||||||
String ToString() const;
|
|
||||||
|
|
||||||
/// \~chinese
|
|
||||||
/// @brief 解析时间段字符串
|
|
||||||
/// @param str 时间段字符串
|
|
||||||
/// @details
|
|
||||||
/// 时间段字符串允许是有符号的浮点数, 并且带有时间单位后缀
|
|
||||||
/// 例如: "300ms", "-1.5h", "2h45m"
|
|
||||||
/// 允许的时间单位有 "ms", "s", "m", "h"
|
|
||||||
/// @return 解析出的时间段
|
|
||||||
/// @throw kiwano::RuntimeError 传入一个不合法的格式时抛出
|
|
||||||
static Duration Parse(const String& str);
|
|
||||||
|
|
||||||
static const Duration Ms; ///< 毫秒
|
|
||||||
static const Duration Second; ///< 秒
|
|
||||||
static const Duration Minute; ///< 分钟
|
|
||||||
static const Duration Hour; ///< 小时
|
|
||||||
|
|
||||||
bool operator==(const Duration&) const;
|
|
||||||
bool operator!=(const Duration&) const;
|
|
||||||
bool operator>(const Duration&) const;
|
|
||||||
bool operator>=(const Duration&) const;
|
|
||||||
bool operator<(const Duration&) const;
|
|
||||||
bool operator<=(const Duration&) const;
|
|
||||||
|
|
||||||
float operator/(const Duration&) const;
|
|
||||||
|
|
||||||
const Duration operator+(const Duration&) const;
|
|
||||||
const Duration operator-(const Duration&) const;
|
|
||||||
const Duration operator-() const;
|
|
||||||
const Duration operator*(int)const;
|
|
||||||
const Duration operator*(unsigned long long)const;
|
|
||||||
const Duration operator*(float)const;
|
|
||||||
const Duration operator*(double)const;
|
|
||||||
const Duration operator*(long double)const;
|
|
||||||
const Duration operator/(int) const;
|
|
||||||
const Duration operator/(float) const;
|
|
||||||
const Duration operator/(double) const;
|
|
||||||
|
|
||||||
Duration& operator+=(const Duration&);
|
|
||||||
Duration& operator-=(const Duration&);
|
|
||||||
Duration& operator*=(int);
|
|
||||||
Duration& operator*=(float);
|
|
||||||
Duration& operator*=(double);
|
|
||||||
Duration& operator/=(int);
|
|
||||||
Duration& operator/=(float);
|
|
||||||
Duration& operator/=(double);
|
|
||||||
|
|
||||||
friend const Duration operator*(int, const Duration&);
|
|
||||||
friend const Duration operator*(float, const Duration&);
|
|
||||||
friend const Duration operator*(double, const Duration&);
|
|
||||||
friend const Duration operator*(long double, const Duration&);
|
|
||||||
friend const Duration operator/(int, const Duration&);
|
|
||||||
friend const Duration operator/(float, const Duration&);
|
|
||||||
friend const Duration operator/(double, const Duration&);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int64_t milliseconds_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \~chinese
|
* \~chinese
|
||||||
* @brief 时间
|
* @brief 时间
|
||||||
|
|
@ -212,6 +74,11 @@ struct KGE_API ClockTime
|
||||||
{
|
{
|
||||||
ClockTime();
|
ClockTime();
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 是否是零时
|
||||||
|
/// @return 若是零时,返回true
|
||||||
|
bool IsZero() const;
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 获取当前时间戳
|
/// @brief 获取当前时间戳
|
||||||
int64_t GetTimeStamp() const;
|
int64_t GetTimeStamp() const;
|
||||||
|
|
@ -247,89 +114,14 @@ private:
|
||||||
int64_t ms_since_epoch_;
|
int64_t ms_since_epoch_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int64_t Duration::GetMilliseconds() const
|
|
||||||
{
|
|
||||||
return milliseconds_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Duration::IsZero() const
|
|
||||||
{
|
|
||||||
return milliseconds_ == 0LL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Duration::SetMilliseconds(int64_t ms)
|
|
||||||
{
|
|
||||||
milliseconds_ = ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Duration::SetSeconds(float seconds)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(seconds * 1000.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Duration::SetMinutes(float minutes)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(minutes * 60 * 1000.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Duration::SetHours(float hours)
|
|
||||||
{
|
|
||||||
milliseconds_ = static_cast<int64_t>(hours * 60 * 60 * 1000.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Time::IsZero() const
|
inline bool Time::IsZero() const
|
||||||
{
|
{
|
||||||
return dur_ == 0;
|
return dur_ == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool ClockTime::IsZero() const
|
||||||
|
{
|
||||||
|
return ms_since_epoch_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
||||||
#if defined(KGE_HAS_LITERALS)
|
|
||||||
|
|
||||||
namespace kiwano
|
|
||||||
{
|
|
||||||
inline namespace literals
|
|
||||||
{
|
|
||||||
inline const kiwano::Duration operator"" _msec(long double val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Ms * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const kiwano::Duration operator"" _msec(unsigned long long val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Ms * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const kiwano::Duration operator"" _sec(long double val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Second * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const kiwano::Duration operator"" _sec(unsigned long long val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Second * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const kiwano::Duration operator"" _min(long double val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Minute * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const kiwano::Duration operator"" _min(unsigned long long val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Minute * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const kiwano::Duration operator"" _hour(long double val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Hour * val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const kiwano::Duration operator"" _hour(unsigned long long val)
|
|
||||||
{
|
|
||||||
return kiwano::Duration::Hour * val;
|
|
||||||
}
|
|
||||||
} // namespace literals
|
|
||||||
} // namespace kiwano
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue