Skip to content

Instantly share code, notes, and snippets.

@tomolatoon
Last active August 13, 2023 08:37
Show Gist options
  • Save tomolatoon/86456ce51d99dca76d22ce016cad6db5 to your computer and use it in GitHub Desktop.
Save tomolatoon/86456ce51d99dca76d22ce016cad6db5 to your computer and use it in GitHub Desktop.
#include <Siv3D.hpp>
struct Interval
{
// ディスパッチ用のタグ
// 何回発火したかの値を返す版
inline static constexpr struct CountTag
{
} Count{};
// 何回発火したかの値を step した版
inline static constexpr struct CountRangeTag
{
} CountRange{};
// 何秒前に発火したかの正の値の配列を返す版
inline static constexpr struct TimesTag
{
} FireTimes{};
Interval(double m_intervalSec)
: m_intervalSec(m_intervalSec) {}
size_t update(CountTag = Count, double deltaTime = Scene::DeltaTime())
{
m_accumulatedTimeSec += deltaTime;
if (m_intervalSec == 0.0)
{
return 1;
}
size_t count = m_accumulatedTimeSec / m_intervalSec;
m_accumulatedTimeSec = Math::Fmod(m_accumulatedTimeSec, m_intervalSec);
return count;
}
// 何回発火したかの値を step した版(std::views::iota が使えればそちらで)
Step<size_t, size_t, int32_t> update(CountRangeTag, double deltaTime = Scene::DeltaTime())
{
m_accumulatedTimeSec += deltaTime;
if (m_intervalSec == 0.0)
{
return step(size_t(1));
}
size_t count = m_accumulatedTimeSec / m_intervalSec;
m_accumulatedTimeSec = Math::Fmod(m_accumulatedTimeSec, m_intervalSec);
return step(count);
}
// 何秒前に発火したかの正の値の配列
Array<double> update(TimesTag, double deltaTime = Scene::DeltaTime())
{
m_accumulatedTimeSec += deltaTime;
if (m_intervalSec == 0.0)
{
return {0};
}
size_t count = m_accumulatedTimeSec / m_intervalSec;
m_accumulatedTimeSec = Math::Fmod(m_accumulatedTimeSec, m_intervalSec);
Array<double> res(count);
size_t i = 0;
std::generate(res.rbegin(), res.rend(), [&]() { return i++ * m_intervalSec; });
return res;
}
private:
double m_intervalSec = 0.0;
double m_accumulatedTimeSec = 0.0;
};
void Main()
{
Interval interval{0.001};
while (System::Update())
{
// .update(Interval::Count) と同じ
for (auto&& c : step(interval.update()))
{
Print << c;
}
for (auto&& c : interval.update(Interval::CountRange))
{
Print << c;
}
for (auto&& t : interval.update(Interval::FireTimes))
{
Print << t;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment