Skip to content

Instantly share code, notes, and snippets.

@Metapyziks
Created May 28, 2012 09:17
Show Gist options
  • Select an option

  • Save Metapyziks/2818097 to your computer and use it in GitHub Desktop.

Select an option

Save Metapyziks/2818097 to your computer and use it in GitHub Desktop.
Component based Entity
public abstract class Component
{
public static T Create<T>( Entity ent )
where T : Component
{
Type t = typeof( T );
ConstructorInfo c = t.GetConstructor( new Type[] { typeof( Entity ) } );
if ( c == null )
throw new MissingMethodException( "Type " + t.FullName + " is missing a valid constructor." );
return (T) c.Invoke( new object[] { ent } );
}
public readonly Entity Entity;
protected Component( Entity ent )
{
Entity = ent;
}
public virtual void OnSpawn()
{
}
public virtual void OnThink( double dt )
{
}
public virtual void OnRemove()
{
}
}
public sealed class Entity : IEnumerable<Component>
{
private Dictionary<Type, Component> myComponents;
private Vector2 myPosition;
private bool myPosChanged;
public readonly City City;
public Block Block
{
get;
private set;
}
public bool IsValid
{
get;
private set;
}
public Vector2 Position
{
get { return myPosition; }
set
{
if ( !myPosition.Equals( value ) )
{
myPosition = value;
myPosChanged = true;
}
}
}
public Entity( City city )
{
myComponents = new Dictionary<Type, Component>();
myPosition = new Vector2();
myPosChanged = true;
City = city;
IsValid = false;
}
public T AddComponent<T>()
where T : Component
{
T comp = Component.Create<T>( this );
Type type = typeof( T );
do
myComponents.Add( typeof( T ), comp );
while ( ( type = type.BaseType ) != typeof( Component ) );
return comp;
}
public bool HasComponent<T>()
where T : Component
{
return myComponents.ContainsKey( typeof( T ) );
}
public bool HasComponent( Type t )
{
return myComponents.ContainsKey( t );
}
public T GetComponent<T>()
where T : Component
{
return (T) myComponents[ typeof( T ) ];
}
public Component GetComponent( Type t )
{
return myComponents[ t ];
}
public void Spawn()
{
if ( !IsValid )
{
IsValid = true;
UpdateBlock();
foreach ( Component comp in this )
comp.OnSpawn();
}
}
public void Remove()
{
if ( IsValid )
{
foreach ( Component comp in this )
comp.OnRemove();
IsValid = false;
}
}
public void Think( double dt )
{
foreach ( Component comp in this )
comp.OnThink( dt );
}
public void UpdateBlock()
{
if ( IsValid && myPosChanged )
{
Block newBlock = City.GetBlock( myPosition );
if ( newBlock != Block )
{
if ( Block != null )
Block.RemoveEntity( this );
Block = City.GetBlock( myPosition );
Block.AddEntity( this );
}
myPosChanged = false;
}
else if ( !IsValid && Block != null )
{
Block.RemoveEntity( this );
Block = null;
}
}
public IEnumerator<Component> GetEnumerator()
{
return myComponents.Values.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment