World
What is a World
?
A World
is a container for resources, with some helper functions that make your life easier.
This chapter will showcase those functions and their usage.
Adding a resource
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
// A simple struct with no data.
struct MyResource;
fn main() {
// We create a new `World` instance.
let mut world = World::new();
// We create our resource.
let my = MyResource;
// We add the resource to the world.
world.insert(my);
}
Fetching a resource
Here's how to fetch a read-only resource. Be aware that this method panics if the resource isn't inserted into Resources
.
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
struct MyResource;
fn main() {
let mut world = World::new();
let my = world.read_resource::<MyResource>();
}
If you are not sure that the resource will be present, use the methods available on Resources
, as shown in the resource chapter.
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
struct MyResource;
fn main() {
let mut world = World::new();
let my = world.entry::<MyResource>().or_insert_with(|| MyResource);
}
Modifying a resource
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
struct MyResource;
fn main() {
let mut world = World::new();
let mut my = world.write_resource::<MyResource>();
}
Creating entities
You first start by creating the entity builder.
Then, you can add components to your entity.
Finally, you call the build() method on the entity builder to get the actual entity.
Please note that in order to use this syntax, you need to import the amethyst::prelude::Builder
trait.
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
struct MyComponent;
impl amethyst::ecs::Component for MyComponent {
type Storage = amethyst::ecs::VecStorage<MyComponent>;
}
fn main() {
let mut world = World::new();
world.register::<MyComponent>();
use amethyst::prelude::Builder;
let mut entity_builder = world.create_entity();
entity_builder = entity_builder.with(MyComponent);
let my_entity = entity_builder.build();
}
Shorter version:
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
struct MyComponent;
impl amethyst::ecs::Component for MyComponent {
type Storage = amethyst::ecs::VecStorage<MyComponent>;
}
fn main() {
let mut world = World::new();
use amethyst::prelude::Builder;
let my_entity = world
.create_entity()
.with(MyComponent)
.build();
}
Internally, the World
interacts with EntitiesRes
, which is a resource holding the entities inside of Resources
.
Accessing a Component
extern crate amethyst;
use amethyst::ecs::{Builder, World, WorldExt};
struct MyComponent;
impl amethyst::ecs::Component for MyComponent {
type Storage = amethyst::ecs::VecStorage<MyComponent>;
}
fn main() {
let mut world = World::new();
// Create an `Entity` with `MyComponent`.
// `World` will implicitly write to the component's storage in `Resources`.
let my_entity = world.create_entity().with(MyComponent).build();
// Get a ReadStorage<MyComponent>
let storage = world.read_storage::<MyComponent>();
// Get the actual component from the storage.
let my = storage.get(my_entity).expect("Failed to get component for entity");
}
Modifying a Component
This is almost the same as accessing a component:
extern crate amethyst;
use amethyst::ecs::{Builder, World, WorldExt};
struct MyComponent;
impl amethyst::ecs::Component for MyComponent {
type Storage = amethyst::ecs::VecStorage<MyComponent>;
}
fn main() {
let mut world = World::new();
let my_entity = world.create_entity().with(MyComponent).build();
let mut storage = world.write_storage::<MyComponent>();
let mut my = storage.get_mut(my_entity).expect("Failed to get component for entity");
}
Getting all entities
It is pretty rare to use this, but can be useful in some occasions.
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
fn main() {
let mut world = World::new();
// Returns `EntitiesRes`
let entities = world.entities();
}
Delete an entity
Single:
extern crate amethyst;
use amethyst::ecs::{Builder, World, WorldExt};
fn main() {
let mut world = World::new();
let my_entity = world.create_entity().build();
world.delete_entity(my_entity).expect("Failed to delete entity. Was it already removed?");
}
Multiple:
extern crate amethyst;
use amethyst::ecs::{Builder, World, WorldExt};
fn main() {
let mut world = World::new();
let entity_vec: Vec<amethyst::ecs::Entity> = vec![world.create_entity().build()];
world.delete_entities(entity_vec.as_slice()).expect("Failed to delete entities from specified list.");
}
All:
extern crate amethyst;
use amethyst::ecs::{World, WorldExt};
fn main() {
let mut world = World::new();
world.delete_all();
}
Note: Entities are lazily deleted, which means that deletion only happens at the end of the frame and not immediately when calling the delete
method.
Check if the entity was deleted
extern crate amethyst;
use amethyst::ecs::{Builder, World, WorldExt};
fn main() {
let mut world = World::new();
let my_entity = world.create_entity().build();
// Returns true if the entity was **not** deleted.
let is_alive = world.is_alive(my_entity);
}
Exec
This is just to show that this feature exists. It is normal to not understand what it does until you read the system chapter
Sometimes, you will want to create an entity where you need to fetch resources to create the correct components for it. There is a function that acts as a shorthand for this:
extern crate amethyst;
use amethyst::ecs::{ReadExpect, World, WorldExt};
struct Dummy;
type SomeSystemData<'a> = ReadExpect<'a, Dummy>;
trait DoSomething {
fn do_something(&mut self);
}
impl<'a> DoSomething for SomeSystemData<'a> {
fn do_something(&mut self) { }
}
fn main() {
let mut world = World::new();
world.exec(|mut data: SomeSystemData| {
data.do_something();
});
}
We will talk about what SystemData
is in the system chapter.