Skip to content

Instantly share code, notes, and snippets.

@Reputeless
Last active August 27, 2023 20:27
Show Gist options
  • Save Reputeless/94df4c03327bffe5f7ea3b8ea5718381 to your computer and use it in GitHub Desktop.
Save Reputeless/94df4c03327bffe5f7ea3b8ea5718381 to your computer and use it in GitHub Desktop.
# include <Siv3D.hpp>
namespace s3d
{
class EventTimer
{
public:
EventTimer() = default;
explicit EventTimer(double interval, StartImmediately startImmediately = StartImmediately::No)
: m_interval{ interval }
, m_accumulatedTime{ (startImmediately ? m_interval : 0.0) }
{
checkInterval();
}
EventTimer(const Duration& interval, StartImmediately startImmediately = StartImmediately::No)
: m_interval{ interval.count() }
, m_accumulatedTime{ (startImmediately ? m_interval : 0.0) }
{
checkInterval();
}
void setInterval(double interval)
{
m_interval = interval;
checkInterval();
}
void setInterval(const Duration& interval)
{
m_interval = interval.count();
checkInterval();
}
Array<double> update(double deltaTime = Scene::DeltaTime())
{
Array<double> deltas;
m_accumulatedTime += deltaTime;
while (m_interval <= m_accumulatedTime)
{
m_accumulatedTime -= m_interval;
deltas.push_back(m_accumulatedTime);
}
return deltas;
}
[[nodiscard]]
double getInterval() const noexcept
{
return m_interval;
}
void resetTime() noexcept
{
m_accumulatedTime = 0.0;
}
private:
static constexpr double DefaultInterval = 1.0;
double m_interval = 0.0;
double m_accumulatedTime = 0.0;
void checkInterval()
{
if (m_interval <= 0.0)
{
m_interval = DefaultInterval;
}
}
};
}
void Main()
{
EventTimer trigger{ 10ms, StartImmediately::Yes };
constexpr double Speed = 800.0;
Array<Circle> circles;
while (System::Update())
{
ClearPrint();
Print << circles.size();
const double deltaTime = Scene::DeltaTime();
for (auto& circle : circles)
{
circle.x += (Speed * deltaTime);
}
for (const auto& delta : trigger.update(deltaTime))
{
circles.emplace_back(-100.0 + (delta * Speed), 300.0, 2.0);
}
circles.remove_if([](const Circle& circle) { return (900.0 < circle.x); });
for (const auto& circle : circles)
{
circle.draw();
}
}
}
# include <Siv3D.hpp>
namespace s3d
{
class EventTrigger
{
public:
EventTrigger() = default;
template <class Fty>
EventTrigger(Fty&& event, double interval, StartImmediately startImmediately = StartImmediately::No)
: m_event{ std::forward<Fty>(event) }
, m_interval{ interval }
, m_accumulatedTime{ (startImmediately ? m_interval : 0.0) }
{
checkInterval();
}
template <class Fty>
EventTrigger(Fty&& event, const Duration& interval, StartImmediately startImmediately = StartImmediately::No)
: m_event{ std::forward<Fty>(event) }
, m_interval{ interval.count() }
, m_accumulatedTime{ (startImmediately ? m_interval : 0.0) }
{
checkInterval();
}
template <class Fty>
void set(Fty&& event, double interval, StartImmediately startImmediately = StartImmediately::No)
{
m_event = std::forward<Fty>(event);
m_interval = interval;
checkInterval();
m_accumulatedTime = (startImmediately ? m_interval : 0.0);
}
template <class Fty>
void set(Fty&& event, const Duration& interval, StartImmediately startImmediately = StartImmediately::No)
{
m_event = std::forward<Fty>(event);
m_interval = interval.count();
checkInterval();
m_accumulatedTime = (startImmediately ? m_interval : 0.0);
}
template <class Fty>
void setEvent(Fty&& event)
{
m_event = std::forward<Fty>(event);
}
void setInterval(double interval)
{
m_interval = interval;
checkInterval();
}
void update(double deltaTime = Scene::DeltaTime())
{
m_accumulatedTime += deltaTime;
while (m_interval <= m_accumulatedTime)
{
m_accumulatedTime -= m_interval;
if (m_event)
{
std::invoke(m_event);
}
}
}
[[nodiscard]]
bool hasEvent() const noexcept
{
return static_cast<bool>(m_event);
}
[[nodiscard]]
const std::function<void()>& getEvent() const noexcept
{
return m_event;
}
[[nodiscard]]
double getInterval() const noexcept
{
return m_interval;
}
void setInterval(const Duration& interval)
{
m_interval = interval.count();
checkInterval();
}
void resetTime() noexcept
{
m_accumulatedTime = 0.0;
}
void resetEvent() noexcept
{
m_event = nullptr;
}
private:
static constexpr double DefaultInterval = 1.0;
std::function<void()> m_event;
double m_interval = 0.0;
double m_accumulatedTime = 0.0;
void checkInterval()
{
if (m_interval <= 0.0)
{
m_interval = DefaultInterval;
}
}
};
}
void Main()
{
EventTrigger trigger1{ []() { Print << U"Hello"; }, 0.5s, StartImmediately::Yes };
EventTrigger trigger2;
trigger2.set([]() { Print << U"World"; }, 1.0s, StartImmediately::Yes);
Array<Circle> circles;
EventTrigger trigger3{ [&]() { circles.emplace_back(RandomVec2(Scene::Rect()), 40.0); }, 0.2s, StartImmediately::Yes };
while (System::Update())
{
const double deltaTime = Scene::DeltaTime();
trigger1.update();
trigger2.update();
trigger3.update();
for (auto& circle : circles)
{
circle.r -= (20.0 * deltaTime);
}
circles.remove_if([](const Circle& circle) { return (circle.r <= 0.0); });
for (const auto& circle : circles)
{
circle.draw(ColorF{ 0.8, 0.9, 1.0, 0.8 });
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment