views:

96

answers:

6

[SOLVED] - The mistake was mine, that I didn't link World (world_) to the entity, so that was null. Thanks for the explanation everyone!


As you may know by now, I'm making a game engine/framework, and I've got stuck linking stuff with references to each other.

Example:

public void Attach(Entity Entity)
{
    entity_ = Entity;
    entity_.world_.renderer_.AddComponent(this);
}

The line that adds component to the renderer fails with NullObjectException. My idea was that it's because it's inside the class implementation (when the object isn't defined yet), but such thing worked in next piece of code:

public TGSGame()
{
    ...
    Renderer = new RenderManager(this);
    ...
}

That part of code is inside TGSGame class implementation too!

Does anyone have idea how can I overcome this exception?

+3  A: 

You need to check entity_, entity_.world_ and entity_.world_.renderer_ - if any of these are null it will explode. If these are fundamental to the object, it is usually a good idea to initialize them in the constructor, and limit whether they can be changed / set back to null. For example:

public class Entity {
    public World World {get;private set;}
    public Entity(World world) {
        if(world == null) throw new ArgumentNullException("world");
        tihs.World = world;
    }
}

The advantage of this is that it is very obvious where the problem is (it will show as an ArgumentNullException, of the "world" argument, with the stack-trace pointing at the World constructor and whatever is calling it, etc)

Marc Gravell
Non of these are null, I checked and debuged step by step. But the problem arose in a piece of test code too, when I passed 'this' as a parameter. Another note, the code, where the exception is, is in a library on which the game part is dependant, could that be a problem maybe? (Thought the exception raises in a code relevant only to the dll)
Johnny
@Johnny - if none of those things are `null`, then the problem is in code that you aren't showing us (presumably inside `AddComponent`). Have you looked at the stack-trace? (for example by catching the `Exception`). What does the stack-trace look like?
Marc Gravell
The problem wasn't in AddComponent, it was in the part for linking World to Entity. Thanks for yor assistance and rapid answer!
Johnny
Every time i see a NullReferenceException, there's likely kind of foo.bar.baz around. Consider employing the LoD principle http://en.wikipedia.org/wiki/Law_of_Demeter
George Polevoy
+1  A: 

Well, the offending line is

entity_.world_.renderer_.AddComponent(this);

so either

entity_.world_

is null or

entity_.world_.renderer_

is null or something bad is happening inside of

entity_.world_.renderer_.AddComponent

A stack trace would help us deduce a little more but those are your culprits. Start by checking if entity_.world_ is being initialized properly and if so if entity_world_.renderer_ is being initialized properly.

Jason
+1  A: 

One of the references in the chain of entity_.world_.renderer_ is null, which isn't surprising, since you just created it in the previous line. Note that having an object add itself that way to an external collection is a bizarre responsibility inversion -- usually whoever is controlling the collection should get control over who adds things to it.

John Feminella
+1  A: 

I'd guess either world_ or renderer_ reference members which have not yet been initialised. Either that or entity_ is passed in as a null. It's a bit hard to tell without more info on what they are though.

runrunraygun
+1  A: 

You need to ensure that "world_" and "renderer_" both exist before the call to Attach.

You could use defensive code:

if ((entity_ != null) && (entity_.world_ != null) && (renderer_ != null)) {
   //... your code here...
} else {
   throw new Exception("...");
}

Beyond that, you need to look at how you build your object graph to ensure that this situation does not arise. A good combination of Factory and Singleton pattern can help in this case.

GrayWizardx
+1  A: 

Perhaps you had NullReferenceException? Anyway, I would double-check that neither

entity_.world_

nor

entity_.world_.renderer_

is not null. Just place a breakpoint and you'll see that your Entity argument isn't completely initialized.

Igor Korkhov