
Hello, Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost. It is an entity-component system, with full abstraction between interface and implementation. In short, users can define objects by combining components (often referred to from here on out as mixins). A mixin is a regular C++ class for which two macros are defined. The main thing however are the messages. Instead of getting the component with some function like `get_component` (which is possible but discouraged in the library), users deal with objects only. They can call messages (inspired by Smalltalk's messages) which are dynamically dispatched to the appropriate mixin. The messages (also defined with macros) are the only thing needed for a user to call methods from the object's mixins. When defining a mixin, the user tells which messages it's going to implement, and when adding this mixin to the object a virtual table of sorts is filled and the object starts responding to those messages by calling the mixin's actual C++ methods. Some of the key features are: * Multicast messages. A message that is implemented and handled by more than one mixin. See the message `trace` in the example. (As opposed to unicast messages, that are handled by a single mixin) * Object access from within the mixin. The macro `bm_this` (Boost.Mixin this). See the renderer do in the example. * "Live" object mutation by adding and removing mixins. As demonstrated in `change_rendering_system` in the example. This is done via the `object_transformer` class and is currently the only way of adding mixins to objects. * Mixin (and message) domains. The domain is a collection of mixins and messages that work together. If you create a set of mixins that will never conceivably have to exist in the same object as another set of mixins, you should use a different domain. Here is a github link to the library: http://github.com/iboB/boost.mixin A working example can be found here: http://github.com/iboB/boost.mixin/tree/master/libs/mixin/example/basic The example is nothing more than some objects and mixins working together as they would hypothetically in a simple game. All "game" code has been shortcut to text outputs like: "right now an object is being rendered by the d3d renderer". The example demonstrates most of the currently supported library features. There is no jamfile yet. I develop it with Qt Creator and Code::Blocks in Linux and MS Visual Studio Express 2008 and 2012 in Windows (the Windows projects might be somewhat outdated), so the are project files for these four in libs/mixin/build. The same goes for the example. I'd qualify the current state of the library as pre-alpha, so it might have some bugs. I also create a small performance testing project (much more is to be added). It calls a regular function, a virtual function, `std::function` and a unicast mixin message a hundred million times. So far I'm generally happy with the performance, which is not to say that I won't be working on improving it. Still my computer is the only one I've tested it on and I'd be happy if somebody else tries the perf project. Here are my results: 100,000,000 x | Debug t | Release t ------------------------------------------ regular method | 781 ms | 211 ms virtual method | 639 ms | 253 ms `std::function` | 10695 ms | 272 ms Mixin message | 3298 ms | 865 ms It should also be noted that currently the library depends on a piece of code from Don Clugston's fastdelegate (found here: http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fa...). The piece in question has been copy-pasted verbatim (wrapped around in the boost::mixin namespace) in the third_party subfolder. Don Clugston has done a wonderful job of creating a platform-independent representation of C++ methods as a pair of pointers. Boost.Mixin heavily relies on such a thing for its virtual tables. For now I am the only developer of the library. Zahary Karadjov (credited in the license) hasn't written anything in it yet, but he is responsible for most of the library's public interface design, the idea to reuse fastdelegate, and the ideas and implementation suggestions for many of the roadmap features listed below. The programming languages Smalltalk, Ruby, and, to a degree, Objective C have also influenced the design. So, here is a project roadmap of sorts: 1. Soon: * Overloaded messages - messages that call overloaded functions. The message's name is different for each overload but the calling function remains the same * Work on more sensible (and helpful) runtime and compile-time errors. Missing messages, ambiguous message priority, etc. * Add multicast result collectors. Like `and` or `or` for boolean return values. Like `sum` for numeric values. Sample usage some_multicast_message(obj, p1, p2, boost::mixin::sum). User-defined result collectors will be possible. * Add a new mixin feature `fact`. Facts are static const variables in a mixin. No multicasts. No virtual tables. * Add object type templates. Instead of manually transforming each object, you would be able to call `type_template::new_object()` * Add more graceful runtime error handling: default message implementations (if none is provided), more specific non-breaking exceptions * Rigorous unit tests * Performance tests * Tutorials 2. Later: * Boost.Jam build files * Full reference documentation * Formal submission to Boost?? * Call mixin constructors when mutating object or constructing them via object type templates. Sample usage: `mutate(obj).add<mixin>("foo", param2).add<other_mixin>(42)` * Reduce library memory footprint * Optional external allocators per domain. Every memory allocation should pass through them. * Make use of the fact that a BIG execution time improvement can be made if a user has no mixins or messages defined in a dynamic library (and has no plans to add such) * Integration with Boost.Serialization. As long as the mixins of an object are serializable, the object will be, too. * "Static" mixins. As long as they're not mutated in or out, it provides a faster message execution. * Reflection. Create objects with mixins by string. Call messages by string. * Object mutation injections. Automatically add some mixins when others are present. Substitute a mentioned mixin with another. Ban a mixin from being added to an object. 3. When humankind becomes a Kardashev type two civilization: * Integration with Boost.Thread. Call messages for a specific thread. * User-defined message hooks. Sample implementation with messages called on objects on another device through Boost.Asio. * A way to mutate static mixins in and out. Slight mutation execution penalty. * Some magic to make it work even faster. * Integration with Boost.Python and luabind. * Remove C++03 backward compatibility???? * Library being accepted in Boost???? I think I will be done with the items form list one by April (some of them are even semi-implemented) and with the items of list two by the end of the year (and if I have more free time maybe even sooner). As for the items in the this list... well... they are nice to think about. I do have at least some vague ideas for each of them, but then again, this is list three. Any questions, comments, and suggestions are welcome. ------ Borislav Stanimirov ------ PS: Whoa. I'm sorry this post turned out so long. I didn't expect it to.

On Wed, Jan 30, 2013 at 11:53 AM, Borislav Stanimirov <b.stanimirov@abv.bg>wrote:
Hello,
Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost.
[...snip long post...] Okay, I'm gonna try to read this later, but it might be helpful (and I'd be more inclined to read the original post) if you included a short code snippet of your library in action. Ideally something that makes me say "whoa, that's cool" :) - Jeff

