Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Session commands to modify sessions from game code #379

Merged
merged 2 commits into from
Apr 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions framework_crates/bones_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@ pub use bones_ecs as ecs;
/// Bones lib prelude
pub mod prelude {
pub use crate::{
ecs::prelude::*, instant::Instant, time::*, Game, GamePlugin, Session, SessionOptions,
SessionPlugin, SessionRunner, Sessions,
ecs::prelude::*, instant::Instant, time::*, Game, GamePlugin, Session, SessionCommand,
SessionOptions, SessionPlugin, SessionRunner, Sessions,
};
}

pub use instant;
pub mod time;

use std::{fmt::Debug, sync::Arc};
use std::{collections::VecDeque, fmt::Debug, sync::Arc};

use crate::prelude::*;

/// A bones game. This includes all of the game worlds, and systems.
#[derive(Deref, DerefMut)]
pub struct Session {
Expand Down Expand Up @@ -408,6 +407,15 @@ impl Game {
}
}

// Execute Session Commands
{
let mut session_commands: VecDeque<Box<SessionCommand>> = default();
std::mem::swap(&mut session_commands, &mut self.sessions.commands);
for command in session_commands.drain(..) {
command(&mut self.sessions);
}
}

// Run after systems
for system in &mut game_systems.after {
system(self)
Expand Down Expand Up @@ -496,12 +504,24 @@ impl GameSystems {
}
}

/// Type of session command
pub type SessionCommand = dyn FnOnce(&mut Sessions) + Sync + Send;

/// Container for multiple game sessions.
///
/// Each session shares the same [`Entities`].
#[derive(HasSchema, Default, Debug)]
#[derive(HasSchema, Default)]
pub struct Sessions {
map: UstrMap<Session>,

/// Commands that operate on [`Sessions`], called after all sessions update.
/// These may be used to add/delete/modify sessions.
///
/// Commands are useful in a situation where you want to remove / recreate
/// a session from within it's own system. You cannot do this while the `Session` is running.
///
/// Commands added inside a session command will not be executed until next frame.
commands: VecDeque<Box<SessionCommand>>,
}

/// Resource that allows you to configure the current session.
Expand Down Expand Up @@ -573,6 +593,11 @@ impl Sessions {
pub fn iter(&self) -> std::collections::hash_map::Iter<Ustr, Session> {
self.map.iter()
}

/// Add a [`SessionCommand`] to queue.
pub fn add_command(&mut self, command: Box<SessionCommand>) {
self.commands.push_back(command);
}
}

// We implement `Clone` so that the world can still be snapshot with this resouce in it, but we
Expand Down
Loading