dimanche 31 décembre 2017

ECS - Generic Component or Casting Component

I am building an Entity Component System for a game from scratch in Java. I understand the theory behind the system, but I cannot quite wrap my head around how to implement it in practice. In theory there are two ways to design components.

  1. as a raw data container i.e.

    Component as raw data container
    public class Component{
        public float[] rawdata;
    
        public Component(float... rawdata){
            this.rawdata = rawdata;
        }
    }
    
    //An example "definition" to interpret raw data
    public class VectorDefinition{
        public final static int
                            X = 0,
                            Y = 1;
    
        public static void setX(Component component, float x){
            component.rawdata[X] = x;
        }
    
        public static void setY(Component component, float y){
            component.rawdata[Y] = y;
        }
    
        public static  float getX(Component component){
            return component.rawdata[X];
        }
    
        public static float getY(Component component){
            return component.rawdata[Y];
        }
    
        public static Component createVectorComponent(float x, float y){
            return new Component(x, y);
        }
    
    }
    
    
  2. or by implementing a common interface, casting when necessary i.e.

    //Component as interface
    public interface Component{
    }
    
    //An example implementation of the component interface
    public class Vector implements Component{
        public float
            X,
            Y;
    
        public Vector(float x, float y){
            X = x;
            Y = y;
        }
    }
    
    

I find that both options are not without their issues. The problem I have with components as raw data containers is the lack of control over available types of data inside of the component (e.g. In order to store String data I would have to include a String[] array in the Component class). I would prefer to just implement a common interface, but I am not sure how to best tackle casting in this manner (e.g. when type erasure inevitably screws me because I am using generic lists/maps to store components).

My questions specifically are:

  1. are any of these methods objectively better, why?
  2. how would I implement either solution properly?

I have been trying to build this for about a month now and I feel that I have read almost everything free that I can find on ECS. Can anyone point me in the right direction? Like I said before, I feel that I have a solid understanding of the theory, I would just like to see some concrete implementation at this point.

Aucun commentaire:

Enregistrer un commentaire