reloading #1
@ -1,2 +0,0 @@
|
|||||||
[profile.dev.package."*"]
|
|
||||||
opt-level = 2
|
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
|
Cargo.lock
|
||||||
|
.cargo
|
||||||
|
7132
Cargo.lock
generated
7132
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,7 @@ optional = true
|
|||||||
features = ["serde"]
|
features = ["serde"]
|
||||||
|
|
||||||
[dependencies.bevy_mod_scripting]
|
[dependencies.bevy_mod_scripting]
|
||||||
version = "0.9"
|
version = "0.11"
|
||||||
features = ["lua54", "bevy_bindings"]
|
features = ["lua54", "bevy_bindings"]
|
||||||
|
|
||||||
[dependencies.bevy_basic_interaction]
|
[dependencies.bevy_basic_interaction]
|
||||||
|
@ -59,7 +59,7 @@ impl Command for DirworldLockDoorCommand {
|
|||||||
.take_read_buffer()
|
.take_read_buffer()
|
||||||
.take_remaining()
|
.take_remaining()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&i| i),
|
.copied(),
|
||||||
);
|
);
|
||||||
match result {
|
match result {
|
||||||
BufferResult::BufferUnderflow => break,
|
BufferResult::BufferUnderflow => break,
|
||||||
@ -75,7 +75,7 @@ impl Command for DirworldLockDoorCommand {
|
|||||||
|
|
||||||
// Insert key hash as payload relationship
|
// Insert key hash as payload relationship
|
||||||
let key_digest = md5::compute(&self.key[..16]);
|
let key_digest = md5::compute(&self.key[..16]);
|
||||||
let mut payload = payload.unwrap_or_else(|| DirworldEntityPayload::new());
|
let mut payload = payload.unwrap_or_else(DirworldEntityPayload::new);
|
||||||
let relationships = payload.relationships.get_or_insert_default();
|
let relationships = payload.relationships.get_or_insert_default();
|
||||||
relationships.insert("key".into(), key_digest.0);
|
relationships.insert("key".into(), key_digest.0);
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ impl Command for DirworldUnlockDoorCommand {
|
|||||||
.take_read_buffer()
|
.take_read_buffer()
|
||||||
.take_remaining()
|
.take_remaining()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&i| i),
|
.copied(),
|
||||||
);
|
);
|
||||||
match result {
|
match result {
|
||||||
BufferResult::BufferUnderflow => break,
|
BufferResult::BufferUnderflow => break,
|
||||||
@ -154,7 +154,7 @@ impl Command for DirworldUnlockDoorCommand {
|
|||||||
let new_path = parent.join(path.file_stem_no_extensions().unwrap());
|
let new_path = parent.join(path.file_stem_no_extensions().unwrap());
|
||||||
let _ = fs::create_dir(new_path.clone());
|
let _ = fs::create_dir(new_path.clone());
|
||||||
command_queue.push(DirworldSaveEntityCommand {
|
command_queue.push(DirworldSaveEntityCommand {
|
||||||
path: new_path.into(),
|
path: new_path,
|
||||||
payload,
|
payload,
|
||||||
});
|
});
|
||||||
return Some(command_queue);
|
return Some(command_queue);
|
||||||
@ -265,7 +265,7 @@ pub trait DirworldCommands {
|
|||||||
fn dirworld_save_entity(&mut self, path: PathBuf, payload: DirworldEntityPayload);
|
fn dirworld_save_entity(&mut self, path: PathBuf, payload: DirworldEntityPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'w, 's> DirworldCommands for Commands<'w, 's> {
|
impl DirworldCommands for Commands<'_, '_> {
|
||||||
fn dirworld_lock_door(&mut self, path: PathBuf, key: Vec<u8>) {
|
fn dirworld_lock_door(&mut self, path: PathBuf, key: Vec<u8>) {
|
||||||
self.queue(DirworldLockDoorCommand { key, path });
|
self.queue(DirworldLockDoorCommand { key, path });
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ impl Condition {
|
|||||||
Condition::ChildOf { .. } => "conditional_child_of",
|
Condition::ChildOf { .. } => "conditional_child_of",
|
||||||
Condition::ParentOf { .. } => "conditional_parent_of",
|
Condition::ParentOf { .. } => "conditional_parent_of",
|
||||||
Condition::DescendantOf { .. } => "conditional_descendant_of",
|
Condition::DescendantOf { .. } => "conditional_descendant_of",
|
||||||
Condition::AncestorOf { .. } =>"conditional_ancestor_of",
|
Condition::AncestorOf { .. } => "conditional_ancestor_of",
|
||||||
Condition::InRoom(_) => "conditional_in_room",
|
Condition::InRoom(_) => "conditional_in_room",
|
||||||
Condition::ObjectInRoom(_) => "conditional_object_in_room",
|
Condition::ObjectInRoom(_) => "conditional_object_in_room",
|
||||||
}
|
}
|
||||||
@ -93,51 +93,37 @@ impl Condition {
|
|||||||
match name {
|
match name {
|
||||||
"conditional_true" => Some(Condition::True),
|
"conditional_true" => Some(Condition::True),
|
||||||
"conditional_child_of" => {
|
"conditional_child_of" => {
|
||||||
let Some(child) = args.get(0).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
let child = args.first().and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
return None;
|
let parent = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
};
|
|
||||||
let Some(parent) = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(Condition::ChildOf { child, parent })
|
Some(Condition::ChildOf { child, parent })
|
||||||
}
|
}
|
||||||
"conditional_parent_of" => {
|
"conditional_parent_of" => {
|
||||||
let Some(child) = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
let child = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
return None;
|
let parent = args.first().and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
};
|
|
||||||
let Some(parent) = args.get(0).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(Condition::ParentOf { child, parent })
|
Some(Condition::ParentOf { child, parent })
|
||||||
}
|
}
|
||||||
"conditional_descendant_of" => {
|
"conditional_descendant_of" => {
|
||||||
let Some(descendant) = args.get(0).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
let descendant = args.first().and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
return None;
|
let ancestor = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
};
|
Some(Condition::DescendantOf {
|
||||||
let Some(ancestor) = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
descendant,
|
||||||
return None;
|
ancestor,
|
||||||
};
|
})
|
||||||
Some(Condition::DescendantOf { descendant, ancestor })
|
|
||||||
}
|
}
|
||||||
"conditional_ancestor_of" => {
|
"conditional_ancestor_of" => {
|
||||||
let Some(descendant) = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
let descendant = args.get(1).and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
return None;
|
let ancestor = args.first().and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
};
|
Some(Condition::AncestorOf {
|
||||||
let Some(ancestor) = args.get(0).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
descendant,
|
||||||
return None;
|
ancestor,
|
||||||
};
|
})
|
||||||
Some(Condition::AncestorOf { descendant, ancestor })
|
|
||||||
}
|
}
|
||||||
"condtitional_in_room" => {
|
"condtitional_in_room" => {
|
||||||
let Some(room_id) = args.get(0).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
let room_id = args.first().and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(Condition::InRoom(room_id))
|
Some(Condition::InRoom(room_id))
|
||||||
}
|
}
|
||||||
"condtitional_object_in_room" => {
|
"condtitional_object_in_room" => {
|
||||||
let Some(object_id) = args.get(0).and_then(|arg| Uuid::parse_str(arg).ok()) else {
|
let object_id = args.first().and_then(|arg| Uuid::parse_str(arg).ok())?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
Some(Condition::ObjectInRoom(object_id))
|
Some(Condition::ObjectInRoom(object_id))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -169,9 +155,7 @@ fn ancestor_of(world: &mut World, ancestor: Uuid, descendant: Uuid) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
AncestorIter::new(&parents, descendant_entity)
|
AncestorIter::new(&parents, descendant_entity).any(|descendant| descendant == ancestor_entity)
|
||||||
.find(|descendant| *descendant == ancestor_entity)
|
|
||||||
.is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent_of(world: &mut World, parent: Uuid, child: Uuid) -> bool {
|
fn parent_of(world: &mut World, parent: Uuid, child: Uuid) -> bool {
|
||||||
@ -203,18 +187,18 @@ fn parent_of(world: &mut World, parent: Uuid, child: Uuid) -> bool {
|
|||||||
|
|
||||||
fn in_room(world: &mut World, room: Uuid) -> bool {
|
fn in_room(world: &mut World, room: Uuid) -> bool {
|
||||||
let current_dir = world.resource::<DirworldCurrentDir>();
|
let current_dir = world.resource::<DirworldCurrentDir>();
|
||||||
current_dir.payload.as_ref().is_some_and(|payload| payload.id == room)
|
current_dir
|
||||||
|
.payload
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|payload| payload.id == room)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn object_in_room(world: &mut World, object: Uuid) -> bool {
|
fn object_in_room(world: &mut World, object: Uuid) -> bool {
|
||||||
let mut dirworld_entities = world.query::<&DirworldEntity>();
|
let mut dirworld_entities = world.query::<&DirworldEntity>();
|
||||||
dirworld_entities
|
dirworld_entities.iter(world).any(|entity| {
|
||||||
.iter(world)
|
entity
|
||||||
.find(|entity| {
|
.payload
|
||||||
entity
|
.as_ref()
|
||||||
.payload
|
.is_some_and(|payload| payload.id == object)
|
||||||
.as_ref()
|
})
|
||||||
.is_some_and(|payload| payload.id == object)
|
|
||||||
})
|
|
||||||
.is_some()
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
//! Plugin for bevy engine enabling interaction with and representation of the file system in the world.
|
//! Plugin for bevy engine enabling interaction with and representation of the file system in the world.
|
||||||
|
|
||||||
@ -131,7 +133,7 @@ impl Extensions for PathBuf {
|
|||||||
|
|
||||||
fn file_stem_no_extensions(&self) -> Option<String> {
|
fn file_stem_no_extensions(&self) -> Option<String> {
|
||||||
let mut temp_path = self.clone();
|
let mut temp_path = self.clone();
|
||||||
while let Some(_) = temp_path.extension() {
|
while temp_path.extension().is_some() {
|
||||||
temp_path.set_extension("");
|
temp_path.set_extension("");
|
||||||
}
|
}
|
||||||
temp_path
|
temp_path
|
||||||
@ -142,7 +144,7 @@ impl Extensions for PathBuf {
|
|||||||
|
|
||||||
fn no_extensions(&self) -> PathBuf {
|
fn no_extensions(&self) -> PathBuf {
|
||||||
let mut temp_path = self.clone();
|
let mut temp_path = self.clone();
|
||||||
while let Some(_) = temp_path.extension() {
|
while temp_path.extension().is_some() {
|
||||||
temp_path.set_extension("");
|
temp_path.set_extension("");
|
||||||
}
|
}
|
||||||
temp_path
|
temp_path
|
||||||
|
@ -190,10 +190,7 @@ fn condition_child_of(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn condition_in_room(
|
fn condition_in_room(ctx: FunctionCallContext, room: String) -> Result<bool, InteropError> {
|
||||||
ctx: FunctionCallContext,
|
|
||||||
room: String,
|
|
||||||
) -> Result<bool, InteropError> {
|
|
||||||
let Ok(room) = Uuid::from_str(&room) else {
|
let Ok(room) = Uuid::from_str(&room) else {
|
||||||
warn!("Provided room is not a valid UUID");
|
warn!("Provided room is not a valid UUID");
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
@ -208,7 +205,7 @@ fn condition_in_room(
|
|||||||
|
|
||||||
fn condition_object_in_room(
|
fn condition_object_in_room(
|
||||||
ctx: FunctionCallContext,
|
ctx: FunctionCallContext,
|
||||||
object: String
|
object: String,
|
||||||
) -> Result<bool, InteropError> {
|
) -> Result<bool, InteropError> {
|
||||||
let Ok(object) = Uuid::from_str(&object) else {
|
let Ok(object) = Uuid::from_str(&object) else {
|
||||||
warn!("Provided object is not a valid UUID");
|
warn!("Provided object is not a valid UUID");
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
events::{
|
events::{
|
||||||
DirworldChangeRoot, DirworldEnterRoom, DirworldLeaveRoom,
|
DirworldChangeRoot, DirworldEnterRoom, DirworldLeaveRoom,
|
||||||
},
|
},
|
||||||
preload::{load_entity, DirworldPreloadBegin, PreloadState, RoomAssets},
|
preload::{load_entity, reload_entity, DirworldPreloadBegin, PreloadState, ReloadPaths, RoomAssets},
|
||||||
resources::{
|
resources::{
|
||||||
DirworldCodecs, DirworldCurrentDir, DirworldObservers, DirworldRootDir, DirworldTasks,
|
DirworldCodecs, DirworldCurrentDir, DirworldObservers, DirworldRootDir, DirworldTasks,
|
||||||
},
|
},
|
||||||
@ -38,19 +38,19 @@ pub fn navigate_from_room(
|
|||||||
|
|
||||||
pub fn navigate_to_room(
|
pub fn navigate_to_room(
|
||||||
trigger: Trigger<DirworldEnterRoom>,
|
trigger: Trigger<DirworldEnterRoom>,
|
||||||
|
mut commands: Commands,
|
||||||
|
mut event_writer: EventWriter<DirworldEnterRoom>,
|
||||||
|
mut preload_event_writer: EventWriter<DirworldPreloadBegin>,
|
||||||
root_dir: Res<DirworldRootDir>,
|
root_dir: Res<DirworldRootDir>,
|
||||||
mut cache: ResMut<DirworldCache>,
|
mut cache: ResMut<DirworldCache>,
|
||||||
observers: Res<DirworldObservers>,
|
observers: Res<DirworldObservers>,
|
||||||
codecs: Res<DirworldCodecs>,
|
codecs: Res<DirworldCodecs>,
|
||||||
mut commands: Commands,
|
|
||||||
mut event_writer: EventWriter<DirworldEnterRoom>,
|
|
||||||
mut preload_event_writer: EventWriter<DirworldPreloadBegin>,
|
|
||||||
mut current_dir: ResMut<DirworldCurrentDir>,
|
mut current_dir: ResMut<DirworldCurrentDir>,
|
||||||
mut next_preload_state: ResMut<NextState<PreloadState>>,
|
mut next_preload_state: ResMut<NextState<PreloadState>>,
|
||||||
mut room_assets: ResMut<RoomAssets>,
|
mut room_assets: ResMut<RoomAssets>,
|
||||||
mut dirworld_tasks: ResMut<DirworldTasks>,
|
mut dirworld_tasks: ResMut<DirworldTasks>,
|
||||||
persitent_entities: Query<&DirworldEntity, With<Persist>>,
|
|
||||||
mut time: ResMut<Time<Physics>>,
|
mut time: ResMut<Time<Physics>>,
|
||||||
|
persitent_entities: Query<&DirworldEntity, With<Persist>>,
|
||||||
) {
|
) {
|
||||||
time.pause();
|
time.pause();
|
||||||
dirworld_tasks.insert("Loading Room".into(), None);
|
dirworld_tasks.insert("Loading Room".into(), None);
|
||||||
@ -67,8 +67,7 @@ pub fn navigate_to_room(
|
|||||||
let entries = match path.read_dir() {
|
let entries = match path.read_dir() {
|
||||||
Ok(entries) => entries
|
Ok(entries) => entries
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|entry| entry.path().canonicalize())
|
.flat_map(|entry| entry.path().canonicalize())
|
||||||
.flatten()
|
|
||||||
.filter(|entry| {
|
.filter(|entry| {
|
||||||
!entry
|
!entry
|
||||||
.file_name()
|
.file_name()
|
||||||
@ -117,12 +116,9 @@ pub fn handle_changes(
|
|||||||
dirworld_entities: Query<(Entity, &DirworldEntity)>,
|
dirworld_entities: Query<(Entity, &DirworldEntity)>,
|
||||||
observers: Res<DirworldObservers>,
|
observers: Res<DirworldObservers>,
|
||||||
codecs: Res<DirworldCodecs>,
|
codecs: Res<DirworldCodecs>,
|
||||||
mut cache: ResMut<DirworldCache>,
|
|
||||||
mut event_writer: EventWriter<DirworldWatcherEvent>,
|
mut event_writer: EventWriter<DirworldWatcherEvent>,
|
||||||
mut next_preload_state: ResMut<NextState<PreloadState>>,
|
|
||||||
mut room_assets: ResMut<RoomAssets>,
|
mut room_assets: ResMut<RoomAssets>,
|
||||||
persitent_entities: Query<&DirworldEntity, With<Persist>>,
|
mut reload_paths: ResMut<ReloadPaths>,
|
||||||
root_dir: Res<DirworldRootDir>,
|
|
||||||
) {
|
) {
|
||||||
let event = &trigger.event().0;
|
let event = &trigger.event().0;
|
||||||
info!("Watcher Event: {event:?}");
|
info!("Watcher Event: {event:?}");
|
||||||
@ -134,45 +130,36 @@ pub fn handle_changes(
|
|||||||
}
|
}
|
||||||
EventKind::Create(_) | EventKind::Modify(ModifyKind::Name(RenameMode::To)) => {
|
EventKind::Create(_) | EventKind::Modify(ModifyKind::Name(RenameMode::To)) => {
|
||||||
for path in &event.paths {
|
for path in &event.paths {
|
||||||
load_entity(
|
reload_entity(
|
||||||
&path,
|
path,
|
||||||
&mut cache,
|
|
||||||
&codecs,
|
&codecs,
|
||||||
&observers,
|
&observers,
|
||||||
&mut commands,
|
&mut commands,
|
||||||
&mut next_preload_state,
|
|
||||||
&mut room_assets,
|
&mut room_assets,
|
||||||
&root_dir,
|
&mut reload_paths,
|
||||||
&persitent_entities,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EventKind::Modify(ModifyKind::Name(RenameMode::Both)) => {
|
EventKind::Modify(ModifyKind::Name(RenameMode::Both)) => {
|
||||||
despawn_entity_by_path(&mut commands, &dirworld_entities, &event.paths[0]);
|
despawn_entity_by_path(&mut commands, &dirworld_entities, &event.paths[0]);
|
||||||
load_entity(
|
reload_entity(
|
||||||
&event.paths[1],
|
&event.paths[1],
|
||||||
&mut cache,
|
|
||||||
&codecs,
|
&codecs,
|
||||||
&observers,
|
&observers,
|
||||||
&mut commands,
|
&mut commands,
|
||||||
&mut next_preload_state,
|
|
||||||
&mut room_assets,
|
&mut room_assets,
|
||||||
&root_dir,
|
&mut reload_paths,
|
||||||
&persitent_entities,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
EventKind::Modify(ModifyKind::Metadata(MetadataKind::Any)) => {
|
EventKind::Modify(ModifyKind::Metadata(MetadataKind::Any)) => {
|
||||||
despawn_entity_by_path(&mut commands, &dirworld_entities, &event.paths[1]);
|
despawn_entity_by_path(&mut commands, &dirworld_entities, &event.paths[1]);
|
||||||
load_entity(
|
reload_entity(
|
||||||
&event.paths[0],
|
&event.paths[0],
|
||||||
&mut cache,
|
|
||||||
&codecs,
|
&codecs,
|
||||||
&observers,
|
&observers,
|
||||||
&mut commands,
|
&mut commands,
|
||||||
&mut next_preload_state,
|
|
||||||
&mut room_assets,
|
&mut room_assets,
|
||||||
&root_dir,
|
&mut reload_paths,
|
||||||
&persitent_entities,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -40,4 +40,3 @@ impl DirworldEntityPayload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,10 @@ impl Plugin for DirworldPreloadPlugin {
|
|||||||
systems::handle_preload.run_if(in_state(PreloadState::Loading)),
|
systems::handle_preload.run_if(in_state(PreloadState::Loading)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_systems(OnEnter(PreloadState::Done), systems::handle_spawn)
|
.add_systems(OnEnter(PreloadState::Spawning), systems::handle_spawn)
|
||||||
|
.add_systems(Update, systems::handle_reloads.run_if(in_state(PreloadState::Done)))
|
||||||
.add_event::<DirworldPreloadBegin>()
|
.add_event::<DirworldPreloadBegin>()
|
||||||
|
.init_resource::<ReloadPaths>()
|
||||||
.insert_resource(PreloadPaths {
|
.insert_resource(PreloadPaths {
|
||||||
src: PathBuf::new(),
|
src: PathBuf::new(),
|
||||||
dst: PathBuf::new(),
|
dst: PathBuf::new(),
|
||||||
@ -48,11 +50,66 @@ pub enum PreloadState {
|
|||||||
/// Indicates assets are in the process of loading
|
/// Indicates assets are in the process of loading
|
||||||
#[default]
|
#[default]
|
||||||
Loading,
|
Loading,
|
||||||
|
/// Initial Spawning
|
||||||
|
Spawning,
|
||||||
/// Indicates all room assets are finished loading, i.e. all assets are loaded with
|
/// Indicates all room assets are finished loading, i.e. all assets are loaded with
|
||||||
/// dependencies
|
/// dependencies
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Begins the reload process for an entity
|
||||||
|
pub fn reload_entity(
|
||||||
|
entry: &PathBuf,
|
||||||
|
codecs: &DirworldCodecs,
|
||||||
|
observers: &DirworldObservers,
|
||||||
|
commands: &mut Commands,
|
||||||
|
room_assets: &mut RoomAssets,
|
||||||
|
reload_paths: &mut ReloadPaths,
|
||||||
|
) {
|
||||||
|
let (payload, data) = extract_entity_payload(entry, codecs);
|
||||||
|
let entry_type = if entry.is_dir() {
|
||||||
|
EntryType::Folder
|
||||||
|
} else {
|
||||||
|
EntryType::File(entry.extensions())
|
||||||
|
};
|
||||||
|
let transform = if entry.file_name().is_none() {
|
||||||
|
payload
|
||||||
|
.as_ref()
|
||||||
|
.map(|payload| {
|
||||||
|
payload
|
||||||
|
.door_destination
|
||||||
|
.as_ref()
|
||||||
|
.expect("Door destination missing from payload!")
|
||||||
|
.0
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
payload
|
||||||
|
.as_ref()
|
||||||
|
.map(|payload| payload.transform.0)
|
||||||
|
.unwrap_or_default()
|
||||||
|
};
|
||||||
|
info!("{transform:?}");
|
||||||
|
let entity = commands
|
||||||
|
.spawn((
|
||||||
|
transform,
|
||||||
|
Visibility::Inherited,
|
||||||
|
DirworldEntity {
|
||||||
|
path: entry.clone(),
|
||||||
|
payload,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
|
||||||
|
info!("Entity: {entity:?}");
|
||||||
|
if let Some(observer) = observers.get(&entry_type) {
|
||||||
|
reload_paths.push(entry.clone());
|
||||||
|
room_assets.insert(entry.clone(), HashMap::default());
|
||||||
|
commands.trigger_targets(DirworldPreload { entity, data }, *observer);
|
||||||
|
info!("Triggered reload for {entry:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Initiates loading of an asset
|
/// Initiates loading of an asset
|
||||||
// TODO: Make into a command extension
|
// TODO: Make into a command extension
|
||||||
pub fn load_entity(
|
pub fn load_entity(
|
||||||
@ -67,7 +124,7 @@ pub fn load_entity(
|
|||||||
persistent_entities: &Query<&DirworldEntity, With<Persist>>,
|
persistent_entities: &Query<&DirworldEntity, With<Persist>>,
|
||||||
) {
|
) {
|
||||||
info!("Entity: {entry:?}");
|
info!("Entity: {entry:?}");
|
||||||
if persistent_entities.iter().find(|e| e.path == *entry).is_some() {
|
if persistent_entities.iter().any(|e| e.path == *entry) {
|
||||||
info!("Entity is persistent, skipping...");
|
info!("Entity is persistent, skipping...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -75,8 +132,8 @@ pub fn load_entity(
|
|||||||
info!("Entity is root directory, skipping...");
|
info!("Entity is root directory, skipping...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (mut payload, data) = extract_entity_payload(&entry, &codecs);
|
let (mut payload, data) = extract_entity_payload(entry, codecs);
|
||||||
payload = payload.map(|p| cache.get_entity_cache(&entry).unwrap_or(p));
|
payload = payload.map(|p| cache.get_entity_cache(entry).unwrap_or(p));
|
||||||
let entry_type = if entry.is_dir() {
|
let entry_type = if entry.is_dir() {
|
||||||
EntryType::Folder
|
EntryType::Folder
|
||||||
} else {
|
} else {
|
||||||
@ -112,7 +169,7 @@ pub fn load_entity(
|
|||||||
if let Some(observer) = observers.get(&entry_type) {
|
if let Some(observer) = observers.get(&entry_type) {
|
||||||
preload_state.set(PreloadState::Loading);
|
preload_state.set(PreloadState::Loading);
|
||||||
room_assets.insert(entry.clone(), HashMap::default());
|
room_assets.insert(entry.clone(), HashMap::default());
|
||||||
commands.trigger_targets(DirworldPreload { entity, data }, observer.clone());
|
commands.trigger_targets(DirworldPreload { entity, data }, *observer);
|
||||||
info!("Triggered preload for {entry:?}");
|
info!("Triggered preload for {entry:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,3 +14,7 @@ pub struct PreloadPaths {
|
|||||||
/// Path of current room
|
/// Path of current room
|
||||||
pub dst: PathBuf,
|
pub dst: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Paths which are currently in the process of being reloaded
|
||||||
|
#[derive(Resource, Deref, DerefMut, Debug, Default)]
|
||||||
|
pub struct ReloadPaths(Vec<PathBuf>);
|
||||||
|
@ -8,9 +8,7 @@ use crate::{
|
|||||||
Extensions,
|
Extensions,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{DirworldPreloadBegin, PreloadPaths, PreloadState, ReloadPaths, RoomAssets};
|
||||||
DirworldPreloadBegin, PreloadPaths, PreloadState, RoomAssets,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn cache_preload_paths(
|
pub fn cache_preload_paths(
|
||||||
mut event_reader: EventReader<DirworldPreloadBegin>,
|
mut event_reader: EventReader<DirworldPreloadBegin>,
|
||||||
@ -35,7 +33,7 @@ pub fn handle_preload(
|
|||||||
.all(|a| asset_server.is_loaded_with_dependencies(a))
|
.all(|a| asset_server.is_loaded_with_dependencies(a))
|
||||||
{
|
{
|
||||||
info!("Preload Done.");
|
info!("Preload Done.");
|
||||||
next_state.set(PreloadState::Done);
|
next_state.set(PreloadState::Spawning);
|
||||||
dirworld_tasks.remove("Loading Room");
|
dirworld_tasks.remove("Loading Room");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,6 +45,7 @@ pub fn handle_spawn(
|
|||||||
observers: Res<DirworldObservers>,
|
observers: Res<DirworldObservers>,
|
||||||
mut event_writer: EventWriter<DirworldNavigationComplete>,
|
mut event_writer: EventWriter<DirworldNavigationComplete>,
|
||||||
mut time: ResMut<Time<Physics>>,
|
mut time: ResMut<Time<Physics>>,
|
||||||
|
mut next_state: ResMut<NextState<PreloadState>>,
|
||||||
) {
|
) {
|
||||||
info!("Spawning");
|
info!("Spawning");
|
||||||
for (entity, DirworldEntity { path, .. }) in dirworld_entity_query.iter() {
|
for (entity, DirworldEntity { path, .. }) in dirworld_entity_query.iter() {
|
||||||
@ -57,7 +56,7 @@ pub fn handle_spawn(
|
|||||||
};
|
};
|
||||||
if let Some(observer) = observers.get(&entry_type) {
|
if let Some(observer) = observers.get(&entry_type) {
|
||||||
info!("Found observer {observer:?} for {entry_type:?}");
|
info!("Found observer {observer:?} for {entry_type:?}");
|
||||||
commands.trigger_targets(DirworldSpawn(entity), observer.clone());
|
commands.trigger_targets(DirworldSpawn(entity), *observer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time.unpause();
|
time.unpause();
|
||||||
@ -65,4 +64,44 @@ pub fn handle_spawn(
|
|||||||
from: preload_paths.src.clone(),
|
from: preload_paths.src.clone(),
|
||||||
to: preload_paths.dst.clone(),
|
to: preload_paths.dst.clone(),
|
||||||
});
|
});
|
||||||
|
next_state.set(PreloadState::Done);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_reloads(
|
||||||
|
room_assets: ResMut<RoomAssets>,
|
||||||
|
mut reload_paths: ResMut<ReloadPaths>,
|
||||||
|
asset_server: Res<AssetServer>,
|
||||||
|
observers: Res<DirworldObservers>,
|
||||||
|
dirworld_entity_query: Query<(Entity, &DirworldEntity), Without<Persist>>,
|
||||||
|
mut commands: Commands,
|
||||||
|
) {
|
||||||
|
reload_paths.retain(|reload_path| {
|
||||||
|
let mut result = true;
|
||||||
|
if let Some(assets) = room_assets.get(reload_path) {
|
||||||
|
if assets
|
||||||
|
.values()
|
||||||
|
.all(|asset| asset_server.is_loaded_with_dependencies(asset))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
if !result {
|
||||||
|
let (entity, _) = dirworld_entity_query
|
||||||
|
.iter()
|
||||||
|
.find(|(_, DirworldEntity { path, .. })| path == reload_path)
|
||||||
|
.unwrap();
|
||||||
|
let entry_type = if reload_path.is_dir() {
|
||||||
|
EntryType::Folder
|
||||||
|
} else {
|
||||||
|
EntryType::File(reload_path.extensions())
|
||||||
|
};
|
||||||
|
if let Some(observer) = observers.get(&entry_type) {
|
||||||
|
info!("RELOAD: Found observer {observer:?} for {entry_type:?}");
|
||||||
|
commands.trigger_targets(DirworldSpawn(entity), *observer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,3 @@ pub fn remove_completed_tasks(mut commands: Commands, mut tasks: ResMut<Dirworld
|
|||||||
None => true,
|
None => true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn sync_entity_transforms(
|
|
||||||
// mut dirworld_entity_query: Query<(&mut DirworldEntity, Ref<Transform>, &GlobalTransform)>,
|
|
||||||
// ) {
|
|
||||||
// for (mut dirworld_entity, transform, global_transform) in dirworld_entity_query.iter_mut() {
|
|
||||||
// if transform.is_changed() && !transform.is_added() {
|
|
||||||
// if let Some(payload) = &mut dirworld_entity.payload {
|
|
||||||
// let transform = global_transform.compute_transform();
|
|
||||||
// *payload.transform = transform;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
47
src/utils.rs
47
src/utils.rs
@ -17,7 +17,9 @@ pub fn extract_entity_payload(
|
|||||||
|
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
let payload_file_path = if path.file_name().is_none() {
|
let payload_file_path = if path.file_name().is_none() {
|
||||||
path.parent().expect(".. missing parent somehow").join(".door")
|
path.parent()
|
||||||
|
.expect(".. missing parent somehow")
|
||||||
|
.join(".door")
|
||||||
} else {
|
} else {
|
||||||
path.join(".door")
|
path.join(".door")
|
||||||
};
|
};
|
||||||
@ -34,34 +36,31 @@ pub fn extract_entity_payload(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if let Some(extensions) = path.extensions() {
|
||||||
if let Some(extensions) = path.extensions() {
|
if let Ok(file_data) = fs::read(path) {
|
||||||
if let Ok(file_data) = fs::read(&path) {
|
if let Some(codec) = codecs.get(&extensions) {
|
||||||
if let Some(codec) = codecs.get(&extensions) {
|
match codec.decode(&file_data) {
|
||||||
match codec.decode(&file_data) {
|
Ok((carrier, extracted_payload)) => {
|
||||||
Ok((carrier, extracted_payload)) => {
|
match rmp_serde::from_slice::<DirworldEntityPayload>(&extracted_payload) {
|
||||||
match rmp_serde::from_slice::<DirworldEntityPayload>(&extracted_payload)
|
Ok(deserialized_payload) => {
|
||||||
{
|
data = Some(carrier);
|
||||||
Ok(deserialized_payload) => {
|
payload = Some(deserialized_payload);
|
||||||
data = Some(carrier);
|
|
||||||
payload = Some(deserialized_payload);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
warn!("Could not deserialize extracted payload: {e:?}");
|
|
||||||
data = Some(file_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
Err(e) => {
|
||||||
Err(e) => match e {
|
warn!("Could not deserialize extracted payload: {e:?}");
|
||||||
occule::Error::DataNotEncoded => {
|
|
||||||
data = Some(file_data);
|
data = Some(file_data);
|
||||||
}
|
}
|
||||||
_ => error!("Could not decode payload: {e:?}"),
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
} else {
|
Err(e) => match e {
|
||||||
data = Some(file_data);
|
occule::Error::DataNotEncoded => {
|
||||||
|
data = Some(file_data);
|
||||||
|
}
|
||||||
|
_ => error!("Could not decode payload: {e:?}"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
data = Some(file_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
use std::{
|
use std::{path::PathBuf, time::Duration};
|
||||||
path::PathBuf,
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_channel::{Receiver, Sender};
|
use async_channel::{Receiver, Sender};
|
||||||
use bevy::{prelude::*, tasks::IoTaskPool};
|
use bevy::{prelude::*, tasks::IoTaskPool};
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use bevy::{log::info, prelude::World};
|
use bevy::{log::info, prelude::World};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::sync::{
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
Arc, Condvar, Mutex,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{actor::resources::FunctionLibrary, conditionals::Condition};
|
use crate::{actor::resources::FunctionLibrary, conditionals::Condition};
|
||||||
|
|
||||||
@ -28,7 +26,7 @@ pub fn setup_yarnspinner_functions(library: &mut FunctionLibrary) {
|
|||||||
|
|
||||||
pub fn process_commands(world: &mut World) {
|
pub fn process_commands(world: &mut World) {
|
||||||
let command_count = YARNSPINNER_COMMAND_COUNT.1.lock().unwrap();
|
let command_count = YARNSPINNER_COMMAND_COUNT.1.lock().unwrap();
|
||||||
if *command_count <= 0 {
|
if *command_count == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +39,7 @@ pub fn process_commands(world: &mut World) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut command_count = YARNSPINNER_COMMAND_COUNT.1.lock().unwrap();
|
let mut command_count = YARNSPINNER_COMMAND_COUNT.1.lock().unwrap();
|
||||||
while !*command_count <= 0 {
|
while !*command_count == 0 {
|
||||||
info!("Command Count: {}", *command_count);
|
info!("Command Count: {}", *command_count);
|
||||||
command_count = YARNSPINNER_COMMAND_COUNT.0.wait(command_count).unwrap();
|
command_count = YARNSPINNER_COMMAND_COUNT.0.wait(command_count).unwrap();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user