
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.