#[cfg(feature = "lua")] pub mod lua; pub mod world; use std::any::TypeId; use lyra_ecs::{Component, ResourceObject}; pub use world::*; pub mod wrap; pub use wrap::*; pub mod host; pub use host::*; pub mod script; pub use script::*; use lyra_game::game::Game; // required for some proc macros :( #[allow(unused_imports)] pub(crate) mod lyra_engine { pub use lyra_ecs as ecs; pub use lyra_reflect as reflect; } use lyra_reflect::{ReflectedComponent, Reflect, FromType, ReflectedResource}; #[derive(Clone)] pub enum ReflectBranch { Component(ReflectedComponent), Resource(ReflectedResource), } impl ReflectBranch { /// Gets self as a [`ReflectedComponent`]. /// /// # Panics /// If `self` is not a variant of [`ReflectBranch::Component`]. pub fn as_component_unchecked(&self) -> &ReflectedComponent { match self { ReflectBranch::Component(c) => c, _ => panic!("`self` is not an instance of `ReflectBranch::Component`") } } /// Returns a boolean indicating if `self` is a reflection of a Component. pub fn is_component(&self) -> bool { matches!(self, ReflectBranch::Component(_)) } /// Gets self as a [`ReflectedResource`]. /// /// # Panics /// If `self` is not a variant of [`ReflectBranch::Resource`]. pub fn as_resource_unchecked(&self) -> &ReflectedResource { match self { ReflectBranch::Resource(v) => v, _ => panic!("`self` is not an instance of `ReflectBranch::Component`") } } /// Gets self as a [`ReflectedResource`], returning `None` if self is not an instance of it. pub fn as_resource(&self) -> Option<&ReflectedResource> { match self { ReflectBranch::Resource(v) => Some(v), _ => None } } /// Returns a boolean indicating if `self` is a reflection of a Resource. pub fn is_resource(&self) -> bool { matches!(self, ReflectBranch::Resource(_)) } /// Returns the type id of the reflected thing pub fn reflect_type_id(&self) -> TypeId { match self { ReflectBranch::Component(c) => c.type_id, ReflectBranch::Resource(r) => r.type_id, } } } pub struct ScriptBorrow { pub(crate) reflect_branch: ReflectBranch, pub(crate) data: Option>, } impl Clone for ScriptBorrow { fn clone(&self) -> Self { let data = self.data.as_ref().map(|b| b.clone_inner()); Self { reflect_branch: self.reflect_branch.clone(), data, } } } impl ScriptBorrow { /// Creates a ScriptBorrow from a Component pub fn from_component(data: Option) -> Self where T: Reflect + Component + 'static { let data = data.map(|d| Box::new(d) as Box<(dyn Reflect + 'static)>); Self { reflect_branch: ReflectBranch::Component(>::from_type()), data, } } /// Creates a ScriptBorrow from a Resource. pub fn from_resource(data: Option) -> Self where T: Reflect + ResourceObject + 'static { let data = data.map(|d| Box::new(d) as Box<(dyn Reflect + 'static)>); Self { reflect_branch: ReflectBranch::Resource(>::from_type()), data, } } } /// An extension trait that adds some helpful methods that makes it easier to do scripting things pub trait GameScriptExt { /// A helper method for adding a ScriptApiProvider into the world. fn add_script_api_provider(&mut self, provider: P) where T: ScriptHost, P: ScriptApiProvider + 'static; } impl GameScriptExt for Game { fn add_script_api_provider(&mut self, mut provider: P) where T: ScriptHost, P: ScriptApiProvider + 'static { let world = self.world_mut(); provider.prepare_world(world); let mut providers = world.get_resource_mut::>(); providers.add_provider(provider); } }