lyra-engine/lyra-scripting/src/lib.rs

150 lines
4.1 KiB
Rust
Raw Normal View History

2024-01-05 01:52:47 +00:00
#[cfg(feature = "lua")]
pub mod lua;
pub mod world;
use std::any::TypeId;
use lyra_ecs::{Component, ResourceObject};
2024-01-05 01:52:47 +00:00
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 :(
2024-01-05 01:52:47 +00:00
#[allow(unused_imports)]
pub(crate) mod lyra_engine {
pub use lyra_ecs as ecs;
pub use lyra_reflect as reflect;
2024-01-05 01:52:47 +00:00
}
use lyra_reflect::{ReflectedComponent, Reflect, FromType, ReflectedResource};
2024-01-05 01:52:47 +00:00
#[derive(Clone)]
pub enum ReflectBranch {
Component(ReflectedComponent),
Resource(ReflectedResource),
2024-01-05 01:52:47 +00:00
}
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`")
2024-01-05 01:52:47 +00:00
}
}
/// Returns a boolean indicating if `self` is a reflection of a Component.
2024-01-05 01:52:47 +00:00
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,
}
}
2024-01-05 01:52:47 +00:00
}
pub struct ScriptBorrow {
pub(crate) reflect_branch: ReflectBranch,
pub(crate) data: Option<Box<dyn Reflect>>,
2024-01-05 01:52:47 +00:00
}
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<T>(data: Option<T>) -> Self
where
T: Reflect + Component + 'static
{
let data = data.map(|d| Box::new(d) as Box<(dyn Reflect + 'static)>);
Self {
reflect_branch: ReflectBranch::Component(<ReflectedComponent as FromType<T>>::from_type()),
data,
}
}
/// Creates a ScriptBorrow from a Resource.
pub fn from_resource<T>(data: Option<T>) -> Self
where
T: Reflect + ResourceObject + 'static
{
let data = data.map(|d| Box::new(d) as Box<(dyn Reflect + 'static)>);
Self {
reflect_branch: ReflectBranch::Resource(<ReflectedResource as FromType<T>>::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<T, P>(&mut self, provider: P)
where
T: ScriptHost,
P: ScriptApiProvider<ScriptContext = T::ScriptContext> + 'static;
}
impl GameScriptExt for Game {
fn add_script_api_provider<T, P>(&mut self, mut provider: P)
where
T: ScriptHost,
P: ScriptApiProvider<ScriptContext = T::ScriptContext> + 'static
{
let world = self.world_mut();
provider.prepare_world(world);
let mut providers = world.get_resource_mut::<ScriptApiProviders<T>>();
providers.add_provider(provider);
}
2024-01-05 01:52:47 +00:00
}