On 01/31/2013 05:31 AM, Jeffrey Lee Hellrung, Jr. wrote:
On Wed, Jan 30, 2013 at 11:53 AM, Borislav Stanimirov <b.stanimirov@abv.bg>wrote:
Hello,
[...snip long post...]
Okay, I'm gonna try to read this later, but it might be helpful (and I'd be more inclined to read the original post) if you included a short code snippet of your library in action. Ideally something that makes me say "whoa, that's cool" :)
You're absolutely right, but unfortunately, as other entity-component libraries, this one is mainly useful when used in medium to big projects. Especially since one of its goals is to reduce spaghetti code. When I was writing the basic example it was hard to illustrate the features in fewer than 22 files :) At least all of them are very short But anyway, let's a shorter snippet. Again, imagine a game (and let me remind you that a mixin is basically a component in the context of entity-component systems): The things from the library used in this example are `object`, the message declaration macros, and the mutate (object_transformer) class. All other symbols are part of the hypothetical product: BOOST_MIXIN_CONST_MESSAGE_1(void, draw, render_target*, target); // handled by: void <some_class>::draw(render_target*, target) const; BOOST_MIXIN_CONST_MULTICAST_MESSAGE_1(void, trace, ostream&, o); // handled by multiple mixins BOOST_MIXIN_MESSAGE_0(void, think) // handle by the ai //.... //.... object* o = new object; // all things added here are regular c++ classes // none of this example code requires to actually // "see" the actual class definitions // it works with forward declarations only mutate(o) .add<scene_element>() .add<d3d_rendering>() .add<animated_model>() .add<monster_ai>() .add<rpg_attributes>(); //.... // the d3d_rendering mixin handles this draw(o, main_target); // this is a mutlicast, so potentially all mixins handle this // output could be: // > scene element with id 14, rendering: d3d, // > animated model: "monster.model" // > ai: monster_ai // > rpg attributes: str 14, cha 3, int 3 trace(o, cout); // we decide to switch the rendering system mutate(o) .remove<d3d_rendering>() .add<opengl_rendeing>(); // now the opengl rendering mixin handles this draw(o, main_target); // we decide to make the monster aggresive mutate(o) .remove<monster_ai>() .add<berserk_ai>(); think(o); // the berserk ai will handle this - Borislav

