Skip to content

Utility Features

genar edited this page Mar 6, 2023 · 15 revisions

Non-Generic API

Almost every generic API has a type-based alternative. This can be used in cases where the types are not known at compile time. However, these APIS are somewhat slower than their generic variant and might also generate garbage. The different variants can be mixed as well. All the Entity-API is also mirrored by the World.

// Create an entity by an array of components instead of generics
var archetype = new ComponentType[]{ typeof(Position), typeof(Velocity), ... };
var entity = world.Create(archetype);

entity.Add(in object cmp);                             // Adds a component to an entity, non generic
entity.AddRange(in List<object> components);           // Adds a list of components to an entity
entity.Remove(in Type cmpType);                        // Remove a component
entity.RemoveRange(in List<Type> componentTypes);      // Remove a list of components
entity.Get(in Type cmpType);                           // Get ref to a component
entity.GetRange(in List<Type> componenTypes);          // Get ref to a list of components
entity.Set(in object cmp);                             // Set component
entity.SetRange(in List<object> components);           // Set multiple components
entity.Has(in Type cmpType);                           // Checks if type of component exists on the entity
entity.HasRange(in List<Type> componentTypes);         // Checks if types exists on entity

Entity References

In some cases, you may want to reference entities among themselves. Instead of an Entity you should refer to an EntityReference instead. This references an entity and also stores a version to check if the original entity still exists.

using var world = World.Create();

var entity = world.Create(_entityGroup);
var reference = world.Reference(entity);  // This should be stored in your component ( entity.Reference() is also available. )

// Checks if the entity is the same as before by comparing the version and its id
if(reference.IsAlive()) {
    var cmps = reference.Entity.Get(...);
}     

Command Buffers

Entity creation, deletion, and structural changes can happen during a query or entity iteration.
Sometimes, however, it makes sense to record operations and later transfer them to the world.
For this reason, command buffers exist.

var entity = world.Create<Transform, Rotation, int>();                                                               // Entity in world.
var bufferedEntity = commandBuffer.Create(new ComponentType[] {typeof(Transform), typeof(Rotation), typeof(int) });  // Later also generic overloads to get rid of arrays. 
        
// Records operations on the existing entity.
commandBuffer.Set(in entity, new Transform{ X = 20, Y = 20});
commandBuffer.Add(in entity, new Ai());
        
// Records operations on the buffered entity. 
commandBuffer.Set(in bufferedEntity, new Transform{ X = 20, Y = 20});
commandBuffer.Add(in bufferedEntity, new Ai());

// Transfers them into the world. 
commandBuffer.Playback();

Buffers are threadsafe and very fast, perfect for such scenarios. They can and should always be reused! :)

Clone this wiki locally