Skip to content

Commit

Permalink
Merge pull request amethyst#2381 from jojolepro/legion_v2
Browse files Browse the repository at this point in the history
Fix warnings in amethyst_core and fix amethyst_tiles
  • Loading branch information
AnneKitsune authored Jul 20, 2020
2 parents 6bab681 + 8ae2c13 commit 9ad190f
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 111 deletions.
64 changes: 59 additions & 5 deletions amethyst_core/src/dispatcher.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{ecs::prelude::*, ArcThreadPool};
use std::collections::BTreeMap;

/// A SystemBundle is a structure that can add multiple systems at once to a dispatcher.
pub trait SystemBundle {
/// Build this SystemBundle.
fn build(
self,
world: &mut World,
Expand Down Expand Up @@ -29,6 +31,7 @@ impl SystemBundle
}
}

/// A bundle inserted going to be consumed by a dispatcher builder.
pub struct DispatcherSystemBundle<B>(B);
impl<B: SystemBundle> ConsumeDesc for DispatcherSystemBundle<B> {
fn consume(
Expand All @@ -43,6 +46,7 @@ impl<B: SystemBundle> ConsumeDesc for DispatcherSystemBundle<B> {
}
}

/// A system inserted in a dispatcher builder.
pub struct DispatcherSystem<F>(RelativeStage, F);
impl<F> ConsumeDesc for DispatcherSystem<F>
where
Expand All @@ -67,6 +71,7 @@ where
}
}

/// A thread local system in a dispatcher builder.
pub struct DispatcherThreadLocalSystem<F>(F);
impl<F> ConsumeDesc for DispatcherThreadLocalSystem<F>
where
Expand All @@ -87,6 +92,7 @@ where
}
}

/// A thread local in a dispatcher builder.
pub struct DispatcherThreadLocal<F>(F);
impl<F> ConsumeDesc for DispatcherThreadLocal<F>
where
Expand All @@ -103,7 +109,10 @@ where
Ok(())
}
}

/// Something that can be consumed by the DispatcherBuilder.
pub trait ConsumeDesc {
/// Consume this resource.
fn consume(
self: Box<Self>,
world: &mut World,
Expand All @@ -113,8 +122,11 @@ pub trait ConsumeDesc {
) -> Result<(), amethyst_error::Error>;
}

/// Something that runs on a local (main) thread.
pub trait ThreadLocal {
/// Run the thread local resource.
fn run(&mut self, world: &mut World, resources: &mut Resources);
/// Get rid of the thread local resource.
fn dispose(self: Box<Self>, world: &mut World, resources: &mut Resources);
}

Expand All @@ -136,13 +148,15 @@ impl Into<Box<dyn ThreadLocal>> for Box<dyn Runnable> {
}
}

/// An object to be built as a thread local.
pub struct ThreadLocalObject<S, F, D>(pub S, pub F, pub D);
impl<S, F, D> ThreadLocalObject<S, F, D>
where
S: 'static,
F: FnMut(&mut S, &mut World, &mut Resources) + 'static,
D: FnOnce(S, &mut World, &mut Resources) + 'static,
{
/// Build the thread local object.
pub fn build(initial_state: S, run_fn: F, dispose_fn: D) -> Box<dyn ThreadLocal> {
Box::new(Self(initial_state, run_fn, dispose_fn))
}
Expand All @@ -161,17 +175,25 @@ where
}
}

/// Converts the type into a relative stage.
pub trait IntoRelativeStage: Copy {
// TODO: Why not just use Into<RelativeStage> ?
/// Convert this type into a relative stage.
fn into_relative(self) -> RelativeStage;
}

/// The default relative execution stages provided by amethyst.
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash, serde::Serialize, serde::Deserialize,
)]
pub enum Stage {
/// Execute at the start of the frame.
Begin,
/// Execute at the time to execute the game logic.
Logic,
/// Execute at the time of rendering.
Render,
/// Execute at the end of the frame, on the main thread.
ThreadLocal,
}
impl IntoRelativeStage for Stage {
Expand All @@ -180,13 +202,22 @@ impl IntoRelativeStage for Stage {
}
}

