From c4b01f92a3f9a2ddcaf2f82d6b711f88661a7713 Mon Sep 17 00:00:00 2001 From: Sander Mertens Date: Mon, 28 Aug 2023 17:05:57 -0700 Subject: [PATCH] Randomize time value for systems with interval to reduce spiking behavior --- flecs.c | 3 ++- flecs.h | 2 ++ src/addons/timer.c | 3 ++- test/cpp_api/src/System.cpp | 3 +++ test/custom_builds/c/timer/src/main.c | 3 +++ test/custom_builds/cpp/timer/src/main.cpp | 5 ++++- 6 files changed, 16 insertions(+), 3 deletions(-) diff --git a/flecs.c b/flecs.c index 79e5bed129..57b81a25dd 100644 --- a/flecs.c +++ b/flecs.c @@ -35945,7 +35945,8 @@ ecs_entity_t ecs_set_interval( timer = ecs_set(world, timer, EcsTimer, { .timeout = interval, - .active = true + .active = true, + .time = ((ecs_ftime_t)rand() / (ecs_ftime_t)RAND_MAX) * interval }); ecs_system_t *system_data = ecs_poly_get(world, timer, ecs_system_t); diff --git a/flecs.h b/flecs.h index 80a95fe33d..267b91cca4 100644 --- a/flecs.h +++ b/flecs.h @@ -565,6 +565,8 @@ extern "C" { #pragma clang diagnostic ignored "-Wenum-constexpr-conversion" /* Very difficult to workaround this warning in C, especially for an ECS. */ #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" +/* This warning gets thrown when trying to cast pointer returned from dlproc */ +#pragma clang diagnostic ignored "-Wcast-function-type-strict" #elif defined(ECS_TARGET_GNU) #ifndef __cplusplus #pragma GCC diagnostic ignored "-Wdeclaration-after-statement" diff --git a/src/addons/timer.c b/src/addons/timer.c index 9a17b10016..8dd6098739 100644 --- a/src/addons/timer.c +++ b/src/addons/timer.c @@ -153,7 +153,8 @@ ecs_entity_t ecs_set_interval( timer = ecs_set(world, timer, EcsTimer, { .timeout = interval, - .active = true + .active = true, + .time = ((ecs_ftime_t)rand() / (ecs_ftime_t)RAND_MAX) * interval }); ecs_system_t *system_data = ecs_poly_get(world, timer, ecs_system_t); diff --git a/test/cpp_api/src/System.cpp b/test/cpp_api/src/System.cpp index 5e99a1a462..b1a84664b6 100644 --- a/test/cpp_api/src/System.cpp +++ b/test/cpp_api/src/System.cpp @@ -2043,6 +2043,9 @@ void System_interval_tick_source(void) { flecs::timer t = ecs.timer().interval(2.1); + flecs::Timer *timer = t.get_mut(); + timer->time = 0; + int32_t sys_a_invoked = 0, sys_b_invoked = 0; ecs.system() diff --git a/test/custom_builds/c/timer/src/main.c b/test/custom_builds/c/timer/src/main.c index 0557a4c27f..8e3534c6b0 100644 --- a/test/custom_builds/c/timer/src/main.c +++ b/test/custom_builds/c/timer/src/main.c @@ -28,6 +28,9 @@ int main(int argc, char *argv[]) { }); assert(s != 0); + EcsTimer *timer = ecs_get_mut(world, s, EcsTimer); + timer->time = 0; + ecs_entity_t e = ecs_new_id(world); ecs_set(world, e, Position, {10, 20}); ecs_set(world, e, Velocity, {1, 2}); diff --git a/test/custom_builds/cpp/timer/src/main.cpp b/test/custom_builds/cpp/timer/src/main.cpp index d2b135e869..3f4e2703cd 100644 --- a/test/custom_builds/cpp/timer/src/main.cpp +++ b/test/custom_builds/cpp/timer/src/main.cpp @@ -12,13 +12,16 @@ struct Velocity { int main(int, char *[]) { flecs::world ecs; - ecs.system() + flecs::entity s = ecs.system() .interval(2.9f) .each([](Position& p, const Velocity& v) { p.x += v.x; p.y += v.y; }); + flecs::Timer *t = s.get_mut(); + t->time = 0; + auto e = ecs.entity() .set({10, 20}) .set({1, 2});