Merge branch 'feature/plugins' into 'main'
This commit is contained in:
commit
eb941794dc
|
@ -30,3 +30,4 @@ edict = "0.5.0"
|
||||||
atomicell = "0.1.9"
|
atomicell = "0.1.9"
|
||||||
aligned-vec = "0.5.0"
|
aligned-vec = "0.5.0"
|
||||||
tracing-appender = "0.2.2"
|
tracing-appender = "0.2.2"
|
||||||
|
stopwatch = "0.0.7"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{collections::{HashMap, VecDeque}, any::{TypeId, Any}, cell::{RefCell, Ref, RefMut}};
|
use std::{collections::{HashMap, VecDeque}, any::{TypeId, Any}, cell::RefCell};
|
||||||
|
|
||||||
use crate::castable_any::CastableAny;
|
use crate::castable_any::CastableAny;
|
||||||
|
|
||||||
|
|
136
src/game.rs
136
src/game.rs
|
@ -1,4 +1,4 @@
|
||||||
use std::sync::Arc;
|
use std::{sync::Arc, collections::VecDeque};
|
||||||
|
|
||||||
use async_std::{task::block_on, sync::Mutex};
|
use async_std::{task::block_on, sync::Mutex};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use tracing_subscriber::{
|
||||||
|
|
||||||
use winit::{window::{WindowBuilder, Window}, event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, DeviceEvent}, event_loop::{EventLoop, ControlFlow}};
|
use winit::{window::{WindowBuilder, Window}, event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, DeviceEvent}, event_loop::{EventLoop, ControlFlow}};
|
||||||
|
|
||||||
use crate::{render::renderer::{Renderer, BasicRenderer}, input_event::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, input::InputSystem};
|
use crate::{render::renderer::{Renderer, BasicRenderer}, input_event::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, input::InputSystem, plugin::Plugin};
|
||||||
|
|
||||||
pub struct Controls<'a> {
|
pub struct Controls<'a> {
|
||||||
pub world: &'a mut edict::World,
|
pub world: &'a mut edict::World,
|
||||||
|
@ -36,14 +36,14 @@ struct GameLoop {
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
renderer: Box<dyn Renderer>,
|
renderer: Box<dyn Renderer>,
|
||||||
|
|
||||||
world: Arc<Mutex<edict::World>>,
|
world: edict::World,
|
||||||
/// higher priority systems
|
/// higher priority systems
|
||||||
engine_sys_dispatcher: SystemDispatcher,
|
engine_sys_dispatcher: SystemDispatcher,
|
||||||
user_sys_dispatcher: SystemDispatcher,
|
user_sys_dispatcher: SystemDispatcher,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameLoop {
|
impl GameLoop {
|
||||||
pub async fn new(window: Arc<Window>, world: Arc<Mutex<edict::World>>, user_systems: SystemDispatcher) -> GameLoop {
|
pub async fn new(window: Arc<Window>, world: edict::World, user_systems: SystemDispatcher) -> GameLoop {
|
||||||
Self {
|
Self {
|
||||||
window: Arc::clone(&window),
|
window: Arc::clone(&window),
|
||||||
renderer: Box::new(BasicRenderer::create_with_window(window).await),
|
renderer: Box::new(BasicRenderer::create_with_window(window).await),
|
||||||
|
@ -60,8 +60,7 @@ impl GameLoop {
|
||||||
|
|
||||||
pub async fn on_init(&mut self) {
|
pub async fn on_init(&mut self) {
|
||||||
// Create the EventQueue resource in the world
|
// Create the EventQueue resource in the world
|
||||||
let mut world = self.world.lock().await;
|
self.world.insert_resource(EventQueue::new());
|
||||||
world.insert_resource(EventQueue::new());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_sync(&mut self, event: Event<()>, control_flow: &mut ControlFlow) {
|
pub fn run_sync(&mut self, event: Event<()>, control_flow: &mut ControlFlow) {
|
||||||
|
@ -69,10 +68,8 @@ impl GameLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update(&mut self) {
|
async fn update(&mut self) {
|
||||||
let mut world = self.world.lock().await;
|
|
||||||
|
|
||||||
let mut controls = Controls {
|
let mut controls = Controls {
|
||||||
world: &mut world,
|
world: &mut self.world,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = self.engine_sys_dispatcher.execute_mut(&mut controls) {
|
if let Err(e) = self.engine_sys_dispatcher.execute_mut(&mut controls) {
|
||||||
|
@ -102,18 +99,14 @@ impl GameLoop {
|
||||||
|
|
||||||
// TODO: Create system for this? or maybe merge into input system, idk
|
// TODO: Create system for this? or maybe merge into input system, idk
|
||||||
InputEvent::CursorEntered { .. } => {
|
InputEvent::CursorEntered { .. } => {
|
||||||
let mut world = self.world.lock().await;
|
let mut state = self.world.with_resource(|| WindowState::new());
|
||||||
|
|
||||||
let mut state = world.with_resource(|| WindowState::new());
|
|
||||||
state.is_cursor_inside_window = true;
|
state.is_cursor_inside_window = true;
|
||||||
|
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
|
||||||
InputEvent::CursorLeft { .. } => {
|
InputEvent::CursorLeft { .. } => {
|
||||||
let mut world = self.world.lock().await;
|
let mut state = self.world.with_resource(|| WindowState::new());
|
||||||
|
|
||||||
let mut state = world.with_resource(|| WindowState::new());
|
|
||||||
state.is_cursor_inside_window = false;
|
state.is_cursor_inside_window = false;
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -127,14 +120,6 @@ impl GameLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_window() {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_item() {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_exit(&mut self) {
|
fn on_exit(&mut self) {
|
||||||
info!("On exit!");
|
info!("On exit!");
|
||||||
}
|
}
|
||||||
|
@ -145,16 +130,14 @@ impl GameLoop {
|
||||||
Event::DeviceEvent { device_id, event } => match event {
|
Event::DeviceEvent { device_id, event } => match event {
|
||||||
// convert a MouseMotion event to an InputEvent
|
// convert a MouseMotion event to an InputEvent
|
||||||
DeviceEvent::MouseMotion { delta } => {
|
DeviceEvent::MouseMotion { delta } => {
|
||||||
let mut world = self.world.lock().await;
|
|
||||||
|
|
||||||
// make sure that the mouse is inside the window and the mouse has focus before reporting mouse motion
|
// make sure that the mouse is inside the window and the mouse has focus before reporting mouse motion
|
||||||
let trigger = match world.get_resource::<WindowState>() {
|
let trigger = match self.world.get_resource::<WindowState>() {
|
||||||
Some(window_state) if window_state.is_focused && window_state.is_cursor_inside_window => true,
|
Some(window_state) if window_state.is_focused && window_state.is_cursor_inside_window => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if trigger {
|
if trigger {
|
||||||
let event_queue = world.with_resource(|| Events::<InputEvent>::new());
|
let event_queue = self.world.with_resource(|| Events::<InputEvent>::new());
|
||||||
|
|
||||||
let input_event = InputEvent::MouseMotion { device_id, delta, };
|
let input_event = InputEvent::MouseMotion { device_id, delta, };
|
||||||
event_queue.push_back(input_event);
|
event_queue.push_back(input_event);
|
||||||
|
@ -173,8 +156,7 @@ impl GameLoop {
|
||||||
// Its possible to receive multiple input events before the update event for
|
// Its possible to receive multiple input events before the update event for
|
||||||
// the InputSystem is called, so we must use a queue for the events.
|
// the InputSystem is called, so we must use a queue for the events.
|
||||||
{
|
{
|
||||||
let world = self.world.lock().await;
|
if let Some(mut event_queue) = self.world.get_resource_mut::<EventQueue>() {
|
||||||
if let Some(mut event_queue) = world.get_resource_mut::<EventQueue>() {
|
|
||||||
event_queue.trigger_event(input_event.clone());
|
event_queue.trigger_event(input_event.clone());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -199,9 +181,7 @@ impl GameLoop {
|
||||||
},
|
},
|
||||||
|
|
||||||
WindowEvent::Focused(is_focused) => {
|
WindowEvent::Focused(is_focused) => {
|
||||||
let mut world = self.world.lock().await;
|
let mut state = self.world.with_resource(|| WindowState::new());
|
||||||
|
|
||||||
let mut state = world.with_resource(|| WindowState::new());
|
|
||||||
state.is_focused = *is_focused;
|
state.is_focused = *is_focused;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -219,12 +199,10 @@ impl GameLoop {
|
||||||
debug!("FPS: {}fps, {:.2}ms/frame", fps, self.fps_counter.get_tick_time());
|
debug!("FPS: {}fps, {:.2}ms/frame", fps, self.fps_counter.get_tick_time());
|
||||||
} */
|
} */
|
||||||
|
|
||||||
let mut world = self.world.lock().await;
|
self.renderer.as_mut().prepare(&mut self.world);
|
||||||
self.renderer.as_mut().prepare(&mut world);
|
if let Some(mut event_queue) = self.world.get_resource_mut::<EventQueue>() {
|
||||||
if let Some(mut event_queue) = world.get_resource_mut::<EventQueue>() {
|
|
||||||
event_queue.update_events();
|
event_queue.update_events();
|
||||||
}
|
}
|
||||||
drop(world);
|
|
||||||
|
|
||||||
match self.renderer.as_mut().render() {
|
match self.renderer.as_mut().render() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
|
@ -246,14 +224,16 @@ impl GameLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
world: Option<Arc<Mutex<edict::World>>>,
|
pub world: Option<edict::World>,
|
||||||
|
plugins: VecDeque<Box<dyn Plugin>>,
|
||||||
system_dispatcher: Option<SystemDispatcher>,
|
system_dispatcher: Option<SystemDispatcher>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Game {
|
impl Default for Game {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
world: None,
|
world: Some(edict::World::new()),
|
||||||
|
plugins: VecDeque::new(),
|
||||||
system_dispatcher: Some(SystemDispatcher::new()),
|
system_dispatcher: Some(SystemDispatcher::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,55 +241,31 @@ impl Default for Game {
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub async fn initialize() -> Game {
|
pub async fn initialize() -> Game {
|
||||||
/* let filter = FilterFn::new(|metadata| {
|
Self::default()
|
||||||
metadata.module_path()
|
|
||||||
.unwrap_or_else(|| metadata.target())
|
|
||||||
.starts_with("lyra_engine") && (LevelFilter::DEBUG >= metadata.level().to_owned())
|
|
||||||
});
|
|
||||||
|
|
||||||
let layer = tracing_subscriber::fmt::layer();
|
|
||||||
|
|
||||||
tracing_subscriber::registry()
|
|
||||||
.with(layer.with_filter(filter))
|
|
||||||
.init(); */
|
|
||||||
|
|
||||||
|
|
||||||
/* tracing_subscriber::registry()
|
|
||||||
.with(fmt::layer().with_writer(stdout_layer))
|
|
||||||
.with(filter::Targets::new()
|
|
||||||
.with_target("lyra_engine", Level::TRACE)
|
|
||||||
.with_default(Level::DEBUG))
|
|
||||||
.init(); */
|
|
||||||
|
|
||||||
/* tracing_subscriber::fmt()
|
|
||||||
.with_max_level(Level::DEBUG)
|
|
||||||
.init(); */
|
|
||||||
|
|
||||||
info!("dheiudfgbwehifwe");
|
|
||||||
|
|
||||||
let mut def = Self::default();
|
|
||||||
def.system_dispatcher.as_mut().unwrap().add_system("input", InputSystem::new(), &[]);
|
|
||||||
def
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_world(&mut self, world: edict::World) -> &mut Self {
|
|
||||||
self.world = Some(Arc::new(Mutex::new(world)));
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_world_arc(&mut self, world: Arc<Mutex<edict::World>>) -> &mut Self {
|
|
||||||
self.world = Some(world);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_system<S>(&mut self, name: &str, system: S, depends: &[&str]) -> &mut Self
|
pub fn with_system<S>(&mut self, name: &str, system: S, depends: &[&str]) -> &mut Self
|
||||||
where
|
where
|
||||||
S: SimpleSystem + 'static
|
S: SimpleSystem + 'static
|
||||||
{
|
{
|
||||||
let dispatcher = self.system_dispatcher.as_mut().unwrap();
|
let system_dispatcher = self.system_dispatcher.as_mut().unwrap();
|
||||||
dispatcher.add_system(name, system, depends);
|
system_dispatcher.add_system(name, system, depends);
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a plugin to the game
|
||||||
|
pub fn with_plugin<P>(&mut self, plugin: P) -> &mut Self
|
||||||
|
where
|
||||||
|
P: Plugin + 'static
|
||||||
|
{
|
||||||
|
self.plugins.push_back(Box::new(plugin));
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_world(&mut self, world: edict::World) -> &mut Self {
|
||||||
|
self.world = Some(world);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -321,18 +277,22 @@ impl Game {
|
||||||
.with(fmt::layer().with_writer(stdout_layer))
|
.with(fmt::layer().with_writer(stdout_layer))
|
||||||
.with(filter::Targets::new()
|
.with(filter::Targets::new()
|
||||||
.with_target("lyra_engine", Level::TRACE)
|
.with_target("lyra_engine", Level::TRACE)
|
||||||
.with_default(Level::INFO))
|
.with_target("wgpu_core", Level::INFO)
|
||||||
|
.with_default(Level::DEBUG))
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let world = self.world.take().expect("ECS World was never given to Game!");
|
|
||||||
|
|
||||||
|
// setup all the plugins
|
||||||
|
while let Some(plugin) = self.plugins.pop_front() {
|
||||||
|
plugin.as_ref().setup(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start winit event loops
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
|
let window = Arc::new(WindowBuilder::new().build(&event_loop).unwrap());
|
||||||
|
|
||||||
let systems = self.system_dispatcher.take().unwrap();
|
let world = self.world.take().unwrap_or_else(|| edict::World::new());
|
||||||
|
let system_dispatcher = self.system_dispatcher.take().unwrap();
|
||||||
let mut g_loop = GameLoop::new(Arc::clone(&window), world, systems).await;
|
let mut g_loop = GameLoop::new(Arc::clone(&window), world, system_dispatcher).await;
|
||||||
|
|
||||||
g_loop.on_init().await;
|
g_loop.on_init().await;
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
|
|
50
src/input.rs
50
src/input.rs
|
@ -5,7 +5,7 @@ use glam::Vec2;
|
||||||
use tracing::{warn, debug};
|
use tracing::{warn, debug};
|
||||||
use winit::event::{ElementState, MouseScrollDelta};
|
use winit::event::{ElementState, MouseScrollDelta};
|
||||||
|
|
||||||
use crate::{ecs::{SimpleSystem, EventQueue}, input_event::InputEvent};
|
use crate::{ecs::{SimpleSystem, EventQueue}, input_event::InputEvent, plugin::Plugin};
|
||||||
|
|
||||||
pub type KeyCode = winit::event::VirtualKeyCode;
|
pub type KeyCode = winit::event::VirtualKeyCode;
|
||||||
|
|
||||||
|
@ -84,8 +84,6 @@ impl From<winit::event::Force> for Force {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// Translated `WindowEvent::Touch` from `winit` crate
|
/// Translated `WindowEvent::Touch` from `winit` crate
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Touch {
|
pub struct Touch {
|
||||||
|
@ -206,22 +204,6 @@ trait InputStorage {
|
||||||
|
|
||||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> InputStorage for InputButtons<T> {
|
impl<T: Clone + Hash + Eq + PartialEq + 'static> InputStorage for InputButtons<T> {
|
||||||
fn update_just_pressed(&mut self) {
|
fn update_just_pressed(&mut self) {
|
||||||
/* for (hash, button) in self.button_events.iter_mut() {
|
|
||||||
|
|
||||||
/* if let ButtonEvent::JustPressed(b) = button {
|
|
||||||
*button = ButtonEvent::Pressed(b.clone());
|
|
||||||
} */
|
|
||||||
match button {
|
|
||||||
ButtonEvent::Pressed(_) => todo!(),
|
|
||||||
ButtonEvent::Released(b) => {
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
ButtonEvent::JustPressed(b) => {
|
|
||||||
*button = ButtonEvent::Pressed(b.clone());
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
self.button_events.retain(|_hash, button| {
|
self.button_events.retain(|_hash, button| {
|
||||||
match button {
|
match button {
|
||||||
// remove released, no need to keep those around.
|
// remove released, no need to keep those around.
|
||||||
|
@ -239,26 +221,10 @@ impl<T: Clone + Hash + Eq + PartialEq + 'static> InputStorage for InputButtons<T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InputSystem {
|
#[derive(Default)]
|
||||||
gilrs: Option<Arc<Mutex<Gilrs>>>, // TODO
|
pub struct InputSystem;
|
||||||
}
|
|
||||||
|
|
||||||
impl InputSystem {
|
impl InputSystem {
|
||||||
pub(crate) fn new() -> Self {
|
|
||||||
let gilrs = match Gilrs::new() {
|
|
||||||
Ok(g) => Some(Arc::new(Mutex::new(g))),
|
|
||||||
Err(e) => {
|
|
||||||
warn!("Failure to initialize gilrs, gamepads will not work!\n{}", e);
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
|
||||||
gilrs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self, event: &InputEvent, world: &mut edict::World) -> bool {
|
pub fn update(&mut self, event: &InputEvent, world: &mut edict::World) -> bool {
|
||||||
let event_queue = world.get_resource_mut::<EventQueue>();
|
let event_queue = world.get_resource_mut::<EventQueue>();
|
||||||
if event_queue.is_none() {
|
if event_queue.is_none() {
|
||||||
|
@ -365,4 +331,14 @@ impl SimpleSystem for InputSystem {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Plugin that runs InputSystem
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct InputPlugin;
|
||||||
|
|
||||||
|
impl Plugin for InputPlugin {
|
||||||
|
fn setup(&self, game: &mut crate::game::Game) {
|
||||||
|
game.with_system("input", InputSystem::default(), &[]);
|
||||||
|
}
|
||||||
}
|
}
|
18
src/lib.rs
18
src/lib.rs
|
@ -5,4 +5,20 @@ pub mod resources;
|
||||||
pub mod ecs;
|
pub mod ecs;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod castable_any;
|
pub mod castable_any;
|
||||||
|
pub mod plugin;
|
||||||
|
|
||||||
|
use plugin::Plugin;
|
||||||
|
|
||||||
|
use crate::input::InputPlugin;
|
||||||
|
|
||||||
|
/// Default plugins of Lyra. Make sure to have these added to the Game first
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct DefaultPlugins;
|
||||||
|
|
||||||
|
impl Plugin for DefaultPlugins {
|
||||||
|
fn setup(&self, game: &mut game::Game) {
|
||||||
|
// setup input
|
||||||
|
InputPlugin::default().setup(game);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
use crate::game::Game;
|
||||||
|
|
||||||
|
/// A Plugin is something you can add to a `Game` that can be used to define systems, or spawn initial entities.
|
||||||
|
pub trait Plugin {
|
||||||
|
/// Setup this plugin. This runs before the game has started
|
||||||
|
fn setup(&self, game: &mut Game);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P> Plugin for P
|
||||||
|
where P: Fn(&mut Game)
|
||||||
|
{
|
||||||
|
fn setup(&self, game: &mut Game) {
|
||||||
|
self(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a set of plugins that will be executed in order they are supplied.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct PluginSet {
|
||||||
|
/// A set of plugins that will be executed in order
|
||||||
|
pub plugins: Vec<Box<dyn Plugin>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginSet {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_plugin<P>(&mut self, plugin: P) -> &mut Self
|
||||||
|
where
|
||||||
|
P: Plugin + 'static
|
||||||
|
{
|
||||||
|
self.plugins.push(Box::new(plugin));
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Plugin for PluginSet {
|
||||||
|
fn setup(&self, game: &mut Game) {
|
||||||
|
for plugin in self.plugins.iter() {
|
||||||
|
plugin.setup(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Macro used for implementing PluginSet for tuples
|
||||||
|
macro_rules! impl_tuple_plugin_set {
|
||||||
|
( $(($name: ident, $index: tt))+ ) => (
|
||||||
|
impl<$($name: Plugin + 'static),+> From<($($name,)+)> for PluginSet {
|
||||||
|
fn from(value: ($($name,)+)) -> Self {
|
||||||
|
let plugins = vec![$(Box::new(value.$index) as Box<(dyn Plugin + 'static)>),+];
|
||||||
|
|
||||||
|
Self {
|
||||||
|
plugins,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) (C8, 8) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) (C8, 8) (C9, 9) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) (C8, 8) (C9, 9) (C10, 10) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) (C8, 8) (C9, 9) (C10, 10) (C11, 11) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) (C8, 8) (C9, 9) (C10, 10) (C11, 11) (C12, 12) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) (C8, 8) (C9, 9) (C10, 10) (C11, 11) (C12, 12) (C13, 13) }
|
||||||
|
impl_tuple_plugin_set! { (C0, 0) (C1, 1) (C2, 2) (C3, 3) (C4, 4) (C5, 5) (C6, 6) (C7, 7) (C8, 8) (C9, 9) (C10, 10) (C11, 11) (C12, 12) (C13, 13) (C14, 14) }
|
Loading…
Reference in New Issue