Skip to content

Commit

Permalink
Merge branch 'master' of github.com:amethyst/amethyst into tiles
Browse files Browse the repository at this point in the history
  • Loading branch information
jaynus committed Sep 18, 2019
2 parents 35cbc70 + 3b45951 commit 7564233
Show file tree
Hide file tree
Showing 15 changed files with 832 additions and 176 deletions.
5 changes: 3 additions & 2 deletions amethyst_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ log = "0.4.6"
num-traits = "0.2.0"
rayon = "1.1.0"
serde = { version = "1", features = ["derive"] }
specs = { version = "0.15", features = ["shred-derive"] }
specs-hierarchy = "0.5.1"
specs = { version = "0.15", default-features = false, features = ["shred-derive"] }
specs-hierarchy = { version = "0.5.1", default-features = false }
getset = "0.0.7"
derive-new = "0.5.6"
derivative = "1.0"
Expand All @@ -38,6 +38,7 @@ amethyst = { path = "..", version = "0.12.0" }
ron = "0.5.1"

[features]
default = ["specs/parallel", "specs-hierarchy/parallel"]
profiler = ["thread_profiler/thread_profiler"]
nightly = ["specs/nightly"]
saveload = ["specs/serde"]
22 changes: 0 additions & 22 deletions amethyst_rendy/src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,28 +518,6 @@ impl Projection {
}
}

/// Returns the near-clip value of the current camera.
pub fn near(&self) -> f32 {
match *self {
Projection::Orthographic(ref s) => s.near(),
Projection::Perspective(ref s) => s.near(),
Projection::CustomMatrix(ref s) => {
panic!("Custom Matrix does not support near and far field projection!")
}
}
}

/// Returns the far-clip value of the current camera.
pub fn far(&self) -> f32 {
match *self {
Projection::Orthographic(ref s) => s.far(),
Projection::Perspective(ref s) => s.far(),
Projection::CustomMatrix(ref s) => {
panic!("Custom Matrix does not support near and far field projection!")
}
}
}

/// Returns a `Ray` going out form the camera through provided screen position. The ray origin lies on camera near plane.
pub fn screen_ray(
&self,
Expand Down
4 changes: 4 additions & 0 deletions amethyst_test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ license = "MIT/Apache-2.0"
amethyst = { path = "..", version = "0.12.0" }
derivative = "1.0"
derive-new = "0.5"
derive_deref = "1.1.0"
lazy_static = "1.3"

[dev-dependencies]
serde = "1.0"

[features]
default = []
nightly = ["amethyst/nightly"]
Expand Down
29 changes: 29 additions & 0 deletions amethyst_test/src/in_memory_source.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::collections::HashMap;

use amethyst::{assets::Source, error::format_err, Error};

use derive_deref::{Deref, DerefMut};
use derive_new::new;

/// Identifies the in-memory asset source.
pub const IN_MEMORY_SOURCE_ID: &str = "in_memory_asset_source";

/// In-memory implementation of an asset `Source`, purely for tests.
#[derive(Debug, Deref, DerefMut, new)]
pub struct InMemorySource(#[new(default)] pub HashMap<String, Vec<u8>>);

impl Source for InMemorySource {
fn modified(&self, _path: &str) -> Result<u64, Error> {
Ok(0)
}

fn load(&self, path: &str) -> Result<Vec<u8>, Error> {
let path = path.to_string();
self.0.get(&path).cloned().ok_or_else(|| {
format_err!(
"The `{}` asset is not registered in the `InMemorySource` asset source",
path
)
})
}
}
4 changes: 4 additions & 0 deletions amethyst_test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,12 @@ pub use crate::{
effect_return::EffectReturn,
fixture::{MaterialAnimationFixture, SpriteRenderAnimationFixture},
game_update::GameUpdate,
in_memory_source::{InMemorySource, IN_MEMORY_SOURCE_ID},
state::{
CustomDispatcherState, CustomDispatcherStateBuilder, FunctionState, PopState,
SequencerState,
},
wait_for_load::WaitForLoad,
};
pub(crate) use crate::{
system_desc_injection_bundle::SystemDescInjectionBundle,
Expand All @@ -343,8 +345,10 @@ mod amethyst_application;
mod effect_return;
mod fixture;
mod game_update;
mod in_memory_source;
pub mod prelude;
mod state;
mod system_desc_injection_bundle;
mod system_injection_bundle;
mod thread_local_injection_bundle;
mod wait_for_load;
99 changes: 99 additions & 0 deletions amethyst_test/src/wait_for_load.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use amethyst::{assets::ProgressCounter, ecs::WorldExt, State, StateData, Trans};
use derive_new::new;

use crate::GameUpdate;

/// Reads a `ProgressCounter` resource and waits for it to be `complete()`.
#[derive(Debug, new)]
pub struct WaitForLoad;

impl<T, E> State<T, E> for WaitForLoad
where
T: GameUpdate,
E: Send + Sync + 'static,
{
fn update(&mut self, data: StateData<'_, T>) -> Trans<T, E> {
data.data.update(&data.world);

let progress_counter = data.world.read_resource::<ProgressCounter>();
if !progress_counter.is_complete() {
Trans::None
} else {
Trans::Pop
}
}
}

#[cfg(test)]
mod tests {
use amethyst::{
assets::{
Asset, AssetStorage, Handle, Loader, ProcessingState, Processor, ProgressCounter,
RonFormat,
},
ecs::{storage::VecStorage, WorldExt},
Error,
};
use serde::{Deserialize, Serialize};

use super::WaitForLoad;
use crate::{AmethystApplication, InMemorySource, IN_MEMORY_SOURCE_ID};

#[test]
fn pops_when_progress_counter_is_complete() -> Result<(), Error> {
AmethystApplication::blank()
.with_system(Processor::<TestAsset>::new(), "test_asset_processor", &[])
.with_effect(|world| {
let mut in_memory_source = InMemorySource::new();
in_memory_source.insert(String::from("file.ron"), b"(val: 123)".to_vec());

let mut loader = world.write_resource::<Loader>();
loader.add_source(IN_MEMORY_SOURCE_ID, in_memory_source);
})
.with_effect(|world| {
let mut progress_counter = ProgressCounter::new();
let test_asset_handle = {
let loader = world.read_resource::<Loader>();
loader.load_from(
"file.ron",
RonFormat,
IN_MEMORY_SOURCE_ID,
&mut progress_counter,
&world.read_resource::<AssetStorage<TestAsset>>(),
)
};

world.insert(test_asset_handle);
world.insert(progress_counter);
})
.with_state(WaitForLoad::new)
.with_assertion(|world| {
let test_asset_handle = world.read_resource::<Handle<TestAsset>>();
let test_assets = world.read_resource::<AssetStorage<TestAsset>>();
let test_asset = test_assets
.get(&test_asset_handle)
.expect("Expected `TestAsset` to be loaded.");

assert_eq!(&TestAsset { val: 123 }, test_asset);
})
.run()
}

#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct TestAsset {
val: u32,
}

impl Asset for TestAsset {
type Data = Self;
type HandleStorage = VecStorage<Handle<Self>>;

const NAME: &'static str = concat!(module_path!(), "::", stringify!(TestAsset));
}

impl From<TestAsset> for Result<ProcessingState<TestAsset>, Error> {
fn from(asset_data: TestAsset) -> Result<ProcessingState<TestAsset>, Error> {
Ok(ProcessingState::Loaded(asset_data))
}
}
}
5 changes: 4 additions & 1 deletion book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* [Resource](./concepts/resource.md)
* [World](./concepts/world.md)
* [System](./concepts/system.md)
* [System Initialization](./concepts/system/system_initialization.md)
* [SystemDesc Derive](./concepts/system/system_desc_derive.md)
* [Implementing the SystemDesc Trait](./concepts/system/implementing_the_system_desc_trait.md)
* [Dispatcher](./concepts/dispatcher.md)
* [Event Channel](./concepts/event-channel.md)
* [Pong Tutorial](pong-tutorial.md)
Expand Down Expand Up @@ -48,7 +51,6 @@
* [Sprites](./sprites.md)
* [Set Up The Render Pass](./sprites/set_up_the_render_pass.md)
* [Load The `Texture`](./sprites/load_the_texture.md)
* [Display The `Texture`](./sprites/display_the_texture.md)
* [Define The `SpriteSheet`](./sprites/define_the_sprite_sheet.md)
* [`SpriteRender` Component](./sprites/sprite_render_component.md)
* [Modify The `Texture`](./sprites/modify_the_texture.md)
Expand All @@ -63,4 +65,5 @@
* [Appendix B: Migration Notes](./appendices/b_migration_notes.md)
* [`cgmath` to `nalgebra`](./appendices/b_migration_notes/cgmath_to_nalgebra.md)
* [Rendy Migration](./appendices/b_migration_notes/rendy_migration.md)
* [Specs Migration](./appendices/b_migration_notes/specs_migration.md)
* [Appendix C: Feature Gates](./appendices/c_feature_gates.md)
3 changes: 2 additions & 1 deletion book/src/appendices/b_migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ At times Amethyst goes through non-trivial changes which may impose additional e
* [0.9 to 0.10](b_migration_notes/cgmath_to_nalgebra.html): `cgmath` to `nalgebra` migration
* [0.10 to 0.12](b_migration_notes/rendy_migration.html): Rendy migration guide
* [0.10 to 0.11](b_migration_notes/transform_api_changes.html): Transform API Changes
* [0.11 to 0.12] Float type removed. Search and replace with 'f32'
* [0.11 to 0.12] Float type removed. Search and replace with 'f32'
* [0.12 to 0.13](b_migration_notes/specs_migration.html): `specs` upgraded to `0.15`.
42 changes: 42 additions & 0 deletions book/src/appendices/b_migration_notes/specs_migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Specs Migration

* Specs migration

Quick fix:

- Add `use amethyst::ecs::WorldExt` to imports.
- Replace `world.add_resource` with `world.insert`.
- Regex replace `\bResources\b` with `World`. Check for false replacements.
- Replace `world.res` with `world`.
- Regex replace `\bres\b` with `world`.

`shred-derive` is re-exported by `amethyst`. Migration steps:

- Remove `shred-derive` from `Cargo.toml`.
- Remove `use amethyst::ecs::SystemData` from imports (if present).
- Add `use amethyst::shred::{ResourceId, SystemData}` to imports.

* `PrefabLoaderSystem` is initialized by `PrefabLoaderSystemDesc`.

**Quick fix:**

- Find: `PrefabLoaderSystem::<([A-Za-z]+)>::default\(\)`,
- Replace: `PrefabLoaderSystemDesc::<\1>::default()`

* `GltfSceneLoaderSystem` is initialized by `GltfSceneLoaderSystemDesc`.

**Quick fix:**

- Find: `GltfSceneLoaderSystem::<([A-Za-z]+)>::default\(\)`,
- Replace: `GltfSceneLoaderSystemDesc::<\1>::default()`

* `AmethystApplication::with_setup` runs the function before the dispatcher.

**Quick fix:**

- Find: `with_setup`,
- Replace: `with_effect`

* Renamed `UiTransformBuilder` to `UiTransformData`.
* Renamed `UiTextBuilder` to `UiTextData`.
* Renamed `UiButtonBuilder` to `UiButtonData`.
83 changes: 0 additions & 83 deletions book/src/concepts/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,89 +28,6 @@ impl<'a> System<'a> for MyFirstSystem {

This system will, on every iteration of the game loop, print "Hello!" in the console. This is a pretty boring system as it does not interact at all with the game. Let us spice it up a bit.

### System Initialization -- The `SystemDesc` Trait

Systems may need to access resources from the `World` in order to be
instantiated. For example, obtaining a `ReaderId` to an `EventChannel` that
exists in the `World`. When there is an existing event channel in the `World`, a
`System` should register itself as a reader of that channel instead of replacing
it, as that invalidates all other readers.

In Amethyst, the `World` that the application begins with is populated with a
number of default resources -- event channels, a thread pool, a frame limiter,
and so on.

Given the default resources begin with special limits, we need a way to pass the
`System` initialization logic through to the application, including parameters to
the `System`'s constructor. This is information the `SystemDesc` trait captures.

For each `System`, an implementation of the `SystemDesc` trait specifies the
logic to instantiate the `System`. For `System`s that do not require special
initialization logic, the `SystemDesc` derive automatically implements the
`SystemDesc` trait on the system type itself:

```rust,edition2018,no_run,noplaypen
# extern crate amethyst;
use amethyst::{
core::SystemDesc,
derive::SystemDesc,
ecs::{System, SystemData, World},
};
#[derive(SystemDesc)]
struct MyFirstSystem;
impl<'a> System<'a> for MyFirstSystem {
type SystemData = ();
fn run(&mut self, data: Self::SystemData) {
println!("Hello!");
}
}
```

If there is one-time logic necessary to modify the `World` as part of system
initialization, the `SystemDesc` trait can be implemented manually:

```rust,edition2018,no_run,noplaypen
# extern crate amethyst;
#
use amethyst::{
audio::output::Output,
core::SystemDesc,
ecs::{System, SystemData, World},
};
# /// Syncs 3D transform data with the audio engine to provide 3D audio.
# #[derive(Debug, Default)]
# pub struct AudioSystem(Output);
# impl<'a> System<'a> for AudioSystem {
# type SystemData = ();
# fn run(&mut self, _: Self::SystemData) {}
# }
#
/// Builds an `AudioSystem`.
#[derive(Default, Debug)]
pub struct AudioSystemDesc {
/// Audio `Output`.
pub output: Output,
}
impl<'a, 'b> SystemDesc<'a, 'b, AudioSystem> for AudioSystemDesc {
fn build(self, world: &mut World) -> AudioSystem {
<AudioSystem as System<'_>>::SystemData::setup(world);
world.insert(self.output.clone());
AudioSystem(self.output)
}
}
// in `main.rs`:
// let game_data = GameDataBuilder::default()
// .with_system_desc(AudioSystemDesc::default(), "", &[]);
```

## Accessing the context of the game

In the definition of a system, the trait requires you to define a type `SystemData`. This type defines what data the system will be provided with on each call of its `run` method. `SystemData` is only meant to carry information accessible to multiple systems. Data local to a system is usually stored in the system's struct itself instead.
Expand Down
Loading

0 comments on commit 7564233

Please sign in to comment.