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