aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs109
1 files changed, 62 insertions, 47 deletions
diff --git a/src/lib.rs b/src/lib.rs
index e6a5f25..7d0749a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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();