/// A relative execution stage.
/// Used for system execution ordering.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
pub struct RelativeStage(pub Stage, pub isize);
pub struct RelativeStage(
/// The internal execution stage.
pub Stage,
/// The stage offset.
pub isize,
);
impl RelativeStage {
/// Get the stage.
pub fn stage(&self) -> Stage {
self.0
}

/// Get the stage offset
pub fn offset(&self) -> isize {
self.1
}
Expand Down Expand Up @@ -214,21 +245,27 @@ impl Ord for RelativeStage {
}
}

/// A System execution dispatcher.
pub struct Dispatcher {
executor: Executor,
/// The defragmentation budget.
pub defrag_budget: Option<usize>,
pub(crate) thread_locals: Vec<Box<dyn ThreadLocal>>,
}
impl Dispatcher {
/// Execute the systems.
pub fn dispatch(&mut self, world: &mut World, resources: &mut Resources) {
self.executor.execute(world, resources);

self.thread_locals
.iter_mut()
.for_each(|local| local.run(world, resources));

// TODO: should we be using this?
//world.defrag(self.defrag_budget);
}

/// Clean and destroy the systems.
pub fn dispose(mut self, world: &mut World, resources: &mut Resources) {
self.thread_locals
.drain(..)
Expand All @@ -241,14 +278,17 @@ impl Dispatcher {
}
}

/// Data used by the Dispatcher.
#[derive(Default)]
pub struct DispatcherData {
/// The defragmentation budget.
pub defrag_budget: Option<usize>,
pub(crate) thread_locals: Vec<Box<dyn ThreadLocal>>,
pub(crate) stages: BTreeMap<RelativeStage, Vec<Box<dyn Schedulable>>>,
}
impl DispatcherData {
pub fn flatten(mut self) -> Dispatcher {
/// Flatten the DispatcherData into a Dispatcher.
pub fn flatten(self) -> Dispatcher {
let mut sorted_systems = Vec::with_capacity(128);
self.stages
.into_iter()
Expand All @@ -270,10 +310,11 @@ impl DispatcherData {
}
}

/// Merge two DispatcherData together.
pub fn merge(mut self, mut other: DispatcherData) -> Self {
self.thread_locals.extend(other.thread_locals.drain(..));

for (k, mut v) in other.stages.iter_mut() {
for (k, v) in other.stages.iter_mut() {
self.stages
.entry(*k)
.or_insert_with(Vec::default)
Expand All @@ -284,6 +325,7 @@ impl DispatcherData {
}
}

/// A Dispatcher builder structure.
pub struct DispatcherBuilder<'a> {
pub(crate) defrag_budget: Option<usize>,
pub(crate) systems: Vec<(RelativeStage, Box<dyn ConsumeDesc + 'a>)>,
Expand All @@ -304,14 +346,16 @@ impl<'a> Default for DispatcherBuilder<'a> {
}
}
impl<'a> DispatcherBuilder<'a> {
/// Add a thread local resource.
pub fn add_thread_local<T: FnOnce(&mut World, &mut Resources) -> Box<dyn ThreadLocal> + 'a>(
&mut self,
desc: T,
) {
self.thread_locals
.push((Box::new(DispatcherThreadLocal(desc)) as Box<dyn ConsumeDesc>));
.push(Box::new(DispatcherThreadLocal(desc)) as Box<dyn ConsumeDesc>);
}

/// Add a thread local resource.
pub fn with_thread_local<T: FnOnce(&mut World, &mut Resources) -> Box<dyn ThreadLocal> + 'a>(
mut self,
desc: T,
Expand All @@ -321,16 +365,18 @@ impl<'a> DispatcherBuilder<'a> {
self
}

/// Add a thread local System.
pub fn add_thread_local_system<
T: FnOnce(&mut World, &mut Resources) -> Box<dyn Runnable> + 'a,
>(
&mut self,
desc: T,
) {
self.thread_locals
.push((Box::new(DispatcherThreadLocalSystem(desc)) as Box<dyn ConsumeDesc>));
.push(Box::new(DispatcherThreadLocalSystem(desc)) as Box<dyn ConsumeDesc>);
}

/// Add a thread local System.
pub fn with_thread_local_system<
T: FnOnce(&mut World, &mut Resources) -> Box<dyn Runnable> + 'a,
>(
Expand All @@ -342,6 +388,7 @@ impl<'a> DispatcherBuilder<'a> {
self
}

/// Add a System.
pub fn add_system<
S: IntoRelativeStage,
T: FnOnce(&mut World, &mut Resources) -> Box<dyn Schedulable> + 'a,
Expand All @@ -356,6 +403,7 @@ impl<'a> DispatcherBuilder<'a> {
));
}

/// Add a System.
pub fn with_system<
S: IntoRelativeStage,
T: FnOnce(&mut World, &mut Resources) -> Box<dyn Schedulable> + 'a,
Expand All @@ -369,29 +417,34 @@ impl<'a> DispatcherBuilder<'a> {
self
}

/// Add a bundle to the dispatcher.
pub fn add_bundle<T: SystemBundle + 'a>(&mut self, bundle: T) {
self.bundles
.push(Box::new(DispatcherSystemBundle(bundle)) as Box<dyn ConsumeDesc>);
}

/// Add a bundle to the dispatcher.
pub fn with_bundle<T: SystemBundle + 'a>(mut self, bundle: T) -> Self {
self.add_bundle(bundle);

self
}

/// Set the defragmentation budget.
pub fn with_defrag_budget(mut self, budget: Option<usize>) -> Self {
self.defrag_budget = budget;

self
}

/// Set the thread pool.
pub fn with_pool(mut self, pool: Option<ArcThreadPool>) -> Self {
self.thread_pool = pool;

self
}

/// Is any system inserted?
pub fn is_empty(&self) -> bool {
self.systems.is_empty() && self.bundles.is_empty()
}
Expand Down Expand Up @@ -440,6 +493,7 @@ impl<'a> DispatcherBuilder<'a> {
dispatcher_data
}

/// Build the dispatcher!
pub fn build(mut self, world: &mut World, resources: &mut Resources) -> Dispatcher {
self.build_data(world, resources).flatten()
}
Expand Down
7 changes: 0 additions & 7 deletions amethyst_core/src/hidden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ impl HiddenPropagate {
}
}

/// Is meant to be used only by HideHierarchySystem.
pub(crate) fn new_propagated() -> Self {
Self {
is_propagated: true,
}
}

/// Returns true if this component was propagated by [HideHierarchySystem](struct.HideHierarchySystem.html) automatically.
pub fn is_propagated(&self) -> bool {
self.is_propagated
Expand Down
17 changes: 6 additions & 11 deletions amethyst_core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
//! A collection of structures and functions useful across the entire amethyst project.
#![warn(
missing_debug_implementations,
missing_docs,
rust_2018_idioms,
rust_2018_compatibility
)]
#![warn(missing_docs, rust_2018_idioms, rust_2018_compatibility)]
#![warn(clippy::all)]
#![allow(clippy::new_without_default)]

