Module dotrix::systems [−][src]
Systems implement logic of your game. A system take a set of crate::services
as
parameters and implements a feature. For example, here is a system that moves camera by X
axis if Right mouse button is pressed:
use dotrix_core::{ Dotrix, input::{ ActionMapper, Button, State as InputState, Mapper }, ecs::{ Const, Mut, System }, services::{ Camera, Frame, Input }, }; // camera moving system pub fn camera_move_x(mut camera: Mut<Camera>, input: Const<Input>, frame: Const<Frame>) { let time_delta = frame.delta().as_secs_f32(); if input.button_state(Button::MouseRight) == Some(InputState::Hold) { camera.target.x += 1.0 * time_delta; } } fn main() { Dotrix::application("My Game") // add system to yout application .with_system(System::from(camera_move_x)) // services should also be there .with_service(Camera::default()) .with_service(Frame::default()) .with_service(Input::new(Box::new(Mapper::<Action>::new()))) .run(); } // Mapping is required for the Input service #[derive(PartialEq, Eq, Clone, Copy, Hash)] enum Action {} impl ActionMapper<Action> for Input { fn action_mapped(&self, action: Action) -> Option<&Button> { let mapper = self.mapper::<Mapper<Action>>(); mapper.get_button(action) } }
crate::ecs::Mut
and crate::ecs::Const
are just the accessors for services to keep
Rust mutability controls. The set of services that system takes as arguments is up to
developer. It can be effortlessly extended at any time. The order of crate::services
in
arguments list does not matter.
What is also important to mention here, is that all services used in systems must be added to your game using the application builder.
Systems with context
Sometimes it is usefull to preserve some data between system executions. It can be done using
a crate::Service
, but it has sense only when the data has to be shared between different
systems. Otherwise it is better to use the crate::ecs::Context
.
System can have only one context and if it does, the context must be always passed as a first
argument. Another requirement is that crate::ecs::Context
structure must implement the
Default
trait.
Example
use dotrix_core::{ ecs::Context, }; #[derive(Default)] struct Counter { value: usize, } fn count_up(mut counter: Context<Counter>) { counter.value += 1; println!("The `counter_up` system has been called {} times", counter.value); }
System run levels
Developer can affect the execution of systems by assigning them specific run levels.
If crate::ecs::RunLevel
is not set explicitly, the RunLevel::Standard
will be used.
use dotrix_core::{ Dotrix, services::Assets, ecs::{ Mut, System, RunLevel }, }; fn init_game(mut assets: Mut<Assets>) { println!("Starting my super game"); assets.import("/path/to/my/asset.png"); } fn main() { Dotrix::application("My Game") .with_system(System::from(init_game).with(RunLevel::Startup)) .with_service(Assets::new()) .run(); }
Functions
camera_control | System controlling camera with mouse |
overlay_update | System feeding overlays with inputs |
skeletal_animation | System handling skeletal animation |
world_renderer | System to render models, skyboxes, wire frames and overlays |