parent
d4fc3000f1
commit
e99153a53d
10 changed files with 119 additions and 82 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1837,6 +1837,7 @@ dependencies = [
|
|||
"lyra-scene",
|
||||
"petgraph",
|
||||
"quote",
|
||||
"rand",
|
||||
"round_mult",
|
||||
"rustc-hash 2.0.0",
|
||||
"syn 2.0.77",
|
||||
|
|
|
@ -204,11 +204,11 @@ impl FnArgFetcher for Commands<'_, '_> {
|
|||
CommandQueue::default()
|
||||
}
|
||||
|
||||
fn apply_deferred<'a>(mut state: Self::State, mut world_ptr: NonNull<World>) {
|
||||
fn apply_deferred<'a, 'state>(state: &'state mut Self::State, mut world_ptr: NonNull<World>) {
|
||||
let world = unsafe { world_ptr.as_mut() };
|
||||
|
||||
let mut cmds = Commands::new(&mut state, world);
|
||||
// safety: Commands has a mut borrow only to entities in the world
|
||||
let mut cmds = Commands::new(state, world);
|
||||
// SAFETY: Commands has a mut borrow only to entities in the world
|
||||
let world = unsafe { world_ptr.as_mut() };
|
||||
cmds.execute(world);
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ impl<Q: Query> FnArgFetcher for ViewOneState<'_, Q> {
|
|||
ViewOneState::<Q>::new(world, Q::new())
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: NonNull<World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: NonNull<World>) { }
|
||||
|
||||
fn create_state(_: NonNull<World>) -> Self::State { () }
|
||||
}
|
|
@ -96,7 +96,7 @@ impl FnArgFetcher for WorldTick {
|
|||
WorldTick(world.current_tick())
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: std::ptr::NonNull<World>) {
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: std::ptr::NonNull<World>) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ pub trait FnArgFetcher {
|
|||
unsafe fn get<'a, 'state>(state: &'state mut Self::State, world: NonNull<World>) -> Self::Arg<'a, 'state>;
|
||||
|
||||
/// Apply some action after the system was ran.
|
||||
fn apply_deferred(state: Self::State, world: NonNull<World>);
|
||||
fn apply_deferred<'state>(state: &'state mut Self::State, world: NonNull<World>);
|
||||
}
|
||||
|
||||
/// A system that is implemented as a function.
|
||||
|
@ -64,22 +64,32 @@ macro_rules! impl_fn_system_tuple {
|
|||
fn execute(&mut self, world: NonNull<World>) -> anyhow::Result<()> {
|
||||
unsafe {
|
||||
paste! {
|
||||
// initialize state if it hasn't been
|
||||
if self.arg_state.is_none() {
|
||||
self.arg_state = Some(vec![
|
||||
$(
|
||||
Box::new($name::create_state(world))
|
||||
),+
|
||||
]);
|
||||
}
|
||||
|
||||
// safe unwrap since state was just initialized
|
||||
let mut state_iter = self.arg_state.as_mut().unwrap().iter_mut();
|
||||
|
||||
$(
|
||||
// get the arg fetcher, create its state, and get the arg
|
||||
let mut [<state_ $name:lower>]: $name::State = $name::create_state(world);
|
||||
let mut [<state_ $name:lower>]: &mut $name::State = state_iter.next()
|
||||
// Safe since state vec is initialized to expected size
|
||||
//.unwrap()
|
||||
.expect("state was not initialized to correct size")
|
||||
.downcast_mut()
|
||||
// Safe due to the ordering of the arguments ensuring the correct
|
||||
// types.
|
||||
.unwrap_or_else(|| panic!("Failed to downcast state '{}' from 'Box<dyn Any>'",
|
||||
std::any::type_name::<$name::State>()));
|
||||
let [<$name:lower>] = $name::get(&mut [<state_ $name:lower>], world);
|
||||
)+
|
||||
|
||||
(self.inner)($( [<$name:lower>] ),+)?;
|
||||
|
||||
let mut state = Vec::new();
|
||||
$(
|
||||
// type erase the now modified state, and store it
|
||||
let boxed = Box::new([<state_ $name:lower>]) as Box<dyn Any>;
|
||||
state.push(boxed);
|
||||
)+
|
||||
|
||||
self.arg_state = Some(state);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -87,14 +97,16 @@ macro_rules! impl_fn_system_tuple {
|
|||
}
|
||||
|
||||
fn execute_deferred(&mut self, world: NonNull<World>) -> anyhow::Result<()> {
|
||||
let state = self.arg_state.as_mut().expect("Somehow there was no state");
|
||||
state.reverse();
|
||||
let mut state = self.arg_state.as_mut()
|
||||
.expect("State was never initialized")
|
||||
.iter_mut();
|
||||
|
||||
$(
|
||||
let arg_state_box = state.pop()
|
||||
.expect("Missing expected arg state");
|
||||
let arg_state = *arg_state_box.downcast::<$name::State>()
|
||||
.expect("Somehow the state cannot be downcasted from boxed Any");
|
||||
let arg_state_box = state.next()
|
||||
.expect("Invalid number of state was initialized");
|
||||
let arg_state = arg_state_box.downcast_mut::<$name::State>()
|
||||
.unwrap_or_else(|| panic!("Failed to downcast state '{}' from 'Box<dyn Any>'",
|
||||
std::any::type_name::<$name::State>()));
|
||||
$name::apply_deferred(arg_state, world);
|
||||
)+
|
||||
|
||||
|
@ -160,7 +172,7 @@ where
|
|||
v
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: NonNull<World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: NonNull<World>) { }
|
||||
|
||||
fn create_state(_: NonNull<World>) -> Self::State {
|
||||
(Q::new(), F::new())
|
||||
|
@ -179,7 +191,7 @@ impl FnArgFetcher for &'_ World {
|
|||
&*world.as_ptr()
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: NonNull<World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: NonNull<World>) { }
|
||||
|
||||
fn create_state(_: NonNull<World>) -> Self::State { () }
|
||||
}
|
||||
|
@ -196,7 +208,7 @@ impl FnArgFetcher for &'_ mut World {
|
|||
&mut *world.as_ptr()
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: NonNull<World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: NonNull<World>) { }
|
||||
|
||||
fn create_state(_: NonNull<World>) -> Self::State { () }
|
||||
}
|
||||
|
@ -220,7 +232,7 @@ impl<R: ResourceObject> FnArgFetcher for Res<'_, R> {
|
|||
.unwrap_or_else(|| panic!("world is missing resource: {}", std::any::type_name::<R>()))
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: NonNull<World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: NonNull<World>) { }
|
||||
|
||||
fn create_state(_: NonNull<World>) -> Self::State { () }
|
||||
}
|
||||
|
@ -236,7 +248,7 @@ impl<R: ResourceObject> FnArgFetcher for ResMut<'_, R> {
|
|||
.unwrap_or_else(|| panic!("world is missing resource: {}", std::any::type_name::<R>()))
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: NonNull<World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: NonNull<World>) { }
|
||||
|
||||
fn create_state(_: NonNull<World>) -> Self::State { () }
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ bind_match = "0.1.2"
|
|||
round_mult = "0.1.3"
|
||||
fast_poisson = { version = "1.0.0", features = ["single_precision"] }
|
||||
atomic_refcell = "0.1.13"
|
||||
rand = "0.8.5"
|
||||
|
||||
[features]
|
||||
tracy = ["dep:tracing-tracy"]
|
||||
tracy = ["dep:tracing-tracy"]
|
||||
|
|
|
@ -77,12 +77,17 @@ pub struct Events<T: Event> {
|
|||
last_cleared_at: Tick,
|
||||
/// Used to indicate when the cursor in readers should be reset to zero.
|
||||
/// This becomes true after the old events are cleared.
|
||||
reset_cursor: bool,
|
||||
//reset_cursor: bool,
|
||||
/// This is set to the amount of elements that were deleted.
|
||||
///
|
||||
/// Its used to decrease the cursor by the amount of elements deleted, instead of resetting
|
||||
/// to zero to avoid rereading events that are in other levels of the vec.
|
||||
decrease_cursor_by: Option<usize>,
|
||||
}
|
||||
|
||||
impl<T: Event> Default for Events<T> {
|
||||
fn default() -> Self {
|
||||
Self { events: Default::default(), last_cleared_at: Default::default(), reset_cursor: false }
|
||||
Self { events: Default::default(), last_cleared_at: Default::default(), decrease_cursor_by: None }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,37 +101,36 @@ impl<T: Event> Events<T> {
|
|||
events.push(event);
|
||||
}
|
||||
|
||||
pub fn reader(&self) -> EventReader<T> {
|
||||
/* pub fn reader(&self) -> EventReader<T> {
|
||||
EventReader {
|
||||
events: self.events.clone(),
|
||||
cursor: Arc::new(AtomicRefCell::new(0)),
|
||||
//cursor: Arc::new(AtomicRefCell::new(0)),
|
||||
cursor: Arc::new(AtomicUsize::new(0)),
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
pub fn writer(&self) -> EventWriter<T> {
|
||||
/* pub fn writer(&self) -> EventWriter<T> {
|
||||
EventWriter {
|
||||
events: self.events.clone(),
|
||||
}
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
pub struct EventReader<T: Event> {
|
||||
pub struct EventReader<'state, T: Event> {
|
||||
events: Arc<AtomicRefCell<WaterfallVec<T>>>,
|
||||
cursor: Arc<AtomicRefCell<usize>>,
|
||||
cursor: &'state mut usize,
|
||||
}
|
||||
|
||||
impl<T: Event> EventReader<T> {
|
||||
pub fn read(&self) -> Option<atomic_refcell::AtomicRef<T>> {
|
||||
impl<'state, T: Event> EventReader<'state, T> {
|
||||
pub fn read(&mut self) -> Option<T> {
|
||||
let events = self.events.borrow();
|
||||
|
||||
let mut cursor = self.cursor.borrow_mut();
|
||||
if *cursor >= events.total_len() {
|
||||
if *self.cursor >= events.total_len() {
|
||||
None
|
||||
} else {
|
||||
let e = atomic_refcell::AtomicRef::map(events,
|
||||
|e| e.get(*cursor).unwrap());
|
||||
*cursor += 1;
|
||||
Some(e)
|
||||
let e = events.get(*self.cursor).unwrap();
|
||||
*self.cursor += 1;
|
||||
Some(e.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,12 +156,19 @@ where
|
|||
|
||||
if last_tick + 2 < world_tick {
|
||||
events.last_cleared_at = *tick;
|
||||
events.reset_cursor = true;
|
||||
|
||||
let mut events = events.events.borrow_mut();
|
||||
events.clear_oldest();
|
||||
let mut events_fall = events.events.borrow_mut();
|
||||
|
||||
// Since oldest will be cleared, we need to decrease the cursor by the removed amount
|
||||
// store the amount it needs to decrease by.
|
||||
let old_len = events_fall.old.len();
|
||||
events_fall.clear_oldest();
|
||||
|
||||
drop(events_fall);
|
||||
|
||||
events.decrease_cursor_by = Some(old_len);
|
||||
} else {
|
||||
events.reset_cursor = false;
|
||||
events.decrease_cursor_by = None;
|
||||
}
|
||||
|
||||
let mut events = events.events.borrow_mut();
|
||||
|
@ -166,34 +177,36 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
impl<T: Event> FnArgFetcher for EventReader<T> {
|
||||
type State = Arc<AtomicRefCell<usize>>;
|
||||
impl<T: Event> FnArgFetcher for EventReader<'_, T> {
|
||||
type State = usize;
|
||||
|
||||
type Arg<'a, 'state> = EventReader<T>;
|
||||
type Arg<'b, 'state> = EventReader<'state, T>;
|
||||
|
||||
fn create_state(_: std::ptr::NonNull<lyra_ecs::World>) -> Self::State {
|
||||
Arc::new(AtomicRefCell::new(0))
|
||||
0
|
||||
}
|
||||
|
||||
unsafe fn get<'a, 'state>(state: &'state mut Self::State, world: std::ptr::NonNull<lyra_ecs::World>) -> Self::Arg<'a, 'state> {
|
||||
unsafe fn get<'b, 'state>(state: &'state mut Self::State, world: std::ptr::NonNull<lyra_ecs::World>) -> Self::Arg<'b, 'state> {
|
||||
let world = world.as_ref();
|
||||
let events = world.get_resource::<Events<T>>()
|
||||
.unwrap_or_else(|| panic!("world missing Events<{}> resource", std::any::type_name::<T>()));
|
||||
|
||||
if events.reset_cursor {
|
||||
let mut state_num = state.borrow_mut();
|
||||
*state_num = 0;
|
||||
if let Some(dec_by) = events.decrease_cursor_by {
|
||||
// The waterfall vec had its oldest events deleted.
|
||||
// The cursor needs to be decreased by the amount of elements deleted, instead of resetting
|
||||
// to zero to avoid rereading events that are in other levels of the vec.
|
||||
*state = state.checked_sub(dec_by).unwrap_or_default();
|
||||
}
|
||||
|
||||
|
||||
let reader = EventReader {
|
||||
events: events.events.clone(),
|
||||
cursor: state.clone(),
|
||||
cursor: state,
|
||||
};
|
||||
|
||||
reader
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: std::ptr::NonNull<lyra_ecs::World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: std::ptr::NonNull<lyra_ecs::World>) { }
|
||||
}
|
||||
|
||||
impl<T: Event> FnArgFetcher for EventWriter<T> {
|
||||
|
@ -209,8 +222,10 @@ impl<T: Event> FnArgFetcher for EventWriter<T> {
|
|||
let world = world.as_ref();
|
||||
let events = world.get_resource::<Events<T>>()
|
||||
.unwrap_or_else(|| panic!("world missing Events<{}> resource", std::any::type_name::<T>()));
|
||||
events.writer()
|
||||
EventWriter {
|
||||
events: events.events.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_deferred(_: Self::State, _: std::ptr::NonNull<lyra_ecs::World>) { }
|
||||
fn apply_deferred<'state>(_: &'state mut Self::State, _: std::ptr::NonNull<lyra_ecs::World>) { }
|
||||
}
|
|
@ -493,7 +493,7 @@ impl ActionHandlerBuilder {
|
|||
//fn actions_system(world: &mut World) -> anyhow::Result<()> {
|
||||
fn actions_system(
|
||||
input_btns: Res<InputButtons<KeyCode>>,
|
||||
mouse_ev: EventReader<MouseMotion>,
|
||||
mut mouse_ev: EventReader<MouseMotion>,
|
||||
mut handler: ResMut<ActionHandler>,
|
||||
) -> anyhow::Result<()> {
|
||||
// clear the states of all axises each frame
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use glam::Vec2;
|
||||
use lyra_ecs::query::ResMut;
|
||||
use winit::{event::{MouseScrollDelta, WindowEvent}, keyboard::PhysicalKey};
|
||||
|
@ -31,8 +29,8 @@ pub fn input_system(
|
|||
mut key_code_res: ResMut<InputButtons<KeyCode>>,
|
||||
mut mouse_btn_res: ResMut<InputButtons<MouseButton>>,
|
||||
mut touches_res: ResMut<Touches>,
|
||||
window_ev: EventReader<WindowEvent>,
|
||||
device_ev: EventReader<DeviceEventPair>,
|
||||
mut window_ev: EventReader<WindowEvent>,
|
||||
mut device_ev: EventReader<DeviceEventPair>,
|
||||
mut mouse_scroll_ev: EventWriter<MouseScroll>,
|
||||
mouse_btn_ev: EventWriter<MouseButton>,
|
||||
mouse_exact_ev: EventWriter<MouseExact>,
|
||||
|
@ -41,7 +39,7 @@ pub fn input_system(
|
|||
mouse_motion_ev: EventWriter<MouseMotion>,
|
||||
) -> anyhow::Result<()> {
|
||||
while let Some(event) = window_ev.read() {
|
||||
match event.deref() {
|
||||
match event {
|
||||
WindowEvent::KeyboardInput { event, .. } => {
|
||||
write_key_event(&mut key_code_res, event.physical_key, event.state);
|
||||
},
|
||||
|
@ -59,7 +57,7 @@ pub fn input_system(
|
|||
mouse_left_ev.write(CursorLeftWindow);
|
||||
},
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
write_scroll_delta(&mut mouse_scroll_ev, delta);
|
||||
write_scroll_delta(&mut mouse_scroll_ev, &delta);
|
||||
},
|
||||
WindowEvent::MouseInput { button, state, .. } => {
|
||||
let button_event = match button {
|
||||
|
@ -68,11 +66,11 @@ pub fn input_system(
|
|||
winit::event::MouseButton::Middle => MouseButton::Middle,
|
||||
winit::event::MouseButton::Back => MouseButton::Back,
|
||||
winit::event::MouseButton::Forward => MouseButton::Forward,
|
||||
winit::event::MouseButton::Other(v) => MouseButton::Other(*v),
|
||||
winit::event::MouseButton::Other(v) => MouseButton::Other(v),
|
||||
};
|
||||
|
||||
mouse_btn_ev.write(button_event);
|
||||
mouse_btn_res.add_input_from_winit(button_event, *state);
|
||||
mouse_btn_res.add_input_from_winit(button_event, state);
|
||||
},
|
||||
WindowEvent::Touch(t) => {
|
||||
let touch = Touch {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use lyra_engine::{
|
||||
assets::ResourceManager,
|
||||
game::App,
|
||||
game::{App, GameStages},
|
||||
gltf::Gltf,
|
||||
input::{
|
||||
Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
|
||||
|
@ -12,9 +12,7 @@ use lyra_engine::{
|
|||
light::{directional::DirectionalLight, SpotLight},
|
||||
},
|
||||
scene::{
|
||||
CameraBundle, FreeFly3dCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT,
|
||||
ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD,
|
||||
ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN,
|
||||
system_update_world_transforms, CameraBundle, FreeFly3dCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -90,11 +88,17 @@ async fn main() {
|
|||
};
|
||||
|
||||
let mut app = App::new();
|
||||
app.with_plugin(lyra_engine::DefaultPlugins);
|
||||
app.with_plugin(setup_scene_plugin);
|
||||
app.with_plugin(action_handler_plugin);
|
||||
//app.with_plugin(camera_debug_plugin)
|
||||
app.with_plugin(FreeFlyCameraPlugin);
|
||||
app.with_plugin(lyra_engine::DefaultPlugins)
|
||||
.with_plugin(setup_scene_plugin)
|
||||
.with_plugin(action_handler_plugin)
|
||||
.add_system_to_stage(
|
||||
GameStages::Last,
|
||||
"update_world_transforms",
|
||||
system_update_world_transforms,
|
||||
&[],
|
||||
)
|
||||
//.with_plugin(camera_debug_plugin)
|
||||
.with_plugin(FreeFlyCameraPlugin);
|
||||
app.run();
|
||||
}
|
||||
|
||||
|
@ -120,7 +124,7 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
.request::<Gltf>("../assets/shadows-platform-palmtree.glb")
|
||||
.unwrap();
|
||||
|
||||
palm_tree_platform_gltf.wait_recurse_dependencies_load();
|
||||
palm_tree_platform_gltf.wait_recurse_dependencies_load().unwrap();
|
||||
let palm_tree_platform_mesh = &palm_tree_platform_gltf.data_ref().unwrap().scenes[0];
|
||||
|
||||
drop(resman);
|
||||
|
@ -236,6 +240,12 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
));
|
||||
}
|
||||
|
||||
/* world.spawn((
|
||||
CameraBundle::default(),
|
||||
Transform::from_xyz(0.0, 0.0, -5.5),
|
||||
FreeFly3dCamera::default(),
|
||||
)); */
|
||||
|
||||
let mut pos = Transform::from_xyz(-1.0, -10.0, -1.5);
|
||||
pos.rotate_x(math::Angle::Degrees(-27.0));
|
||||
pos.rotate_y(math::Angle::Degrees(-90.0));
|
||||
|
|
Loading…
Add table
Reference in a new issue