SanderMertens / flecs

A fast entity component system (ECS) for C & C++

Home Page:https://www.flecs.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

delta_time() functions don't always provide consistent values

yanto77 opened this issue · comments

Describe the bug
The flecs::iter::delta_time() and flecs::entity_view::delta_time() functions don't always provide consistent values.

To Reproduce

Repro code
#include <flecs/flecs.h>

int main(void)
{
    flecs::world world;
    world.entity().set<Vector3>({});
    world.set_target_fps(60);

    auto sys1 = world.system<Vector3>()
        .each([](flecs::entity e, Vector3&) {
            TraceLog(LOG_INFO, "    each: %f", e.delta_time());
        });

    auto sys2 = world.system<Vector3>()
        .iter([](flecs::iter& it, Vector3*) {
            TraceLog(LOG_INFO, "    iter: %f", it.delta_time());
        });

    TraceLog(LOG_INFO, "world progress:");
    // world.progress(5.0f); // << Experiment with different values

    TraceLog(LOG_INFO, "implicit delta:");
    sys1.run();
    sys2.run();

    TraceLog(LOG_INFO, "explicit delta:");
    sys1.run(10.0f);
    sys2.run(10.0f);

    return 0;
}

Expected behavior

Please find below example outputs collected from repro code above. The unexpected values are marked.

  • In 1st case, it seems like explicitly given delta_time is always ignored, and instead world's own delta_time is used.
  • In 2nd case, it seems like the value is always zero.
1. flecs::entity_view::delta_time() ignores explicit delta_time parameter
without world.progress:
    INFO: world progress:
    INFO: implicit delta:   each: 0.000000
    INFO: explicit delta:   each: 0.000000          << should be 10.0

with world.progress():            
    INFO: world progress:   each: 0.016667
    INFO: implicit delta:   each: 0.016667
    INFO: explicit delta:   each: 0.016667          << should be 10.0

with world.progress(5.0):
    INFO: world progress:   each: 5.000000
    INFO: implicit delta:   each: 5.000000
    INFO: explicit delta:   each: 5.000000          << should be 10.0
2. flecs::iter::delta_time() ignores world's delta_time
without progress:
    INFO: world progress:
    INFO: implicit delta:   iter: 0.000000          << ok
    INFO: explicit delta:   iter: 10.000000

with progress():            
    INFO: world progress    iter: 0.016667
    INFO: implicit delta:   iter: 0.000000          << should be 0.016667
    INFO: explicit delta:   iter: 10.000000

with progress(5.0)
    INFO: world progress:   iter: 5.000000
    INFO: implicit delta:   iter: 0.000000          << should be 5.000000
    INFO: explicit delta:   iter: 10.000000

Additional context

I'm relatively new to the library, so I'm maybe misunderstanding/misusing something. I've read the Systems / Using delta_time part of the documentation. I can reproduce this on the latest commit (822fe0b). The issue is not a blocker, as it's possible to use the pairs that work as expected (explicit delta + iter.delta_time() OR implicit delta + entity.delta_time()).

Ah this happens as a result of how e.delta_time() gets its value, which is from a source that's only set when you call world.progress().

I'll remove the entity_view::delta_time function, it doesn't really belong on the entity, and there is now a variant of the iteration function that allows for accessing flecs::iter from each which makes it redundant:

    auto sys1 = world.system<Vector3>()
        .each([](flecs::iter& it, size_t i, Vector3&) {
            flecs::entity e = it.entity(i);
            TraceLog(LOG_INFO, "    each: %f", iter.delta_time());
        });

After the changes, the output looks like this, which is expected:

// implicit progress: measures dt when no argument is provided
each: delta_time: 0.0166667
iter: delta_time: 0.0166667

// explicit progress
each: delta_time: 2
iter: delta_time: 2

// implicit s.run(): does not measure dt when no argument is provided
implicit
each: delta_time: 0
iter: delta_time: 0

// explicit s.run()
each: delta_time: 10
iter: delta_time: 10

Awesome, thank you!