using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MessagingInCSharp
{
class Program
{
static void Main( string[] args )
{
// Create a scene manager
SceneManager sceneMgr = new SceneManager();
// Have scene manager create an entity for us, which
// automatically puts the object into the scene as well
Entity myEntity = sceneMgr.CreateEntity();
// Create a render component
RenderComponent renderComp = new RenderComponent();
// Attach render component to the entity we made
myEntity.AddComponent(renderComp);
// Set 'myEntity' position to (1, 2, 3)
MsgSetPosition msgSetPos = new MsgSetPosition(myEntity.uniqueID, 1.0f, 2.0f, 3.0f);
sceneMgr.SendMessage(msgSetPos);
Console.WriteLine("Position set to (1, 2, 3) on entity with ID: " + myEntity.uniqueID);
Console.WriteLine("Retreiving position from entity with ID: " + myEntity.uniqueID);
// Get 'myEntity' position to verify it was set properly
MsgGetPosition msgGetPos = new MsgGetPosition(myEntity.uniqueID);
sceneMgr.SendMessage(msgGetPos);
Console.WriteLine("X: " + msgGetPos.x);
Console.WriteLine("Y: " + msgGetPos.y);
Console.WriteLine("Z: " + msgGetPos.z);
}
}
public enum MessageType
{
SetPosition,
GetPosition
}
public class Vector3
{
public float x = 0.0f;
public float y = 0.0f;
public float z = 0.0f;
}
public class BaseMessage
{
public int destEntityID;
public MessageType messageType;
protected BaseMessage( int destinationEntityID, MessageType messageType )
{
this.destEntityID = destinationEntityID;
this.messageType = messageType;
}
}
public class PositionMessage : BaseMessage
{
public float x;
public float y;
public float z;
protected PositionMessage( int destinationEntityID, MessageType messageType,
float X = 0.0f, float Y = 0.0f, float Z = 0.0f) :
base(destinationEntityID, messageType)
{
this.x = X;
this.y = Y;
this.z = Z;
}
}
public class MsgSetPosition : PositionMessage
{
public MsgSetPosition( int destinationEntityID, float X, float Y, float Z ) :
base(destinationEntityID, MessageType.SetPosition, X, Y, Z)
{}
}
public class MsgGetPosition : PositionMessage
{
public MsgGetPosition( int destinationEntityID) :
base(destinationEntityID, MessageType.GetPosition, 0.0f, 0.0f, 0.0f)
{}
}
public abstract class BaseComponent
{
public virtual bool SendMessage( BaseMessage msg )
{
return false;
}
}
public class RenderComponent : BaseComponent
{
public override bool SendMessage( BaseMessage msg )
{
// Entity has a switch for any messages it cares about
switch (msg.messageType)
{
case MessageType.SetPosition:
{
// Update render mesh position/translation
Console.WriteLine("RenderComponent handling SetPosition");
}
break;
default:
return base.SendMessage(msg);
}
return true;
}
}
public class Entity
{
public int uniqueID;
public int UniqueID
{
get { return this.uniqueID; }
set { this.uniqueID = value; }
}
private Vector3 position = new Vector3();
private List<BaseComponent> components = new List<BaseComponent>();
public Entity( int uniqueID )
{
this.uniqueID = uniqueID;
}
public void AddComponent( BaseComponent component )
{
this.components.Add(component);
}
public bool SendMessage( BaseMessage msg )
{
bool messageHandled = false;
// Entity has a switch for any messages it cares about
switch (msg.messageType)
{
case MessageType.SetPosition:
{
MsgSetPosition msgSetPos = msg as MsgSetPosition;
position.x = msgSetPos.x;
position.y = msgSetPos.y;
position.z = msgSetPos.z;
messageHandled = true;
Console.WriteLine("Entity handled SetPosition");
}
break;
case MessageType.GetPosition:
{
MsgGetPosition msgGetPos = msg as MsgGetPosition;
msgGetPos.x = position.x;
msgGetPos.y = position.y;
msgGetPos.z = position.z;
messageHandled = true;
Console.WriteLine("Entity handled GetPosition");
}
break;
default:
return PassMessageToComponents(msg);
}
// If the entity didn't handle the message but the component
// did, we return true to signify it was handled by something.
messageHandled |= PassMessageToComponents(msg);
return messageHandled;
}
private bool PassMessageToComponents( BaseMessage msg )
{
bool messageHandled = false;
this.components.ForEach(c => messageHandled |= c.SendMessage(msg) );
return messageHandled;
}
}
public class SceneManager
{
private Dictionary<int, Entity> entities = new Dictionary<int,Entity>();
private static int nextEntityID = 0;
// Returns true if the entity or any components handled the message
public bool SendMessage( BaseMessage msg )
{
// We look for the entity in the scene by its ID
Entity entity;
if ( entities.TryGetValue(msg.destEntityID, out entity) )
{
// Entity was found, so send it the message
return entity.SendMessage(msg);
}
// Entity with the specified ID wasn't found
return false;
}
public Entity CreateEntity()
{
Entity newEntity = new Entity(SceneManager.nextEntityID++);
entities.Add(newEntity.UniqueID, newEntity);
return newEntity;
}
}
}
A blog by a professional game developer, about game programming and development. My posts will range in comments from beginners to game development to those at a more advanced level.
Saturday, February 11, 2012
Game Engine Architecture, C#
Here's the same architecture as my last two posts, but this time in C# (the last two were in Scala and C++).
Labels:
C#,
game architecture,
game engine,
messaging
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment