I have a simple toy ECS object implementation below. The signature of the DerefData(GameBehavior behavior)
method requires a GameBehavior
parameter to use as an index lookup.
The GameBehavior
value should be set by the type,Flyable.BehaviorID
. But to know that, we need an instance, which doesn’t work, since the point of the deref method is to get the instance from the generic type.
Preferably no use of Reflection as to be as speedy as possible.
Can this be refactored to only need BaseGameObject<U> DerefData()
with no parameter?
using System;
GameObject gameobj = new();
Flyable fdata = new Flyable { Velocity = 0d };
gameobj.AddBehavior(fdata);
var flightdata = gameobj.DerefData<Flyable>(GameBehavior.Flyable);
// i'd like to remove the parameter from this method signature.
// Which means we need access to IBehavior.BehaviorID,
// which is a 'type-level' property that in theory shouldn't need an object to lookup the value.
interface IBehavior
{
GameBehavior BehaviorID { get; }
}
struct Flyable : IBehavior
{
public GameBehavior BehaviorID => GameBehavior.Flyable;
public double Velocity;
}
[Flags]
enum GameBehavior : int
{
Flyable,
Burnable
}
class GameObject : BaseGameObject<IBehavior>{}
abstract class BaseGameObject<T> where T : IBehavior
{
T[] Items = new T[32]; // Max number of enum flags; this ECS is limited to at max 32 behaviors per game object
public U DerefData<U>(GameBehavior behavior) where U : T
{
return (U)Items[(int)behavior]; // We don't have an object instance to lookup behavior ID
}
public void AddBehavior<U>(U obj) where U : T
{
Items[(int)obj.BehaviorID] = obj; // we have an object instance to lookup BehaviorID
}
}