diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 109 |
1 files changed, 62 insertions, 47 deletions
@@ -1,26 +1,23 @@ -// #![warn(missing_docs)] +#![warn(missing_docs)] //! Plugin for bevy engine enabling interaction with and representation of the file system in the world. use std::{ffi::OsStr, path::PathBuf}; use actor::ActorPlugin; -use bevy::render::mesh::ExtrusionBuilder; use bevy::{ecs::system::IntoObserverSystem, prelude::*}; -use bevy_scriptum::{runtimes::lua::LuaRuntime, BuildScriptingRuntime, ScriptingRuntimeBuilder}; -use events::{ - DirworldChangeRoot, DirworldEnterRoom, DirworldLeaveRoom, DirworldNavigationEvent, - DirworldSpawn, -}; +use bevy_mod_scripting::core::{AddScriptApiProvider, AddScriptHost, AddScriptHostHandler, ScriptingPlugin}; +use bevy_mod_scripting::lua::LuaScriptHost; +use cache::DirworldCache; +use events::{DirworldChangeRoot, DirworldEnterRoom, DirworldLeaveRoom, DirworldSpawn}; use occule::Codec; -use resources::DirworldCache; +use preload::{DirworldPreload, DirworldPreloadPlugin}; +use resources::EntryType; use resources::{ DirworldCodecs, DirworldCurrentDir, DirworldObservers, DirworldRootDir, DirworldTasks, - EntryType, }; pub use watcher::DirworldWatcherEvent; pub use watcher::DirworldWatcherSet; -use yarnspinner::core::Library; /// Components used by this plugin pub mod components; @@ -31,15 +28,10 @@ pub mod events; /// Resources used by this plugin pub mod resources; -mod watcher; - /// Commands for this plugin pub mod commands; -mod systems; - -mod observers; - +/// Utility functions pub mod utils; /// Payload for dirworld entities @@ -48,27 +40,37 @@ pub mod payload; /// Actor component pub mod actor; +/// System for dirworld-related condition checking +pub mod conditionals; + +/// Room/asset preloading +pub mod preload; + +mod cache; + +mod yarnspinner_api; + mod lua_api; -pub mod conditionals; +mod systems; -pub mod yarnspinner_api; +mod observers; -pub mod room_generation; +mod watcher; /// Plugin which enables high-level interaction #[derive(Default)] -pub struct DirworldPlugin { - pub register_custom_lua_api: - Option<Box<dyn Fn(ScriptingRuntimeBuilder<LuaRuntime>) + Send + Sync>>, -} +pub struct DirworldPlugin; impl Plugin for DirworldPlugin { fn build(&self, app: &mut App) { - info!("building"); - app.add_plugins(ActorPlugin { - custom_function_registration: Some(yarnspinner_api::setup_yarnspinner_functions), - }) + app.add_plugins(( + ActorPlugin { + custom_function_registration: Some(yarnspinner_api::setup_yarnspinner_functions), + }, + DirworldPreloadPlugin, + ScriptingPlugin, + )) .add_systems(Startup, watcher::setup) .add_systems( Update, @@ -78,18 +80,12 @@ impl Plugin for DirworldPlugin { yarnspinner_api::process_commands, ), ) - .add_systems( - PostUpdate, - watcher::update, - ) - .add_scripting::<LuaRuntime>(|runtime| { - let runtime = lua_api::register(runtime); - if let Some(register_custom) = &self.register_custom_lua_api { - (register_custom)(runtime); - } - }) - .init_resource::<DirworldCache>() + .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>() .init_resource::<DirworldCurrentDir>() .init_resource::<DirworldTasks>() .init_resource::<DirworldObservers>() @@ -98,18 +94,22 @@ impl Plugin for DirworldPlugin { .add_event::<DirworldLeaveRoom>() .add_event::<DirworldChangeRoot>() .add_event::<DirworldWatcherEvent>() - .observe(observers::navigate_to_room) - .observe(observers::handle_changes) - .observe(observers::change_root) - .observe(observers::navigate_from_room); + .add_observer(observers::navigate_to_room) + .add_observer(observers::handle_changes) + .add_observer(observers::change_root) + .add_observer(observers::navigate_from_room); } } +/// Extension trait for working with multiple file extensions on paths pub trait Extensions { + /// Get all the extensions on this path if applicable fn extensions(&self) -> Option<String>; + /// Gets the file stem (without any extensions) of this path if applicable fn file_stem_no_extensions(&self) -> Option<String>; + /// Gets the path with any extensions removed fn no_extensions(&self) -> PathBuf; } @@ -148,13 +148,20 @@ impl Extensions for PathBuf { } } +/// Extension trait providing functions for registering callbacks and codecs for filesystem entries pub trait DirworldApp { - fn register_dirworld_entry_callback<B: Bundle, M>( + /// Register callbacks to be executed when a file with given [`EntryType`]s is loaded. The + /// `preload_callback` parameter controls loading assets and is called before spawning any + /// entities in the room, and the `spawn_callback` handles initializing the spawned entities. + fn register_dirworld_entry_callbacks<B: Bundle, M, PB: Bundle, PM>( &mut self, extensions: Vec<EntryType>, - observer: impl IntoObserverSystem<DirworldSpawn, B, M>, + preload_callback: Option<impl IntoObserverSystem<DirworldPreload, PB, PM>>, + spawn_callback: impl IntoObserverSystem<DirworldSpawn, B, M>, ) -> &mut Self; + /// Register a [`Codec`] to be used to extract [`crate::payload::DirworldEntityPayload`]s from + /// files with matching extensions. fn register_dirworld_entry_codec<C: Codec + Send + Sync + 'static>( &mut self, extensions: Vec<String>, @@ -163,10 +170,11 @@ pub trait DirworldApp { } impl DirworldApp for App { - fn register_dirworld_entry_callback<B: Bundle, M>( + fn register_dirworld_entry_callbacks<B: Bundle, M, PB: Bundle, PM>( &mut self, extensions: Vec<EntryType>, - observer: impl IntoObserverSystem<DirworldSpawn, B, M>, + preload_callback: Option<impl IntoObserverSystem<DirworldPreload, PB, PM>>, + spawn_observer: impl IntoObserverSystem<DirworldSpawn, B, M>, ) -> &mut Self { let world = self.world_mut(); let observer_entity_id; @@ -174,7 +182,14 @@ impl DirworldApp for App { { let mut observer_entity = world.spawn_empty(); observer_entity_id = observer_entity.id(); - observer_entity.insert(Observer::new(observer).with_entity(observer_entity_id)); + if let Some(preload_callback) = preload_callback { + observer_entity.with_children(|parent| { + parent.spawn(Observer::new(preload_callback).with_entity(observer_entity_id)); + }); + } + observer_entity.with_children(|parent| { + parent.spawn(Observer::new(spawn_observer).with_entity(observer_entity_id)); + }); } world.flush(); |