diff options
-rw-r--r-- | Cargo.toml | 14 | ||||
-rw-r--r-- | src/lib.rs | 9 | ||||
-rw-r--r-- | src/lua_api.rs | 227 |
3 files changed, 138 insertions, 112 deletions
@@ -5,14 +5,14 @@ edition = "2021" [dependencies] async-channel = "2.3" -notify = "7.0" +notify = "8.0" tar = "0.4" xz2 = "0.1" rust-crypto = "0.2" multi_key_map = "0.3" serde = "1.0" rmp-serde = "1.3" -notify-debouncer-full = "0.4" +notify-debouncer-full = "0.5" md5 = "0.7" aes = "0.8" hex = "0.4" @@ -30,7 +30,7 @@ version = "0.2" features = ["serialize"] [dependencies.occule] -git = "https://git.exvacuum.dev/occule" +git = "https://git.soaos.dev/occule" tag = "v0.3.1" [dependencies.yarnspinner] @@ -39,15 +39,15 @@ optional = true features = ["serde"] [dependencies.bevy_mod_scripting] -version = "0.8" -features = ["lua54", "lua_script_api"] +version = "0.9" +features = ["lua54", "bevy_bindings"] [dependencies.bevy_basic_interaction] -git = "https://git.exvacuum.dev/bevy_basic_interaction" +git = "https://git.soaos.dev/bevy_basic_interaction" tag = "v0.2.0" [dependencies.strum] -version = "0.26" +version = "0.27" features = ["derive"] [features] @@ -6,8 +6,8 @@ use std::{ffi::OsStr, path::PathBuf}; use actor::ActorPlugin; use bevy::{ecs::system::IntoObserverSystem, prelude::*}; -use bevy_mod_scripting::core::{AddScriptApiProvider, AddScriptHost, AddScriptHostHandler, ScriptingPlugin}; -use bevy_mod_scripting::lua::LuaScriptHost; +use bevy_mod_scripting::core::ScriptingPlugin; +use bevy_mod_scripting::lua::LuaScriptingPlugin; use cache::DirworldCache; use events::{DirworldChangeRoot, DirworldEnterRoom, DirworldLeaveRoom, DirworldNavigationComplete, DirworldSpawn}; use occule::Codec; @@ -69,7 +69,7 @@ impl Plugin for DirworldPlugin { custom_function_registration: Some(yarnspinner_api::setup_yarnspinner_functions), }, DirworldPreloadPlugin, - ScriptingPlugin, + LuaScriptingPlugin::default(), )) .add_systems(Startup, watcher::setup) .add_systems( @@ -80,9 +80,6 @@ impl Plugin for DirworldPlugin { yarnspinner_api::process_commands, ), ) - .add_script_host::<LuaScriptHost<()>>(PostUpdate) - .add_script_handler::<LuaScriptHost<()>, 0, 0>(PostUpdate) - .add_api_provider::<LuaScriptHost<()>>(Box::new(lua_api::ConditionalAPI)) .add_systems(PostUpdate, watcher::update) .init_resource::<DirworldRootDir>() .init_resource::<DirworldCache>() diff --git a/src/lua_api.rs b/src/lua_api.rs index 53252a5..88d7193 100644 --- a/src/lua_api.rs +++ b/src/lua_api.rs @@ -1,37 +1,40 @@ -use std::{str::FromStr, sync::Mutex}; +use std::str::FromStr; use bevy::prelude::*; -use bevy_mod_scripting::api::providers::bevy_reflect::LuaVec3; -use bevy_mod_scripting::{api::providers::bevy_ecs::LuaEntity, lua::tealr::mlu::mlua::Error as LuaError}; -use bevy_mod_scripting::lua::LuaEvent; -use bevy_mod_scripting::prelude::*; +use bevy_mod_scripting::core::{ + bindings::function::{ + from::Val, + namespace::{GlobalNamespace, NamespaceBuilder}, + script_function::FunctionCallContext, + }, + callback_labels, + error::InteropError, + event::ScriptCallbackEvent, +}; use uuid::Uuid; use crate::{components::DirworldEntity, conditionals::Condition}; -pub fn trigger_update(mut w: PriorityEventWriter<LuaEvent<()>>) { - let event = LuaEvent::<()> { - args: (), - hook_name: "on_update".into(), - recipients: Recipients::All, - }; - w.send(event, 0); +callback_labels!(OnUpdate => "on_update"); + +pub fn trigger_update(mut w: EventWriter<ScriptCallbackEvent>) { + w.send(ScriptCallbackEvent::new_for_all(OnUpdate, vec![])); } // ACTUAL API STUFF BELOW THIS POINT {{{ macro_rules! register_fns { - ($runtime:expr, $($function:expr),+) => { + ($world:expr, $($function:expr),+) => { { - let ctx = $runtime.get_mut().unwrap(); - $(ctx.globals().set(stringify!($function).to_string(), ctx.create_function($function).unwrap()).unwrap();)+ + NamespaceBuilder::<GlobalNamespace>::new_unregistered($world) + $(.register(stringify!($function), $function))+; } }; } -pub fn register(api: &mut Mutex<Lua>) { +pub fn register(world: &mut World) { register_fns!( - api, + world, translate, rotate, get_dirworld_id, @@ -45,65 +48,57 @@ pub fn register(api: &mut Mutex<Lua>) { ) } -fn translate(ctx: &Lua, (entity, translation): (LuaEntity, LuaVec3)) -> Result<(), LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); - if let Some(mut transform) = world.entity_mut(entity.inner().unwrap()).get_mut::<Transform>() { - transform.translation += translation.inner().unwrap(); - } - Ok(()) +fn translate(ctx: FunctionCallContext, entity: Val<Entity>, translation: Val<Vec3>) { + let world = ctx.world().unwrap(); + world.with_global_access(|world| { + if let Some(mut transform) = world.entity_mut(*entity).get_mut::<Transform>() { + transform.translation += *translation; + } + }); } -fn rotate(ctx: &Lua, (entity, axis, angle): (LuaEntity, LuaVec3, f32)) -> Result<(), LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); - if let Some(mut transform) = world.entity_mut(entity.inner().unwrap()).get_mut::<Transform>() { - transform.rotation *= Quat::from_axis_angle(axis.inner().unwrap(), angle); - } - Ok(()) +fn rotate(ctx: FunctionCallContext, entity: Val<Entity>, axis: Val<Vec3>, angle: f32) { + let world = ctx.world().unwrap(); + world.with_global_access(|world| { + if let Some(mut transform) = world.entity_mut(*entity).get_mut::<Transform>() { + transform.rotation *= Quat::from_axis_angle(*axis, angle); + } + }); } -fn get_dirworld_id(ctx: &Lua, (entity,): (LuaEntity,)) -> Result<String, LuaError> { - let world = ctx.get_world()?; - let world = world.read(); - if let Some(dirworld_entity) = world.entity(entity.inner().unwrap()).get::<DirworldEntity>() { - dirworld_entity.payload.as_ref().map(|p| p.id.to_string()).ok_or(LuaError::runtime("Failed to get entity id from payload")) - } else { - Err(LuaError::runtime("Entity missing DirworldEntity component")) - } +fn get_dirworld_id(ctx: FunctionCallContext, entity: Val<Entity>) -> Result<String, InteropError> { + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = if let Some(dirworld_entity) = world.entity(*entity).get::<DirworldEntity>() { + Ok(dirworld_entity + .payload + .as_ref() + .map(|p| p.id.to_string()) + .unwrap()) + } else { + Err(InteropError::missing_entity(*entity)) + }; + }); + result } // Conditionals -pub struct ConditionalAPI; - -impl APIProvider for ConditionalAPI { - type APITarget = Mutex<Lua>; - - type ScriptContext = Mutex<Lua>; - - type DocTarget = LuaDocFragment; - - fn attach_api( - &mut self, - api: &mut Self::APITarget, - ) -> Result<(), bevy_mod_scripting::prelude::ScriptError> { - register(api); - Ok(()) - } +fn condition_true(ctx: FunctionCallContext) -> Result<bool, InteropError> { + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = Ok(Condition::True.evaluate(world)); + }); + result } - - -fn condition_true(ctx: &Lua, _: ()) -> Result<bool, LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); - Ok(Condition::True.evaluate(&mut world)) -} - -fn condition_ancestor_of(ctx: &Lua, (ancestor, descendant): (String, String)) -> Result<bool, LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); +fn condition_ancestor_of( + ctx: FunctionCallContext, + ancestor: String, + descendant: String, +) -> Result<bool, InteropError> { let Ok(ancestor) = Uuid::from_str(&ancestor) else { warn!("Provided ancestor is not a valid UUID"); return Ok(false); @@ -112,15 +107,23 @@ fn condition_ancestor_of(ctx: &Lua, (ancestor, descendant): (String, String)) -> warn!("Provided descendant is not a valid UUID"); return Ok(false); }; - Ok(Condition::AncestorOf { - ancestor, - descendant, - }.evaluate(&mut world)) + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = Ok(Condition::AncestorOf { + ancestor, + descendant, + } + .evaluate(world)); + }); + result } -fn condition_descendant_of(ctx: &Lua, (descendant, ancestor): (String, String)) -> Result<bool, LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); +fn condition_descendant_of( + ctx: FunctionCallContext, + descendant: String, + ancestor: String, +) -> Result<bool, InteropError> { let Ok(ancestor) = Uuid::from_str(&ancestor) else { warn!("Provided ancestor is not a valid UUID"); return Ok(false); @@ -129,15 +132,23 @@ fn condition_descendant_of(ctx: &Lua, (descendant, ancestor): (String, String)) warn!("Provided descendant is not a valid UUID"); return Ok(false); }; - Ok(Condition::DescendantOf { - ancestor, - descendant, - }.evaluate(&mut world)) + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = Ok(Condition::DescendantOf { + ancestor, + descendant, + } + .evaluate(world)); + }); + result } -fn condition_parent_of(ctx: &Lua, (parent, child): (String, String)) -> Result<bool, LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); +fn condition_parent_of( + ctx: FunctionCallContext, + parent: String, + child: String, +) -> Result<bool, InteropError> { let Ok(parent) = Uuid::from_str(&parent) else { warn!("Provided ancestor is not a valid UUID"); return Ok(false); @@ -146,15 +157,19 @@ fn condition_parent_of(ctx: &Lua, (parent, child): (String, String)) -> Result<b warn!("Provided descendant is not a valid UUID"); return Ok(false); }; - Ok(Condition::ParentOf { - parent, - child, - }.evaluate(&mut world)) + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = Ok(Condition::ParentOf { parent, child }.evaluate(world)); + }); + result } -fn condition_child_of(ctx: &Lua, (child, parent): (String, String)) -> Result<bool, LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); +fn condition_child_of( + ctx: FunctionCallContext, + child: String, + parent: String, +) -> Result<bool, InteropError> { let Ok(parent) = Uuid::from_str(&parent) else { warn!("Provided ancestor is not a valid UUID"); return Ok(false); @@ -163,30 +178,44 @@ fn condition_child_of(ctx: &Lua, (child, parent): (String, String)) -> Result<bo warn!("Provided descendant is not a valid UUID"); return Ok(false); }; - Ok(Condition::ChildOf { - parent, - child, - }.evaluate(&mut world)) + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = Ok(Condition::ChildOf { parent, child }.evaluate(world)); + }); + result } -fn condition_in_room(ctx: &Lua, (room,): (String,)) -> Result<bool, LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); +fn condition_in_room( + ctx: FunctionCallContext, + room: String, +) -> Result<bool, InteropError> { let Ok(room) = Uuid::from_str(&room) else { warn!("Provided room is not a valid UUID"); return Ok(false); }; - Ok(Condition::InRoom(room).evaluate(&mut world)) + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = Ok(Condition::InRoom(room).evaluate(world)); + }); + result } -fn condition_object_in_room(ctx: &Lua, (object,): (String,)) -> Result<bool, LuaError> { - let world = ctx.get_world()?; - let mut world = world.write(); +fn condition_object_in_room( + ctx: FunctionCallContext, + object: String +) -> Result<bool, InteropError> { let Ok(object) = Uuid::from_str(&object) else { warn!("Provided object is not a valid UUID"); return Ok(false); }; - Ok(Condition::ObjectInRoom(object).evaluate(&mut world)) + let world = ctx.world()?; + let mut result = Ok(Default::default()); + world.with_global_access(|world| { + result = Ok(Condition::ObjectInRoom(object).evaluate(world)); + }); + result } // }}} |