Dealing with multiple references to Objects

Started by
6 comments, last by japro 13 years, 4 months ago
Hi,

at some point in almost all my projects there are multiple other objects/data structures that keep track of a single object. Usually there is just a list of all objects, then there is some other structure like a tree or grid to optimize certain operations like collisions or visibility tests and occasionally there are objects having direct pointers to other objects (the target of a guided missile or some unit following another one etc.). Then there are operations on these objects that require me to also update those structures somehow (destruction being the most obvious). Quite often I only know which object is affected so i need a way to get all the structures/other objects that point to it or find another way to tell those structures of the change. The obvious solution i guess would be to store all iterators and other objects that point to this one in the object, but I hate that idea because the design of the object shouldn't depend on how it is stored, also I don't want to change a lot of code just because I decided to use std::vector instead of std::list... The other method I used was to just set some sort of status flag (destroyed = true) and have all the other structures drop it when they come across a destroyed object, which also kinda sucks, since it's very easy to mess up the order of operations.

The most elegant solution for the destruction problem I came up with was writing some sort of pointer wrapper for the object, so when the object gets destroyed it notifies all it's pointers and those can then be tested for their validity before using them.

The problem I have now is, that there are multiple lists of objects in my program. One is the environment, one has static objects, another one dynamic objects etc. Now, I've run across the problem that on detecting a collisions one object has to move the other from the static list to the dynamic one. But at that point in the code, I only have a direct pointer to the object that needs moving but don't know it's iterator in the first list. So to remove it from that list, I'd have to search that list... In other situations it might even not be clear which list an object belongs to.

Is there some obvious solution to this? Or do I have to bloat my object classes up with lots of cross references to locations they occupy? Or is this kind of multiple referencing a sign of bad design and I screwed this up somewhere earlier in the design process? If so, how do I avoid it?
Advertisement
Shared pointers are your friends. boost has some, and depending on your compiler/standard library version, they might be already included under a namespace you already have.
Quote:Original post by Telastyn
Shared pointers are your friends. boost has some, and depending on your compiler/standard library version, they might be already included under a namespace you already have.


Those (together with weak pointers) handle the destruction problem but don't help me with the "update my grid"- or "move from this to that list"-Problem or am I missing something?

Edit: actually they don't help me, they solve the inverse problem of all pointers being destroyed and the object being "orphaned". I have to destroy all other pointers to the object along with the object.

Say there are references to the object in a list, a grid and a missile that is following it. Now the missile hits the object and has to destroy it, at the same time the object has to be removed from the list and the grid (so they don't contain pointers to invalid objects).
Destroyed in the game does not need to (and often times should not) equate to being removed from memory. Weak pointers are built for those cases where different places need to reference something but not own it.

Having a good sane ownership structure can be challenging, but that is a design problem, not a technical one.

[edit: that was pretty vague]

In general, it's a sign you screwed up earlier in the design process. One of the core pieces of design is who owns what. Weak pointers can provide mechanisms where persistent shared reference without ownership is needed. Event/messaging systems can solve some of the other 'something needs to happen when something dies/changes' problems. There's a few other things depending on your particular need/requirements.
Quote:Original post by Telastyn
Destroyed in the game does not need to (and often times should not) equate to being removed from memory.

So the "correct" solution is the destruction flag in the object and either reusing it or having it automatically deleted by a shared pointer when the dead object has been dropped from all data structures?
If I understand your question correct, here is my opinions.

I will do,
1, Clear the object ownership. There is only one owner is responding to free the objects. In your case, one primary list may be the owner.
All other lists are the users rather than owner, they can use the objects but can't free them.
2, Adjust the design so no "users" using the objects after they got deleted. If you can't do that, add some callback to notify the users before deleting the objects.

For the problem that you need to search a list to find an object, some complicated data structure may help you, such as quad linked node discussed here
With that kind of node, the child may always unlink itself from parent without any searching.

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

japro, may I ask what language you're using? It appears that it might be C++ based on your first post, just confirming.
Jep, I'm using c++.

This topic is closed to new replies.

Advertisement