Skip to content
Jeff Campbell edited this page Jun 19, 2020 · 1 revision

Overview

A context defines a slice of simulation for a collection of related entities and components. An application can have one or more contexts, each with their own distinct type of entities and components, that encapsulate the data for different parts of the application.

Multiple Contexts

A context is somewhat similar to a table in a database and deciding when to separate a context into multiple is akin to normalization. The number of contexts for an application depends on:

  • How many types of components there are; each entity belonging to a context is backed with an array of components associated with that context. In this way, if there are areas of your application that require only a small subset of the total components in the project, associating these with their own separate context can help to reduce the overall memory impact.

For example, one context could be used to describe entities/components for gameplay and another for the user interface.

Pooling

A context maintains pools for entities and components in order to avoid garbage collection. For the most part they are automatically reference counted and recycled back to their respective pools when an entity is destroyed or component removed.

There is an exception to this for entities where this reference count can be increased by calling Retain(object owner) and decreased by calling Release(object owner). This can allow for an entity to be cached and used locally without fear that it may suddenly become destroyed and recycled back into a pool. However, failing to call Release for an entity that goes out of scope will result in memory leak as the entity will never be destroyed or recycled.

If caching an entity in order to maintain a reference to it from another entity, consider using an EntityIndex or PrimaryEntityIndex instead.

Entities

When an entity is created and then destroyed, it is returned to the pool.

Events

There are several events which can be subscribed to on any given Context; these help to notify subscribers of lifecycle changes to entities on that Context.

  • OnEntityCreated
  • OnEntityWillBeDestroyed
  • OnEntityDestroyed
  • OnGroupCreated

Code Generation and Implementation

EntitasRedux takes advantage of code generation via Genesis to create much of the application-contextual API and implementation of each context. Contexts are defined in GenesisSettings config asset by specifying a list of names in the EntitasRedux Context Names section.

When code generation is executed for a given defined context (for demonstration sake, the name of the context is Foo), it generates code for:

  • A FooContext class that allows for creation of and pooling for FooEntity instances, any components associated with FooContext, events, etc...
  • An attribute [FooContext] that can be used to decorate components to associate them with the FooContext. By default, components that are not associated with a specific context by way of this attribute will be associated with the first defined context. Usage of this attribute will ensure that this component is only associated with FooContext and any other contexts it has been associated with by way of a similar attribute.
  • A FooEntity class that allows for adding, removing, or replacing any component associated with the FooContext. When an entity is created from FooContext, it will be of FooEntity type.
  • A FooMatcher static class that enables defining simple queries for FooEntity by way of any associated components. This is typically used to help create groups and entity indexes.
  • A FooComponentsLookup static class that defines the indexes used for storing and retrieving components in internal arrays and pools. It helps to support much of the rich-API for components on Entities and Matchers.