@@ -30,6 +30,7 @@ void stbi_image_free(void *);
3030#include < thread>
3131#include < unordered_map>
3232#include < vector>
33+ #include < deque>
3334#include < atomic>
3435
3536#include < climits>
@@ -132,6 +133,8 @@ class Overlay {
132133 std::vector<int > m_selector_indices;
133134 std::discrete_distribution<> m_selector;
134135 std::mt19937 m_rng{std::random_device{}()};
136+ std::deque<std::chrono::steady_clock::time_point> m_spawn_times;
137+ int m_badges_per_second_max = 12 ;
135138 gl::Texture m_texture;
136139 gl::VertexArray m_vao;
137140 gl::Buffer m_vbo;
@@ -204,6 +207,7 @@ bool Overlay::init(const app::Config &cfg, std::optional<std::filesystem::path>
204207 }
205208 m_badge_min_px = cfg.badge_min_px ();
206209 m_badge_max_px = cfg.badge_max_px ();
210+ m_badges_per_second_max = cfg.badges_per_second_max ();
207211 update_frame_interval ();
208212#ifdef LIZARD_TEST
209213 if (emoji_path && emoji_path->extension () == " .png" ) {
@@ -677,6 +681,15 @@ void Overlay::spawn_badge(int sprite, float x, float y) {
677681 return ;
678682 }
679683
684+ auto now = std::chrono::steady_clock::now ();
685+ while (!m_spawn_times.empty () && now - m_spawn_times.front () > std::chrono::seconds (1 )) {
686+ m_spawn_times.pop_front ();
687+ }
688+ if (m_badges_per_second_max > 0 &&
689+ static_cast <int >(m_spawn_times.size ()) >= m_badges_per_second_max) {
690+ return ;
691+ }
692+
680693 float px = x;
681694 float py = y;
682695 if (m_spawn_strategy == BadgeSpawnStrategy::RandomScreen) {
@@ -712,6 +725,7 @@ void Overlay::spawn_badge(int sprite, float x, float y) {
712725
713726 m_badges.emplace_back (Badge{px, py, vx, vy, phase, scale, 0 .0f , rotation, 0 .0f , lifetime, fade_in,
714727 fade_out, sprite});
728+ m_spawn_times.push_back (now);
715729}
716730
717731void Overlay::stop () { m_running = false ; }
0 commit comments