mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Resource system functions
This commit is contained in:
parent
d5a33c9d0d
commit
092f3888ca
5 changed files with 99 additions and 35 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue