[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;
开发者_如何学Python 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?
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)
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.
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.
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.
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.
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.
精彩评论