use crate::{
ComponentManager, FrameManager, Gpu, GpuDefaults, Input, Scene, SceneManager, ScreenConfig,
Shura, StateManager, Vector, WorldCamera,
};
#[cfg(feature = "serde")]
use crate::{ComponentTypeId, SceneSerializer, SerializedComponentStorage, StateTypeId};
#[cfg(feature = "serde")]
use rustc_hash::FxHashMap;
#[cfg(feature = "audio")]
use crate::audio::AudioManager;
#[cfg(feature = "physics")]
use crate::physics::World;
#[cfg(feature = "gui")]
use crate::gui::Gui;
pub struct Context<'a> {
pub scene_id: &'a u32,
pub scene_resized: &'a bool,
pub scene_switched: &'a bool,
pub scene_started: &'a bool,
pub render_components: &'a mut bool,
pub screen_config: &'a mut ScreenConfig,
pub scene_states: &'a mut StateManager,
pub world_camera: &'a mut WorldCamera,
pub components: &'a mut ComponentManager,
#[cfg(feature = "physics")]
pub world: &'a mut World,
pub frame: &'a FrameManager,
pub defaults: &'a GpuDefaults,
pub input: &'a Input,
pub gpu: &'a Gpu,
pub end: &'a mut bool,
pub scenes: &'a mut SceneManager,
pub window: &'a mut winit::window::Window,
pub global_states: &'a mut StateManager,
#[cfg(feature = "gui")]
pub gui: &'a mut Gui,
#[cfg(feature = "audio")]
pub audio: &'a mut AudioManager,
pub window_size: Vector<u32>,
}
impl<'a> Context<'a> {
pub(crate) fn new(shura: &'a mut Shura, scene: &'a mut Scene) -> Context<'a> {
let mint: mint::Vector2<u32> = shura.window.inner_size().into();
let window_size = mint.into();
Self {
scene_id: &scene.id,
scene_resized: &scene.resized,
scene_started: &scene.started,
scene_switched: &scene.switched,
render_components: &mut scene.render_components,
screen_config: &mut scene.screen_config,
world_camera: &mut scene.world_camera,
components: &mut scene.components,
scene_states: &mut scene.states,
#[cfg(feature = "physics")]
world: &mut scene.world,
frame: &shura.frame,
defaults: &shura.defaults,
input: &shura.input,
gpu: &shura.gpu,
end: &mut shura.end,
scenes: &mut shura.scenes,
window: &mut shura.window,
global_states: &mut shura.states,
#[cfg(feature = "gui")]
gui: &mut shura.gui,
#[cfg(feature = "audio")]
audio: &mut shura.audio,
window_size,
}
}
#[cfg(feature = "serde")]
pub fn serialize_scene(
&mut self,
mut serialize: impl FnMut(&mut SceneSerializer),
) -> Result<Vec<u8>, Box<bincode::ErrorKind>> {
let components = &self.components;
let mut serializer =
SceneSerializer::new(components, &self.global_states, &self.scene_states);
(serialize)(&mut serializer);
#[derive(serde::Serialize)]
struct Scene<'a> {
id: u32,
resized: bool,
switched: bool,
started: bool,
render_components: bool,
screen_config: &'a ScreenConfig,
world_camera: &'a WorldCamera,
components: &'a ComponentManager,
#[cfg(feature = "physics")]
world: &'a World,
}
#[cfg(feature = "physics")]
{
use crate::physics::WorldChanges;
let (ser_components, ser_scene_state, ser_global_state) = serializer.finish();
let mut world_cpy = self.world.clone();
let mut changes = WorldChanges::default();
for (_, ty) in self.components.types() {
if !ser_components.contains_key(&ty.component_type_id()) {
match &ty.storage {
crate::ComponentTypeStorage::Single { component, .. } => {
if let Some(component) = component {
changes.register_remove(component);
}
}
crate::ComponentTypeStorage::Multiple(multiple) => {
for (_, component) in &multiple.components {
changes.register_remove(component);
}
}
crate::ComponentTypeStorage::MultipleGroups(groups) => {
for (_, group) in groups {
for (_, component) in &group.components {
changes.register_remove(component);
}
}
}
}
}
}
changes.apply(&mut world_cpy);
let scene = Scene {
id: *self.scene_id,
resized: true,
switched: true,
started: true,
render_components: *self.render_components,
screen_config: self.screen_config,
world_camera: self.world_camera,
components: self.components,
world: &world_cpy,
};
let scene: (
&Scene,
FxHashMap<ComponentTypeId, SerializedComponentStorage>,
FxHashMap<StateTypeId, Vec<u8>>,
FxHashMap<StateTypeId, Vec<u8>>,
) = (&scene, ser_components, ser_scene_state, ser_global_state);
let result = bincode::serialize(&scene);
return result;
}
#[cfg(not(feature = "physics"))]
{
let (ser_components, ser_scene_state, ser_global_state) = serializer.finish();
let scene = Scene {
id: *self.scene_id,
resized: true,
switched: true,
started: true,
screen_config: self.screen_config,
world_camera: self.world_camera,
components: self.components,
render_components: *self.render_components,
};
let scene: (
&Scene,
FxHashMap<ComponentTypeId, SerializedComponentStorage>,
FxHashMap<StateTypeId, Vec<u8>>,
FxHashMap<StateTypeId, Vec<u8>>,
) = (&scene, ser_components, ser_scene_state, ser_global_state);
let result = bincode::serialize(&scene);
return result;
}
}
}