alecthomas / entityx

EntityX - A fast, type-safe C++ Entity-Component system
MIT License
2.22k stars 295 forks source link

Component buffer #150

Closed reinzor closed 8 years ago

reinzor commented 8 years ago

For an application, I would like to use your entity x framework. However, this application requires accessing components from specific timestamps. It would be nice if I could buffer the components over time with a fixed buffer size and query those for example; example API:

Entity e = em.create();
e.assign<Position>(1, 2, time::now());
e.assign<Position>(2, 3, time::now() + 1.0);

e.component<Position>(time::now()); // 1,2
e.component<Position>(time::now()+2); // 2,3 - zero order hold or with possible system model that tells us how the component evolves over time

Can you give me your thoughts about this?

Thanks!

sansumbrella commented 8 years ago

You probably want some kind of Channel implementation for your data. Then you can store channels of that data as/within components. EntityX only supports assignment of one component of each type to your entities, so the second assignment in your sample code would: a) throw an assertion in debug and b) silently overwrite the first assignment in release.

Instead, consider having your Position value store a channel of values of interest to you. I wrote a reasonably useful channel implementation as part of Choreograph. Using that, your code could look like the following:

struct Position {
   ch::Channel<vec2> values;
};

auto c = e.assign<Position>();
c->values.insertKey(vec2(1, 2), time::now(), Curve::Linear);
c->values.insertKey(vec2(2, 3), time::now() + 2.0, Curve::Hold);

c->values.value(time::now() + 1.0); // vec2(1.5, 2.5)
c->values.value(time::now() + 2.0); // clamped to end value

You can of course write your own Channel implementation to have the behavior you desire. I think the above provides something close to what you wrote above.

reinzor commented 8 years ago

Hi @sansumbrella ,

Thanks for your input; I will try this :)