Boost logo

Boost :

Subject: Re: [boost] [mixin] New library reminder
From: Borislav Stanimirov (b.stanimirov_at_[hidden])
Date: 2013-07-13 07:11:35


On 07/13/2013 12:31 PM, Klaim - Joël Lamotte wrote:
>
>
>
> From what I understand, the allocator might be enough to allow the user of
> the library to set up a pool or dynarray or non-ressizing vector of
> components of the same type,
> which would be the feature I'm asking for.
> I'm not sure though. Would it be problematic to allow the user to provide a
> factory function for the component on addition, so that there is a simple
> way to
> make sure the component is created the way we want?
>
> Something like:
>
> mutate(o).add( [&]{ return world_components.create<book_data>() ); //
> template parametter types implicitely inferred
> // the added data_book is allocated in an array (or stable vector or
> pool or...)
> // here add would take a unique_pointer or similar - or maybe a second
> function for deletion - or maybe an object providing both, like an alocator
> but dynamic.
>

Unfortunately allowing the user to maintain their own pool of
pre-created mixins is not possible (well it may be possible with some
arrangements, but it's not likely that I'll address this in the near
future). The main problem with this is the need for `bm_this`.

bm_this is a macro that gets you the object from which this mixins is a
part of. In order for this to work the memory that's internally
allocated for a mixin is `sizeof(object*)+sizeof(ActualMixinType)` bytes
and then the constructor is called for the second piece of memory.
Essentially bm_this expands to in the sense of
`(object*)(this-Ptr_bytes)`. There is no other non-intrusive way to do this.

I do mean to address the constructor problem, though, but again, not
soon. I will allow the users to choose which constructor is called for
their mixins.

> Which then would allow something like:
>
> world_components.for_all<book_data>( [&]( book_data& data ){ data.update(
> info ); } ); // go through the array of book_data to update them all
>

I'm not sure what this is supposed to do. You could do something like

for(auto o : objects_with_book_data) // your own array
{
     o->get<book_data>()->update(info);
}

You could also have a message called update (handled by not necessarily
only book_data) and code:

for(auto o : objects)
{
     update(o, info);
}

> What I fear is that the allocator would not be enough to allow different
> pool/list/whatever of these components to be defined,
> for different "contexts". I have a case where I need different "worlds" to
> exists in parallel and components are gathered in type-specific (stable)
> arrays.
>

The allocator works like this.

When an object is created or mutated it first allocates the array of
mixin pointers for its mixins, then it allocates memory for each new
mixin (plus object*) and arranges them in this array.

You're allowed to set a global allocator that takes care for all these
allocations, and you're also allowed to assign specific allocators per
mixin type. For example book_data_allocator, which will take care to
allocate memory only for mixins of type book_data.

So if your programs often mutates a huge group of objects by adding and
removing specific mixin to them it's a good idea to provide a specific
allocator for that mixin type and pre-allocate the entire chunk memory.

As for your worlds example you could easily set the allocator to all
rendering mixins to be A, and to all physics mixins to be B.

-- Borislav


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