mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
Corrections to resource reloading, material deep copy, etc.
This commit is contained in:
@@ -685,6 +685,11 @@ impl AssetBrowser {
|
||||
.path
|
||||
.clone();
|
||||
|
||||
if asset_path.as_os_str().is_empty() {
|
||||
err!("Selecting AssetItem with empty path: {selected_asset}");
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(selection) = entry.selection.as_ref::<AssetSelection>() {
|
||||
if selection.contains(&asset_path) {
|
||||
return;
|
||||
@@ -830,7 +835,7 @@ impl AssetBrowser {
|
||||
}
|
||||
drop(registry);
|
||||
|
||||
for path in paths {
|
||||
for path in paths.into_iter().filter(|p| !p.as_os_str().is_empty()) {
|
||||
self.add_asset(&path, ui, &engine.resource_manager, &sender);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,10 @@ impl AssetSelection {
|
||||
}
|
||||
|
||||
pub fn selected_path(&self) -> Option<&Path> {
|
||||
self.resources.first().map(|r| r.path.as_path())
|
||||
self.resources
|
||||
.first()
|
||||
.map(|r| r.path.as_path())
|
||||
.filter(|p| !p.as_os_str().is_empty())
|
||||
}
|
||||
|
||||
pub fn selected_import_options(&self) -> Option<RefMut<Box<dyn BaseImportOptions>>> {
|
||||
|
||||
@@ -376,6 +376,9 @@ fn run_normal(
|
||||
}
|
||||
Event::WindowEvent { event, .. } => {
|
||||
match event {
|
||||
WindowEvent::Focused(true) => {
|
||||
engine.resource_manager.state().process_filesystem_events();
|
||||
}
|
||||
WindowEvent::CloseRequested => active_event_loop.exit(),
|
||||
WindowEvent::Resized(size) => {
|
||||
if let Err(e) = engine.set_frame_size(size.into()) {
|
||||
|
||||
@@ -567,10 +567,10 @@ impl RenderDataBundle {
|
||||
{
|
||||
err_once!(
|
||||
self.data.key() as usize,
|
||||
"There's no render pass {} in {} shader! \
|
||||
"There's no render pass {} in {:?} shader! \
|
||||
If it is not needed, add it to disabled passes.",
|
||||
render_context.render_pass_name,
|
||||
shader_state.kind()
|
||||
shader_data.definition.name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -760,7 +760,7 @@ impl Display for ModelLoadError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ModelLoadError::Visit(v) => {
|
||||
write!(f, "An error occurred while reading a data source {v:?}")
|
||||
write!(f, "An error occurred while reading a data source: {v}")
|
||||
}
|
||||
ModelLoadError::NotSupported(v) => {
|
||||
write!(f, "Model format is not supported: {v}")
|
||||
|
||||
@@ -459,15 +459,13 @@ impl NodeTrait for Sound {
|
||||
ResourceState::Unloaded => {
|
||||
Err("Sound buffer is unloaded because it was never requested.".to_string())
|
||||
}
|
||||
ResourceState::LoadError { ref error, .. } => {
|
||||
match &error.0 {
|
||||
None => Err("Sound buffer is failed to load, the reason is unknown!"
|
||||
.to_string()),
|
||||
Some(err) => {
|
||||
Err(format!("Sound buffer is failed to load. Reason: {err:?}"))
|
||||
}
|
||||
ResourceState::LoadError { ref error, .. } => match &error.0 {
|
||||
None => {
|
||||
Err("Sound buffer is failed to load, the reason is unknown!"
|
||||
.to_string())
|
||||
}
|
||||
}
|
||||
Some(err) => Err(format!("Sound buffer is failed to load. Reason: {err}")),
|
||||
},
|
||||
}
|
||||
}
|
||||
None => Err("Sound buffer is not set, the sound won't play!".to_string()),
|
||||
|
||||
+13
-14
@@ -9,7 +9,6 @@ use fxhash::FxHashMap;
|
||||
use fyrox_core::{
|
||||
algebra::{Matrix2, Matrix3, Matrix4, Vector2, Vector3, Vector4},
|
||||
color::Color,
|
||||
futures::executor::block_on,
|
||||
io::FileError,
|
||||
parking_lot::Mutex,
|
||||
reflect::prelude::*,
|
||||
@@ -32,7 +31,7 @@ use std::{
|
||||
any::Any,
|
||||
error::Error,
|
||||
fmt::{Display, Formatter},
|
||||
path::{Path, PathBuf},
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
};
|
||||
use strum_macros::{AsRefStr, EnumString, VariantNames};
|
||||
@@ -1143,21 +1142,21 @@ impl MaterialResourceExtension for MaterialResource {
|
||||
}
|
||||
|
||||
fn deep_copy(&self) -> MaterialResource {
|
||||
if let Err(error) = block_on(self.clone()) {
|
||||
return MaterialResource::new_load_error(
|
||||
ResourceKind::Embedded,
|
||||
PathBuf::default(),
|
||||
error,
|
||||
);
|
||||
}
|
||||
let material_state = self.header();
|
||||
match material_state.state {
|
||||
ResourceState::Pending { .. }
|
||||
| ResourceState::Unloaded
|
||||
| ResourceState::LoadError { .. } => {
|
||||
unreachable!("The resource should be loaded by now")
|
||||
ResourceState::Unloaded => self.resource_uuid().into(),
|
||||
ResourceState::Pending { .. } => {
|
||||
MaterialResource::new_pending(self.resource_uuid(), ResourceKind::External)
|
||||
}
|
||||
ResourceState::Ok { ref data, .. } => MaterialResource::new_ok(
|
||||
ResourceState::LoadError {
|
||||
ref error,
|
||||
ref path,
|
||||
} => MaterialResource::new_load_error(
|
||||
ResourceKind::External,
|
||||
path.clone(),
|
||||
error.clone(),
|
||||
),
|
||||
ResourceState::Ok { ref data } => MaterialResource::new_ok(
|
||||
Uuid::new_v4(),
|
||||
ResourceKind::Embedded,
|
||||
(&**data as &dyn Any)
|
||||
|
||||
@@ -47,6 +47,7 @@ use crate::{
|
||||
untyped::ResourceKind,
|
||||
Resource, TypedResourceData, UntypedResource,
|
||||
};
|
||||
use fxhash::FxHashSet;
|
||||
use fyrox_core::{
|
||||
futures::executor::block_on, make_relative_path, notify::Event, ok_or_return, some_or_continue,
|
||||
some_or_return,
|
||||
@@ -495,7 +496,6 @@ impl ResourceManager {
|
||||
}
|
||||
|
||||
/// Find the resource for the given UUID without loading the resource.
|
||||
/// A new unloaded resource is created if one does not already exist.
|
||||
/// If the resource is not already loading, then it will be returned in
|
||||
/// the [`ResourceState::Unloaded`] state, and [`Self::request_resource`] may
|
||||
/// be used to begin the loading process.
|
||||
@@ -967,20 +967,19 @@ impl ResourceManagerState {
|
||||
/// This may involve updating the registry to reflect changes to the resources, and it may
|
||||
/// involve creating new meta files for resources that are missing meta files.
|
||||
pub fn process_filesystem_events(&mut self) {
|
||||
while let Some(evt) = self.try_get_event() {
|
||||
let mut modified_files = FxHashSet::default();
|
||||
while let Some(mut evt) = self.try_get_event() {
|
||||
if evt.need_rescan() {
|
||||
info!("Filesystem watcher has forced a rescan!");
|
||||
self.update_or_load_registry();
|
||||
self.reload_resources();
|
||||
} else {
|
||||
use notify::event::{CreateKind, DataChange, ModifyKind, RemoveKind, RenameMode};
|
||||
use notify::event::{CreateKind, ModifyKind, RemoveKind, RenameMode};
|
||||
use notify::EventKind;
|
||||
match evt.kind {
|
||||
EventKind::Create(CreateKind::Any | CreateKind::File) => {
|
||||
self.on_create_event(evt.paths.first())
|
||||
}
|
||||
EventKind::Modify(ModifyKind::Data(DataChange::Content)) => {
|
||||
self.on_file_content_event(evt.paths.first())
|
||||
}
|
||||
EventKind::Modify(ModifyKind::Name(RenameMode::From)) => {
|
||||
self.on_remove_event(evt.paths.first())
|
||||
}
|
||||
@@ -991,6 +990,10 @@ impl ResourceManagerState {
|
||||
self.on_remove_event(evt.paths.first());
|
||||
self.on_create_event(evt.paths.get(1));
|
||||
}
|
||||
EventKind::Modify(ModifyKind::Any | ModifyKind::Data(_)) => {
|
||||
let path = evt.paths.get_mut(0).map(std::mem::take);
|
||||
modified_files.insert(path);
|
||||
}
|
||||
EventKind::Remove(RemoveKind::Any | RemoveKind::File) => {
|
||||
self.on_remove_event(evt.paths.first())
|
||||
}
|
||||
@@ -998,6 +1001,9 @@ impl ResourceManagerState {
|
||||
}
|
||||
}
|
||||
}
|
||||
for path in modified_files {
|
||||
self.on_file_content_event(path.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
fn on_create_event(&mut self, path: Option<&PathBuf>) {
|
||||
@@ -1043,7 +1049,13 @@ impl ResourceManagerState {
|
||||
.safe_lock()
|
||||
.is_supported_resource(&relative_path)
|
||||
{
|
||||
Self::on_new_resource_file(registry.modify(), relative_path);
|
||||
Self::on_new_resource_file(registry.modify(), relative_path.clone());
|
||||
drop(registry);
|
||||
if self.try_reload_resource_from_path(&relative_path) {
|
||||
info!(
|
||||
"File {relative_path:?} was created, trying to reload a respective resource...",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A new resource file has been discovered through an event. Check if there is a corresponding meta file,
|
||||
@@ -1314,8 +1326,11 @@ impl ResourceManagerState {
|
||||
self.built_in_resources.add(resource)
|
||||
}
|
||||
|
||||
/// Find the resource for the given UUID without loading the resource.
|
||||
/// Searches the resource manager to find a resource with the given UUID, including built-in resources.
|
||||
/// If no resource is found, a new UUID is generated and an unloaded resource is returned.
|
||||
/// If no resource is found, a new unloaded external resource is returned for the given UUID,
|
||||
/// because it is presumed that this is a real UUID for some resource that is not currently managed
|
||||
/// and therefore it should be added to the manager.
|
||||
pub fn find_uuid(&mut self, uuid: Uuid) -> UntypedResource {
|
||||
if let Some(built_in_resource) = self.built_in_resources.find_by_uuid(uuid) {
|
||||
return built_in_resource.resource.clone();
|
||||
@@ -1483,11 +1498,21 @@ impl ResourceManagerState {
|
||||
));
|
||||
}
|
||||
Err(error) => {
|
||||
Log::info(format!(
|
||||
"Resource {path:?} failed to load. Reason: {error:?}",
|
||||
));
|
||||
|
||||
resource.commit_error(path.to_path_buf(), error);
|
||||
if reload {
|
||||
if resource.is_ok() {
|
||||
info!("Resource {path:?} failed to reload, keeping the existing version. Reason: {error}");
|
||||
}
|
||||
else
|
||||
{
|
||||
info!("Resource {path:?} failed to reload. Reason: {error}");
|
||||
resource.commit_error(path.to_path_buf(), error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info!("Resource {path:?} failed to load. Reason: {error}");
|
||||
resource.commit_error(path.to_path_buf(), error);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1628,7 +1653,9 @@ impl ResourceManagerState {
|
||||
}
|
||||
let mut header = resource.lock();
|
||||
if !header.state.is_loading() {
|
||||
header.state.switch_to_pending_state();
|
||||
if !header.state.is_ok() {
|
||||
header.state.switch_to_pending_state();
|
||||
}
|
||||
drop(header);
|
||||
self.spawn_loading_task(resource, true)
|
||||
}
|
||||
|
||||
@@ -283,7 +283,6 @@ impl ResourceRegistryRefMut<'_> {
|
||||
panic!("Registering empty path.");
|
||||
}
|
||||
use std::collections::btree_map::Entry;
|
||||
//self.registry.paths.insert(uuid, path)
|
||||
match self.registry.paths.entry(uuid) {
|
||||
Entry::Vacant(entry) => {
|
||||
info!("Registered: {uuid} -> {path:?}");
|
||||
|
||||
Reference in New Issue
Block a user