I guess I've asked a few similar questions before, but I was beating around the bush. I think this is the real problem that I can't quite lay to rest.
I'm dealing with a third party library, and there's an object that can't create itself, b2Body
. The b2World
has to instantiate it. I personally don't like this design pattern very much; I think the b2Body
should be able to exist independently of the world, and then be added to the world when needed. Anyway, I've wrapped b2Body
with my own class class, Body
, because I need to add some extra stuff to it anyway. Similarly, I have a World
wrapper. Now I figure I have 3 options:
- Have
Body
's constructor takes a pointer toWorld
so that it can be fully instantiated (callsb2World::CreateBody
somewhere inside) -- i.e. have a constructor likeBody *b = new Body(world_ptr)
- Pass
Body
to someWorld::CreateBody
method like how the library already does it -- i.e.Body *b = world.CreateBody(params);
- Duplicate all the data in
b2Body
so that you can use it however you want, and then after you add it to the world it will 'switch over' to use theb2Body
data -- i.e.Body b
and laterworld.addBody(b)
.
(1) and (2) mean that you can't have a Body
without a World
, which I probably won't need, but it might be nice to have that option [so that I can use it as a template for other objects and such]. Not sure what other pros and cons there are. (3) seems nicer, but it's a lot more work to implement, and it means I have to duplicate most of the data that's already contained in b2Body
.
What are your thoughts? I'll CW
this just so no one frets.
I still can't lay this to rest. This is what each of the options would look like:
Option 1: (what I prefer)
World w;
Body b;
Fixture f;
b.addFixture(f);
w.addBody(b);
Option 2: (somewhere in the middle)
World w;
Body b(w);
Fixture f(b);
Option 3: (how Box2D does it)
World *w = new World;
Body *b = w->CreateBody(args);
Fixture *f = b->CreateFixture(args);
Options 2 and 3 aren't so different, but it changes who has control over is creating the objects.
How would I actually implement option 3 though? World::CreateBody()
has to call b2World::CreateBody(args)
which calls b2Body::b2Body()
and returns b2Body
but never calls Body::Body(args)
which is a problem. The b2Body
would get fully initialized, but my wrapper has no place to do it's thing... More specifically, how would I write World::CreateBody(const BodyDef &bd)
? Assuming BodyDef inherited from b2BodyDef, Body from b2Body, World from b2World, etc.