Sign in to follow this  
CableGuy

Scene graphs and shared_ptr

Recommended Posts

CableGuy    1335
Hello,

I've created a simple scene graph implementation and have a problem with cyclic referencing. In my implementation you never hold a node or reference to a node but rather a NodePtr which is just a typedef for shared_ptr<Node>. Also each node stores internally a list of all it's children(a vector of NodePtr) and a parent which is also a NodePtr. As you can see this leads to a cyclic referencing of nodes and their parents.
I tried to come up with ideas that might solve this but still retain the same interface( using shared pointers) but the only solution I could come up with is having some kind of a SceneGraph class that hold a NodePtr to the root and when this object is destroyed iterate over the graph and break all the connections(lets assume that every NodePtr can only be a member of a single SceneGraph). I must say I'm not too fond of this solution so if anyone has got a better idea please share.

Thanks.

Share this post


Link to post
Share on other sites
_the_phantom_    11250
First a question; why does the child need to know about its parent?

Second; if the child really does need to know then is it valid for the child to exist without a parent? If not then a reference to the parent is probably a better idea than a pointer. If the object can be reassigned to another parent then a weak_ptr might be the correct choice.

End of the day it is all about ownership; shared_ptr are for when ownership is truely shared. Chances are shared_ptr is technically the wrong tool for the job here as the ownship is scoped and maybe transferable but not shareable in any logical sense.

Don't get me wrong, shared_ptr is a useful tool however it isn't always the right tool.

Share this post


Link to post
Share on other sites
CableGuy    1335
1. Nodes need a pointer to their parent since for example when their transformation changes they not to mark all bounding volumes up the tree as invalid.
2. A child can exist without it's parent since a child is just another node( it can become a root node or attached to another one)

the weak_ptr idea sounds nice since there is no point in having a pointer to the middle of the graph but nothing to it's upper part, although technically possible which will
result in the weak_ptr being invalidated.

I agreet that shared_ptr might not be the best tool for the job and that the ownership is not shareable since a child does not "own" it parent, but the problem still stands.
I need memory to be released when nothing points to it and I don't want to created some sophisticated garbage collection mechanism nor store a pointer to all nodes
ever allocated in some central list.

Thanks for your answer.

Share this post


Link to post
Share on other sites
_the_phantom_    11250
For holding the parent the case could be made for a raw pointer; if a parent is released then it's children should be released so you won't get dangling pointers and children will either have a live pointer to their parent or a null if they have no parent.

There is no memory clean up issue as parents can still hold children by shared_ptr which ensures automatic clean up. Also 'boost::scoped_ptr' might be a better fit for holding references to children, although it might require some extra work if you are copying instances around as it is non-copyable via the assignment/copy-constructor.

Share this post


Link to post
Share on other sites
CableGuy    1335
[quote]For holding the parent the case could be made for a raw pointer; if a parent is released then it's children should be released so you won't get dangling pointers and children will either have a live pointer to their parent or a null if they have no parent.[/quote] But if there are two instances: P which is the parent of C. And there are two pointers, one pointing to P and the other one to C.
When the first pointer goes out of scope P will get destroyed but it is actually still needed since there is a pointer to C and P is it's parent. But then again I can't think of this scenario happening in reality.

Will have to read on boost::scoped_ptr...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this