#[cfg(all(target_os = "emscripten", not(no_threading)))]
compile_error!("the cfg flag \"no_threading\" is required when building for emscripten");

#[macro_use]
extern crate getset;
#[macro_use]
extern crate derive_new;

pub use alga;
pub use approx;
pub use legion as ecs;
Expand All @@ -34,10 +24,15 @@ pub use self::{
};

//pub mod deferred_dispatcher_operation;
/// The dispatcher module.
pub mod dispatcher;
/// The frame limiter module.
pub mod frame_limiter;
/// The geometry module.
pub mod geometry;
/// The timing module.
pub mod timing;
/// The transformation module.
pub mod transform;

mod axis;
Expand Down
1 change: 1 addition & 0 deletions amethyst_core/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use amethyst_error::Error;

pub use legion_transform::prelude::*;

/// Bundle to add the transformation systems.
#[derive(Debug, Default)]
pub struct TransformBundle;

Expand Down
1 change: 0 additions & 1 deletion amethyst_tiles/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ pub struct TileMap<T: Tile, E: CoordinateEncoder = crate::MortonEncoder2D> {
impl<T: Tile, E: CoordinateEncoder> Asset for TileMap<T, E> {
const NAME: &'static str = "tiles::map";
type Data = Self;
type HandleStorage = HashMapStorage<Handle<Self>>;
}
impl<T: Tile, E: CoordinateEncoder> Component for TileMap<T, E> {
type Storage = HashMapStorage<Self>;
Expand Down
Loading

0 comments on commit 9ad190f

Please sign in to comment.