DCES Examples - Basic

This subsection documents the example application dces_basic.

This example instantiates a single world. It creates three entities each with an assigned component that provides the property “name”, “depth” and “size”.

A size system will query the entity store and manipulate the width and height struct values of components that provide and match a key “size”. As a rudimentary use case, we do simply increment by one.

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

The project root

Change to your project root directory. If you didn’t already create the app in the first place, go ahead and type the following in your console:

$ cd ~/guide/examples

Create the source code

Next we will use cargo to create the app. All boilerplate tasks are handled using cargo’s inherited template handling.

$ cargo new dces_basic
$ cd dces_basic

The first command, cargo new, takes the name of the project (“dces_basic”) as the first argument. The second command changes to the new project’s directory.

Look at the generated Cargo.toml file:

[package]
name = "dces_example"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

Listing 1-1: Default metadata “dces_basic”

With cargo new, a default project structure is created. Maybe the author information is already exchanged if Cargo could obtain a definition from your environment. Cargo also generated source code for a “Hello, world!” program. Let’s Check out the corresponding src/main.rs file:

fn main() {
    println!("Hello DECS!");
}

Listing 1-2: Default source file “main.rs”

No need to compile that stage with cargo run, since we are going to exchange the project metadata, as well as the dces source code right away.

Update Cargo.toml

First reopen the Cargo.toml file and enter the Code in Listing 1-3 into Cargo.toml

[package]
name = "dces_basic"
version = "0.4.0"
authors = [
	"Florian Blasius <flovanpt@posteo.de>",
	"Ralf Zerres <ralf.zerres.de@gmail.com>",
]
description = "DCES - Basic 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]]
name = "dces_basic"
path = "src/main.rs"

Listing 1-3: Project metadata “dces_basic”

You may wonder, why the name property inside the Cargo.toml is formatted like dces_basic.

name = "dces_basic"

It is a good habit to follow rusts naming convention, that encourages you to use snake_case naming. While expanding the DCES example sources, we will keep the grouping prefix dces. That way we end up to call our first target binary dces_basic.

Update main.rs

All of the DCES specific code that is needed to build our first example is shown in Listing 1-4, that you encode into src/main.rs.

Save your changes to the file and go back to the terminal window. Enter the following commands to compile and run the file in debug mode:

$ cargo run --example basic

The following output should be printed inside your console window:

Button width: 6; height: 6
CheckBox width: 4; height: 4
RadioButton width: 5; height: 7

Recap and annotation

The anatomy of a DCES application

Let’s review in detail what just happened in your DCES-basic application. Here are the relevant pieces of the puzzle:

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

The first line is introducing a use declaration. A use declaration is used to shorten the path required to refer to rust module items. The prelude is a convenient way to a list of things, that rust will automatically import to you program. Here, we bind the path dces::prelude. All default items defined in this path (referenced with ::) are now accessible in your source using their shorthand name. No need to type in their common prefix (dces::prelude::)

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

The main function is special: it defines the first execution point inside a compiled Rust binary (leaving rust’s minimal runtime out of scope). In our example the function name main has no parameters and returns nothing. If there were parameters, they would go inside the parentheses, ().

Also, note that the function body is wrapped in curly brackets, {}. Rust requires these around all function bodies. It’s good style to place the opening curly bracket on the same line as the function declaration, adding one space in between.

An automatic formatter tool called rustfmt will help you to stick to a standard style across Rust projects. DCES is following this guidance. rustfmt will format your code in a particular style. Depending on the version of your rust toolchain, it is probably already installed on your computer! Check the online documentation for more details.

Lets focus on some other important details:

  • First, Rust style is to indent with four spaces, not a tab.
  • Second, we create five entities inside a world.
  • Third, we create two systems inside a world.
  • Forth, we start the run loop for our world.

As a first step, we do instantiate a mutable world structure. This structure will make use of an EnityStore.

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

Next we create five new entities inside the our world. For each entity we assign components. The components are constructed consuming the method ComponentBuilder to define their values (uppercase string). The corresponding keys are name, depth, and size (in parentheses). A terminating block is calling the build method, that finally instantiates the code.

Following code block extracts the definition of the first entity:

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

Please note, that “size” itself is a structure that handles the values width and height.

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

We should mention, that our example-code defines all entities with the same number and names of component elements. This is not a requirement nor a design restriction. Which components are attached to which entities may differ significantly and is completely arbitrary.

Our binary will consume a Size- and a Print-System. Both of them do handle entity manipulation via the EntityComponentManager (ECM). The ECM is capable to borrow or mutate Enities and Components via its EntityStore. Thus we can assign distinct store structures for each of them (here: e_store, c_store).

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

Next we simply loop over the store in question and use the get() method to consume the values of the given entities and components that match our query.

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

Complete example source

Find attached the complete source code for our dces_basic example.

use dces::prelude::*;

#[derive(Default)]
struct Size {
    width: u32,
    height: u32,
}

#[derive(Default)]
struct Name(String);

#[derive(Default)]
struct Depth(u32);

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

        for entity in &e_store.inner {
            if let Ok(comp) = c_store.get_mut::<Size>("size", *entity) {
                comp.width += 1;
                comp.height += 1;
            }
        }
    }
}

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

        for entity in &e_store.inner {
            if let Ok(name) = c_store.get::<Name>("name", *entity) {
                if let Ok(size) = c_store.get::<Size>("size", *entity) {
                    println!("{} width: {}; height: {}", name.0, size.width, size.height);
                }
            }
        }
    }
}

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

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("Button")))
                .with("depth", Depth(4))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 5,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("CheckBox")))
                .with("depth", Depth(1))
                .with(
                    "size",
                    Size {
                        width: 3,
                        height: 3,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("name", Name(String::from("RadioButton")))
                .with("detph", Depth(2))
                .with(
                    "size",
                    Size {
                        width: 4,
                        height: 6,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(3))
                .with(
                    "size",
                    Size {
                        width: 10,
                        height: 4,
                    },
                )
                .build(),
        )
        .build();

    world
        .create_entity()
        .components(
            ComponentBuilder::new()
                .with("depth", Depth(0))
                .with(
                    "size",
                    Size {
                        width: 5,
                        height: 8,
                    },
                )
                .build(),
        )
        .build();

    world.create_system(PrintSystem).with_priority(1).build();

    world.create_system(SizeSystem).with_priority(0).build();

    world.run();
}

Listing 1-4: dces_basic - Create a World, its entities and systems.

Compiling and Running Are Separate Steps

Before you are able to run a DCES application, you must compile its source code. A typical DCES project will generate the executable binary code using cargo and place the result in the target subfolder of the project.

Profiles may be used to configure compiler options such as optimization levels and debug settings. By default the dev or test profiles are used. If the --release flag is given, then the release or bench profiles are used.

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

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

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