aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authorLibravatar Silas Bartha <silas@exvacuum.dev>2024-10-11 16:02:07 -0400
committerLibravatar Silas Bartha <silas@exvacuum.dev>2024-10-11 16:02:07 -0400
commit16c1574e400d73198713336e18975ff37ab78290 (patch)
treedb370db8e0caea99a9e6e3c501c7ea7e3b6dd708 /src/lib.rs
parent462d6c5aaa2281bf875e04d5e2c3241a13256836 (diff)
Way too many changes (0.2)
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs158
1 files changed, 144 insertions, 14 deletions
diff --git a/src/lib.rs b/src/lib.rs
index f4bd783..2bfbc57 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,12 +1,19 @@
-#![warn(missing_docs)]
+// #![warn(missing_docs)]
//! Plugin for bevy engine enabling interaction with and representation of the file system in the world.
-use std::path::PathBuf;
+use std::{ffi::OsStr, path::PathBuf};
-use bevy::{asset::io::AssetSource, prelude::*};
-use events::DirworldNavigationEvent;
-use resources::{Dirworld, DirworldConfig};
+use bevy::{ecs::system::IntoObserverSystem, prelude::*};
+use bevy_scriptum::{runtimes::lua::LuaRuntime, BuildScriptingRuntime, ScriptingRuntimeBuilder};
+use events::{DirworldNavigationEvent, DirworldSpawn};
+use occule::Codec;
+use resources::{
+ DirworldCodecs, DirworldCurrentDir, DirworldObservers, DirworldRootDir, DirworldTasks,
+ EntryType,
+};
+pub use watcher::DirworldWatcherEvent;
+pub use watcher::DirworldWatcherSet;
/// Components used by this plugin
pub mod components;
@@ -17,21 +24,144 @@ pub mod events;
/// Resources used by this plugin
pub mod resources;
+mod watcher;
+
+/// Commands for this plugin
+pub mod commands;
+
+mod systems;
+
+/// Payload for dirworld entities
+pub mod payload;
+
+/// Actor component
+pub mod actor;
+
+mod lua_api;
+
/// Plugin which enables high-level interaction
+#[derive(Default)]
pub struct DirworldPlugin {
- /// Root path of world
- pub path: PathBuf,
+ pub register_custom_lua_api:
+ Option<Box<dyn Fn(ScriptingRuntimeBuilder<LuaRuntime>) + Send + Sync>>,
}
impl Plugin for DirworldPlugin {
fn build(&self, app: &mut App) {
- info!("building");
- let path_string = self.path.to_string_lossy().to_string();
- app.insert_resource(DirworldConfig::new(self.path.clone()))
- .register_asset_source("dirworld", AssetSource::build()
- .with_reader(AssetSource::get_default_reader(path_string.clone()))
- .with_watcher(|_| None))
+ info!("building");
+ app.add_systems(Startup, watcher::setup)
+ .add_systems(
+ Update,
+ (systems::remove_completed_tasks, lua_api::trigger_update),
+ )
+ .add_systems(PostUpdate, watcher::update)
+ .add_systems(
+ PreUpdate,
+ watcher::handle_changes,
+ )
+ .add_scripting::<LuaRuntime>(|runtime| {
+ let runtime = lua_api::register(runtime);
+ if let Some(register_custom) = &self.register_custom_lua_api {
+ (register_custom)(runtime);
+ }
+ })
.add_event::<DirworldNavigationEvent>()
- .init_resource::<Dirworld>();
+ .init_resource::<DirworldRootDir>()
+ .init_resource::<DirworldCurrentDir>()
+ .init_resource::<DirworldTasks>()
+ .init_resource::<DirworldObservers>()
+ .init_resource::<DirworldCodecs>()
+ .add_event::<DirworldWatcherEvent>();
+ }
+}
+
+pub trait Extensions {
+ fn extensions(&self) -> Option<String>;
+
+ fn file_stem_no_extensions(&self) -> Option<String>;
+
+ fn no_extensions(&self) -> PathBuf;
+}
+
+impl Extensions for PathBuf {
+ fn extensions(&self) -> Option<String> {
+ let mut temp_path = self.clone();
+ let mut extensions = Vec::<String>::new();
+ while let Some(extension) = temp_path.extension() {
+ extensions.insert(0, extension.to_string_lossy().into());
+ temp_path.set_extension("");
+ }
+ if extensions.is_empty() {
+ None
+ } else {
+ Some(extensions.join("."))
+ }
+ }
+
+ fn file_stem_no_extensions(&self) -> Option<String> {
+ let mut temp_path = self.clone();
+ while let Some(_) = temp_path.extension() {
+ temp_path.set_extension("");
+ }
+ temp_path
+ .file_stem()
+ .and_then(OsStr::to_str)
+ .map(str::to_string)
+ }
+
+ fn no_extensions(&self) -> PathBuf {
+ let mut temp_path = self.clone();
+ while let Some(_) = temp_path.extension() {
+ temp_path.set_extension("");
+ }
+ temp_path
+ }
+}
+
+pub trait DirworldApp {
+ fn register_dirworld_entry_callback<B: Bundle, M>(
+ &mut self,
+ extensions: Vec<EntryType>,
+ observer: impl IntoObserverSystem<DirworldSpawn, B, M>,
+ ) -> &mut Self;
+
+ fn register_dirworld_entry_codec<C: Codec + Send + Sync + 'static>(
+ &mut self,
+ extensions: Vec<String>,
+ codec: C,
+ ) -> &mut Self;
+}
+
+impl DirworldApp for App {
+ fn register_dirworld_entry_callback<B: Bundle, M>(
+ &mut self,
+ extensions: Vec<EntryType>,
+ observer: impl IntoObserverSystem<DirworldSpawn, B, M>,
+ ) -> &mut Self {
+ let world = self.world_mut();
+ let observer_entity_id;
+
+ {
+ let mut observer_entity = world.spawn_empty();
+ observer_entity_id = observer_entity.id();
+ observer_entity.insert(Observer::new(observer).with_entity(observer_entity_id));
+ }
+
+ world.flush();
+ world
+ .resource_mut::<DirworldObservers>()
+ .insert_many(extensions, observer_entity_id);
+ self
+ }
+
+ fn register_dirworld_entry_codec<C: Codec + Send + Sync + 'static>(
+ &mut self,
+ extensions: Vec<String>,
+ codec: C,
+ ) -> &mut Self {
+ self.world_mut()
+ .resource_mut::<DirworldCodecs>()
+ .insert_many(extensions, Box::new(codec));
+ self
}
}