Le 30/01/13 20:53, Borislav Stanimirov a écrit :
Hello,
Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost.
It is an entity-component system, with full abstraction between interface and implementation.
In short, users can define objects by combining components (often referred to from here on out as mixins). A mixin is a regular C++ class for which two macros are defined. The main thing however are the messages. Instead of getting the component with some function like `get_component` (which is possible but discouraged in the library), users deal with objects only. They can call messages (inspired by Smalltalk's messages) which are dynamically dispatched to the appropriate mixin.
The messages (also defined with macros) are the only thing needed for a user to call methods from the object's mixins. When defining a mixin, the user tells which messages it's going to implement, and when adding this mixin to the object a virtual table of sorts is filled and the object starts responding to those messages by calling the mixin's actual C++ methods.
Some of the key features are: * Multicast messages. A message that is implemented and handled by more than one mixin. See the message `trace` in the example. (As opposed to unicast messages, that are handled by a single mixin) * Object access from within the mixin. The macro `bm_this` (Boost.Mixin this). See the renderer do in the example. * "Live" object mutation by adding and removing mixins. As demonstrated in `change_rendering_system` in the example. This is done via the `object_transformer` class and is currently the only way of adding mixins to objects. * Mixin (and message) domains. The domain is a collection of mixins and messages that work together. If you create a set of mixins that will never conceivably have to exist in the same object as another set of mixins, you should use a different domain.
Here is a github link to the library: http://github.com/iboB/boost.mixin A working example can be found here: http://github.com/iboB/boost.mixin/tree/master/libs/mixin/example/basic
Hi, IIUC your library is related to the subject-role [1] but a mixin is more an aspect of an entity than a role. Could the user define a typed subjects, that is an entity that have some specific mixins? Could the user see an object restricted to some of his mixins? Best, Vicente [1] Roles :Conceptual Abstraction Theory & Practical Language Issues

On 01/31/2013 09:30 AM, Vicente J. Botet Escriba wrote:
Le 30/01/13 20:53, Borislav Stanimirov a écrit :
Hello,
Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost.
It is an entity-component system, with full abstraction between interface and implementation.
[... snip ...] Here is a github link to the library: http://github.com/iboB/boost.mixin A working example can be found here: http://github.com/iboB/boost.mixin/tree/master/libs/mixin/example/basic
Hi,
IIUC your library is related to the subject-role [1] but a mixin is more an aspect of an entity than a role.
Could the user define a typed subjects, that is an entity that have some specific mixins?
Right now this is possible with the object_transformer class, wich allows you to manually add specific mixins to an object (or remove them). A planned feature is to have object type templates, where just calling `new` will create an object with a list of specific mixins
Could the user see an object restricted to some of his mixins?
This is a planned feature too. Also automatically injecting specific mixins. Also automatically replacing given mixins with others.
Best, Vicente
[1] Roles :Conceptual Abstraction Theory & Practical Language Issues

On 01/31/2013 09:30 AM, Vicente J. Botet Escriba wrote:
Le 30/01/13 20:53, Borislav Stanimirov a écrit :
Hello,
Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost.
It is an entity-component system, with full abstraction between interface and implementation.
[... snip ...] Here is a github link to the library: http://github.com/iboB/boost.mixin A working example can be found here: http://github.com/iboB/boost.mixin/tree/master/libs/mixin/example/basic
Hi,
IIUC your library is related to the subject-role [1] but a mixin is more an aspect of an entity than a role.
Could the user define a typed subjects, that is an entity that has some specific mixins?
Right now this is possible with the object_transformer class, wich allows you to manually add specific mixins to an object (or remove them). A planned feature is to have object type templates, where just calling `new` will create an object with a list of specific mixins By typed subjects I meant a class that could check at compile time that
Le 31/01/13 08:44, Borislav Stanimirov a écrit : the mixins that can be added belongs to a list of types. Something like subject<E, M1, M2> s; s.add<E>().add<M1>().add<M2>(); // Ok. s.add<AnotherType>(); // compile fails IIUC your library is not strongly typed (based on Smalltalk message paradigm). I would be more interested in a library that reach to manage with static typed mixins that doesn't compile when a mixin is not on the list of mixins, but I don't see how both approaches could conciliate.
Could the user see an object restricted to some of his mixins?
This is a planned feature too. Also automatically injecting specific mixins. Also automatically replacing given mixins with others.
I meant something like subject<E, M1, M2> s; s.add<E>().add<M1>().add<M2>(); // Ok. subject_view<E, M1> sv(s); // Now any specific message m2 of mixing M2 sent to sv should not compile. // Now any multicast message sent to sv would take in account only E and M1. BTW, the function add() could let think that the same mixin type could be added several time, but I suspect that this is not the case. Maybe set() could be more appropriated. I have found the name mixin on other context where mixins are staked the ones on top of the others (look for GenVoca on www or [1]). The structure of a mixin is something like template <typename Final, typename Derived> struct Mixin : Derived { void specific_message() { // do something } void multicast_message() { // do something this->Derived.multicast_message(); } }; With this architecture, the responsability for multicast is shared by all the mixins by forwarding to the next mixin. Of course this architecture doesn't respond to your needs, as the mixins are fixed at compile time but maybe this could inspire you to adapt your library to be able to manage with user defined multicast messages and improve the performances and the memory footprint. HTH, Vicente [1]/Generative Programming/ : /Methods/, /Tools, and Applications/ by Krzysztof Czarnecki

On 01/31/2013 08:58 PM, Vicente J. Botet Escriba wrote:
On 01/31/2013 09:30 AM, Vicente J. Botet Escriba wrote:
Le 30/01/13 20:53, Borislav Stanimirov a écrit :
Hello,
Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost.
It is an entity-component system, with full abstraction between interface and implementation.
[... snip ...] Here is a github link to the library: http://github.com/iboB/boost.mixin A working example can be found here: http://github.com/iboB/boost.mixin/tree/master/libs/mixin/example/basic
Hi,
IIUC your library is related to the subject-role [1] but a mixin is more an aspect of an entity than a role.
Could the user define a typed subjects, that is an entity that has some specific mixins?
Right now this is possible with the object_transformer class, wich allows you to manually add specific mixins to an object (or remove them). A planned feature is to have object type templates, where just calling `new` will create an object with a list of specific mixins By typed subjects I meant a class that could check at compile time that
Le 31/01/13 08:44, Borislav Stanimirov a écrit : the mixins that can be added belongs to a list of types. Something like
subject<E, M1, M2> s;
s.add<E>().add<M1>().add<M2>(); // Ok.
s.add<AnotherType>(); // compile fails
IIUC your library is not strongly typed (based on Smalltalk message paradigm).
I would be more interested in a library that reach to manage with static typed mixins that doesn't compile when a mixin is not on the list of mixins, but I don't see how both approaches could conciliate.
Aha. I get it now. In this case, no. The main purpose of the library is "live" object mutation. Compile-time types while maintaining the previous goal are not planned. And yes. Smalltalk was one of the main inspirations for the library. Anyway (at least at first glance) the code you write will sort of possible be possible to implement within the library but then the user code will suffer. For example having collections of objects requires them to have the same type. For your code to work, one could have a common parent to all objects, say `parent`, but then nothing could stop the users from writing: parent& p = o; p.add<AnotherType>; Having truly strongly typed objects defies the purpose of the library entirely.
Could the user see an object restricted to some of his mixins?
This is a planned feature too. Also automatically injecting specific mixins. Also automatically replacing given mixins with others.
I meant something like
subject<E, M1, M2> s; s.add<E>().add<M1>().add<M2>(); // Ok. subject_view<E, M1> sv(s); // Now any specific message m2 of mixing M2 sent to sv should not compile. // Now any multicast message sent to sv would take in account only E and M1.
Messages are in no way bound to a specific mixin. Hence they are dynamically dispatched. The compiler doesn't know (and has no way of knowing) which messages M2 implements. So for this one, again, no.
BTW, the function add() could let think that the same mixin type could be added several time, but I suspect that this is not the case. Maybe set() could be more appropriated.
The function add is chosen, because one adds a mixin to objects. I guess "set" would imply that without calling it something remains "not set", which is not the case. Calling `add` constructs a new type with this mixin present and assigns it to the object, thus you might say (this is simplified) that an object with mixins M1 and M2, takes up sizeof(M1) + sizeof(M2) memory, whereas and object with mixins M1, M2, and M3 takes up sizeof(M1) + sizeof(M2) + sizeof(M23). This is indeed adding.
I have found the name mixin on other context where mixins are staked the ones on top of the others (look for GenVoca on www or [1]). The structure of a mixin is something like
template <typename Final, typename Derived> struct Mixin : Derived { void specific_message() { // do something } void multicast_message() { // do something this->Derived.multicast_message(); } };
With this architecture, the responsability for multicast is shared by all the mixins by forwarding to the next mixin. Of course this architecture doesn't respond to your needs, as the mixins are fixed at compile time but maybe this could inspire you to adapt your library to be able to manage with user defined multicast messages and improve the performances and the memory footprint.
I guess this design is exactly the opposite of what I'm trying to achieve. My library's goal is abstraction. Message clients don't know anything about the mixins. They only know messages. See here: http://github.com/iboB/boost.mixin/blob/master/libs/mixin/example/basic/main... This is the main function of the basic example of the library. It calls different messages, without knowing anything about the mixins that may or may not be included in the object. So, in short. I'm afraid that no compile time checks (of types, or implementations) will be present in this library. -- Borislav

On Thu, Jan 31, 2013 at 8:29 PM, Borislav Stanimirov <b.stanimirov@abv.bg>wrote:
Aha. I get it now. In this case, no. The main purpose of the library is "live" object mutation. Compile-time types while maintaining the previous goal are not planned.
I can see this library as an interesting part of a game engine, in particular because it let the C++ code be static while allow script code or editor code to change the objects nature on the fly. I don't have much time but I recognize it could be interesting to see in practice (in my domain which is games) how it works. I don't know if it would be interesting in other domains than interactive media. Joel Lamotte

On 01/31/2013 10:15 PM, Klaim - Joël Lamotte wrote:
On Thu, Jan 31, 2013 at 8:29 PM, Borislav Stanimirov <b.stanimirov@abv.bg>wrote:
Aha. I get it now. In this case, no. The main purpose of the library is "live" object mutation. Compile-time types while maintaining the previous goal are not planned.
I can see this library as an interesting part of a game engine, in particular because it let the C++ code be static while allow script code or editor code to change the objects nature on the fly.
I don't have much time but I recognize it could be interesting to see in practice (in my domain which is games) how it works. I don't know if it would be interesting in other domains than interactive media.
I'd say that any big project with complex objects could benefit from this. Indeed games and game engines are a prime example of such a project, but there are many others. Any software that has optional dynamic library plug-ins, for example. I can also see this working great for most CAD systems, graph editors, project management tools, and many others. -- Borislav

A friend pointed out to me that fastdelegate uses non-stadard methods, and because of that it is unlikely to be accepted in boost. So I removed it and switched to an alternative call method, as suggested by: http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates Initially I thought this method would make the calls a bit slower (that's why I didn't choose it the first time), but curiously it makes them a bit faster. Yay! -- Borislav

Hi, On Wed, Jan 30, 2013 at 8:53 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
Hello,
Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost.
[..8<...] This library certainly looks interesting. It reminds me of the Crystal Entity Layer from the Crystal Space engine. Are you familiar with it, and if so could you compare the two ? Best, Matus

On 02/01/2013 01:55 PM, Matus Chochlik wrote:
Hi,
On Wed, Jan 30, 2013 at 8:53 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
Hello,
Boost.Mixin is a library I'm developing with the idea to someday submit it to Boost.
[..8<...]
This library certainly looks interesting. It reminds me of the Crystal Entity Layer from the Crystal Space engine. Are you familiar with it, and if so could you compare the two ?
I'm not familiar with it, but I took a look at it and here's what I can say (correct me if im wrong). CEL is a clasic interface entity-component system. It's entities are bags of interfaces to components. Here's how such a system works (the following example is not their exact code, but I think the idea behind it is almost identical) // ============= creation ============= entity e; e.add_component<iserializable>(new text_file_serializer); // text_file_serializer definition must be included for this line e.add_component<irendering>(new d3d_rendering); // d3d_rendering definition must be included for this line // both iserializable and irendering are derived from icomponent // this provides children with get_owning_object, generates ids... etc // ============= use ============= e.get_component<iserializable>()->serialize(); // iserializable definition must be included for this line e.get_component<irendering>()->render(); // irendering definition must be included for this line // ============= mutation ============= e.change_component<irendering>(new opengl_rendering) // opengl_rendering definition must be included for this line Now, a similar piece of code could be written with Boost.Mixin. However this is not the preferred way of using the library. First. It is non-intrusive. Your mixins are your regular classes. They don't need to derive from anything. You use macros to identify them as components, and you don't need to change the class code. Second you don't need to bind a series of messages to a predefined interface. The messages are simply stand-alone functions and mixins can choose whether to implement them or not. You could even hide the visibility of some implementations with others. Here is a Boost.Mixin example // ============= creation ============= object o; mutate(o) .add<text_file_serializer>() .add<d3d_rendering>(); // only mixin declarations are required for the previous lines // basically here nothing is known about both classes except their // forward declarations // ============= use ============= serialize(o); // only the message declaration is needed for the previous line // for all we know the rendering mixin might implement it render(o); // again only the message is known here // ============= mutation ============= mutate(o) .remove<d3d_rendering>() .add<opengl_rendering>(); // same as creation // something cool // say we have a mixin which is defined like that class stub_rendering { public: void render() {} }; BOOST_DEFINE_MIXIN(stub_rendering, priority(10000, render_msg); // note the high priority chosen for render // this means that any mixin implementing the same message with // lower priority (default is 0) will have its implementation hidden // by this mutate(o).add<stub_rendering>(); render(o); // it doesn't matter for the previous call if the object has // d3d or opengl rendering, their render-s will be overriden // by the method in stub_rendering, and nothing will happen // (well as long as their priorities for render are lower than 10000) One thing that CEL supports but Boost.Mixin doesn't (yet) is the ease of mutating entities, without caring for component consistency. See how in order to substitute the `d3d_rendering` with `opengl_rendering` the user didn't need to care what's already there. It could've been say, `software_rendering`. In Boost.Mixin right now in order to remove mixins from the object, you need to know exactly which one you need to remove. So the code from above could've been more like: object_transformer transformer(o); if(o.has<d3d_rendering>()) transformer.remove<d3d_rendering>(); else if(o.has<software_rendering>()) transformer.remove<software_rendering>(); transformer.apply(); // does the actual mutation This is pretty incovenient. But good news! In no more than two weeks I'll introduce the notion of mutually-exclusive mixins. I'm not sure of the exact code yet, but it will be something similar to this: mutually_exclusive_mixins mem_rendering; mem_rendering.add<d3d_rendering>(); mem_rendering.add<opengl_rendering>(); // any mutation occuring after the execution of the previous line, // will automatically remove one mixin if the mutation // tries to add the other mem_rendering.add<software_rendering>(); // any mutation occuring after the execution of the previous line, // will automatically remove any two of the three mixins // if the mutation tries to add the third As a whole, as far as entity-component systems go, CEL seems basic. However, they do have lots of other features. The engine comes with a big number of predefined components, which is very useful, while Boost.Mixin is just a bare system. It doesn't offer any mixins. The most important (and huge) thins is that they have reflection and script integration. While there are plans for Boost.Mixin to have those too, thay are... to put it mildly... set for the distant future. -- Borislav

On Fri, Feb 1, 2013 at 10:56 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
On 02/01/2013 01:55 PM, Matus Chochlik wrote:
Hi,
On Wed, Jan 30, 2013 at 8:53 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
[...]
uur This library certainly looks interesting. It reminds me of the Crystal Entity Layer from the Crystal Space engine. Are you familiar with it, and if so could you compare the two ?
I'm not familiar with it, but I took a look at it and here's what I can say (correct me if im wrong). CEL is a clasic interface entity-component system. It's entities are bags of interfaces to components. Here's how such a system works (the following example is not their exact code, but I think the idea behind it is almost identical)
Thanks for the extensive comparison. IMO once you implement the things on your TODO list this libary would be a very useful addition to Boost. BR, Matus

Hi again, On Sat, Feb 2, 2013 at 5:02 PM, Matus Chochlik <chochlik@gmail.com> wrote:
On Fri, Feb 1, 2013 at 10:56 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
[...] I've been playing with the library and I would like to ask a couple of questions: 1) Is it (/will it be) possible to check is a specific message can be sent to an object, instead of checking for mixin type. 2) Will it be possible through mutate::add<Mixin>() to add an existing instance of the Mixin, that could be shared among several objects ? For example, in a game that supports item modification, default unmodified items could share some common mixin that would manage the default properties, and when the item is modified this shared mixin would be replaced by an unique instance of the mixin specific to the particular modified item. 3) Will some kind of "message overloading" be supported? For example: class named { private: string _name public: void name(const string& new_name){ _name = new_name; } const std::string& name(void) const { return _name; } }; BOOST_DECLARE_MIXIN(named); BOOST_MIXIN_CONST_MESSAGE_0(const string&, name); BOOST_MIXIN_MESSAGE_1(void, name, const string&, new_name); ... TIA, Matus

On 05-Feb-13 16:51, Matus Chochlik wrote:
Hi again,
On Sat, Feb 2, 2013 at 5:02 PM, Matus Chochlik <chochlik@gmail.com> wrote:
On Fri, Feb 1, 2013 at 10:56 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
[...]
I've been playing with the library and I would like to ask a couple of questions:
1) Is it (/will it be) possible to check is a specific message can be sent to an object, instead of checking for mixin type.
Yes, quite easily. I don't even know why I haven't added it by now. It's literally 6 new lines of code in the current repo. The syntax will be `obj->implements(some_message_msg);` In the basic example from the repo `o->implements(render_msg)` will always return true (since all objects implement that message). The problem is that my PC broke yesterday, and I won't be able to push this until Friday (my workplace's proxy server hates github and I can't do it from here). However if you want this, I could send you a patch for it.
2) Will it be possible through mutate::add<Mixin>() to add an existing instance of the Mixin, that could be shared among several objects ?
For example, in a game that supports item modification, default unmodified items could share some common mixin that would manage the default properties, and when the item is modified this shared mixin would be replaced by an unique instance of the mixin specific to the particular modified item.
No. Mixin instances are bound to object instances. That's why `bm_this` (pointer to the owning object) is possible. If objects could share mixin instances, `bm_this` would be ambiguous (not to mention impossible to implement if we want to keep things non-intrusive). The example you gave could be implemented in two ways: 1. With an item holder mixin that holds a pointer to either a shared unmodified item or to its own instance of a modified item. 2. With two mixins: `unmodified_item`, which again holds a pointer to the shared unmodified item, and `item` which represents a modified one. As long as both implement the same messages everything will work fine. Still I have to think about this some more, and I might add a feature that will help in such cases (as they do seem common). But I'm not sure if it would be possible to implement something like that gracefully. In any case, this feature, if it even comes to existence, won't be available soon.
3) Will some kind of "message overloading" be supported? For example:
class named { private: string _name public: void name(const string& new_name){ _name = new_name; } const std::string& name(void) const { return _name; } };
BOOST_DECLARE_MIXIN(named);
BOOST_MIXIN_CONST_MESSAGE_0(const string&, name); BOOST_MIXIN_MESSAGE_1(void, name, const string&, new_name);
...
Yes but not quite in the way you suggested. I had message overloading in mind since the start and all provisions have been made for this feature and it would really take probably half an hour to implement in the current repo. The main problem is that it's impossible to have messages of the same name. So here's how your example will work after I add the changes: BOOST_MIXIN_CONST_MESSAGE_0(const string&, name); BOOST_MIXIN_MESSAGE_1_OVERLOAD(name_setter, void, name, const string&, new_name); // ^ ^ // message name | actual method name or alternatively: BOOST_MIXIN_CONST_MESSAGE_0_OVERLOAD(name_getter, const string&, name); BOOST_MIXIN_MESSAGE_1(void, name, const string&, new_name); or even: BOOST_MIXIN_CONST_MESSAGE_0_OVERLOAD(name_getter, const string&, name); BOOST_MIXIN_MESSAGE_1_OVERLOAD(name_setter, void, name, const string&, new_name); and then in the mixin definition: BOOST_DEFINE_MIXIN(named, name_setter_msg & name_getter_msg); // we use the message names here after all that, calling the messages will be by the actual method name so the code: name(o, "Hildegard"); cout << name(o); // outputs Hildegard will work just as regular function overloads. To check for implementation, you'll have to call `o->implements(name_setter_msg)` -- Borislav

On Tue, Feb 5, 2013 at 8:18 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
On 05-Feb-13 16:51, Matus Chochlik wrote:
[...]
I've been playing with the library and I would like to ask a couple of questions:
1) Is it (/will it be) possible to check is a specific message can be sent to an object, instead of checking for mixin type.
Yes, quite easily. I don't even know why I haven't added it by now. It's literally 6 new lines of code in the current repo. The syntax will be `obj->implements(some_message_msg);` In the basic example from the repo `o->implements(render_msg)` will always return true (since all objects implement that message).
The problem is that my PC broke yesterday, and I won't be able to push this until Friday (my workplace's proxy server hates github and I can't do it from here). However if you want this, I could send you a patch for it.
Thanks,I suspected that it should be easy but, I didn't find it anywhere in the code. I'll wait till Friday then, or if it's not a big problem please send me the patch.
2) Will it be possible through mutate::add<Mixin>() to add an existing instance of the Mixin, that could be shared among several objects ?
For example, in a game that supports item modification, default unmodified items could share some common mixin that would manage the default properties, and when the item is modified this shared mixin would be replaced by an unique instance of the mixin specific to the particular modified item.
No. Mixin instances are bound to object instances. That's why `bm_this` (pointer to the owning object) is possible. If objects could share mixin instances, `bm_this` would be ambiguous (not to mention impossible to implement if we want to keep things non-intrusive).
Hm
The example you gave could be implemented in two ways: 1. With an item holder mixin that holds a pointer to either a shared unmodified item or to its own instance of a modified item.
2. With two mixins: `unmodified_item`, which again holds a pointer to the shared unmodified item, and `item` which represents a modified one. As long as both implement the same messages everything will work fine.
I actually tried some variations on these approaches, it works, but it does not scale very well since you have to write a lot of code that just forwards the messages and this usage pattern is quite common.
Still I have to think about this some more, and I might add a feature that will help in such cases (as they do seem common). But I'm not sure if it would be possible to implement something like that gracefully. In any case, this feature, if it even comes to existence, won't be available soon.
3) Will some kind of "message overloading" be supported? For example:
class named { private: string _name public: void name(const string& new_name){ _name = new_name; } const std::string& name(void) const { return _name; } };
BOOST_DECLARE_MIXIN(named);
BOOST_MIXIN_CONST_MESSAGE_0(const string&, name); BOOST_MIXIN_MESSAGE_1(void, name, const string&, new_name);
...
Yes but not quite in the way you suggested. I had message overloading in mind since the start and all provisions have been made for this feature and it would really take probably half an hour to implement in the current repo. The main problem is that it's impossible to have messages of the same name. So here's how your example will work after I add the changes:
BOOST_MIXIN_CONST_MESSAGE_0(const string&, name); BOOST_MIXIN_MESSAGE_1_OVERLOAD(name_setter, void, name, const string&, new_name); // ^ ^ // message name | actual method name
or alternatively:
BOOST_MIXIN_CONST_MESSAGE_0_OVERLOAD(name_getter, const string&, name);
BOOST_MIXIN_MESSAGE_1(void, name, const string&, new_name);
or even:
BOOST_MIXIN_CONST_MESSAGE_0_OVERLOAD(name_getter, const string&, name); BOOST_MIXIN_MESSAGE_1_OVERLOAD(name_setter, void, name, const string&, new_name);
and then in the mixin definition:
BOOST_DEFINE_MIXIN(named, name_setter_msg & name_getter_msg); // we use the message names here
Ok, the "registering" syntax is not too important, if it works.
after all that, calling the messages will be by the actual method name so the code:
name(o, "Hildegard"); cout << name(o); // outputs Hildegard
will work just as regular function overloads.
To check for implementation, you'll have to call `o->implements(name_setter_msg)`
BR, Matus

