1
\$\begingroup\$

I'm not sure if this exact question has been asked before, but all I could find were questions about how to work with GameComponent, or why something wasn't working.

I understand that you overload the Initialize, Draw, and Update methods with your own code, and XNA will then invoke them when the time is right. But what exactly is the purpose of Initialize? If you're writing something that extends from GameComponent, why wouldn't you just put all your initialize logic in the constructor?

For example, if my classes have a reference type that needs to be initialized, such as a collection or dictionary, I make of point of doing so in the constructor, and this pattern follows me into my GameComponent class design.


EDIT: Having worked with it a bit more, it looks like the primary purpose is to allow for more flexibility.

For example, IGameComponent merely exposes one method -- Initialize() -- and by implementing this, you are allowed to plug it into the Game.Components collection. This means that GameComponent, with all of its various properties, even the reference to Game, is just an implementation detail.

Another use I've found is when one component contains a collection of other components. In this case, the constructor for the container is called, and you now have empty collections. This pattern allows you to populate the collections, then call the initialize on both the parent and children objects.

I'm still stumped as to what I would specifically put into Initialize, but I understand the reasoning behind it.

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

The reason you wouldn't put the initialize logic in the constructor is because Initialize is the first point where you can be sure that GraphicsDevice is set up.

Recall that, while your constructor for your Game-derived class may create GraphicsDeviceManager, the graphics device itself is only created when Game.Run() is called (an instance method, so it requires an instance, which requires calling the constructor).


A more interesting question would be: Why is there Initialize and LoadContent? Why not just LoadContent?

Partly this goes back to XNA 1.0 (there's a certain degree of backwards-compatibility in the API). Back then, there was no LoadContent method, but instead there was a LoadGraphicsContent method. That method would get called whenever the graphics device was reset, in order to reload all of your GPU resources - such as textures (you were expected to handle this correctly).

(Aside: A device reset can happen if the user minimises the window, locks their workstation, etc.)

From XNA 2.0 onwards, XNA will automatically reload textures (and other GPU resources) for you - and the method was renamed LoadContent. Although, in the very rare case where the automatic-reload fails, XNA will still call LoadContent to attempt to recreate the resources from scratch.

(Most people don't bother writing LoadContent carefully enough to handle this situation correctly.)

In either case, having an Initialize method gives you a separate code-path that is only called once at startup, when the graphics device is available, but is not part of the reset-handling.

The methods in (Drawable)GameComponent are the way they are largely to mirror what is in Game, but the same reasoning as above applies.


You might also find this answer interesting.

\$\endgroup\$
3
  • \$\begingroup\$ Actually, that other answer is pretty helpful/interesting. So basically, it's set up in this way to guarantee that the GDM is in a usable state by the time components get around to initializing themselves, or using textures or other resources that rely on the graphic device. Makes sense. On a related note, I've noticed I can actually call new GraphicsDeviceManager(this); and it still sets everything up correctly anyways (albeit without a reference to the GDM). Usually, I would expect this sort of 'automatic' behavior to be in a static method, not a constructor. What gives? \$\endgroup\$
    – Kyle Baran
    Commented Oct 19, 2014 at 12:42
  • 1
    \$\begingroup\$ I'm not sure I fully understand the question. When GraphicsDeviceManager(this) runs, where this is a reference to Game, it inserts itself into the given Game.Services as both IGraphicsDeviceService and IGraphicsDeviceManager. This is how Game.Run is able to find the GDM to set up the GraphicsDevice. If you were so inclined, you could provide your own implementations of those two interfaces, and Game would work as expected. You could even skip Game all together and initialize GraphicsDevice yourself. \$\endgroup\$ Commented Oct 19, 2014 at 14:49
  • \$\begingroup\$ Okay cool, that's exactly what I wanted to know. I didn't realize that it inserted itself into Game.Services \$\endgroup\$
    – Kyle Baran
    Commented Oct 19, 2014 at 14:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .