DCES Examples - Resource

This subsection documents the example application dces_resource.

Again, we create a single world instance. Next one entity is build and we assignes one component that provides the property “name”. A mutable resource consuming type “HelloDCES” is assigned as well. Inside the print system we take care to print out any property value that matches the component key “name”. In addition the “say_hello()” method of resource “HelloDCES” is executed, that simply returns the String “Hello DCES!”.

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_resource"
# ANCHOR_END: Name
version = "0.4.0"
authors = [
	"Florian Blasius <flovanpt@posteo.de>",
	"Ralf Zerres <ralf.zerres.de@gmail.com>",
]
description = "DCES - Resource 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 = [
	"orbital",
	"widget",
	"ui",
]
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_resource"
# ANCHOR_END: Name
path = "src/main.rs"
# ANCHOR_END: All

Listing 1-1: Projects metadata “dces_resources”

Program source code

All of the DCES specific code that is needed to build the dces_resources example is shown in Listing 1-2, 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 resource

The following output should be printed inside your console window:

DCES
Hello DCES!

Recap and annotation

The anatomy of the dces_resource application

Let’s review the relevant parts of the dces_resource 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>, res: &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);
            }
        }

        println!("{}", res.get::<HelloDCES>().say_hello());
    }
}

The value of component key "name" will be processed as already documented. The new part is inside the handling of the Resource-Structure via the PrintSystem.

struct HelloDCES;

The code implements a the HelloDCES type which provides the say_hello() method.

impl HelloDCES {
    pub fn say_hello(&self) -> &str {
        return "Hello DCES!";
    }
}

With the resource get() method, we chain the call to its say_hello() method. It returns a String that is passed over to the println!() macro.

        println!("{}", res.get::<HelloDCES>().say_hello());

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

Complete example source

Find attached the complete source code for our dces_resource example.

use dces::prelude::*;

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

struct HelloDCES;

impl HelloDCES {
    pub fn say_hello(&self) -> &str {
        return "Hello DCES!";
    }
}

struct PrintSystem;

impl System<EntityStore> for PrintSystem {
    fn run(&self, ecm: &mut EntityComponentManager<EntityStore>, res: &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);
            }
        }

        println!("{}", res.get::<HelloDCES>().say_hello());
    }
}

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.resources_mut().insert(HelloDCES);

    world.create_system(PrintSystem).build();

    world.run();
}

Listing 1-2: dces_resource - Create a World, its entities, resources and a print systems.

Compiling and Running Are Separate Steps

The compiled dces_resource with cargo will be placed the resulting binary in the target subfolder of the project.

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

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

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