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.
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
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"
[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.
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
.
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
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();
}
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.
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