На 05-Feb-13 21:56, Matus Chochlik написа:
On Tue, Feb 5, 2013 at 8:18 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote:
On 05-Feb-13 16:51, Matus Chochlik wrote: [...]
2) Will it be possible through mutate::add<Mixin>() to add an existing instance of the Mixin, that could be shared among several objects ?
For example, in a game that supports item modification, default unmodified items could share some common mixin that would manage the default properties, and when the item is modified this shared mixin would be replaced by an unique instance of the mixin specific to the particular modified item.
No. Mixin instances are bound to object instances. That's why `bm_this` (pointer to the owning object) is possible. If objects could share mixin instances, `bm_this` would be ambiguous (not to mention impossible to implement if we want to keep things non-intrusive).
Hm
The example you gave could be implemented in two ways: 1. With an item holder mixin that holds a pointer to either a shared unmodified item or to its own instance of a modified item.
2. With two mixins: `unmodified_item`, which again holds a pointer to the shared unmodified item, and `item` which represents a modified one. As long as both implement the same messages everything will work fine.
I actually tried some variations on these approaches, it works, but it does not scale very well since you have to write a lot of code that just forwards the messages and this usage pattern is quite common.
A longer reply to this point: I realize that this could be a commonly requested feature and that it is supported in at least some entity component systems, but I'd argue that this isn't what "mixin" is. Mixins are not references to objects a class can contain. They are the actual building blocks of the class. If you have changed and unchanged items, those are different instances (possibly the same class). So, the politically correct way of implementing this would be to have different object instances (consisting of the same mixins) for those kinds of items. Now I also realize that this means that you have to copy all of the object's data, unrelated to its... er... itemness, when you decide to change an item and that's unpleasant, but it seems that (generally speaking) mixins are not something that can help you there. You'd have to go and implement it in the way you would have, if you didn't have mixins available. Either in the aforementioned way, or, possibly, if you don't want to copy the interface, by adding a simple `get_item` message. It may return `item*` or it may even return `object*` allowing you to have other mixins in an item, specific for this instance. I am still going to think of how this could be addressed in some way in the library (and whether it should), but for now this seems highly unlikely. -- Borislav

