Boost logo

Boost :

Subject: Re: [boost] [mixin] Introducing a new library.
From: Borislav Stanimirov (b.stanimirov_at_[hidden])
Date: 2013-02-05 14:18:14


On 05-Feb-13 16:51, Matus Chochlik wrote:
> Hi again,
>
> On Sat, Feb 2, 2013 at 5:02 PM, Matus Chochlik <chochlik_at_[hidden]> wrote:
>> On Fri, Feb 1, 2013 at 10:56 PM, Borislav Stanimirov
>> <b.stanimirov_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk