The Ingredients

DCES provides a dense ECS rust centric architecture. The interaction with DCES is managed via the Entity Component Manager(ECM), a wrapper API.

In contrast to the Object Oriented Programming (OOP) paradigma, the DCES separates data from behavior. Behaviors are handled via systems. Systems provide the logic and implement the behavior on how to act on entities with given properties. Data are bound to components that are assigned to entities. Thus entities are unique identifiers, that may have multiple, dynamically changable components. The components itself are usually preceived as properties in the consuming rust codebase.

The Architecture view

To break up the architecture of an ECS it’s quite a help to first define the building blocks. Here we go:

  • Entity: Is an uniquely identifyed object. The Entity can contain zero or more components.

  • Component: You are able to save datatypes inside a component. We will call the saved value of a component it’s property. The property may be looked up via its component key.

  • Entity_Component_Manager: The ECM keeps track of an entity store (bound entities and an associated component store).

  • Resource: A resource is a data slot which lives in a World. The data are shared between systems. Resources can only be accessed according to Rust’s typical borrowing model (one writer xor multiple readers). You may structure the components using resources.

  • Store: For any given storage provider the DCES defines an instance. It is quite common to utilize different, specialized stores. The store handles multiple entities, componets or resources.

  • Systems: The behaviors are processed with functions. This behavior will be processed for all matching entities of a component query.

  • World: A world represents the root of the DECS tree. Since it is totally leagal to have multiple world instances, each one represents a distinguished entity storage provider. This instances are handled via the methods of the entity_component_manager (ECM).

The following ClassDiagramms visualizes the involved DCES elements. To improve visibility, we will break up the complete tree into detailed sub-trees.

classDiagram

World --o EntityComponentManager
World --o Resource
World --o SystemStore

EntityComponentManager --o EntityStore
EntityComponentManager --o ComponentStore

EntityComponentManager : entity_store[EntityStore]
EntityComponentManager : component_store[ComponentStore]
EntityComponentManager : component_store()
EntityComponentManager : component_store_mut()
EntityComponentManager : create_entity()
EntityComponentManager : entity_counter[u32]
EntityComponentManager : entity_store()
EntityComponentManager : entity_store_mut()
EntityComponentManager : new()
EntityComponentManager : register_entity()
EntityComponentManager : remove_entity()
EntityComponentManager : stores()
EntityComponentManager : stores_mut()

Resource: FxHashMap[TypeId, Box->dyn Any]
Resource : contains()
Resource : get()
Resource : get_mut()
Resource : insert()
Resource : is_empty()
Resource : len()
Resource : new()
Resource : try_get()
Resource : try_get_mut()

World : entity_component_manager[EntityComponetManager]
World : resources[FxHashmap]
World : system_counter[u32]
World : system_store[SystemStore]
World : first_run bool
World : create_entity()
World : create_system()
World : drop()
World : entity_component_manager()
World : from_entity_store()
World : insert_resource()
World : print_entity()
World : register_init_system()
World : resource_mut()
World : remove_entity()
World : run()

Workflow 1-1: Global DCES architecture view

Next we have a look at the pieces inside the Entity hierarchy.

classDiagram

Trait_EntityStore --o VecEntityStore
Trait_EntityStore --o EntityBuilder
VecEntityStore --o Entity
EntityBuilder --o Entity
EntityBuilder --o Component

EntityBuilder : EntityStore[Entity, ComponentStore, EntityStore]
EntityBuilder : build()
EntityBuilder : components()

VecEntityStore : Vec[Entity]
VecEntityStore : register_entity()
VecEntityStore : remove_entity()

Trait_EntityStore : Entity
Trait_EntityStore : register_entity()
Trait_EntityStore : remove_entity()

Entity : Entity[u32]

Component: E[Any]

Workflow 1-2: Detailed Entity architecture view

Next we present an isolated visualizaton of the Componets hierarchy.

classDiagram

Trait_Component --o ComponentStore
Trait_Component --o ComponentBuilder
Trait_Component --o ComponentBox
ComponentBox --o SharedComponentBox
ComponentBox --o Component
SharedComponentBox --o Component
ComponentStore --o Component
ComponentBuilder --o Component

Component : E[Any]

ComponentBuilder : ComponentBuilder[components, shared]
ComponentBuilder : build()
ComponentBuilder : new()
ComponentBuilder : with()
ComponentBuilder : with_shared()

ComponentBox : ComponentBox[Box->dyn Any, TypeId]
ComponentBox : consume()
ComponentBox : new()

ComponentStore : ComponentStore[Components, SharedComponents]
ComponentStore : append()
ComponentStore : entities_of_component()
ComponentStore : get()
ComponentStore : get_mut()
ComponentStore : is()
ComponentStore : is_empty()
ComponentStore : is_origin()
ComponentStore : len()
ComponentStore : print_entity()
ComponentStore : register()
ComponentStore : register_box()
ComponentStore : register_shared()
ComponentStore : register_shared_box()
ComponentStore : register_shared_box_by_source_key()
ComponentStore : register_shared_by_source_key()
ComponentStore : remove_entity()
ComponentStore : source()
ComponentStore : source_from_shared()
ComponentStore : target_key()

SharedComponentBox : SharedComponentBox[Entity, TypeId]
SharedComponentBox : consume()
SharedComponentBox : new()

Trait_Component : E[Any]

Workflow 1-3: Detailed Component architecture view

Followed by the presentation of an isolated visualizaton of the System hierarchy.

classDiagram

Trait_System --o SystemStore

SystemStore --o SystemStoreBuilder
SystemStore --o EntitySystem
SystemStoreBuilder --o EntitySystem

SystemStoreBuilder <-- InitSystem
SystemStoreBuilder <-- CleanupSystem


Trait_System : EntityStore[Any]
Trait_System : run()

EntitySystem: EntitySystem[Box->dyn System, priority]
EntitySystem: new()

SystemStore : EntityStore[entity_system->HashMap, init_system>Option, cleanup_system->Option, priorities->BTreeMap]
SystemStore : borrow_cleanup_system()
SystemStore : borrow_init_system()
SystemStore : new()
SystemStore : register_cleanup_system()
SystemStore : register_init_system()
SystemStore : register_priority()
SystemStore : register_system()
SystemStore : remove_system()

SystemStoreBuilder: SystemStoreBuilder[entity_system_id, system_store, priority]
SystemStoreBuilder: build()
SystemStoreBuilder: with_priority()

Workflow 1-4: Detailed System architecture view