On Tue, Feb 5, 2013 at 10:40 PM, Borislav Stanimirov <b.stanimirov@abv.bg> wrote: [...]
No. Mixin instances are bound to object instances. That's why `bm_this` (pointer to the owning object) is possible. If objects could share mixin instances, `bm_this` would be ambiguous (not to mention impossible to implement if we want to keep things non-intrusive).
Hm
The example you gave could be implemented in two ways: 1. With an item holder mixin that holds a pointer to either a shared unmodified item or to its own instance of a modified item.
2. With two mixins: `unmodified_item`, which again holds a pointer to the shared unmodified item, and `item` which represents a modified one. As long as both implement the same messages everything will work fine.
I actually tried some variations on these approaches, it works, but it does not scale very well since you have to write a lot of code that just forwards the messages and this usage pattern is quite common.
A longer reply to this point:
I realize that this could be a commonly requested feature and that it is supported in at least some entity component systems, but I'd argue that this isn't what "mixin" is. Mixins are not references to objects a class can contain. They are the actual building blocks of the class. If you have changed and unchanged items, those are different instances (possibly the same class). So, the politically correct way of implementing this would be to have different object instances (consisting of the same mixins) for those kinds of items.
Now I also realize that this means that you have to copy all of the object's data, unrelated to its... er... itemness, when you decide to change an item and that's unpleasant, but it seems that (generally speaking) mixins are not something that can help you there. You'd have to go and implement it in the way you would have, if you didn't have mixins available. Either in the aforementioned way, or, possibly, if you don't want to copy the interface, by adding a simple `get_item` message. It may return `item*` or it may even return `object*` allowing you to have other mixins in an item, specific for this instance.
I am still going to think of how this could be addressed in some way in the library (and whether it should), but for now this seems highly unlikely.
After looking at the implementation I now understand why this could be a problem. Anyway if you come up with some solution, this feature would be nice to have. There are also a couple of things I would like to suggest: 1) Please add perfect forwarding (std::forward) to the macros and the caller# functions in gen/message_macros.ipp so that properties can be move-assigned. 2) Would it be possible to have object.implements<message>() in addition to object.implements(message_msg). IMO the former is more generic.
From a glance at the implementation this would require some changes to the representation of messages, but it should be doable.
3) Please add <some-message>(object&, <other-params>) in addition to <some-message>(object*, <other-params>), if possible. thanks, Matus

