update Time & Duration
This commit is contained in:
parent
de5a51462e
commit
aa921e53ba
|
|
@ -63,8 +63,8 @@ namespace easy2d
|
|||
{
|
||||
E2D_NOT_USED(dt);
|
||||
|
||||
frame_time_.push_back(time::Now());
|
||||
while (frame_time_.back() - frame_time_.front() >= time::Second)
|
||||
frame_time_.push_back(Time::Now());
|
||||
while (frame_time_.back() - frame_time_.front() >= time::Sec)
|
||||
{
|
||||
frame_time_.erase(frame_time_.begin());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,6 @@ namespace easy2d
|
|||
|
||||
protected:
|
||||
TextPtr debug_text_;
|
||||
Array<TimePoint> frame_time_;
|
||||
Array<Time> frame_time_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,65 +28,82 @@ namespace easy2d
|
|||
namespace time
|
||||
{
|
||||
//-------------------------------------------------------
|
||||
// TimePoint
|
||||
// Time
|
||||
//-------------------------------------------------------
|
||||
|
||||
TimePoint::TimePoint()
|
||||
Time::Time()
|
||||
{
|
||||
}
|
||||
|
||||
TimePoint::TimePoint(long dur)
|
||||
Time::Time(long dur)
|
||||
: dur_(dur)
|
||||
{
|
||||
}
|
||||
|
||||
const TimePoint TimePoint::operator+(const Duration & dur) const
|
||||
const Time Time::operator+(const Duration & dur) const
|
||||
{
|
||||
return TimePoint{ dur_ + dur.Milliseconds() };
|
||||
return Time{ dur_ + dur.Milliseconds() };
|
||||
}
|
||||
|
||||
const TimePoint TimePoint::operator-(const Duration & dur) const
|
||||
const Time Time::operator-(const Duration & dur) const
|
||||
{
|
||||
return TimePoint{ dur_ - dur.Milliseconds() };
|
||||
return Time{ dur_ - dur.Milliseconds() };
|
||||
}
|
||||
|
||||
TimePoint & TimePoint::operator+=(const Duration & other)
|
||||
Time & Time::operator+=(const Duration & other)
|
||||
{
|
||||
dur_ += other.Milliseconds();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
TimePoint & TimePoint::operator-=(const Duration &other)
|
||||
Time & Time::operator-=(const Duration &other)
|
||||
{
|
||||
dur_ -= other.Milliseconds();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const Duration TimePoint::operator-(const TimePoint & other) const
|
||||
const Duration Time::operator-(const Time & other) const
|
||||
{
|
||||
return Duration(dur_ - other.dur_);
|
||||
}
|
||||
|
||||
Time Time::Now() E2D_NOEXCEPT
|
||||
{
|
||||
static LARGE_INTEGER freq = {};
|
||||
if (freq.QuadPart == 0LL)
|
||||
{
|
||||
// the function will always succceed on systems that run Windows XP or later
|
||||
QueryPerformanceFrequency(&freq);
|
||||
}
|
||||
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
|
||||
const long long whole = (count.QuadPart / freq.QuadPart) * 1000LL;
|
||||
const long long part = (count.QuadPart % freq.QuadPart) * 1000LL / freq.QuadPart;
|
||||
return Time{ static_cast<long>(whole + part) };
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Duration
|
||||
//-------------------------------------------------------
|
||||
|
||||
const Duration Millisecond = 1L;
|
||||
const Duration Second = 1000 * Millisecond;
|
||||
const Duration Minute = 60 * Second;
|
||||
const Duration Hour = 60 * Minute;
|
||||
const Duration Ms = 1L;
|
||||
const Duration Sec = 1000 * Ms;
|
||||
const Duration Min = 60 * Sec;
|
||||
const Duration Hour = 60 * Min;
|
||||
|
||||
namespace
|
||||
{
|
||||
const auto duration_regex = std::wregex(LR"([-+]?([0-9]*(\.[0-9]*)?[a-z]+)+)");
|
||||
|
||||
typedef std::unordered_map<std::wstring, Duration> UnitMap;
|
||||
typedef std::unordered_map<String, Duration> UnitMap;
|
||||
const auto unit_map = UnitMap
|
||||
{
|
||||
{L"ms", Millisecond},
|
||||
{L"s", Second},
|
||||
{L"m", Minute},
|
||||
{L"ms", Ms},
|
||||
{L"s", Sec},
|
||||
{L"m", Min},
|
||||
{L"h", Hour}
|
||||
};
|
||||
}
|
||||
|
|
@ -103,49 +120,53 @@ namespace easy2d
|
|||
|
||||
float Duration::Seconds() const
|
||||
{
|
||||
long long sec = milliseconds_ / Second.milliseconds_;
|
||||
long long ms = milliseconds_ % Second.milliseconds_;
|
||||
long sec = milliseconds_ / Sec.milliseconds_;
|
||||
long ms = milliseconds_ % Sec.milliseconds_;
|
||||
return static_cast<float>(sec) + static_cast<float>(ms) / 1000.f;
|
||||
}
|
||||
|
||||
float Duration::Minutes() const
|
||||
{
|
||||
long long min = milliseconds_ / Minute.milliseconds_;
|
||||
long long ms = milliseconds_ % Minute.milliseconds_;
|
||||
long min = milliseconds_ / Min.milliseconds_;
|
||||
long ms = milliseconds_ % Min.milliseconds_;
|
||||
return static_cast<float>(min) + static_cast<float>(ms) / (60 * 1000.f);
|
||||
}
|
||||
|
||||
float Duration::Hours() const
|
||||
{
|
||||
long long hour = milliseconds_ / Hour.milliseconds_;
|
||||
long long ms = milliseconds_ % Hour.milliseconds_;
|
||||
long hour = milliseconds_ / Hour.milliseconds_;
|
||||
long ms = milliseconds_ % Hour.milliseconds_;
|
||||
return static_cast<float>(hour) + static_cast<float>(ms) / (60 * 60 * 1000.f);
|
||||
}
|
||||
|
||||
std::wstring easy2d::time::Duration::ToString() const
|
||||
String easy2d::time::Duration::ToString() const
|
||||
{
|
||||
if (IsZero())
|
||||
{
|
||||
return std::wstring(L"0s");
|
||||
return String(L"0s");
|
||||
}
|
||||
|
||||
std::wstring result;
|
||||
long long hour = milliseconds_ / Hour.milliseconds_;
|
||||
long long min = milliseconds_ / Minute.milliseconds_ - hour * 60;
|
||||
long long sec = milliseconds_ / Second.milliseconds_ - (hour * 60 * 60 + min * 60);
|
||||
long long ms = milliseconds_ % Second.milliseconds_;
|
||||
|
||||
if (milliseconds_ < 0)
|
||||
String result;
|
||||
long total_ms = milliseconds_;
|
||||
if (total_ms < 0)
|
||||
{
|
||||
result.append(L"-");
|
||||
total_ms = -total_ms;
|
||||
}
|
||||
|
||||
long hour = total_ms / Hour.milliseconds_;
|
||||
long min = total_ms / Min.milliseconds_ - hour * 60;
|
||||
long sec = total_ms / Sec.milliseconds_ - (hour * 60 * 60 + min * 60);
|
||||
long ms = total_ms % Sec.milliseconds_;
|
||||
|
||||
if (hour)
|
||||
{
|
||||
result.append(std::to_wstring(hour)).append(L"h");
|
||||
result.append(std::to_wstring(min)).append(L"m");
|
||||
result.append(easy2d::to_wstring(hour)).append(L"h");
|
||||
result.append(easy2d::to_wstring(min)).append(L"m");
|
||||
}
|
||||
else if(min)
|
||||
{
|
||||
result.append(std::to_wstring(min)).append(L"m");
|
||||
result.append(easy2d::to_wstring(min)).append(L"m");
|
||||
}
|
||||
|
||||
if (ms != 0)
|
||||
|
|
@ -162,7 +183,7 @@ namespace easy2d
|
|||
}
|
||||
else if (sec != 0)
|
||||
{
|
||||
result.append(std::to_wstring(sec)).append(L"s");
|
||||
result.append(easy2d::to_wstring(sec)).append(L"s");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -340,51 +361,16 @@ namespace easy2d
|
|||
return dur * val;
|
||||
}
|
||||
|
||||
std::wostream & easy2d::time::operator<<(std::wostream & out, const Duration & dur)
|
||||
{
|
||||
return out << dur.ToString();
|
||||
}
|
||||
|
||||
std::wistream & easy2d::time::operator>>(std::wistream & in, Duration & dur)
|
||||
{
|
||||
std::wstring str;
|
||||
in >> str;
|
||||
dur = time::ParseDuration(str);
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Functions
|
||||
//-------------------------------------------------------
|
||||
|
||||
TimePoint easy2d::time::Now() E2D_NOEXCEPT
|
||||
{
|
||||
static LARGE_INTEGER freq = {};
|
||||
if (freq.QuadPart == 0LL)
|
||||
{
|
||||
// the function will always succceed on systems that run Windows XP or later
|
||||
QueryPerformanceFrequency(&freq);
|
||||
}
|
||||
|
||||
LARGE_INTEGER count;
|
||||
QueryPerformanceCounter(&count);
|
||||
|
||||
const long long whole = (count.QuadPart / freq.QuadPart) * 1000LL;
|
||||
const long long part = (count.QuadPart % freq.QuadPart) * 1000LL / freq.QuadPart;
|
||||
return TimePoint{ static_cast<long>(whole + part) };
|
||||
}
|
||||
|
||||
Duration easy2d::time::ParseDuration(const std::wstring & str)
|
||||
Duration Duration::Parse(const String& str)
|
||||
{
|
||||
size_t len = str.length();
|
||||
size_t pos = 0;
|
||||
bool negative = false;
|
||||
Duration d;
|
||||
|
||||
if (!std::regex_match(str, duration_regex))
|
||||
if (!std::regex_match(str.c_str(), duration_regex))
|
||||
{
|
||||
E2D_ERROR_LOG(L"time::ParseDuration failed, invalid duration");
|
||||
E2D_ERROR_LOG(L"Duration::Parse failed, invalid duration");
|
||||
return Duration();
|
||||
}
|
||||
|
||||
|
|
@ -410,12 +396,12 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
std::wstring num_str = str.substr(pos, i - pos);
|
||||
String num_str = str.substr(pos, i - pos);
|
||||
pos = i;
|
||||
|
||||
if (num_str.empty() || num_str == L".")
|
||||
{
|
||||
E2D_ERROR_LOG(L"time::ParseDuration failed, invalid duration");
|
||||
E2D_ERROR_LOG(L"Duration::Parse failed, invalid duration");
|
||||
return Duration();
|
||||
}
|
||||
|
||||
|
|
@ -429,16 +415,16 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
std::wstring unit_str = str.substr(pos, i - pos);
|
||||
String unit_str = str.substr(pos, i - pos);
|
||||
pos = i;
|
||||
|
||||
if (unit_map.find(unit_str) == unit_map.end())
|
||||
{
|
||||
E2D_ERROR_LOG(L"time::ParseDuration failed, invalid duration");
|
||||
E2D_ERROR_LOG(L"Duration::Parse failed, invalid duration");
|
||||
return Duration();
|
||||
}
|
||||
|
||||
double num = std::stod(num_str);
|
||||
double num = std::wcstod(num_str.c_str(), nullptr);
|
||||
Duration unit = unit_map.at(unit_str);
|
||||
d += unit * num;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
#pragma once
|
||||
#include "../macros.h"
|
||||
#include "../common/String.h"
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -28,9 +31,9 @@ namespace easy2d
|
|||
// 时间段
|
||||
//
|
||||
// 时间段表示法:
|
||||
// 5 秒: time::Second * 5
|
||||
// 5 秒: time::Sec * 5
|
||||
// 1.5 小时: time::Hour * 1.5
|
||||
// 3 小时 45 分 15 秒: time::Hour * 3 + time::Minute * 45 + time::Second * 15
|
||||
// 3 小时 45 分 15 秒: time::Hour * 3 + time::Min * 45 + time::Sec * 15
|
||||
// 在 VS2015 及更高版本可以使用 time literals:
|
||||
// 5 秒: 5_s
|
||||
// 1.5 小时: 1.5_h
|
||||
|
|
@ -60,7 +63,7 @@ namespace easy2d
|
|||
inline bool IsZero() const { return milliseconds_ == 0LL; }
|
||||
|
||||
// 转为字符串
|
||||
std::wstring ToString() const;
|
||||
String ToString() const;
|
||||
|
||||
inline operator bool() const { return !IsZero(); }
|
||||
|
||||
|
|
@ -102,60 +105,75 @@ namespace easy2d
|
|||
friend const Duration operator/ (float, const Duration &);
|
||||
friend const Duration operator/ (double, const Duration &);
|
||||
|
||||
friend std::wostream& operator<< (std::wostream &, const Duration &);
|
||||
friend std::wistream& operator>> (std::wistream &, Duration &);
|
||||
public:
|
||||
// 时间段格式化
|
||||
//
|
||||
// 时间段字符串允许是有符号的浮点数, 并且带有时间单位后缀
|
||||
// 例如: "300ms", "-1.5h", "2h45m"
|
||||
// 允许的时间单位有 "ms", "s", "m", "h"
|
||||
static Duration Parse(const String& parse_str);
|
||||
|
||||
template <typename _Char>
|
||||
friend inline std::basic_ostream<_Char>& operator<<(std::basic_ostream<_Char>& out, const Duration& dur)
|
||||
{
|
||||
return out << dur.ToString();
|
||||
}
|
||||
|
||||
template <typename _Char>
|
||||
friend inline std::basic_istream<_Char>& operator>>(std::basic_istream<_Char>& in, Duration& dur)
|
||||
{
|
||||
String str;
|
||||
if (in >> str)
|
||||
{
|
||||
dur = Duration::Parse(str);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
private:
|
||||
long milliseconds_;
|
||||
};
|
||||
|
||||
/* 预定义的时间段 */
|
||||
E2D_API extern const Duration Millisecond; // 毫秒
|
||||
E2D_API extern const Duration Second; // 秒
|
||||
E2D_API extern const Duration Minute; // 分钟
|
||||
E2D_API extern const Duration Ms; // 毫秒
|
||||
E2D_API extern const Duration Sec; // 秒
|
||||
E2D_API extern const Duration Min; // 分钟
|
||||
E2D_API extern const Duration Hour; // 小时
|
||||
|
||||
|
||||
// 时间
|
||||
//
|
||||
// 获取当前时间: TimePoint now = time::Now();
|
||||
// 获取当前时间: Time now = Time::Now();
|
||||
// 两时间相减, 得到一个 Duration 对象, 例如:
|
||||
// TimePoint t1, t2;
|
||||
// Time t1, t2;
|
||||
// int ms = (t2 - t1).Milliseconds(); // 获取两时间相差的毫秒数
|
||||
//
|
||||
struct E2D_API TimePoint
|
||||
struct E2D_API Time
|
||||
{
|
||||
TimePoint();
|
||||
Time();
|
||||
|
||||
TimePoint(long);
|
||||
Time(long);
|
||||
|
||||
// 是否是零时
|
||||
inline bool IsZero() const { return dur_ == 0; }
|
||||
|
||||
const TimePoint operator + (const Duration &) const;
|
||||
const TimePoint operator - (const Duration &) const;
|
||||
const Time operator + (const Duration &) const;
|
||||
const Time operator - (const Duration &) const;
|
||||
|
||||
TimePoint& operator += (const Duration &);
|
||||
TimePoint& operator -= (const Duration &);
|
||||
Time& operator += (const Duration &);
|
||||
Time& operator -= (const Duration &);
|
||||
|
||||
const Duration operator - (const TimePoint &) const;
|
||||
const Duration operator - (const Time &) const;
|
||||
|
||||
public:
|
||||
// 获取当前时间
|
||||
// 由于该时间点基于系统启动时间开始计算, 所以无法格式化该时间,
|
||||
// 也无法获得该时间的 Unix 时间戳
|
||||
static Time Now() E2D_NOEXCEPT;
|
||||
|
||||
private:
|
||||
long dur_;
|
||||
};
|
||||
|
||||
// 获取当前时间
|
||||
//
|
||||
// 由于该时间点基于系统启动时间开始计算, 所以无法格式化该时间,
|
||||
// 也无法获得该时间的 Unix 时间戳
|
||||
E2D_API TimePoint Now() E2D_NOEXCEPT;
|
||||
|
||||
// 时间段格式化
|
||||
//
|
||||
// 时间段字符串允许是有符号的浮点数, 并且带有时间单位后缀
|
||||
// 例如: "300ms", "-1.5h", "2h45m"
|
||||
// 允许的时间单位有 "ms", "s", "m", "h"
|
||||
E2D_API Duration ParseDuration(const std::wstring& parse_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,17 +190,17 @@ namespace easy2d
|
|||
{
|
||||
inline const easy2d::time::Duration operator "" _ms(long double val)
|
||||
{
|
||||
return easy2d::time::Millisecond * val;
|
||||
return easy2d::time::Ms * val;
|
||||
}
|
||||
|
||||
inline const easy2d::time::Duration operator "" _s(long double val)
|
||||
{
|
||||
return easy2d::time::Second * val;
|
||||
return easy2d::time::Sec * val;
|
||||
}
|
||||
|
||||
inline const easy2d::time::Duration operator "" _m(long double val)
|
||||
{
|
||||
return easy2d::time::Minute * val;
|
||||
return easy2d::time::Min * val;
|
||||
}
|
||||
|
||||
inline const easy2d::time::Duration operator "" _h(long double val)
|
||||
|
|
@ -192,17 +210,17 @@ namespace easy2d
|
|||
|
||||
inline const easy2d::time::Duration operator "" _ms(unsigned long long val)
|
||||
{
|
||||
return easy2d::time::Millisecond * val;
|
||||
return easy2d::time::Ms * val;
|
||||
}
|
||||
|
||||
inline const easy2d::time::Duration operator "" _s(unsigned long long val)
|
||||
{
|
||||
return easy2d::time::Second * val;
|
||||
return easy2d::time::Sec * val;
|
||||
}
|
||||
|
||||
inline const easy2d::time::Duration operator "" _m(unsigned long long val)
|
||||
{
|
||||
return easy2d::time::Minute * val;
|
||||
return easy2d::time::Min * val;
|
||||
}
|
||||
|
||||
inline const easy2d::time::Duration operator "" _h(unsigned long long val)
|
||||
|
|
|
|||
|
|
@ -351,6 +351,9 @@ namespace easy2d
|
|||
std::basic_ostream<String::value_type>& operator<<(std::basic_ostream<String::value_type>& os, const String & str);
|
||||
std::basic_istream<String::value_type>& operator>>(std::basic_istream<String::value_type>& is, String & str);
|
||||
|
||||
std::basic_ostream<char>& operator<<(std::basic_ostream<char>& os, const String& str);
|
||||
std::basic_istream<char>& operator>>(std::basic_istream<char>& is, String& str);
|
||||
|
||||
//
|
||||
// to_string functions
|
||||
//
|
||||
|
|
@ -1236,6 +1239,21 @@ namespace easy2d
|
|||
return is;
|
||||
}
|
||||
|
||||
inline std::basic_ostream<char>& operator<<(std::basic_ostream<char>& os, const String& str)
|
||||
{
|
||||
return os << str.to_string();
|
||||
}
|
||||
|
||||
inline std::basic_istream<char>& operator>>(std::basic_istream<char>& is, String& str)
|
||||
{
|
||||
std::string tmp;
|
||||
if (is >> tmp)
|
||||
{
|
||||
str = tmp;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
//
|
||||
// details of to_string functions
|
||||
//
|
||||
|
|
|
|||
|
|
@ -328,9 +328,9 @@ namespace easy2d
|
|||
|
||||
void Application::Update()
|
||||
{
|
||||
static auto last = time::Now();
|
||||
static auto last = Time::Now();
|
||||
|
||||
const auto now = time::Now();
|
||||
const auto now = Time::Now();
|
||||
const auto dt = (now - last) * time_scale_;
|
||||
last = now;
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ namespace easy2d
|
|||
|
||||
if (collecting_data_)
|
||||
{
|
||||
status_.start = time::Now();
|
||||
status_.start = Time::Now();
|
||||
status_.primitives = 0;
|
||||
}
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ namespace easy2d
|
|||
|
||||
if (collecting_data_)
|
||||
{
|
||||
status_.duration = time::Now() - status_.start;
|
||||
status_.duration = Time::Now() - status_.start;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace easy2d
|
|||
{
|
||||
struct RenderStatus
|
||||
{
|
||||
TimePoint start;
|
||||
Time start;
|
||||
Duration duration;
|
||||
int primitives;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
#include "easy2d.h"
|
||||
|
||||
using namespace easy2d;
|
||||
|
||||
const int WINDOW_WIDTH = 640;
|
||||
const int WINDOW_HEIGHT = 480;
|
||||
|
||||
class MainScene
|
||||
: public easy2d::Scene
|
||||
: public Scene
|
||||
{
|
||||
public:
|
||||
MainScene()
|
||||
{
|
||||
// 创建文字节点
|
||||
easy2d::TextPtr text = new easy2d::Text(L"Hello Easy2D!");
|
||||
TextPtr text = new Text(L"Hello Easy2D!");
|
||||
// 设置节点大小为文字布局大小
|
||||
text->SetSize(text->GetLayoutSize());
|
||||
// 修改节点位置, 使节点在屏幕上居中
|
||||
|
|
@ -29,10 +31,10 @@ int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
|||
try
|
||||
{
|
||||
// 创建 Easy2D 程序实例
|
||||
easy2d::Application app;
|
||||
Application app;
|
||||
|
||||
// 创建初始化选项
|
||||
easy2d::Options options;
|
||||
Options options;
|
||||
// 设置窗口宽高
|
||||
options.width = WINDOW_WIDTH;
|
||||
options.height = WINDOW_HEIGHT;
|
||||
|
|
@ -40,7 +42,7 @@ int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
|||
app.Init(options);
|
||||
|
||||
// 创建场景并进入
|
||||
easy2d::ScenePtr scene = new MainScene;
|
||||
ScenePtr scene = new MainScene;
|
||||
app.EnterScene(scene);
|
||||
|
||||
// 运行
|
||||
|
|
|
|||
Loading…
Reference in New Issue