On Sun, Jan 11, 2015 at 8:41 AM, Matus Chochlik
On Sun, Jan 11, 2015 at 2:05 AM, Klaim - Joël Lamotte
wrote: On Sat, Jan 10, 2015 at 8:46 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
[8<]
Basically allow very flexible composition even at runtime (which helps tools dev too). It's also have been mentionned in the documentation after these discussions. (the doc is actually wrong in thinking that all engines component systems rely on inheritance by the way).
Last months I have seen mentionned several implemetnations of this pattern in C++11/14 on github but was not pleased with any design so far. The design of Boost.Mixin is close to what I want but don't reach my needs yet (or at least last time I looked at it).
I've been playing with some ECS designs lately and tried to implement two of my own [1],[2] (maybe those are among those you've already seen) (and sorry for the shameless plug). Based on what I've seen, if the ECS is to be used according to the usage patterns you usually see in a game (or rendering) engine, I believe it is better for the component instances to be stored together, outside of the entities (for locality of reference, efficient (re-)allocation, etc.).
I violently agree.
The entity should IMO be just an unique identifier
My experiments so far reach to the same conclusion: it's the most flexible and potentially efficient approach.
and in both of my implementations there is a `manager` class that can be used to store/modify/query/remove/etc. the components of an entity. This way operations that are common, like execute this function (every iteration of the update loop) on all entities with this set of components can be implemented more efficiently.
In my current implementation I call the object holding all components a "cluster". The Cluster hold one "pool" of component by type of components. Currently all the pools are the same type and basically are augmented flat_maps but I recently realized that a more flexible system could be implemented by letting the cluster user insert different kinds of polls depending on how he wants the component type to be memory managed ( like a vector or like an actual pool or with allocated nodes?), how "updates" are processed (in parallel, concurrent, jsut a loop?). I plan to try this design in the coming months. I didn't solve the component-inter-requirements problem though, I'm not sure if I should implement this at all, and if yes should it be compile-time checked as Vincente suggests? In which case the cluster would have to know the types it can manage at compile time too, because I see no way for an entity to be able to be checked at compile time except for a construct like the suggested "subject".
From what I've seen in `Mixin` sources (quite some time ago, maybe it has changed in the meantime) it does not do this. But the Mixin docs state that it is not exactly an ECS and maybe its usage patterns are different.
* Respect to subjective programming: it would be great to be able to create subject from an entity so that only the mixins of the subject would play when a reference to this subject is addressed.
subject
s (o); o.get
() works as expected. o.get<Other>() compile fails if not equal to any Mix_k
Interesting.
In the [1] implementation you can do this by creating a `manager` that has a statically assigned group of component types. The usage is then close to the following:
struct cmpnt_1 { }; struct cmpnt_2 { }; struct cmpnt_3 { }; struct cmpnt_4 { };
//declare group_x to contain component types cmpnt_1, cmpnt_2, cmpnt_3.
manager
m; entity e;
m.add(e, cmpnt_1(...), cmpnt_2(...)); use(m.get
(e).whatever); m.add (e); m.for_each (func); m.remove (e); m.add(e, cmpnt_4()); // compilation fails m.get
(e); // compilation fails m.remove (e); // compilation fails But having implemented several apps using this approach I find it quite limiting in some situations that the group of components is static. Sometimes it is useful (for example for debugging) to have the ability to add/remove component *types* on-the-fly. [2] allows this but its unfinished.
[8<]
I can do that in my implementation indeed, it is helpful. As said before I think it can be improved by allowing the user to provide the container of component for a type, making him chose how to manage them as long as the container match a specific set of requirement (concept?).
* Can a mixin D inherit from another mixin B? Could the mixing D be retrieved when getting the mixing B?
mutate(o).add<D>;
o.get<B>()->f() // f been a virtual function on B?
I am failing to see the point or usefulness of this?
Most of the literature I've seen on ECS warns against trying too hard to combine OOP and the data-driven programming style used by E/C systems. Such logic should be encapsulated in the `systems` that work on the entity's components. But again maybe Mixin tries to fill a different niche than 'typical'/'traditional' ECS's do.
[8<]
[1] https://github.com/matus-chochlik/exces [2] https://github.com/matus-chochlik/eagine/tree/develop/include/eagine/ecs
BR
Matus
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost