Resource system functions

This commit is contained in:
Carter Anderson 2020-04-28 02:31:01 -07:00
parent d5a33c9d0d
commit 092f3888ca
5 changed files with 99 additions and 35 deletions

View file

@ -207,6 +207,16 @@ impl AppBuilder {
self
}
pub fn add_resource_init<R>(&mut self) -> &mut Self
where
R: for<'a> From<&'a mut Resources> + Send + Sync + 'static,
{
let resources = self.resources_mut();
let resource = R::from(resources);
resources.insert(resource);
self
}
pub fn set_runner(&mut self, run_fn: impl Fn(App) + 'static) -> &mut Self {
self.app_mut().runner = Some(Box::new(run_fn));
self

View file

@ -16,6 +16,6 @@ pub mod prelude {
resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut},
schedule::{Executor, Runnable, Schedulable, Schedule},
System, SystemBuilder,
into_system,
into_system, into_resource_system
};
}

View file

@ -14,11 +14,11 @@ use std::marker::PhantomData;
use bit_set::BitSet;
pub fn into_system<'a, Q, F, R, X>(name: &'static str, system: F) -> Box<dyn Schedulable>
pub fn into_system<'a, Q, F, R, X>(name: &'static str, mut system: F) -> Box<dyn Schedulable>
where
Q: IntoQuery + DefaultFilter<Filter = R>,
<Q as View<'a>>::Iter: Iterator<Item = Q> + 'a,
F: Fn(&mut X, Q) + Send + Sync + 'static,
F: FnMut(&mut X, Q) + Send + Sync + 'static,
R: EntityFilter + Sync + 'static,
X: ResourceSet<PreparedResources = X> + 'static,
{
@ -57,6 +57,41 @@ where
})
}
pub fn into_resource_system<'a, F, X>(name: &'static str, mut system: F) -> Box<dyn Schedulable>
where
F: FnMut(&mut X) + Send + Sync + 'static,
X: ResourceSet<PreparedResources = X> + 'static,
{
let mut resource_access: Access<ResourceTypeId> = Access::default();
resource_access.reads.extend(X::read_types().iter());
resource_access.writes.extend(X::write_types().iter());
let component_access: Access<ComponentTypeId> = Access::default();
let run_fn = SystemFnWrapper(
move |_,
_,
resources: &mut X,
_| {
system(resources);
},
PhantomData,
);
Box::new(System {
name: name.into(),
queries: AtomicRefCell::new(()),
access: SystemAccess {
resources: resource_access,
components: component_access,
tags: Access::default(),
},
archetypes: ArchetypeAccess::Some(BitSet::default()),
_resources: PhantomData::<X>,
command_buffer: FxHashMap::default(),
run_fn: AtomicRefCell::new(run_fn),
})
}
#[cfg(test)]
mod tests {
use super::into_system;

View file

@ -1,44 +1,63 @@
use bevy::prelude::*;
struct MyEvent {
pub message: String,
}
fn main() {
App::build()
.add_default_plugins()
.add_event::<MyEvent>()
.add_system(event_trigger_system())
.add_system_init(event_listener_system)
.add_resource(EventTriggerState::default())
.add_resource_init::<EventListenerState>()
.add_system(into_resource_system("event_trigger", event_trigger_system))
.add_system(into_resource_system(
"event_listener",
event_listener_system,
))
.run();
}
// sends MyEvent every second
fn event_trigger_system() -> Box<dyn Schedulable> {
let mut elapsed = 0.0;
SystemBuilder::new("event_trigger")
.read_resource::<Time>()
.write_resource::<Events<MyEvent>>()
.build(move |_, _, (time, my_events), _| {
elapsed += time.delta_seconds;
if elapsed > 1.0 {
my_events.send(MyEvent {
message: "Hello World".to_string(),
});
struct MyEvent {
pub message: String,
}
elapsed = 0.0;
}
})
#[derive(Default)]
struct EventTriggerState {
elapsed: f32,
}
// sends MyEvent every second
fn event_trigger_system(
(state, my_events, time): &mut (
ResourceMut<EventTriggerState>,
ResourceMut<Events<MyEvent>>,
Resource<Time>,
),
) {
state.elapsed += time.delta_seconds;
if state.elapsed > 1.0 {
my_events.send(MyEvent {
message: "Hello World".to_string(),
});
state.elapsed = 0.0;
}
}
struct EventListenerState {
my_event_reader: EventReader<MyEvent>,
}
impl From<&mut Resources> for EventListenerState {
fn from(resources: &mut Resources) -> Self {
EventListenerState {
my_event_reader: resources.get_event_reader::<MyEvent>(),
}
}
}
// prints events as they come in
fn event_listener_system(resources: &mut Resources) -> Box<dyn Schedulable> {
let mut my_event_reader = resources.get_event_reader::<MyEvent>();
SystemBuilder::new("event_listener")
.read_resource::<Events<MyEvent>>()
.build(move |_, _, my_events, _| {
for my_event in my_events.iter(&mut my_event_reader) {
println!("{}", my_event.message);
}
})
}
fn event_listener_system(
(state, my_events): &mut (ResourceMut<EventListenerState>, Resource<Events<MyEvent>>),
) {
for my_event in my_events.iter(&mut state.my_event_reader) {
println!("{}", my_event.message);
}
}

View file

@ -55,7 +55,7 @@ pub use legion::{
resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut},
schedule::{Executor, Runnable, Schedulable, Schedule},
SubWorld, System, SystemBuilder,
into_system
into_system, into_resource_system
},
world::{Universe, World},
};