use crate::context::{ResourceContext, ServiceContext, SystemContext};
use async_trait::async_trait;
pub mod director;
pub use director::SceneDirector;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SceneTransition<S> {
Stay,
Switch(S),
Push(S),
Pop,
Quit,
}
#[async_trait]
pub trait Scene: Send + Sized {
async fn on_enter(
&mut self,
_services: &ServiceContext,
_systems: &mut SystemContext,
_resources: &mut ResourceContext,
) {
}
async fn on_exit(
&mut self,
_services: &ServiceContext,
_systems: &mut SystemContext,
_resources: &mut ResourceContext,
) {
}
async fn on_suspend(
&mut self,
_services: &ServiceContext,
_systems: &mut SystemContext,
_resources: &mut ResourceContext,
) {
}
async fn on_resume(
&mut self,
_services: &ServiceContext,
_systems: &mut SystemContext,
_resources: &mut ResourceContext,
) {
}
async fn on_update(
&mut self,
_services: &ServiceContext,
_systems: &mut SystemContext,
_resources: &mut ResourceContext,
) -> SceneTransition<Self> {
SceneTransition::Stay
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Scene;
#[derive(Scene)]
struct TestScene {
entered: bool,
}
#[tokio::test]
async fn test_derived_scene() {
let mut scene = TestScene { entered: false };
assert!(!scene.entered);
scene
.on_enter(
&crate::context::ServiceContext::new(),
&mut crate::context::SystemContext::new(),
&mut crate::context::ResourceContext::new(),
)
.await;
let transition = scene
.on_update(
&crate::context::ServiceContext::new(),
&mut crate::context::SystemContext::new(),
&mut crate::context::ResourceContext::new(),
)
.await;
assert!(matches!(transition, SceneTransition::Stay));
scene
.on_exit(
&crate::context::ServiceContext::new(),
&mut crate::context::SystemContext::new(),
&mut crate::context::ResourceContext::new(),
)
.await;
}
#[derive(Scene)]
#[allow(dead_code)]
enum GameScene {
Title,
Combat,
}
#[tokio::test]
async fn test_derived_enum_scene() {
let mut scene = GameScene::Title;
scene
.on_enter(
&crate::context::ServiceContext::new(),
&mut crate::context::SystemContext::new(),
&mut crate::context::ResourceContext::new(),
)
.await;
let transition = scene
.on_update(
&crate::context::ServiceContext::new(),
&mut crate::context::SystemContext::new(),
&mut crate::context::ResourceContext::new(),
)
.await;
assert!(matches!(transition, SceneTransition::Stay));
scene
.on_exit(
&crate::context::ServiceContext::new(),
&mut crate::context::SystemContext::new(),
&mut crate::context::ResourceContext::new(),
)
.await;
}
}