Skip to content

Commit 73f89de

Browse files
authored
Merge pull request #94 from supermarsx/smx/track-timestamps-for-recent-spawns-2025-09-11
Limit badge spawns per second
2 parents 53a0756 + 8999294 commit 73f89de

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

src/overlay/overlay.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

717731
void Overlay::stop() { m_running = false; }

src/tests/overlay_tests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,14 @@ TEST_CASE("cursor_follow strategy uses provided coordinates", "[overlay]") {
203203
REQUIRE(b.x == Approx(0.25f));
204204
REQUIRE(b.y == Approx(0.75f));
205205
}
206+
207+
TEST_CASE("badge spawns respect per-second limit", "[overlay]") {
208+
Config cfg(std::filesystem::temp_directory_path());
209+
cfg.badges_per_second_max_ = 2;
210+
Overlay ov;
211+
ov.init(cfg);
212+
ov.spawn_badge(0, 0.0f, 0.0f);
213+
ov.spawn_badge(0, 0.0f, 0.0f);
214+
ov.spawn_badge(0, 0.0f, 0.0f);
215+
REQUIRE(OverlayTestAccess::badges(ov).size() == 2);
216+
}

0 commit comments

Comments
 (0)