Hi, could someone please explain simply how to turn a GameComponent that I've written into a GameService that can be accessed by any GameComponent. i.e. What class needs to implement IMyGameService What should it expose How do I go about registering my service with the Game. A link to a thread/article or a new explanation that explains this would be great. I've seen a few half-explanations around, but nothing full. Still, a concise but thorough summary would be the best. Thanks a lot...

GameServices
Ravi Nidhonkar
ICamera camera = this.Directory.Find<ICamera>();
If you have to write two or more extra classes and several methods for every service you wish to use (CameraService, CameraProvider ) then you will end up doing more "plumbing" then programming.
dotnetorjava
A GameService is a GameComponent that needs to expose functionality that other GameComponents need to use.
Take a look at this: http://www.openxna.net/node/60
Chaseman
Thanks very much for all your answers - leclerc and Kris especially. I'll take a look at it all asap.
PiGuy
ICamera camera; // retained reference.
ICamera Camera // property used internally to get the service
{
get
{
if (this.camera == null || this.camera.Disposed)
this.camera = this.Directory.Find<ICamera>();
return this.camera;
}
}
Doing this removes the need for any "ServiceChanged" type of event, and therefore gets rid of the whole need for a "ServiceProvider" interface. The Service IS the Provider.
Furthermore... what happens when you run a split screen game, and there are suddenly two or more cameras How does a component find the right camera using the simple one level deep service model you are using In the model I'm using, you will find the first ICamera implementation that is registered with your component, or any of your ancestor components. So components can find the appropriate services based upon where they are defined in the scene graph.
Hope this answers your question. Like I said above, I'm not using the built-in service model.
(Once again, whenever a service (any component) is removed, it's disposed. Since consumers check this before usage, it handles the critical "referenced changed" issue you mentioned, and without requiring an intermediate class.)
Byenary
It's a short crash course to the GameComponents/GameServices concept and explains how the GameServices work to let GameComponents interact with each other. At the end of that article, there's some example code containing a GameComponent that publishes a custom GameService.
-Markus-
Jacob Pettersson
I'll give you an example from my engine for creating a camera service since the linked example leaves a couple of important things out. One method for adding a camera to components that use one would be to make public properties for each component and hook the camera to each of them in the component design view. However, this can get tedious if you have many components that use the camera. A cleaner method is to create a service that provides the camera and updates components when the camera changes or is created.
Here is my camera class that is used by many components:
public abstract partial class Camera : GameComponent
{
public abstract Vector3 Position
{get; set;}
public abstract Matrix ViewProjection
{get;}
public abstract Matrix World
{get;}
}
The world matrix is nullable because most cameras don't change the location of objects they look at.
Next, I need to create an interface for a service that tells camera-using components when the camera is created, when it is changed, and gives a way to access the camera.
public interface ICameraService
{
event EventHandler CameraCreated;
event EventHandler CameraChanged;
Camera Camera {get;} // null if the camera has not yet been created
}
Afer defining the means by which components will access and receive updates about the camera, we need to create a class that provides the service:
public class CameraProvider : ICameraService
{
private Camera cam = null;
public event EventHandler CameraCreated;
public event EventHandler CameraChanged;
public void AddCamera(Camera cam)
{
if (this.cam == null) && CameraCreated != null)
{
this.cam = cam;
CameraCreated(this, new EventArgs());
}
else
{
this.cam = cam;
if (CameraChanged != null)
CameraChanged(this, new EventArgs());
}
}
public Camera Camera
{ get { return cam; } }
}
Before I go on, I'll say that there are a number of ways deciding on how objects are added to your service and when to add the service to your game. Should we add the service to the game in the constructor Should the game add cameras to the service, or should each camera add itself to the service when created You will have to answer these questions yourself, but I prefer to create the service in the games constructor and add each camera to the service in the Start() method of the camera. Note that if you ever want to change cameras, you will have to do that outside the Camera class since Start() is only called once.
So, in the Camera class, we can add this:
public override void Start()
{
base.Start();
CameraProvider provider = (CameraProvider)
Game.GameServices.GetService<ICameraService>();
provider.AddCamera(this);
}
And in the Game constructor:
public MyGame()
{
CameraProvider camProvider = new CameraProvider();
GameServices.AddService(typeof(ICameraService), camProvider);
InitializeComponent();
}
Now, we have created the service and added it to the game before it starts. One question is left: how do we use the service Here is a simple class that just prints the position of the camera every frame:
public partial class CameraUser : GameComponent
{
private ICameraService cam;
public CameraUser()
{ InitializeComponent(); }
public override void Start()
{ cam = Game.GameServices.GetService<ICameraService>(); }
public override void Update()
{
if (cam.Camera != null) // could also subscribe to service events and store reference to actual camera
{
Console.Clear();
Console.WriteLine(cam.Camera.Position);
}
}
}
I could create a whole variety of cameras that inherit Camera, and they would automatically be added to the games cameras ervice for use by any component that needs a camera (model viewer, grid, etc.).
rwbogosian
Alex Stevens
@leclerc9
Very nice example. Thanks.
terryhohoho
The camera class is the class that is being provided to clients, and you can't directly add that as a service since it is not guaranteed to exist at all, and the reference can change.
I'm not sure what you are getting at here, this seems to be the min-threshold to achieve what game services were intended for. I have one class for the service provider and one class for the object that the service provides. All you need to do to get the service in my example is call:
GameServices.GetService<ICameraService>();
I'd be very interested in seeing your simpler version.