Sign In
Mitch Walker
XNA Game Studio
Translate This Page
Translate this page
Powered by
Microsoft® Translator
Options
Blog Home
Email Blog Author
Share this
RSS for posts
Atom
RSS for comments
Search
Advanced search options...
Search In:
Everything
Blogs
Forums
People
Groups
Places
Pages
Date range:
All Time
Last Year
Last 6 Months
Last 3 Months
Last Month
Last Week
Last Two Days
Tags
Game Programming
General
Pages
XNA Game Studio
Archive
Archives
November 2008
(1)
October 2008
(1)
May 2008
(1)
April 2007
(3)
December 2006
(1)
October 2006
(1)
September 2006
(3)
August 2006
(3)
June 2006
(2)
April 2006
(3)
December 2005
(1)
October 2005
(1)
September 2005
(2)
August 2005
(2)
May 2005
(1)
February 2005
(1)
October 2004
(2)
September 2004
(1)
July 2004
(6)
June 2004
(2)
March 2004
(3)
February 2004
(10)
January 2004
(2)
Game.GameServices
MSDN Blogs
>
Mitch Walker
>
Game.GameServices
Game.GameServices
mitchw
6 Sep 2006 12:54 PM
Comments
21
I was originally going to create a tutorial that walks you through creating a custom
GameComponent
, perhaps the Framerate component from my demo or an event driven Keyboard component, but I’ve actually seen several of these pop up over the last few days so perhaps you’ve got the hang of it.
J
What I have seen are a few questions about are game services and particularly
IGraphicsDeviceService
. So I thought I’d write up a quick description of game services as well as the proper way to query and use the
IGraphicsDeviceService
.
GameServices
A game service can be thought of as a service that is available to anyone that has a reference to a
Game
. The idea behind it was there are certain types, or services, that a component should be able to depend on for its functionality. If that service isn’t available, then the component can’t operate correctly. The first one we thought of (and one of the reasons behind introducing services) was making a
GraphicsDevice
reference available across a game. Originally we had the Game own the
GraphicsDevice
and expose it via a property like
Game.GraphicsDevice
. The problem with this was that this tightly bound the
GraphicsDevice
to the
Game
, not allowing someone else to “own” the device (such as a renderer) and preventing someone from using a future updated
GraphicsDevice
without shipping a new version of
Game
that wouldn’t be backwards compatible. So to achieve the loose coupling of a
GraphicsDevice
and a
Game
, we factored the device management and ownership into a
GameComponent
, which is how
GraphicsComponent
came to be. We still needed to make the
GraphicsDevice
available across a
Game
or even outside of the
Game
. As long as someone has a reference to a
Game
, they should be able to get a hold of a
GraphicsDevice
, if it’s available. That’s the idea behind a game service. The
GraphicsComponent
“publishes” an interface,
IGraphicsDeviceService
, as a service that others can query for and obtain a reference to. In this sense, a service is a singleton that is keyed off the type of the service itself. So a component that needs to render using a
GraphicsDevice
, doesn’t have to be tied to a
GraphicsComponent
, it can just query for the
IGraphicsDeviceService
instead. Imagine if someone wanted to create a high-level renderer that owned the
GraphicsDevice
itself, rather than use the
GraphicsComponent
. They could create the renderer as a
GameComponent
and publish an instance of the
IGraphicsDeviceService
themselves and now the Game has use of a new renderer and all game components that depended on a
GraphicsDevice
will still work too!
One other benefit of services is that
Game.GameServices
can be passed to the
ContentManager
so the type loaders in the content manager can query for services (this is how textures load for instance). Because the container is passed one can add additional content types to the content manager (via a custom type loader) that relies on a custom game service without any intervention on our part.
So that was a quick explanation of a game service (complete with a
GraphicsComponent
history!) but it should help convey what the purpose of a service is and when you’d use them. They really are meant to be a system wide service that something can query for.
IGraphicsDeviceService
As mentioned above, game components that wish to render something on the screen need to get a reference to a
GraphicsDevice
. They could expose a property that is of type
GraphicsComponent
, but this would cause them to not work if a
Game
used something else to manage the
GraphicsDevice
, such as a custom renderer. Instead a
GameComponent
that wishes to make use of the
GraphicsDevice
should query for the
IGraphicsDeviceService
from
Game
with the following line of code:
IGraphicsDeviceService
graphicsService = Game.GameServices.GetService<
IGraphicsDeviceService
>();
Here’s what the
IGraphicsDeviceService
interface looks like:
// Summary:
// Defines a mechanism for retrieving GraphicsDevice objects.
public
interface
IGraphicsDeviceService
{
// Summary:
// Retrieves a graphcs device.
//
// Returns:
// A graphics device.
GraphicsDevice
GraphicsDevice {
get
; }
// Summary:
// The event that occurs when a graphics device is created.
event
EventHandler
DeviceCreated;
//
// Summary:
// The event that occurs when a graphics device is disposing.
event
EventHandler
DeviceDisposing;
//
// Summary:
// The event that occurs when a graphics device is reset.
event
EventHandler
DeviceReset;
//
// Summary:
// The event that occurs when a graphics device is in the process of resetting.
event
EventHandler
DeviceResetting;
}
As you can see the interface provides a reference to the
GraphicsDevice
as well as several events that you should use to properly detect when you need to load and unload your graphic resources such as textures, vertex buffers, index buffers and effects. It’s also important to note that you should only cache a reference to the interface, not a reference to the
GraphicsDevice
. This is because the reference to the
GraphicsDevice
can (and most likely will) change over the course of a Game due to window resizing, changing monitors, etc. The reference to the service, however, will remain the same throughout the game.
So you should typically query for the service and hook up the events you care about inside of the Start method of a
GameComponent
like so:
public
override
void
Start()
{
this
.graphics =
this
.Game.GameServices.GetService<
IGraphicsDeviceService
>();
this
.graphics.DeviceReset +=
new
EventHandler
(graphics_DeviceReset);
this
.graphics.DeviceResetting +=
new
EventHandler
(graphics_DeviceResetting);
this
.graphics.DeviceCreated +=
new
EventHandler
(graphics_DeviceCreated);
this
.graphics.DeviceDisposing +=
new
EventHandler
(graphics_DeviceDisposing);
LoadContent();
}
And provide event handlers like so:
void
graphics_DeviceDisposing(
object
sender,
EventArgs
e)
{
ReleaseContent();
}
void
graphics_DeviceCreated(
object
sender,
EventArgs
e)
{
LoadContent();
}
void
graphics_DeviceResetting(
object
sender,
EventArgs
e)
{
ReleaseContent();
}
void
graphics_DeviceReset(
object
sender,
EventArgs
e)
{
LoadContent();
}
And lastly it’s a good practice to put your loading and unloading of resources into a couple of common functions:
private
void
LoadContent()
{
this
.font =
new
Font
(
this
.graphics.GraphicsDevice,
"Components"
,
"Comic Sans MS_16"
);
}
private
void
ReleaseContent()
{
if
(
this
.font !=
null
)
{
this
.font.Dispose();
this
.font =
null
;
}
}
So I hope this was a helpful explanation of what game services are, why they are important and also what the
IGraphicsDeviceService
is for and how to use it. Please let us know what you think over at the
XNA Framework forum
.
21 Comments
Blog - Comment List MSDN TechNet
Comments
Loading...