[Mixin] Some comments
Hi,
First of all, I want to say that I like your library too much. It is
quite close to a library I was working one EntityRoleSubject. You
library could be extended to to take in account the subjective
programming paradigm (see below).
I have some comments/remarks/questions:
* I have some doubts about the name mixin. What a mixin has more than a
facet or an aspect? Mixins in C++ have a specific mean in the context of
CRTP. Why have you chosen the mixin name?
* The construction of the mixins in the tutorial is done always with the
default constructor. Can we do emplace construction? How can you ensure
the invariants of some mixing classes?
* The priority of the messages doens't compose well. The user needs to
have a global view of the application so that it can assign the correct
priority. I have not a better suggestion, but I think that this issue
would need more insight.
* 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
On Sat, Jan 10, 2015 at 8:46 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
First of all, I want to say that I like your library too much. It is quite close to a library I was working one EntityRoleSubject. You library could be extended to to take in account the subjective programming paradigm (see below).
I have some comments/remarks/questions:
* I have some doubts about the name mixin. What a mixin has more than a facet or an aspect? Mixins in C++ have a specific mean in the context of CRTP. Why have you chosen the mixin name?
I aree with this remark. As I mentionned in previous discussions on this mailing list, it looks far more like a "flexible but not performant" implementation the Entity Component "pattern". Wikipedia: http://en.wikipedia.org/wiki/Entity_component_system Explainations about why it's used a lot in game engine code: http://gameprogrammingpatterns.com/component.html 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).
* 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.
* The entity-mixin relation is not recursive, that is, a mixin can not have associated mixins, or can them?
Usually it makes no sense, except if you mean that one mixin type require another mixin type to be available for the object instance to work. In which case I don't see a mechanism for automating this check in Boost.Mixin, and I'm not sure if it's the right place for that.
* 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?
* The example of the mixin headphones_player show that the play() implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
I believe that there are a lot of better (non game related) example for such library. A simple 3D space editor allowing to associate behaviours to 3D objects is a good enough example and is very simple to visualize mentally.
That's all for now.I will come back later when i will read more.
A BTW, the reference documentation doesn't contain the add<M>/get<M> mutate functions?
Best, Vicente
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/ mailman/listinfo.cgi/boost
On Sun, Jan 11, 2015 at 2:05 AM, Klaim - Joël Lamotte
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.). The entity should IMO be just an unique identifier 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.
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
* 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
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
On 11.1.2015 г. 03:05 ч., Klaim - Joël Lamotte wrote:
On Sat, Jan 10, 2015 at 8:46 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
* I have some doubts about the name mixin. What a mixin has more than a facet or an aspect? Mixins in C++ have a specific mean in the context of CRTP. Why have you chosen the mixin name?
I aree with this remark. As I mentionned in previous discussions on this mailing list, it looks far more like a "flexible but not performant" implementation the Entity Component "pattern". Wikipedia: http://en.wikipedia.org/wiki/Entity_component_system Explainations about why it's used a lot in game engine code: http://gameprogrammingpatterns.com/component.html
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).
The types of ecs are briefly mentioned here: http://ibob.github.io/boost.mixin/boost_mixin/appendix.html#boost_mixin.appe...
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).
Yes I remember our discussion from a year ago. Indeed the library isn't what you need and it's not moving in that direction. While the library is faster than some similar ones, it is by no means suitable for heavy performance code where even the cache locality is important. Still it could be used in other parts of your program :) -- snip --
* The example of the mixin headphones_player show that the play() implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
I believe that there are a lot of better (non game related) example for such library. A simple 3D space editor allowing to associate behaviours to 3D objects is a good enough example and is very simple to visualize mentally.
That's a very good idea. I may change the example to that (or at least add such an example) in the near future. -- Borislav
On Sun, Jan 11, 2015 at 8:59 AM, Borislav Stanimirov
On 11.1.2015 г. 03:05 ч., Klaim - Joël Lamotte wrote:
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).
Yes I remember our discussion from a year ago. Indeed the library isn't what you need and it's not moving in that direction.
Fair enough. It looks like a Stateshart/MSM situation where different approaches meets different needs (Vincente wants a compile-time checked system, I see how to do it but not how to make open to runtime extensions)
While the library is faster than some similar ones, it is by no means suitable for heavy performance code where even the cache locality is important.
I am also thinking about parallelization of processing by batches some of the mixins. But yes that's a concern in my use cases, maybe not yours.
Still it could be used in other parts of your program :)
We'll see. :)
-- snip --
* The example of the mixin headphones_player show that the play()
implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
I believe that there are a lot of better (non game related) example for such library. A simple 3D space editor allowing to associate behaviours to 3D objects is a good enough example and is very simple to visualize mentally.
That's a very good idea. I may change the example to that (or at least add such an example) in the near future.
-- Borislav
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/ mailman/listinfo.cgi/boost
On 11.1.2015 г. 16:52 ч., Klaim - Joël Lamotte wrote:
On Sun, Jan 11, 2015 at 8:59 AM, Borislav Stanimirov
wrote: On 11.1.2015 г. 03:05 ч., Klaim - Joël Lamotte wrote:
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).
Yes I remember our discussion from a year ago. Indeed the library isn't what you need and it's not moving in that direction.
Fair enough. It looks like a Stateshart/MSM situation where different approaches meets different needs (Vincente wants a compile-time checked system, I see how to do it but not how to make open to runtime extensions)
I don't think it's possible (or, at the very least, practicle). The compile time constructed objects will need to be template classes, which can't work well with the run time polymorphism that the library provides. -- Borislav
Le 11/01/15 02:05, Klaim - Joël Lamotte a écrit :
On Sat, Jan 10, 2015 at 8:46 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
First of all, I want to say that I like your library too much. It is quite close to a library I was working one EntityRoleSubject. You library could be extended to to take in account the subjective programming paradigm (see below).
I have some comments/remarks/questions:
* I have some doubts about the name mixin. What a mixin has more than a facet or an aspect? Mixins in C++ have a specific mean in the context of CRTP. Why have you chosen the mixin name?
I aree with this remark. As I mentionned in previous discussions on this mailing list, it looks far more like a "flexible but not performant" implementation the Entity Component "pattern". Wikipedia: http://en.wikipedia.org/wiki/Entity_component_system Explainations about why it's used a lot in game engine code: http://gameprogrammingpatterns.com/component.html
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).
* 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. Instead of subject I should be used view. A subject must have the listed mixin. You can be interested in reading this old paper
Roles: conceptual abstraction theory and practical language issue Bent Bruun Kristensen and Kasper sterbye http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0CC8QFjAB&url=http%3A%2F%2Fwww.itu.dk%2Fpeople%2Fkasper%2Fpapers%2Fosterbye_R8.pdf&ei=QjWyVMO4CoaaygOC4YCQBA&usg=AFQjCNEczlV4c-61kWGJ_qoUe0AhDGhRYg&sig2=PKFjzFly_B9jvY26uNLKcA&bvm=bv.83339334,d.bGQ
* The entity-mixin relation is not recursive, that is, a mixin can not have associated mixins, or can them?
Usually it makes no sense, except if you mean that one mixin type require another mixin type to be available for the object instance to work. Yes this is what I mean. In which case I don't see a mechanism for automating this check in Boost.Mixin, and I'm not sure if it's the right place for that.
It seems this is achievable at run-time adapting the mutation rules. :( I'm locking for something that can be checked at compile-time.
* 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?
If suggest you to read the paper. In principle as for classes, the user must be able to specialize mixins. I'm not talking about the Game domain that don't know and for which maybe this is not what they need. You can think of a class This is needed when you associate a mixing to a specific kind of entity. The Mixin library don't classify the entities, something that I'm locking for. Having a classification of Entities, it is reasonable to state which roles/facets/subjects/mixins it can support. This allows to have a first compile type checking. A specialized entity could require a specialized role. entity B {}; entity D : B {}; B role X {}; D role Y : X {};
* The example of the mixin headphones_player show that the play() implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
I believe that there are a lot of better (non game related) example for such library. A simple 3D space editor allowing to associate behaviours to 3D objects is a good enough example and is very simple to visualize mentally.
I'm sure you are right, and that the library has its value. I find, however that this framework don't help to force compile type integrity. If the entity don't has an associated mixing that plays the get_sound function, the user will get an exception in the best case. When we work with strongle typed languages as C++ we expect something better. Vicente
On Sun, Jan 11, 2015 at 10:05 AM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Le 11/01/15 02:05, Klaim - Joël Lamotte a écrit :
* 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.
Instead of subject I should be used view. A subject must have the listed mixin. You can be interested in reading this old paper
Roles: conceptual abstraction theory and practical language issue
Bent Bruun Kristensen and Kasper sterbye
http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web& cd=2&cad=rja&uact=8&ved=0CC8QFjAB&url=http%3A%2F%2Fwww.itu.dk%2Fpeople% 2Fkasper%2Fpapers%2Fosterbye_R8.pdf&ei=QjWyVMO4CoaaygOC4YCQBA&usg= AFQjCNEczlV4c-61kWGJ_qoUe0AhDGhRYg&sig2=PKFjzFly_ B9jvY26uNLKcA&bvm=bv.83339334,d.bGQ
Thanks, will read.
* The entity-mixin relation is not recursive, that is, a mixin can not
have associated mixins, or can them?
Usually it makes no sense, except if you mean that one mixin type require another mixin type to be available for the object instance to work.
Yes this is what I mean.
In which case I don't see a mechanism for automating this check in Boost.Mixin, and I'm not sure if it's the right place for that.
It seems this is achievable at run-time adapting the mutation rules. :( I'm locking for something that can be checked at compile-time.
Maybe by requiring mixins to provide a typedef tuple of other mixin types they require to be present? That might be an ugly solution though.
* 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?
If suggest you to read the paper. In principle as for classes, the user must be able to specialize mixins. I'm not talking about the Game domain that don't know and for which maybe this is not what they need. You can think of a class This is needed when you associate a mixing to a specific kind of entity. The Mixin library don't classify the entities, something that I'm locking for. Having a classification of Entities, it is reasonable to state which roles/facets/subjects/mixins it can support. This allows to have a first compile type checking. A specialized entity could require a specialized role.
entity B {}; entity D : B {};
B role X {}; D role Y : X {};
Would something like the translation tables of MSM work? Just stating the relationship between mixn types.
* The example of the mixin headphones_player show that the play()
implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
I believe that there are a lot of better (non game related) example for such library. A simple 3D space editor allowing to associate behaviours to 3D objects is a good enough example and is very simple to visualize mentally.
I'm sure you are right, and that the library has its value. I find, however that this framework don't help to force compile type integrity. If the entity don't has an associated mixing that plays the get_sound function, the user will get an exception in the best case. When we work with strongle typed languages as C++ we expect something better.
Indeed.
Vicente
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/ mailman/listinfo.cgi/boost
On 10.1.2015 г. 21:46 ч., Vicente J. Botet Escriba wrote:
Hi,
First of all, I want to say that I like your library too much. It is quite close to a library I was working one EntityRoleSubject. You library could be extended to to take in account the subjective programming paradigm (see below).
I have some comments/remarks/questions:
* I have some doubts about the name mixin. What a mixin has more than a facet or an aspect? Mixins in C++ have a specific mean in the context of CRTP. Why have you chosen the mixin name?
The name is chosen to match the term mixin in Ruby. Ruby was the inspiration for the library. I though about naming it "component" or "dynamic polymorphism" or even something vague like "hameleon" or "zeus". Do you have any other suggestions for a name?
* The construction of the mixins in the tutorial is done always with the default constructor. Can we do emplace construction? How can you ensure the invariants of some mixing classes?
For now a default constructor is a requirement for the mixins. I know how to proceed in order to have non-default constructors, and it is in the roadmap so this is an upcoming feature for sure.
* The priority of the messages doens't compose well. The user needs to have a global view of the application so that it can assign the correct priority. I have not a better suggestion, but I think that this issue would need more insight.
I have thought about that, too. I will continue to think of a better way to assign priorities. For now in the software I've written with the library I use enums with elements like "mixin_x_message_y_priority" or "message_x_low_priority"
* 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
This subject class can be made, but it won't have a relation with the boost::mixin::object class. `object` is not a template class and I don't want to make it one. Such a functionality could be added to the object class if the error is run time and not compile time. I have some upcoming features which will introduce somewhat similar behavior - the multiple domains. I'm not sure why this is a desired feature. How is this any different from simple inheritance or composition without any templates?
* The macro bm_this :(
Is the name a problem or the fact that it's a macro? :)
* I would like to see what is behind the scenes the different macros in an implementation section.
That's a good idea to add in the documentation. I'll add it to the upcoming tasks for the library.
* The entity-mixin relation is not recursive, that is, a mixin can not have associated mixins, or can them?
I'm not sure what you're asking. A mixin can have associated mixins via mutation rules (see http://ibob.github.io/boost.mixin/boost_mixin/tutorials.html#boost_mixin.tut... ) But I wouldn't call this recursive. It's more like a sibling (or enemy) connection.
* 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?
A mixin can inherit from another as any class can but it can't be obtained via get<Parent> (or receive messages automatically). Inheriting a mixin from another is not registered or noticed by the library. To the library those are like any two unrelated classes. You could easily implement that feature via a message. Let's say you have a class `behavior` and two children `enemy_behavior` and `friendly_behavior`. You chould add a method to the children behavior* get_behavior() { return this; } Then you could make it into a message and use code like: ::get_behavior(some_object)->f()
* The example of the mixin headphones_player show that the play() implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
You could add a dependency on a concrete mixin via the mutation rules as mentioned above, but that will prevent you from having polymorphism for get_sound, as illustrated in the example by the two sound providers: cd_player and mp3_player. A compilation error is impossible for such a case. The exception thrown if an object doesn't implement a message is bad_message_call.
That's all for now.I will come back later when i will read more.
A BTW, the reference documentation doesn't contain the add<M>/get<M> mutate functions?
Get is documented here: http://ibob.github.io/boost.mixin/boost/mixin/object.html#idp9180592-bb (numbers 2 and 3) Add/remove is not a member of object because the mutations are done by mutators. And you're right that they're not documented. I'll fix this on Monday. Thanks for the interest and I look forward to hearing from you :) -- Borislav
Le 11/01/15 08:50, Borislav Stanimirov a écrit :
On 10.1.2015 г. 21:46 ч., Vicente J. Botet Escriba wrote:
Hi,
First of all, I want to say that I like your library too much. It is quite close to a library I was working one EntityRoleSubject. You library could be extended to to take in account the subjective programming paradigm (see below).
I have some comments/remarks/questions:
* I have some doubts about the name mixin. What a mixin has more than a facet or an aspect? Mixins in C++ have a specific mean in the context of CRTP. Why have you chosen the mixin name?
The name is chosen to match the term mixin in Ruby. Ruby was the inspiration for the library. I though about naming it "component" or "dynamic polymorphism" or even something vague like "hameleon" or "zeus". Do you have any other suggestions for a name? I will reserve Mixin for a library that helps to define C++ CRTP mixins. You provide a E/C framework (I have removed the system part of ECL intentionally), why not ECF/ECL.
* The construction of the mixins in the tutorial is done always with the default constructor. Can we do emplace construction? How can you ensure the invariants of some mixing classes?
For now a default constructor is a requirement for the mixins. I know how to proceed in order to have non-default constructors, and it is in the roadmap so this is an upcoming feature for sure. Why not allow the construction of the mixing outside the entity? Why do you want it to be constructed by the entity? In the context en entity/roles a role can change of the entity that is playing it.
* The priority of the messages doens't compose well. The user needs to have a global view of the application so that it can assign the correct priority. I have not a better suggestion, but I think that this issue would need more insight.
I have thought about that, too. I will continue to think of a better way to assign priorities. For now in the software I've written with the library I use enums with elements like "mixin_x_message_y_priority" or "message_x_low_priority" You priority approach has value. Having the possibility to associate a mixing to an existing mixing could help to express the override obtained with the priority. Having mixin composition, could help to define explicitly the order and the combinator of the messages inside this composed mixin.
* 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
This subject class can be made, but it won't have a relation with the boost::mixin::object class. `object` is not a template class and I don't want to make it one. Such a functionality could be added to the object class if the error is run time and not compile time. I have some upcoming features which will introduce somewhat similar behavior - the multiple domains. I don't know what multiple domain is.
I'm not sure why this is a desired feature. How is this any different from simple inheritance or composition without any templates?
I can understand that in your domain you don't need it. Your library checks everything at run-time and I'm locking for something that can be checked at compile-time :( Clearly it is difficult to conciliate the two views.
* The macro bm_this :(
Is the name a problem or the fact that it's a macro? :)
Both.
* I would like to see what is behind the scenes the different macros in an implementation section.
That's a good idea to add in the documentation. I'll add it to the upcoming tasks for the library.
Great.
* The entity-mixin relation is not recursive, that is, a mixin can not have associated mixins, or can them?
I'm not sure what you're asking. A mixin can have associated mixins via mutation rules (see http://ibob.github.io/boost.mixin/boost_mixin/tutorials.html#boost_mixin.tut... )
But I wouldn't call this recursive. It's more like a sibling (or enemy) connection.
I'm not for the recursive name if you want. What it is important is to be able to state the relation at compile time.
* 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?
A mixin can inherit from another as any class can but it can't be obtained via get<Parent> (or receive messages automatically). Inheriting a mixin from another is not registered or noticed by the library. To the library those are like any two unrelated classes.
You could easily implement that feature via a message. Let's say you have a class `behavior` and two children `enemy_behavior` and `friendly_behavior`. You chould add a method to the children
behavior* get_behavior() { return this; }
Then you could make it into a message and use code like:
::get_behavior(some_object)->f()
Is there already a complete example on the documentation? if not I will appreciate one.
* The example of the mixin headphones_player show that the play() implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
You could add a dependency on a concrete mixin via the mutation rules as mentioned above, but that will prevent you from having polymorphism for get_sound, as illustrated in the example by the two sound providers: cd_player and mp3_player. A compilation error is impossible for such a case.
I missed this possibility. Could you elaborate?
The exception thrown if an object doesn't implement a message is bad_message_call.
That's all for now.I will come back later when i will read more.
A BTW, the reference documentation doesn't contain the add<M>/get<M> mutate functions?
Get is documented here: http://ibob.github.io/boost.mixin/boost/mixin/object.html#idp9180592-bb (numbers 2 and 3)
Add/remove is not a member of object because the mutations are done by mutators. And you're right that they're not documented. I'll fix this on Monday. I was expecting to find them in the mutate class :(
best, Vicente
On 11.1.2015 г. 11:34 ч., Vicente J. Botet Escriba wrote:
Le 11/01/15 08:50, Borislav Stanimirov a écrit :
On 10.1.2015 г. 21:46 ч., Vicente J. Botet Escriba wrote:
Hi,
First of all, I want to say that I like your library too much. It is quite close to a library I was working one EntityRoleSubject. You library could be extended to to take in account the subjective programming paradigm (see below).
I have some comments/remarks/questions:
* I have some doubts about the name mixin. What a mixin has more than a facet or an aspect? Mixins in C++ have a specific mean in the context of CRTP. Why have you chosen the mixin name?
The name is chosen to match the term mixin in Ruby. Ruby was the inspiration for the library. I though about naming it "component" or "dynamic polymorphism" or even something vague like "hameleon" or "zeus". Do you have any other suggestions for a name? I will reserve Mixin for a library that helps to define C++ CRTP mixins. You provide a E/C framework (I have removed the system part of ECL intentionally), why not ECF/ECL.
Maybe Boost.EntityComponent could be a better name... I'll make a separate thread about it.
* The construction of the mixins in the tutorial is done always with the default constructor. Can we do emplace construction? How can you ensure the invariants of some mixing classes?
For now a default constructor is a requirement for the mixins. I know how to proceed in order to have non-default constructors, and it is in the roadmap so this is an upcoming feature for sure.
Why not allow the construction of the mixing outside the entity? Why do you want it to be constructed by the entity? In the context en entity/roles a role can change of the entity that is playing it.
Firstly, that's because of the way the entity holds its components. It doesn't just contain a list of buffers for each component. The buffers are bigger than needed to hold a pointer to the enity (so bm_this could work). So each component is constructed by a placement constructor and the allocation needs to happen from the entity. Custom allocators are the library's alternative for this.
* The priority of the messages doens't compose well. The user needs to have a global view of the application so that it can assign the correct priority. I have not a better suggestion, but I think that this issue would need more insight.
I have thought about that, too. I will continue to think of a better way to assign priorities. For now in the software I've written with the library I use enums with elements like "mixin_x_message_y_priority" or "message_x_low_priority"
You priority approach has value. Having the possibility to associate a mixing to an existing mixing could help to express the override obtained with the priority. Having mixin composition, could help to define explicitly the order and the combinator of the messages inside this composed mixin.
If you're talking about compile time composition, this is not a planned feature of the library.
* 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
This subject class can be made, but it won't have a relation with the boost::mixin::object class. `object` is not a template class and I don't want to make it one. Such a functionality could be added to the object class if the error is run time and not compile time. I have some upcoming features which will introduce somewhat similar behavior - the multiple domains.
I don't know what multiple domain is.
It's a future feature of the library that allows you to register mixins and messages to different "domains", such that you cannot construct an object from mixins of different domains. This may be useful if two independent systems of the application use the library, and their mixins and messages shouldn't be mixed.
I'm not sure why this is a desired feature. How is this any different from simple inheritance or composition without any templates?
I can understand that in your domain you don't need it. Your library checks everything at run-time and I'm locking for something that can be checked at compile-time :( Clearly it is difficult to conciliate the two views.
Indeed. The library's focus are run time features.
* The macro bm_this :(
Is the name a problem or the fact that it's a macro? :)
Both.
Alas I can't think of another way to have this functionality.
* I would like to see what is behind the scenes the different macros in an implementation section.
That's a good idea to add in the documentation. I'll add it to the upcoming tasks for the library.
Great.
* The entity-mixin relation is not recursive, that is, a mixin can not have associated mixins, or can them?
I'm not sure what you're asking. A mixin can have associated mixins via mutation rules (see http://ibob.github.io/boost.mixin/boost_mixin/tutorials.html#boost_mixin.tut... )
But I wouldn't call this recursive. It's more like a sibling (or enemy) connection.
I'm not for the recursive name if you want. What it is important is to be able to state the relation at compile time.
* 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?
A mixin can inherit from another as any class can but it can't be obtained via get<Parent> (or receive messages automatically). Inheriting a mixin from another is not registered or noticed by the library. To the library those are like any two unrelated classes.
You could easily implement that feature via a message. Let's say you have a class `behavior` and two children `enemy_behavior` and `friendly_behavior`. You chould add a method to the children
behavior* get_behavior() { return this; }
Then you could make it into a message and use code like:
::get_behavior(some_object)->f()
Is there already a complete example on the documentation? if not I will appreciate one.
No there is not. I'll make one.
* The example of the mixin headphones_player show that the play() implementation makes use of get_sound() provided by other mixins. This dependency is not explicit. I would expect to be able to say that headphones_player depends on another mixing providing the get_sound message.
You could add a dependency on a concrete mixin via the mutation rules as mentioned above, but that will prevent you from having polymorphism for get_sound, as illustrated in the example by the two sound providers: cd_player and mp3_player. A compilation error is impossible for such a case.
I missed this possibility. Could you elaborate?
Both cd_player and mp3_player in the example implement the message "get_sound". You're asking to make a dependency between mixins, so when I construct an object with headphones_player, the message get_sound will be available. Due to the nature of the library this will be a run time error. The library provides mutation rules, which can add a specific mixin when some mixins are added. This is not helpful, because we're not interested in a specific mixin, but in the message get_sound, regardless from where it comes. I could make a feature that would trigger a runtime error if an object is constructed, that lacks a specific message but I'm not sure whether it would be very helpful, since incomplete objects are a common occurrence when using the library. Still I'll add such a feature to the roadmap. It may not be used often enough, but it won't be harmful. Again, though, this will lead to an exception when an incomplete object is constructed. It cannot be a compilation error. -- Borislav
participants (4)
-
Borislav Stanimirov
-
Klaim - Joël Lamotte
-
Matus Chochlik
-
Vicente J. Botet Escriba