Skip to content

Commit

Permalink
add shared whole-game level state, add access to settings from egui
Browse files Browse the repository at this point in the history
  • Loading branch information
pillowtrucker committed Feb 16, 2024
1 parent 9bcf0bd commit 489d54d
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 44 deletions.
84 changes: 66 additions & 18 deletions brainworms_demented_robotic_meat_grinder_machine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,25 @@ pub fn my_macro(input: TokenStream) -> TokenStream {
/// Example of user-defined [derive mode macro][1]
///
/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#derive-mode-macros
#[proc_macro_derive(Scenic)]
#[proc_macro_derive(Scenic, attributes(user_data_struct))]
pub fn derive_scenic_partial(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = input.ident;
let the_user_data_struct: &Ident = &input
.attrs
.iter()
.find(|a| {
a.path()
.get_ident()
.is_some_and(|aa| aa == "user_data_struct")
})
.map(|aa| {
aa.parse_args()
.expect("user_data_struct attribute required")
})
.expect("user_data_struct attribute required");
let tokens = quote! {
impl brainworms_lib::theater::play::scene::Scenic for #ident {
impl brainworms_lib::theater::play::scene::Scenic<#the_user_data_struct> for #ident {

fn raw_definition(&mut self) -> &mut brainworms_lib::theater::play::Definitions {
&mut self.definition
Expand All @@ -51,15 +64,17 @@ pub fn derive_scenic_partial(input: TokenStream) -> TokenStream {
renderer: std::sync::Arc<brainworms_lib::rend3::Renderer>,
routines: std::sync::Arc<brainworms_lib::theater::play::backstage::plumbing::DefaultRoutines>,
rts: &brainworms_lib::tokio::runtime::Runtime,
orchestra: std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>
orchestra: std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>,
user_data: std::sync::Arc<brainworms_lib::parking_lot::Mutex<#the_user_data_struct>>
) {
self.implement(
settings,
event_loop,
renderer,
routines,
rts,
orchestra)
orchestra,
user_data)
}
fn scene_starting_cam_info(&self) -> brainworms_lib::theater::play::scene::CamInfo {
self.starting_cam_info()
Expand All @@ -70,14 +85,27 @@ pub fn derive_scenic_partial(input: TokenStream) -> TokenStream {

tokens.into()
}
#[proc_macro_derive(Choral)]
#[proc_macro_derive(Choral, attributes(user_data_struct))]
pub fn derive_choral(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = input.ident;
let the_user_data_struct: &Ident = &input
.attrs
.iter()
.find(|a| {
a.path()
.get_ident()
.is_some_and(|aa| aa == "user_data_struct")
})
.map(|aa| {
aa.parse_args()
.expect("user_data_struct attribute required")
})
.expect("user_data_struct attribute required");
let tokens = quote! {
impl brainworms_lib::theater::play::scene::chorus::Choral for #ident {
fn implement_chorus_for_choral(&self, egui_ctx: brainworms_lib::egui::Context, orchestra: std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>) {
self.implement_chorus(egui_ctx, orchestra);
impl brainworms_lib::theater::play::scene::chorus::Choral<#the_user_data_struct> for #ident {
fn implement_chorus_for_choral(&self, egui_ctx: brainworms_lib::egui::Context, orchestra: std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>,settings: &brainworms_lib::theater::basement::cla::GameProgrammeSettings, user_data: std::sync::Arc<brainworms_lib::parking_lot::Mutex<#the_user_data_struct>>) {
self.implement_chorus(egui_ctx, orchestra,settings,user_data);
}
fn chorus_uuid(&self) -> brainworms_lib::uuid::Uuid {
self.uuid
Expand All @@ -102,7 +130,7 @@ pub fn derive_choral(input: TokenStream) -> TokenStream {
}

// enum_dispatch doesn't work across crates..
#[proc_macro_derive(Playable, attributes(input_context_enum))]
#[proc_macro_derive(Playable, attributes(input_context_enum, user_data_struct))]
pub fn derive_playable(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

Expand All @@ -121,11 +149,24 @@ pub fn derive_playable(input: TokenStream) -> TokenStream {
.expect("input_context_enum attribute required")
})
.expect("input_context_enum attribute required");
let the_user_data_struct: &Ident = &input
.attrs
.iter()
.find(|a| {
a.path()
.get_ident()
.is_some_and(|aa| aa == "user_data_struct")
})
.map(|aa| {
aa.parse_args()
.expect("user_data_struct attribute required")
})
.expect("user_data_struct attribute required");
let out = match input.data {
syn::Data::Struct(_) => {
quote! {
use brainworms_lib::theater::play::scene::chorus::Choral as _;
impl brainworms_lib::theater::play::Playable<#the_input_context_enum> for #ident
impl brainworms_lib::theater::play::Playable<#the_input_context_enum, #the_user_data_struct> for #ident
{
fn playable_uuid(&self) -> brainworms_lib::uuid::Uuid {
self.chorus_uuid()
Expand Down Expand Up @@ -153,16 +194,18 @@ pub fn derive_playable(input: TokenStream) -> TokenStream {
renderer:std::sync::Arc<brainworms_lib::rend3::Renderer>,
routines:std::sync::Arc<brainworms_lib::theater::play::backstage::plumbing::DefaultRoutines>,
rts: &brainworms_lib::tokio::runtime::Runtime,
orchestra:std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>,) {
orchestra:std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>,
user_data: std::sync::Arc<brainworms_lib::parking_lot::Mutex<#the_user_data_struct>>
) {

}

fn define_playable(&mut self) {
self.define_chorus()
}

fn implement_chorus_for_playable(&self,egui_ctx:brainworms_lib::egui::Context,orchestra:std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>) {
self.implement_chorus_for_choral(egui_ctx,orchestra)
fn implement_chorus_for_playable(&self,egui_ctx:brainworms_lib::egui::Context,orchestra:std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>, settings: &brainworms_lib::theater::basement::cla::GameProgrammeSettings, user_data: std::sync::Arc<brainworms_lib::parking_lot::Mutex<#the_user_data_struct>>) {
self.implement_chorus_for_choral(egui_ctx,orchestra,settings,user_data)
}

fn handle_input_for_playable(&mut self,settings: &brainworms_lib::theater::basement::cla::GameProgrammeSettings,state: &mut brainworms_lib::GameProgrammeState<#the_input_context_enum>,window: &std::sync::Arc<brainworms_lib::winit::window::Window>,) {
Expand Down Expand Up @@ -197,14 +240,17 @@ pub fn derive_playable(input: TokenStream) -> TokenStream {
let def_pl = imp_fn("define_playable", "");
let imp_pl = imp_fn(
"implement_playable",
"settings,event_loop,renderer,routines,rts,orchestra",
"settings,event_loop,renderer,routines,rts,orchestra,user_data",
);
let imp_chr = imp_fn(
"implement_chorus_for_playable",
"egui_ctx,orchestra,settings,user_data",
);
let imp_chr = imp_fn("implement_chorus_for_playable", "egui_ctx,orchestra");
let pl_def = imp_fn("playable_definition", "");
let pl_imp = imp_fn("playable_implementation", "");
let pl_inp = imp_fn("handle_input_for_playable", "settings,state,window");
quote! {
impl brainworms_lib::theater::play::Playable<#the_input_context_enum> for #ident {
impl brainworms_lib::theater::play::Playable<#the_input_context_enum, #the_user_data_struct> for #ident {
fn playable_uuid(&self) -> brainworms_lib::uuid::Uuid {
match self {
#(#imp_pl_uuid),*
Expand All @@ -225,7 +271,9 @@ pub fn derive_playable(input: TokenStream) -> TokenStream {
renderer:std::sync::Arc<brainworms_lib::rend3::Renderer>,
routines:std::sync::Arc<brainworms_lib::theater::play::backstage::plumbing::DefaultRoutines>,
rts: &brainworms_lib::tokio::runtime::Runtime,
orchestra:std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>,) {
orchestra:std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>,
user_data: std::sync::Arc<brainworms_lib::parking_lot::Mutex<#the_user_data_struct>>
) {
match self {
#(#imp_pl),*
}
Expand All @@ -236,7 +284,7 @@ pub fn derive_playable(input: TokenStream) -> TokenStream {
#(#def_pl),*
}
}
fn implement_chorus_for_playable(&self, egui_ctx: brainworms_lib::egui::Context, orchestra: std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>) {
fn implement_chorus_for_playable(&self, egui_ctx: brainworms_lib::egui::Context, orchestra: std::sync::Arc<brainworms_lib::theater::play::orchestra::Orchestra>,settings: &brainworms_lib::theater::basement::cla::GameProgrammeSettings,user_data: std::sync::Arc<brainworms_lib::parking_lot::Mutex<#the_user_data_struct>>) {
match self {
#(#imp_chr),*
}
Expand Down
16 changes: 12 additions & 4 deletions brainworms_lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(variant_count, exact_size_is_empty, array_chunks, iter_array_chunks)]
#![allow(clippy::too_many_arguments)]
pub mod the_great_mind_palace_of_theatrical_arts;
// the reexports suck but this stays until I can focus on wrapping this

Expand All @@ -11,7 +12,8 @@ pub use glam;
use glam::{Mat3A, Vec3};
pub use log;
use log::info;
pub use parking_lot::*;
pub use parking_lot;
use parking_lot::Mutex;
pub use rend3;

pub use enum_dispatch;
Expand Down Expand Up @@ -92,12 +94,14 @@ pub struct GameProgrammeState<InputContextEnum: InputContext> {
pub orchestra: Option<Arc<Orchestra>>,
}
pub struct GameProgramme<
PlayablesEnum: Playable<InputContextEnum>,
PlayablesEnum: Playable<InputContextEnum, UserData>,
InputContextEnum: InputContext + 'static,
UserData: Default,
> {
pub data: GameProgrammeData<PlayablesEnum>,
pub state: GameProgrammeState<InputContextEnum>,
pub settings: GameProgrammeSettings,
pub user_data: Arc<Mutex<UserData>>,
pub rts: Option<tokio::runtime::Runtime>,
}
pub type MyEvent = MyWinitEvent<AstinkScene, AstinkSprite>;
Expand All @@ -111,9 +115,10 @@ pub enum MyWinitEvent<TS, TA: 'static> {
}

impl<
PlayablesEnum: Playable<InputContextEnum> + 'static,
PlayablesEnum: Playable<InputContextEnum, UserData> + 'static,
InputContextEnum: InputContext + 'static,
> GameProgramme<PlayablesEnum, InputContextEnum>
UserData: Default + 'static,
> GameProgramme<PlayablesEnum, InputContextEnum, UserData>
{
pub async fn async_start(mut self, window_builder: WindowBuilder) {
let iad = self.create_iad().await.unwrap();
Expand Down Expand Up @@ -299,6 +304,8 @@ impl<
current_scene.implement_chorus_for_playable(
egui_ctx.clone(),
game_state.orchestra.as_ref().unwrap().clone(),
&self.settings,
self.user_data.clone(),
);
egui::Window::new("FPS").show(&egui_ctx, |ui| {
ui.label(std::format!(
Expand Down Expand Up @@ -633,6 +640,7 @@ impl<
playable_routines_copy,
self.rts.as_ref().unwrap(),
self.state.orchestra.as_ref().unwrap().clone(),
self.user_data.clone(),
);

let skybox_renderer_copy = Arc::clone(&renderer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{collections::HashMap, sync::Arc};
use brainworms_arson::egui;
use egui::Context;
use enum_dispatch::enum_dispatch;
use parking_lot::Mutex;
use rend3::Renderer;
use tokio::runtime::Runtime;
use uuid::Uuid;
Expand Down Expand Up @@ -31,7 +32,7 @@ pub struct Play<PlayablesEnum> {
}

#[enum_dispatch]
pub trait Playable<InputContextEnum: InputContext> {
pub trait Playable<InputContextEnum: InputContext, UserData> {
fn playable_uuid(&self) -> Uuid;
fn playable_name(&self) -> &str;
fn playable_definition(&mut self) -> &mut Definitions;
Expand All @@ -45,9 +46,16 @@ pub trait Playable<InputContextEnum: InputContext> {
routines: Arc<DefaultRoutines>,
rts: &Runtime,
orchestra: Arc<Orchestra>,
user_data: Arc<Mutex<UserData>>,
);
fn define_playable(&mut self);
fn implement_chorus_for_playable(&self, egui_ctx: Context, orchestra: Arc<Orchestra>);
fn implement_chorus_for_playable(
&self,
egui_ctx: Context,
orchestra: Arc<Orchestra>,
settings: &GameProgrammeSettings,
user_data: Arc<Mutex<UserData>>,
);
// fn get_current_input_context(&self) -> &InputContext<TO>;
fn handle_input_for_playable(
&mut self,
Expand Down Expand Up @@ -78,8 +86,9 @@ pub enum Implementations {

impl<
InputContextEnum: InputContext,
T: Scenic + Choral + HandlesInputContexts<InputContextEnum>,
> Playable<InputContextEnum> for T
T: Scenic<UserData> + Choral<UserData> + HandlesInputContexts<InputContextEnum>,
UserData: Default,
> Playable<InputContextEnum, UserData> for T
{
fn playable_uuid(&self) -> Uuid {
self.scene_uuid()
Expand All @@ -101,15 +110,24 @@ impl<
routines: Arc<DefaultRoutines>,
rts: &Runtime,
orchestra: Arc<Orchestra>,
user_data: Arc<Mutex<UserData>>,
) {
self.implement_scene(settings, event_loop, renderer, routines, rts, orchestra)
self.implement_scene(
settings, event_loop, renderer, routines, rts, orchestra, user_data,
)
}

fn define_playable(&mut self) {
self.define_scene()
}
fn implement_chorus_for_playable(&self, egui_ctx: Context, orchestra: Arc<Orchestra>) {
self.implement_chorus_for_choral(egui_ctx, orchestra);
fn implement_chorus_for_playable(
&self,
egui_ctx: Context,
orchestra: Arc<Orchestra>,
settings: &GameProgrammeSettings,
user_data: Arc<Mutex<UserData>>,
) {
self.implement_chorus_for_choral(egui_ctx, orchestra, settings, user_data);
}

fn playable_definition(&mut self) -> &mut Definitions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ pub(crate) struct StoredSurfaceInfo {
pub(crate) present_mode: PresentMode,
}

impl<PlayablesEnum: Playable<InputContextEnum> + 'static, InputContextEnum: InputContext>
GameProgramme<PlayablesEnum, InputContextEnum>
impl<
PlayablesEnum: Playable<InputContextEnum, UserData> + 'static,
InputContextEnum: InputContext,
UserData: Default + 'static,
> GameProgramme<PlayablesEnum, InputContextEnum, UserData>
{
pub fn start(self, window_builder: WindowBuilder) {
{
Expand All @@ -65,6 +68,7 @@ impl<PlayablesEnum: Playable<InputContextEnum> + 'static, InputContextEnum: Inpu
settings: GameProgrammeSettings::new(),
rts: tokio::runtime::Builder::new_multi_thread().build().ok(),
state: GameProgrammeState::default(),
user_data: Arc::new(Mutex::new(UserData::default())),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub struct SceneImplementation {
pub cameras: HashMap<String, Camera>,
// script: String, // I'm really kinda stuck on this chicken and egg problem with script <-> actual game logic
}
pub trait Scenic {
pub trait Scenic<UserData> {
fn scene_uuid(&self) -> Uuid;
fn scene_name(&self) -> &str;
fn define_scene(&mut self);
Expand All @@ -103,6 +103,7 @@ pub trait Scenic {
routines: Arc<DefaultRoutines>,
rts: &Runtime,
orchestra: Arc<Orchestra>,
user_data: Arc<Mutex<UserData>>,
);
fn scene_starting_cam_info(&self) -> CamInfo;
fn raw_definition(&mut self) -> &mut Definitions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@ use std::sync::Arc;

use brainworms_arson::egui;
use egui::Context;
use parking_lot::Mutex;
use uuid::Uuid;

use crate::theater::play::{orchestra::Orchestra, Definitions, Implementations};
use crate::theater::{
basement::cla::GameProgrammeSettings,
play::{orchestra::Orchestra, Definitions, Implementations},
};

pub trait Choral {
fn implement_chorus_for_choral(&self, egui_ctx: Context, orchestra: Arc<Orchestra>);
pub trait Choral<UserData> {
fn implement_chorus_for_choral(
&self,
egui_ctx: Context,
orchestra: Arc<Orchestra>,
settings: &GameProgrammeSettings,
user_data: Arc<Mutex<UserData>>,
);
fn chorus_uuid(&self) -> Uuid;
fn chorus_name(&self) -> &str;
fn chorus_definition(&mut self) -> &mut Definitions;
Expand Down
4 changes: 3 additions & 1 deletion src/brainworms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ use bl::{
use brainworms_lib as bl;
use curtain::Curtain;
use linac_lab::{LinacLabIC, LinacLabScene};

#[derive(Default, Debug)]
pub struct BrainwormsData;
#[bl::enum_dispatch::enum_dispatch(Playable)] // this doesnt work across crates but it does generate at least the from and into stuff
#[derive(Playable)]
#[input_context_enum(MyInputContexts)]
#[user_data_struct(BrainwormsData)]
pub enum MyPlayables {
LinacLabScene(LinacLabScene),
Curtain(Curtain), // loading screens and menus
Expand Down
Loading

0 comments on commit 489d54d

Please sign in to comment.