DCES Examples - Minimal

This subsection documents the example application dces_minimal.

In a minimalistic use-case, this example creates a single world. It creates one entity and assignes one component that provides the property “name”.

A print system will queries into the entity store “e_store”, collects the given entity and prints out the “value” of any component that has a matching component with the property key “name”. Without any fancy magic, they are printed to stdout.

Update Cargo.toml

First have a look at the corresponding Cargo.toml file as shown in Listing 1-1.

# ANCHOR: All
[package]
# ANCHOR: Name
name = "dces_minimal"
# ANCHOR_END: Name
version = "0.4.0"
authors = [
	"Florian Blasius <flovanpt@posteo.de>",
	"Ralf Zerres <ralf.zerres.de@gmail.com>",
]
description = "DCES - Minimal example"
documentation = "https://doc.redox-os.org/dces-guide"
repository = "https://gitlab.redox-os.org/redox-os/dces-guide"
readme = "README.md"
license = "MIT"
keywords = [
	"dces",
	"ecs",
]
edition = "2021"

[profile.dev]
opt-level = 1

[dependencies]
dces = { git = "https://gitlab.redox-os.org/redox-os/dces-rust.git", branch = "develop" }

[[bin]]
# ANCHOR: Name
name = "dces_minimal"
# ANCHOR_END: Name
path = "src/main.rs"
# ANCHOR_END: All

Listing 1-1: Projects metadata “dces_minimal”

Program source code

All of the DCES specific code that is needed to build the dces_minimal example is shown in [Listing 1-2][dces_minimal, that is encode in src/main.rs.

Enter the following commands inside the terminal window to compile and run in debug mode:

$ cargo run --example miminal

The following output should be printed inside your console window:

DCES

Recap and annotation

The anatomy of the dces_minimal application

Let’s review the relevant parts of the dces_minimal application. A more in depth view of a typical DCES application is documented inside the annotated dces_basic source.

Following code block extracts the implementation of the PrintSystem:

impl System<EntityStore> for PrintSystem {
    fn run(&self, ecm: &mut EntityComponentManager<EntityStore>, _: &mut Resources) {
        let (e_store, c_store) = ecm.stores();

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get::<Name>("name", *entity) {
                println!("{}", comp.value);
            }
            // ANCHOR_END Print_ComponentValue
        }
    }
}

We loop over the given entity store “e_store” and get any component with a key matching "name". If the value us non-null, it will be printed to stdout.

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get::<Name>("name", *entity) {
                println!("{}", comp.value);
            }
            // ANCHOR_END Print_ComponentValue
        }

As a result, the string DCES! will make it as the console output.

Complete example source

Find attached the complete source code for our dces_minimal example.

use dces::prelude::*;

#[derive(Default)]
struct Name {
    value: String,
}

struct PrintSystem;

impl System<EntityStore> for PrintSystem {
    fn run(&self, ecm: &mut EntityComponentManager<EntityStore>, _: &mut Resources) {
        let (e_store, c_store) = ecm.stores();

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get::<Name>("name", *entity) {
                println!("{}", comp.value);
            }
            // ANCHOR_END Print_ComponentValue
        }
    }
}

fn main() {
    let mut world = World::from_entity_store(EntityStore::default());

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with(
                    "name",
                    Name {
                        value: String::from("DCES"),
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).build();
    world.run();
}

Listing 1-2: dces_minimal - Create a World, an entities, and a print systems.

Compiling and Running Are Separate Steps

The cargo call to compile dces_minimal will place the resulting binary in the target subfolder of the project.

$ cargo build --release --bin dces_minimal.rs
$ ../target/release/dces_minimal

On Windows, you need to use backslash as a path delimiter:

> cargo build --release --bin dces_minimal.rs
> ..\target\release\dces_minimal.exe