custom resource example

This commit is contained in:
Dmitry
2023-05-13 22:43:42 +03:00
parent 6594d3377f
commit c0805e8522
3 changed files with 161 additions and 2 deletions
+159
View File
@@ -0,0 +1,159 @@
use fyrox::{
asset::{
event::ResourceEventBroadcaster,
loader::{BoxedLoaderFuture, ResourceLoader},
untyped::UntypedResource,
ResourceData,
},
core::{
io::{self},
pool::Handle,
reflect::prelude::*,
uuid::{uuid, Uuid},
visitor::prelude::*,
TypeUuidProvider,
},
engine::{executor::Executor, GraphicsContextParams},
event_loop::ControlFlow,
plugin::{Plugin, PluginConstructor, PluginContext},
scene::Scene,
window::WindowAttributes,
};
use fyrox_core::futures::executor;
use std::{
any::Any,
borrow::Cow,
path::{Path, PathBuf},
};
#[derive(Debug, Visit, Reflect)]
struct CustomResource {
// You resource must store the path.
path: PathBuf,
some_data: String,
}
impl TypeUuidProvider for CustomResource {
// Every resource must provide a unique identifier, that is used for dynamic type
// casting, serialization, etc.
fn type_uuid() -> Uuid {
uuid!("15551157-651b-4f1d-a5fb-6874fbfe8637")
}
}
impl ResourceData for CustomResource {
fn path(&self) -> Cow<Path> {
Cow::Borrowed(&self.path)
}
fn set_path(&mut self, path: PathBuf) {
self.path = path;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn type_uuid(&self) -> Uuid {
<Self as TypeUuidProvider>::type_uuid()
}
}
struct CustomResourceLoader;
impl ResourceLoader for CustomResourceLoader {
fn extensions(&self) -> &[&str] {
&["my_resource"]
}
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn load(
&self,
resource: UntypedResource,
event_broadcaster: ResourceEventBroadcaster,
reload: bool,
) -> BoxedLoaderFuture {
Box::pin(async move {
let path = resource.path();
match io::load_file(&path).await {
Ok(content) => {
let my_resource = CustomResource {
path,
some_data: String::from_utf8(content).unwrap(),
};
resource.commit_ok(my_resource);
// Notify potential subscribers that the resource was loader.
event_broadcaster.broadcast_loaded_or_reloaded(resource, reload);
}
Err(err) => {
resource.commit_error(path, err);
}
}
})
}
}
struct Game {}
impl Plugin for Game {
fn update(&mut self, context: &mut PluginContext, _control_flow: &mut ControlFlow) {}
}
struct GameConstructor;
impl PluginConstructor for GameConstructor {
fn create_instance(
&self,
_override_scene: Handle<Scene>,
_context: PluginContext,
) -> Box<dyn Plugin> {
_context
.resource_manager
.state()
.loaders
.set(CustomResourceLoader);
let resource = executor::block_on(
_context
.resource_manager
.request::<CustomResource, _>("examples/data/custom.my_resource"),
)
.unwrap();
println!("{}", resource.data_ref().some_data);
Box::new(Game {})
}
}
fn main() {
let mut executor = Executor::from_params(
Default::default(),
GraphicsContextParams {
window_attributes: WindowAttributes {
title: "Example - Custom Resource".to_string(),
..Default::default()
},
vsync: true,
},
);
executor.add_plugin_constructor(GameConstructor);
executor.run()
}
+1
View File
@@ -0,0 +1 @@
This is a custom resource!
+1 -2
View File
@@ -51,8 +51,7 @@ mod quadtree;
/// Current implementation version marker.
pub const VERSION: u8 = 1;
/// Layers is a set of textures for rendering + mask texture to exclude some pixels from
/// rendering. Terrain can have as many layers as you want, but each layer slightly decreases
/// Layers is a material Terrain can have as many layers as you want, but each layer slightly decreases
/// performance, so keep amount of layers on reasonable level (1 - 5 should be enough for most
/// cases).
#[derive(Debug, Clone, Visit, Reflect, PartialEq)]