@@ -7,21 +7,37 @@ namespace safecrowd::engine {
77namespace {
88
99void validateDescriptor (const SystemDescriptor& descriptor) {
10- if (descriptor.triggerPolicy == TriggerPolicy::Interval) {
11- throw std::invalid_argument (" TriggerPolicy::Interval is not supported yet." );
12- }
13-
14- if (descriptor.phase == UpdatePhase::FixedSimulation &&
15- descriptor.triggerPolicy != TriggerPolicy::FixedStep) {
10+ if (descriptor.triggerPolicy == TriggerPolicy::Interval &&
11+ descriptor.intervalTicks == 0 ) {
1612 throw std::invalid_argument (
17- " FixedSimulation systems must use TriggerPolicy::FixedStep ." );
13+ " TriggerPolicy::Interval requires intervalTicks > 0 ." );
1814 }
1915
20- if (descriptor.phase != UpdatePhase::FixedSimulation &&
21- descriptor.phase != UpdatePhase::Startup &&
22- descriptor.triggerPolicy != TriggerPolicy::EveryFrame) {
23- throw std::invalid_argument (
24- " Frame phases must use TriggerPolicy::EveryFrame." );
16+ switch (descriptor.phase ) {
17+ case UpdatePhase::Startup:
18+ if (descriptor.triggerPolicy != TriggerPolicy::EveryFrame) {
19+ throw std::invalid_argument (
20+ " Startup systems must use TriggerPolicy::EveryFrame." );
21+ }
22+ break ;
23+
24+ case UpdatePhase::FixedSimulation:
25+ if (descriptor.triggerPolicy == TriggerPolicy::EveryFrame) {
26+ throw std::invalid_argument (
27+ " FixedSimulation systems must use TriggerPolicy::FixedStep or "
28+ " TriggerPolicy::Interval." );
29+ }
30+ break ;
31+
32+ case UpdatePhase::PreSimulation:
33+ case UpdatePhase::PostSimulation:
34+ case UpdatePhase::RenderSync:
35+ if (descriptor.triggerPolicy == TriggerPolicy::FixedStep) {
36+ throw std::invalid_argument (
37+ " Frame phases must use TriggerPolicy::EveryFrame or "
38+ " TriggerPolicy::Interval." );
39+ }
40+ break ;
2541 }
2642}
2743
@@ -55,15 +71,46 @@ void SystemScheduler::executeStartup(EngineWorld& world, const EngineStepContext
5571 buffer_.flush (core_);
5672}
5773
58- void SystemScheduler::executePhase (UpdatePhase phase, TriggerPolicy triggerPolicy,
59- EngineWorld& world, const EngineStepContext& ctx) {
74+ void SystemScheduler::executePhase (UpdatePhase phase, EngineWorld& world,
75+ const EngineStepContext& ctx) {
76+ auto shouldExecuteInterval = [](Entry& entry) {
77+ if (entry.intervalCountdown == 0 ) {
78+ entry.intervalCountdown = entry.descriptor .intervalTicks - 1 ;
79+ return true ;
80+ }
81+
82+ --entry.intervalCountdown ;
83+ return false ;
84+ };
85+
6086 for (auto & e : entries_) {
61- if (e.descriptor .phase == phase &&
62- e.descriptor .triggerPolicy == triggerPolicy) {
87+ if (e.descriptor .phase != phase) {
88+ continue ;
89+ }
90+
91+ bool shouldExecute = false ;
92+ switch (e.descriptor .triggerPolicy ) {
93+ case TriggerPolicy::EveryFrame:
94+ case TriggerPolicy::FixedStep:
95+ shouldExecute = true ;
96+ break ;
97+
98+ case TriggerPolicy::Interval:
99+ shouldExecute = shouldExecuteInterval (e);
100+ break ;
101+ }
102+
103+ if (shouldExecute) {
63104 e.system ->update (world, ctx);
64105 }
65106 }
66107 buffer_.flush (core_);
67108}
68109
110+ void SystemScheduler::resetCadenceState () {
111+ for (auto & e : entries_) {
112+ e.intervalCountdown = 0 ;
113+ }
114+ }
115+
69116} // namespace safecrowd::engine
0 commit comments