On 6.2.2013 г. 16:57 ч., Matus Chochlik wrote: [...]
There are also a couple of things I would like to suggest:
1) Please add perfect forwarding (std::forward) to the macros and the caller# functions in gen/message_macros.ipp so that properties can be move-assigned.
I have this and much more C++11 features in mind, but I'm going to start adding them after a couple of months, after I have a C++03 version I'm happy with. Unfortunately lots of users still use C++03 and the C++11 support the popular compilers varies, and focusing on this now, will prevent me from adding critical features, that I would like people to try-out.
2) Would it be possible to have object.implements<message>() in addition to object.implements(message_msg). IMO the former is more generic.
From a glance at the implementation this would require some changes to the representation of messages, but it should be doable.
That would be a no. I mean it is technically possible, but I don't think adding another representation of messages would help. The plan is to stick to this simple rule of thumb: When you're referring to a message, you use `<message_name>_msg`. When calling a message you use `<method_name>`. Remember the overloaded messages: they introduce different message names for the same method name. Adding this feature would require me to have a third way of referring to messages `<message_name>` without the _msg. It would get confusing. Now, I see that this makes things seem a bit inconsistent, but I have really thought hard about the public interface. And considering all the things I'm going to add to the library in the near future, this seems like the best way to go. For example messages are not going to remain the only mixin features. Very soon I'll add "facts" which are static member constants within the mixin class. In the more distant future I'll be adding serialization and thread safety features and I will allow users to add some custom ones. Imagine this (circa 2014): BOOST_DEFINE_MIXIN(d3d_rendering, has_rendering_fact & max_buffers_fact & paralelize(draw_msg) & log(load_data_msg) & debug(trace_msg) & per_frame_memory_access_hint & block_serialization_hint)
3) Please add <some-message>(object&, <other-params>) in addition to <some-message>(object*, <other-params>), if possible.
Check. That's another thing that I had just forgotten (along with object::implements). I'll add it by the end of the week. -- Borislav

Hi all, Since a couple of minutes ago, there are three new big library features: 1. Overloaded messages - used in the basic example ( https://github.com/iboB/boost.mixin/blob/master/libs/mixin/example/basic/ren... ) 2. Object mutation rules - used in the basic example and also in these tests: https://github.com/iboB/boost.mixin/tree/master/libs/mixin/test/mutation_rul... 3. Multicast message result combinators - used here https://github.com/iboB/boost.mixin/blob/master/libs/mixin/test/combinators.... I'll be focusing on the documentation and unit tests in the next couple of weeks and there won't be any new features added until the end of March. Again, I'll be glad to hear any questions or recommendations. -- Borislav
participants (6)
-
Borislav Stanimirov
-
Fabio Fracassi
-
Jeffrey Lee Hellrung, Jr.
-
Klaim - Joël Lamotte
-
Matus Chochlik
-
Vicente J. Botet Escriba