/CaboodleES

Provides a DOD infrastructure.

Primary LanguageC#MIT LicenseMIT

CaboodleES

A fast and simple Entity System Framework library for C# using .Net Framework 3.5.

How to use?

Components are mostly organized sequentially in memory for fast access.

  • Entities (Entity) - internally are integers (ulong) that act as a container for components. An entity can not have multilpe components of the same type.
  • Components (Component) - Hold data.
  • Systems (Processor) - Processes components and events.
  • Caboodle - A collection of entities, components, and systems. Can communicate with other caboodle objects.

A caboodle is an entity world that encapsulates entities, components, and systems. Systems can only process entities within the same caboodle they exist in, however you can copy/union data between caboodle objects.

Getting started

First include the library.

using CaboodleES;

Next, you will want to instantiate a Caboodle object to manage your components, entities, and systems.

var caboodle = new Caboodle();

Call union to unify two caboodle's.

caboodle.Union(anotherCaboodle);

Adding Entities

You can think of entities as containers of components. Internally they do not actually contain any components they only contain an integer id that can be used as a key for accessing components from component collections.

To create an entity you must call the create method inside the caboodle object.

var entity = caboodle.Entities.Create();

Removing Entities

Removing an entity will release all of its components back to the pool.

Entities can be removed two ways.

entity.Destroy();
    // or
caboodle.Entities.Remove(entity)

Adding Components

When you create a new entity and add a new component, a component collection is allocated for storing that specific type of components. Systems choose the component collections they are interested in.

Components can be added two ways.

var c = entity.AddComponent<Rigid>();
    // or
var c = caboodle.Entities.Components.AddComponent<Rigid>(entity.Id);

Removing Components

Components can be removed two ways.

var c = entity.RemoveComponent<Rigid>();
    // or
var c = caboodle.Entities.Components.RemoveComponent<Rigid>(entity.Id);

Processors (Systems)

Processors (Systems) process (Update) a set of entities that contain the components of interest.

Attributes

[CaboodleES.Attributes.ComponentUsageAttribute( priority, loopType, aspect, components...)]

  • Priority - Used to organize the execution of systems
  • loopType - Determines how the processor will be executed (e.g. Once, Update, Reactive)
  • Aspect - The type of interest in the set of components (e.g. Complement, Has, Match)
  • Components - The set of components of interest in respect to the aspect
Inter-System-Communication

Processors can communicate with each other via the EventManager. Use the AddEvent<>(myEvent) method to add a new event. Newly added events are handled at the end of an update (process). To add a handler to handle the event(s) use AddHandler<>(myHandler) method.

Usage
public class ExampleEvent : IEventArg {
   public string exampleVariable;
}

[CaboodleES.Attributes.ComponentUsageAttribute(1, Attributes.LoopType.Update, Aspect.Match, typeof(ExampleComponent))]
public class ExampleSystem : Processor
{
   public override void Start() 
   {
       AddHandler<ExampleEvent>(ExampleHandler);
   }
   
   public override void Process(IDictionary<int, Entity> entities) 
   {
       foreach(var entity in entities.Values) 
       {
           // entities to process
       }
       
       // Add a new event for testing purposes
       AddEvent<ExampleEvent>(new ExampleEvent());
   }
   
   // The handler is called when an event of its type is added
   public void ExampleHandler(ExampleEvent e) 
   {
   
   }
}

Compiling & Installation

Build the CaboodleES project library then use the .dll in the bin folder.

You will need Visual Studio 2015.

Unity3D Setup

Place the CaboodleES.dll into Unity3D's plugin folder within your project or place the source code inside your assets folder. Inside of your project create an empty GameObject and add a new monobehavior.

using UnityEngine;
using CaboodleES;

// The new monobehavior that will interface with CaboodleES
public class CaboodleFoo : MonoBehavior
{
    // Entity world
    private Caboodle world;

    public CaboodleFoo()
    {
        this.world = new Caboodle();
    
        // Registers all systems within the calling assembly
        world.Systems.Add(Assembly.GetCallingAssembly());
        
        // To add individual systems
        world.Systems.Add<MyProcessor>();
    
        // Creating an entity
        CaboodleES.Entity ent = word.Entities.Create();
        FooComp c = ent.AddComponent<FooComp>();
        c.data = "Hello, world";
    }

    void Start()
    {
        world.Systems.Init();
    }

    void Update()
    {
        world.Systems.Process();
    }
}

public class FooComp : CaboodleES.Component
{
    public string data;
}

TODO List

  • Optimize memory usage
  • system loop-type attribute
  • update documentation