mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-11 22:50:08 +00:00
Reflect::try_clone_box
- `#[reflect(non_cloneable)]` for types that cannot be cloned
This commit is contained in:
@@ -18,7 +18,6 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
use crate::fyrox::core::reflect::Reflect;
|
||||
use crate::fyrox::graph::BaseSceneGraph;
|
||||
use crate::fyrox::{
|
||||
asset::{manager::ResourceManager, options::BaseImportOptions},
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
struct LightmapperSettings {
|
||||
#[reflect(
|
||||
description = "Amount of texels per unit. It defines 'pixels density' per unit of area (square meters). The \
|
||||
|
||||
@@ -69,7 +69,7 @@ use fyrox::asset::manager::ResourceManager;
|
||||
use fyrox::gui::inspector::InspectorContextArgs;
|
||||
use std::{ops::Range, sync::Arc};
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
pub struct RagdollPreset {
|
||||
#[reflect(description = "A handle of a hips (pelvis) bone.")]
|
||||
hips: Handle<Node>,
|
||||
|
||||
@@ -172,6 +172,10 @@ impl ResourceData for AutoTileInstance {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TileSetTerrainSource<'a, 'b> {
|
||||
|
||||
@@ -39,7 +39,7 @@ const REMOVE_TOOLTIP: &str = "Remove the selected cell from this macro.";
|
||||
const CELL_WITH_MACRO_COLOR: Color = Color::DARK_SLATE_BLUE;
|
||||
const CELL_WITHOUT_MACRO_COLOR: Color = Color::opaque(50, 50, 50);
|
||||
|
||||
#[derive(Visit, Reflect)]
|
||||
#[derive(Visit, Clone, Reflect)]
|
||||
pub struct MacroInspector {
|
||||
handle: Handle<UiNode>,
|
||||
content: Handle<UiNode>,
|
||||
@@ -66,16 +66,19 @@ impl Debug for MacroInspector {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Item {
|
||||
macro_id: Uuid,
|
||||
editor: Option<ItemEditor>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ItemEditor {
|
||||
handle: Handle<UiNode>,
|
||||
header: ItemHeader,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ItemHeader {
|
||||
handle: Handle<UiNode>,
|
||||
label: Handle<UiNode>,
|
||||
|
||||
@@ -722,7 +722,7 @@ impl ColliderEditors {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Visit, Reflect)]
|
||||
#[derive(Visit, Reflect, Clone)]
|
||||
pub struct TileInspector {
|
||||
handle: Handle<UiNode>,
|
||||
/// The shared state that represents the user's currently selected tool and tiles.
|
||||
|
||||
@@ -254,6 +254,10 @@ impl ResourceData for WfcInstance {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl BrushMacro for WfcMacro {
|
||||
|
||||
@@ -255,7 +255,7 @@ impl GameScene {
|
||||
let scene = &mut engine.scenes[self.scene];
|
||||
|
||||
let editor_root = self.editor_objects_root;
|
||||
let (pure_scene, _) = scene.clone(
|
||||
let (pure_scene, _) = scene.clone_ex(
|
||||
self.scene_content_root,
|
||||
&mut |node, _| node != editor_root,
|
||||
&mut |_, _| {},
|
||||
|
||||
@@ -135,6 +135,10 @@ impl ResourceData for AnimationTracksData {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// A resource that holds animation tracks. This resource can be shared across multiple animations.
|
||||
|
||||
@@ -74,6 +74,10 @@ macro_rules! define_two_args_node {
|
||||
Self::derived_types()
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &'static str {
|
||||
type_name::<Self>()
|
||||
}
|
||||
@@ -347,6 +351,10 @@ impl<T: EntityId> Reflect for NotNode<T> {
|
||||
let this = std::mem::replace(self, value.take()?);
|
||||
Ok(Box::new(this))
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// A node responsible for logical operations evaluation. It can have any number of descendant nodes.
|
||||
|
||||
@@ -473,7 +473,7 @@ mod test {
|
||||
use crate::value::{BoundValue, TrackValue, ValueBinding, ValueType};
|
||||
use fyrox_core::{reflect::prelude::*, variable::InheritableVariable};
|
||||
|
||||
#[derive(Reflect, Debug, PartialEq)]
|
||||
#[derive(Reflect, Debug, Clone, PartialEq)]
|
||||
struct OtherStruct {
|
||||
field: u32,
|
||||
inheritable_variable: InheritableVariable<u32>,
|
||||
@@ -488,7 +488,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Reflect, Debug, PartialEq)]
|
||||
#[derive(Default, Reflect, Clone, Debug, PartialEq)]
|
||||
struct MyStruct {
|
||||
some_bool: bool,
|
||||
some_property: f32,
|
||||
|
||||
@@ -321,6 +321,20 @@ fn gen_impl(
|
||||
}
|
||||
});
|
||||
|
||||
let try_clone_box = if ty_args.non_cloneable {
|
||||
quote! {
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let types = ty_args
|
||||
.derived_type
|
||||
.iter()
|
||||
@@ -337,6 +351,8 @@ fn gen_impl(
|
||||
file!()
|
||||
}
|
||||
|
||||
#try_clone_box
|
||||
|
||||
fn type_name(&self) -> &'static str {
|
||||
std::any::type_name::<Self>()
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
use darling::*;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use syn::__private::bool;
|
||||
use syn::*;
|
||||
|
||||
pub type Fields = ast::Fields<FieldArgs>;
|
||||
@@ -58,6 +59,9 @@ pub struct TypeArgs {
|
||||
|
||||
#[darling(multiple)]
|
||||
pub derived_type: Vec<Path>,
|
||||
|
||||
#[darling(default)]
|
||||
pub non_cloneable: bool,
|
||||
}
|
||||
|
||||
impl TypeArgs {
|
||||
|
||||
@@ -40,10 +40,10 @@ pub struct Struct {
|
||||
hidden: usize,
|
||||
}
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
pub struct Tuple(usize, usize);
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
pub enum Enum {
|
||||
Named { field: usize },
|
||||
Tuple(usize),
|
||||
@@ -122,7 +122,7 @@ fn reflect_field_accessors() {
|
||||
|
||||
#[test]
|
||||
fn reflect_containers() {
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct DerefContainer<T> {
|
||||
data: T,
|
||||
}
|
||||
@@ -140,7 +140,7 @@ fn reflect_containers() {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
struct X {
|
||||
#[reflect(deref)]
|
||||
container: DerefContainer<Struct>,
|
||||
@@ -161,8 +161,8 @@ fn reflect_containers() {
|
||||
|
||||
x.get_resolve_path::<usize>("container.field", &mut |result| assert_eq!(result, Ok(&0)));
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[reflect(bounds = "T: Reflect")]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
#[reflect(bounds = "T: Reflect + Clone")]
|
||||
struct B<T> {
|
||||
#[reflect(deref)]
|
||||
data: Box<T>,
|
||||
@@ -181,7 +181,7 @@ fn reflect_containers() {
|
||||
|
||||
#[test]
|
||||
fn reflect_path() {
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
struct Hierarchy {
|
||||
s: Struct,
|
||||
e: Enum,
|
||||
@@ -222,12 +222,12 @@ fn reflect_list_path() {
|
||||
let data = vec![vec![0usize, 1], vec![2, 3, 4]];
|
||||
data.get_resolve_path("[0][1]", &mut |result| assert_eq!(result, Ok(&1usize)));
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
struct X {
|
||||
data: Vec<usize>,
|
||||
}
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
struct A {
|
||||
xs: Vec<X>,
|
||||
}
|
||||
@@ -248,7 +248,8 @@ fn reflect_list_path() {
|
||||
|
||||
#[test]
|
||||
fn reflect_custom_setter() {
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
#[reflect(bounds = "T: Reflect + Clone")]
|
||||
pub struct Wrapper<T> {
|
||||
#[reflect(setter = "set_value")]
|
||||
value: T,
|
||||
@@ -276,7 +277,7 @@ fn reflect_custom_setter() {
|
||||
|
||||
#[test]
|
||||
fn reflect_fields_list_of_struct() {
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
struct Foo {
|
||||
field_a: f32,
|
||||
field_b: String,
|
||||
@@ -306,7 +307,7 @@ fn reflect_fields_list_of_struct() {
|
||||
|
||||
#[test]
|
||||
fn reflect_fields_list_of_enum() {
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
enum Foo {
|
||||
Bar { field_a: f32 },
|
||||
Baz { field_b: u32, field_c: String },
|
||||
@@ -362,7 +363,7 @@ fn default_prop_metadata() -> FieldMetadata<'static> {
|
||||
|
||||
#[test]
|
||||
fn inspect_default() {
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Default, Clone, Reflect)]
|
||||
pub struct Data {
|
||||
the_field: String,
|
||||
another_field: f32,
|
||||
@@ -398,13 +399,13 @@ fn inspect_default() {
|
||||
|
||||
#[test]
|
||||
fn inspect_attributes() {
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Default, Clone, Reflect)]
|
||||
pub struct AarGee {
|
||||
aar: u32,
|
||||
gee: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Default, Clone, Reflect)]
|
||||
pub struct Data {
|
||||
// NOTE: Even though this field is skipped, the next field is given index `1` for simplicity
|
||||
#[reflect(hidden)]
|
||||
@@ -459,7 +460,7 @@ fn inspect_attributes() {
|
||||
|
||||
#[test]
|
||||
fn inspect_struct() {
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Default, Clone, Reflect)]
|
||||
struct Tuple(f32, f32);
|
||||
|
||||
let x = Tuple::default();
|
||||
@@ -488,7 +489,7 @@ fn inspect_struct() {
|
||||
)
|
||||
});
|
||||
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Default, Clone, Reflect)]
|
||||
struct Unit;
|
||||
|
||||
let x = Unit;
|
||||
@@ -497,12 +498,12 @@ fn inspect_struct() {
|
||||
|
||||
#[test]
|
||||
fn inspect_enum() {
|
||||
#[derive(Debug, Reflect)]
|
||||
#[derive(Debug, Clone, Reflect)]
|
||||
pub struct NonCopy {
|
||||
inner: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Reflect)]
|
||||
#[derive(Debug, Clone, Reflect)]
|
||||
pub enum Data {
|
||||
Named { x: u32, y: u32, z: NonCopy },
|
||||
Tuple(f32, f32),
|
||||
@@ -596,7 +597,7 @@ fn inspect_enum() {
|
||||
#[test]
|
||||
fn inspect_prop_key_constants() {
|
||||
#[allow(dead_code)]
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
pub struct SStruct {
|
||||
field: usize,
|
||||
#[reflect(hidden)]
|
||||
@@ -609,11 +610,11 @@ fn inspect_prop_key_constants() {
|
||||
// hidden properties
|
||||
// assert_eq!(SStruct::HIDDEN, "hidden");
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
pub struct STuple(usize);
|
||||
assert_eq!(STuple::F_0, "0");
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
#[allow(unused)]
|
||||
pub enum E {
|
||||
Tuple(usize),
|
||||
@@ -689,7 +690,7 @@ fn test_hash_map() {
|
||||
});
|
||||
|
||||
// Check path resolution.
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
struct Something {
|
||||
hash_map: HashMap<String, Struct>,
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ use fyrox_core_derive::{impl_reflect, impl_visit};
|
||||
use std::fmt::Debug;
|
||||
|
||||
impl_reflect!(
|
||||
pub struct Rect<T: Debug> {}
|
||||
pub struct Rect<T: Debug + Copy> {}
|
||||
);
|
||||
|
||||
impl<T> Visit for Rect<T>
|
||||
|
||||
@@ -123,6 +123,10 @@ impl<T: Reflect> Reflect for Handle<T> {
|
||||
T::derived_types()
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(*self))
|
||||
}
|
||||
|
||||
fn query_derived_types(&self) -> &'static [TypeId] {
|
||||
Self::derived_types()
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ impl<T, P> Reflect for Pool<T, P>
|
||||
where
|
||||
T: Reflect,
|
||||
P: PayloadContainer<Element = T> + Reflect,
|
||||
Pool<T, P>: Clone,
|
||||
{
|
||||
#[inline]
|
||||
fn source_path() -> &'static str {
|
||||
@@ -111,6 +112,10 @@ where
|
||||
&[]
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn query_derived_types(&self) -> &'static [TypeId] {
|
||||
Self::derived_types()
|
||||
}
|
||||
@@ -189,6 +194,7 @@ impl<T, P> ReflectArray for Pool<T, P>
|
||||
where
|
||||
T: Reflect,
|
||||
P: PayloadContainer<Element = T> + Reflect,
|
||||
Pool<T, P>: Clone,
|
||||
{
|
||||
#[inline]
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
|
||||
@@ -219,7 +219,10 @@ pub trait ReflectBase: Any + Debug {
|
||||
fn as_any_raw_mut(&mut self) -> &mut dyn Any;
|
||||
}
|
||||
|
||||
impl<T: Reflect> ReflectBase for T {
|
||||
impl<T> ReflectBase for T
|
||||
where
|
||||
T: Reflect,
|
||||
{
|
||||
fn as_any_raw(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
@@ -257,6 +260,8 @@ pub trait Reflect: ReflectBase {
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>>;
|
||||
|
||||
fn query_derived_types(&self) -> &'static [TypeId];
|
||||
|
||||
fn type_name(&self) -> &'static str;
|
||||
@@ -1203,6 +1208,10 @@ macro_rules! blank_reflect {
|
||||
&[]
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
|
||||
Self::derived_types()
|
||||
}
|
||||
@@ -1279,6 +1288,10 @@ macro_rules! delegate_reflect {
|
||||
&[]
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
|
||||
Self::derived_types()
|
||||
}
|
||||
@@ -1456,7 +1469,7 @@ mod test {
|
||||
use std::any::TypeId;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Reflect, Default, Debug)]
|
||||
#[derive(Reflect, Clone, Default, Debug)]
|
||||
struct Foo {
|
||||
bar: Bar,
|
||||
baz: f32,
|
||||
@@ -1464,12 +1477,12 @@ mod test {
|
||||
hash_map: HashMap<String, Item>,
|
||||
}
|
||||
|
||||
#[derive(Reflect, Default, Debug)]
|
||||
#[derive(Reflect, Clone, Default, Debug)]
|
||||
struct Item {
|
||||
payload: u32,
|
||||
}
|
||||
|
||||
#[derive(Reflect, Default, Debug)]
|
||||
#[derive(Reflect, Clone, Default, Debug)]
|
||||
struct Bar {
|
||||
stuff: String,
|
||||
}
|
||||
@@ -1503,7 +1516,7 @@ mod test {
|
||||
assert_eq!(names[9], "hash_map[Foobar].payload");
|
||||
}
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
#[reflect(derived_type = "Derived")]
|
||||
struct Base;
|
||||
|
||||
|
||||
@@ -27,24 +27,24 @@ use std::fmt::Debug;
|
||||
use crate::reflect::prelude::*;
|
||||
|
||||
impl_reflect! {
|
||||
pub struct Matrix<T: 'static, R: Dim + 'static, C: Dim + 'static, S: 'static> {
|
||||
pub struct Matrix<T: Copy + 'static, R: Dim + 'static, C: Dim + 'static, S: Copy + 'static> {
|
||||
pub data: S,
|
||||
// _phantoms: PhantomData<(T, R, C)>,
|
||||
}
|
||||
}
|
||||
|
||||
impl_reflect! {
|
||||
pub struct ArrayStorage<T: Debug, const R: usize, const C: usize>(pub [[T; R]; C]);
|
||||
pub struct ArrayStorage<T: Copy + Debug, const R: usize, const C: usize>(pub [[T; R]; C]);
|
||||
}
|
||||
|
||||
impl_reflect! {
|
||||
pub struct Unit<T: Debug + 'static> {
|
||||
pub struct Unit<T: Copy + Debug + 'static> {
|
||||
// pub(crate) value: T,
|
||||
}
|
||||
}
|
||||
|
||||
impl_reflect! {
|
||||
pub struct Quaternion<T: Debug> {
|
||||
pub struct Quaternion<T: Copy + Debug> {
|
||||
pub coords: Vector4<T>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ macro_rules! impl_reflect_tuple {
|
||||
)*
|
||||
) => {
|
||||
$(
|
||||
impl< $($t: Reflect),* > Reflect for ( $($t,)* ) {
|
||||
impl< $($t: Clone + Reflect),* > Reflect for ( $($t,)* ) {
|
||||
blank_reflect!();
|
||||
}
|
||||
)*
|
||||
@@ -82,7 +82,7 @@ impl_reflect_tuple! {
|
||||
(T0, T1, T2, T3, T4,);
|
||||
}
|
||||
|
||||
impl<const N: usize, T: Reflect> Reflect for [T; N] {
|
||||
impl<const N: usize, T: Reflect + Clone> Reflect for [T; N] {
|
||||
blank_reflect!();
|
||||
|
||||
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
|
||||
@@ -94,7 +94,7 @@ impl<const N: usize, T: Reflect> Reflect for [T; N] {
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize, T: Reflect> ReflectArray for [T; N] {
|
||||
impl<const N: usize, T: Reflect + Clone> ReflectArray for [T; N] {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
if let Some(item) = self.get(index) {
|
||||
Some(item)
|
||||
@@ -118,10 +118,10 @@ impl<const N: usize, T: Reflect> ReflectArray for [T; N] {
|
||||
|
||||
impl_reflect! {
|
||||
#[reflect(ReflectList, ReflectArray)]
|
||||
pub struct Vec<T: Reflect>;
|
||||
pub struct Vec<T: Reflect + Clone>;
|
||||
}
|
||||
|
||||
impl<T: Reflect> ReflectArray for Vec<T> {
|
||||
impl<T: Reflect + Clone> ReflectArray for Vec<T> {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
self.get(index).map(|x| x as &dyn Reflect)
|
||||
}
|
||||
@@ -136,7 +136,7 @@ impl<T: Reflect> ReflectArray for Vec<T> {
|
||||
}
|
||||
|
||||
/// REMARK: `Reflect` is implemented for `Vec<T>` where `T: Reflect` only.
|
||||
impl<T: Reflect> ReflectList for Vec<T> {
|
||||
impl<T: Reflect + Clone> ReflectList for Vec<T> {
|
||||
fn reflect_push(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
||||
self.push(*value.downcast::<T>()?);
|
||||
Ok(())
|
||||
@@ -170,9 +170,9 @@ impl<T: Reflect> ReflectList for Vec<T> {
|
||||
|
||||
impl<K, V, S> Reflect for HashMap<K, V, S>
|
||||
where
|
||||
K: Reflect + Eq + Hash + 'static,
|
||||
V: Reflect,
|
||||
S: BuildHasher + 'static,
|
||||
K: Reflect + Eq + Hash + Clone + 'static,
|
||||
V: Reflect + Clone,
|
||||
S: BuildHasher + Clone + 'static,
|
||||
{
|
||||
blank_reflect!();
|
||||
|
||||
@@ -187,9 +187,9 @@ where
|
||||
|
||||
impl<K, V, S> ReflectHashMap for HashMap<K, V, S>
|
||||
where
|
||||
K: Reflect + Eq + Hash + 'static,
|
||||
V: Reflect,
|
||||
S: BuildHasher + 'static,
|
||||
K: Reflect + Eq + Hash + Clone + 'static,
|
||||
V: Reflect + Clone,
|
||||
S: BuildHasher + Clone + 'static,
|
||||
{
|
||||
fn reflect_insert(
|
||||
&mut self,
|
||||
@@ -281,20 +281,20 @@ impl_reflect! {
|
||||
}
|
||||
|
||||
impl_reflect! {
|
||||
pub enum Option<T> {
|
||||
pub enum Option<T: Clone> {
|
||||
Some(T),
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl_reflect! {
|
||||
pub struct Range<Idx> {
|
||||
pub struct Range<Idx: Clone> {
|
||||
pub start: Idx,
|
||||
pub end: Idx,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Reflect> Reflect for Box<T> {
|
||||
impl<T: Reflect + Clone> Reflect for Box<T> {
|
||||
delegate_reflect!();
|
||||
}
|
||||
|
||||
@@ -310,6 +310,11 @@ macro_rules! impl_reflect_inner_mutability {
|
||||
&[]
|
||||
}
|
||||
|
||||
fn try_clone_box(&$self) -> Option<Box<dyn Reflect>> {
|
||||
let guard = $acquire_lock_guard;
|
||||
Some(Box::new(guard.clone()))
|
||||
}
|
||||
|
||||
fn query_derived_types(&self) -> &'static [std::any::TypeId] {
|
||||
T::derived_types()
|
||||
}
|
||||
@@ -438,24 +443,24 @@ macro_rules! impl_reflect_inner_mutability {
|
||||
};
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for parking_lot::Mutex<T> {
|
||||
impl<T: Reflect + Clone> Reflect for parking_lot::Mutex<T> {
|
||||
impl_reflect_inner_mutability!(self, { self.lock() }, { self.into_inner() });
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for parking_lot::RwLock<T> {
|
||||
impl<T: Reflect + Clone> Reflect for parking_lot::RwLock<T> {
|
||||
impl_reflect_inner_mutability!(self, { self.write() }, { self.into_inner() });
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_mutex_lock)]
|
||||
impl<T: Reflect> Reflect for std::sync::Mutex<T> {
|
||||
impl<T: Reflect + Clone> Reflect for std::sync::Mutex<T> {
|
||||
impl_reflect_inner_mutability!(self, { self.lock().unwrap() }, { self.into_inner() });
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for std::sync::RwLock<T> {
|
||||
impl<T: Reflect + Clone> Reflect for std::sync::RwLock<T> {
|
||||
impl_reflect_inner_mutability!(self, { self.write().unwrap() }, { self.into_inner() });
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for Arc<parking_lot::Mutex<T>> {
|
||||
impl<T: Reflect + Clone> Reflect for Arc<parking_lot::Mutex<T>> {
|
||||
impl_reflect_inner_mutability!(self, { self.lock() }, {
|
||||
Arc::into_inner(*self)
|
||||
.expect("Value cannot be shared!")
|
||||
@@ -463,7 +468,7 @@ impl<T: Reflect> Reflect for Arc<parking_lot::Mutex<T>> {
|
||||
});
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for Arc<std::sync::Mutex<T>> {
|
||||
impl<T: Reflect + Clone> Reflect for Arc<std::sync::Mutex<T>> {
|
||||
impl_reflect_inner_mutability!(self, { self.lock().unwrap() }, {
|
||||
Arc::into_inner(*self)
|
||||
.expect("Value cannot be shared!")
|
||||
@@ -471,7 +476,7 @@ impl<T: Reflect> Reflect for Arc<std::sync::Mutex<T>> {
|
||||
});
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for Arc<std::sync::RwLock<T>> {
|
||||
impl<T: Reflect + Clone> Reflect for Arc<std::sync::RwLock<T>> {
|
||||
impl_reflect_inner_mutability!(self, { self.write().unwrap() }, {
|
||||
Arc::into_inner(*self)
|
||||
.expect("Value cannot be shared!")
|
||||
@@ -479,7 +484,7 @@ impl<T: Reflect> Reflect for Arc<std::sync::RwLock<T>> {
|
||||
});
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for Arc<parking_lot::RwLock<T>> {
|
||||
impl<T: Reflect + Clone> Reflect for Arc<parking_lot::RwLock<T>> {
|
||||
impl_reflect_inner_mutability!(self, { self.write() }, {
|
||||
Arc::into_inner(*self)
|
||||
.expect("Value cannot be shared!")
|
||||
@@ -487,11 +492,11 @@ impl<T: Reflect> Reflect for Arc<parking_lot::RwLock<T>> {
|
||||
});
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for RefCell<T> {
|
||||
impl<T: Reflect + Clone> Reflect for RefCell<T> {
|
||||
impl_reflect_inner_mutability!(self, { self.borrow_mut() }, { self.into_inner() });
|
||||
}
|
||||
|
||||
impl<T: Reflect> Reflect for Rc<RefCell<T>> {
|
||||
impl<T: Reflect + Clone> Reflect for Rc<RefCell<T>> {
|
||||
impl_reflect_inner_mutability!(self, { self.borrow_mut() }, {
|
||||
Rc::into_inner(*self)
|
||||
.expect("Value cannot be shared!")
|
||||
|
||||
@@ -381,6 +381,10 @@ where
|
||||
file!()
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn derived_types() -> &'static [TypeId]
|
||||
where
|
||||
Self: Sized,
|
||||
@@ -839,7 +843,7 @@ mod test {
|
||||
assert!(va.value_equals(&vb))
|
||||
}
|
||||
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
enum SomeEnum {
|
||||
Bar(InheritableVariable<f32>),
|
||||
Baz {
|
||||
|
||||
+10
-2
@@ -1598,6 +1598,10 @@ mod test {
|
||||
fn query_derived_types(&self) -> &'static [TypeId] {
|
||||
Self::derived_types()
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl NameProvider for Node {
|
||||
@@ -1622,7 +1626,7 @@ mod test {
|
||||
|
||||
/// A wrapper for node pool record that allows to define custom visit method to have full
|
||||
/// control over instantiation process at deserialization.
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Default, Clone, Reflect)]
|
||||
pub struct NodeContainer(Option<Node>);
|
||||
|
||||
impl Visit for NodeContainer {
|
||||
@@ -1711,7 +1715,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, TypeUuidProvider, Visit, Reflect, Debug)]
|
||||
#[derive(Default, Clone, TypeUuidProvider, Visit, Reflect, Debug)]
|
||||
#[type_uuid(id = "fc887063-7780-44af-8710-5e0bcf9a83fd")]
|
||||
pub struct Graph {
|
||||
root: Handle<Node>,
|
||||
@@ -1730,6 +1734,10 @@ mod test {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl PrefabData for Graph {
|
||||
|
||||
@@ -283,6 +283,7 @@ struct SceneLoadingOptions {
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// #[derive(Visit, Reflect, Debug)]
|
||||
/// #[reflect(non_cloneable)]
|
||||
/// struct MyGame {
|
||||
/// scene: Handle<Scene>,
|
||||
/// }
|
||||
@@ -1707,7 +1708,7 @@ impl Engine {
|
||||
// some methods (`Base::root_resource` in particular) won't work
|
||||
// correctly.
|
||||
scene: scene
|
||||
.clone(
|
||||
.clone_ex(
|
||||
scene.graph.get_root(),
|
||||
&mut |_, _| true,
|
||||
&mut |_, _| {},
|
||||
|
||||
@@ -103,6 +103,7 @@ impl TaskPoolHandler {
|
||||
/// # use std::{fs::File, io::Read};
|
||||
///
|
||||
/// #[derive(Visit, Reflect, Debug)]
|
||||
/// #[reflect(non_cloneable)]
|
||||
/// struct MyGame {
|
||||
/// data: Option<Vec<u8>>,
|
||||
/// }
|
||||
|
||||
@@ -765,6 +765,10 @@ impl ResourceData for Material {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of possible errors that can occur when working with materials.
|
||||
|
||||
@@ -543,7 +543,7 @@ pub const STANDARD_SHADER_SOURCES: [&str; 6] = [
|
||||
///
|
||||
/// Usually you don't need to access internals of the shader, but there sometimes could be a need to
|
||||
/// read shader definition, to get supported passes and properties.
|
||||
#[derive(Default, Debug, Reflect, Visit)]
|
||||
#[derive(Default, Debug, Clone, Reflect, Visit)]
|
||||
pub struct Shader {
|
||||
/// Shader definition contains description of properties and render passes.
|
||||
#[visit(optional)]
|
||||
@@ -561,7 +561,7 @@ impl TypeUuidProvider for Shader {
|
||||
}
|
||||
|
||||
/// A render pass definition. See [`ShaderResource`] docs for more info about render passes.
|
||||
#[derive(Default, Serialize, Deserialize, Debug, PartialEq, Eq, Reflect, Visit)]
|
||||
#[derive(Default, Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Reflect, Visit)]
|
||||
pub struct RenderPassDefinition {
|
||||
/// A name of render pass.
|
||||
pub name: String,
|
||||
@@ -581,7 +581,7 @@ pub struct RenderPassDefinition {
|
||||
}
|
||||
|
||||
/// A definition of the shader.
|
||||
#[derive(Default, Serialize, Deserialize, Debug, PartialEq, Reflect, Visit)]
|
||||
#[derive(Default, Clone, Serialize, Deserialize, Debug, PartialEq, Reflect, Visit)]
|
||||
pub struct ShaderDefinition {
|
||||
/// A name of the shader.
|
||||
pub name: String,
|
||||
@@ -845,6 +845,10 @@ impl ResourceData for Shader {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of possible error variants that can occur during shader loading.
|
||||
|
||||
@@ -227,6 +227,7 @@ impl dyn Plugin {
|
||||
/// # use std::str::FromStr;
|
||||
///
|
||||
/// #[derive(Default, Visit, Reflect, Debug)]
|
||||
/// #[reflect(non_cloneable)]
|
||||
/// struct MyPlugin {}
|
||||
///
|
||||
/// impl Plugin for MyPlugin {
|
||||
|
||||
@@ -74,7 +74,7 @@ impl From<VisitError> for CurveResourceError {
|
||||
}
|
||||
|
||||
/// State of the [`CurveResource`]
|
||||
#[derive(Debug, Visit, Default, Reflect)]
|
||||
#[derive(Debug, Clone, Visit, Default, Reflect)]
|
||||
pub struct CurveResourceState {
|
||||
/// Actual curve.
|
||||
pub curve: Curve,
|
||||
@@ -93,6 +93,10 @@ impl ResourceData for CurveResourceState {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeUuidProvider for CurveResourceState {
|
||||
|
||||
@@ -80,7 +80,7 @@ use strum_macros::{AsRefStr, EnumString, VariantNames};
|
||||
pub mod loader;
|
||||
|
||||
/// See module docs.
|
||||
#[derive(Debug, Visit, Reflect)]
|
||||
#[derive(Debug, Clone, Visit, Reflect)]
|
||||
pub struct Model {
|
||||
#[visit(skip)]
|
||||
pub(crate) mapping: NodeMapping,
|
||||
@@ -612,6 +612,10 @@ impl ResourceData for Model {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Model {
|
||||
|
||||
@@ -186,6 +186,18 @@ pub struct Graph {
|
||||
instance_id_map: FxHashMap<SceneNodeId, Handle<Node>>,
|
||||
}
|
||||
|
||||
impl Clone for Graph {
|
||||
fn clone(&self) -> Self {
|
||||
self.clone_ex(
|
||||
self.root,
|
||||
&mut |_, _| true,
|
||||
&mut |_, _| {},
|
||||
&mut |_, _, _| {},
|
||||
)
|
||||
.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Graph {
|
||||
fn default() -> Self {
|
||||
let (script_message_sender, script_message_receiver) = channel();
|
||||
@@ -1408,7 +1420,7 @@ impl Graph {
|
||||
/// Creates deep copy of graph. Allows filtering while copying, returns copy and
|
||||
/// old-to-new node mapping.
|
||||
#[inline]
|
||||
pub fn clone<F, Pre, Post>(
|
||||
pub fn clone_ex<F, Pre, Post>(
|
||||
&self,
|
||||
root: Handle<Node>,
|
||||
filter: &mut F,
|
||||
|
||||
@@ -250,6 +250,10 @@ impl ResourceData for SurfaceData {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl SurfaceData {
|
||||
|
||||
@@ -238,6 +238,12 @@ pub struct Scene {
|
||||
pub enabled: InheritableVariable<bool>,
|
||||
}
|
||||
|
||||
impl Clone for Scene {
|
||||
fn clone(&self) -> Self {
|
||||
self.clone_one_to_one().0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Scene {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -465,7 +471,7 @@ impl Scene {
|
||||
|
||||
/// Creates deep copy of a scene, filter predicate allows you to filter out nodes
|
||||
/// by your criteria.
|
||||
pub fn clone<F, Pre, Post>(
|
||||
pub fn clone_ex<F, Pre, Post>(
|
||||
&self,
|
||||
root: Handle<Node>,
|
||||
filter: &mut F,
|
||||
@@ -479,7 +485,7 @@ impl Scene {
|
||||
{
|
||||
let (graph, old_new_map) =
|
||||
self.graph
|
||||
.clone(root, filter, pre_process_callback, post_process_callback);
|
||||
.clone_ex(root, filter, pre_process_callback, post_process_callback);
|
||||
|
||||
(
|
||||
Self {
|
||||
@@ -495,7 +501,7 @@ impl Scene {
|
||||
|
||||
/// Creates deep copy of a scene. Same as [`Self::clone`], but does 1:1 cloning.
|
||||
pub fn clone_one_to_one(&self) -> (Self, NodeHandleMap<Node>) {
|
||||
self.clone(
|
||||
self.clone_ex(
|
||||
self.graph.get_root(),
|
||||
&mut |_, _| true,
|
||||
&mut |_, _| {},
|
||||
|
||||
@@ -35,7 +35,7 @@ use fyrox_core::visitor::error::VisitError;
|
||||
|
||||
/// A wrapper for node pool record that allows to define custom visit method to have full
|
||||
/// control over instantiation process at deserialization.
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Clone, Default, Reflect)]
|
||||
pub struct NodeContainer(Option<Node>);
|
||||
|
||||
fn read_node(name: &str, visitor: &mut Visitor) -> Result<Node, VisitError> {
|
||||
|
||||
@@ -611,6 +611,10 @@ impl Reflect for Node {
|
||||
fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
|
||||
self.0.deref_mut().field_mut(name, func)
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -243,6 +243,10 @@ impl Reflect for Limb {
|
||||
let this = std::mem::replace(self, value.take()?);
|
||||
Ok(Box::new(this))
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for Limb {
|
||||
|
||||
@@ -568,6 +568,10 @@ impl ResourceData for TileMapBrush {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Standard tile map brush loader.
|
||||
|
||||
@@ -207,6 +207,10 @@ impl ResourceData for TileMapData {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl TileSource for TileMapData {
|
||||
|
||||
@@ -402,7 +402,7 @@ pub enum PageType {
|
||||
/// Both pages and tiles have a TileDefinitionHandle and are rendered using
|
||||
/// [`TileRenderData`]. For pages this is due to having an icon to allow the user to select the page.
|
||||
/// Both pages and tiles can be selected by the user, moved, and deleted.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Reflect)]
|
||||
pub enum ResourceTilePosition {
|
||||
/// This position refers to some page, and so it lacks tile coordinates.
|
||||
Page(Vector2<i32>),
|
||||
|
||||
@@ -194,6 +194,10 @@ impl ResourceData for CustomTileCollider {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl OrthoTransform for CustomTileCollider {
|
||||
|
||||
@@ -57,22 +57,22 @@ fn position_to_vector(source: PalettePosition) -> Vector2<i32> {
|
||||
|
||||
/// A 2D grid that contains tile data.
|
||||
#[derive(Default, Debug, Clone, PartialEq, Reflect)]
|
||||
pub struct TileGridMap<V: Debug>(FxHashMap<Vector2<i32>, V>);
|
||||
pub struct TileGridMap<V: Debug + Clone>(FxHashMap<Vector2<i32>, V>);
|
||||
|
||||
impl<V: Visit + Default + Debug> Visit for TileGridMap<V> {
|
||||
impl<V: Visit + Default + Debug + Clone> Visit for TileGridMap<V> {
|
||||
fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
|
||||
self.0.visit(name, visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Debug> Deref for TileGridMap<V> {
|
||||
impl<V: Debug + Clone> Deref for TileGridMap<V> {
|
||||
type Target = FxHashMap<Vector2<i32>, V>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Debug> DerefMut for TileGridMap<V> {
|
||||
impl<V: Debug + Clone> DerefMut for TileGridMap<V> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
@@ -381,7 +381,7 @@ pub struct Stamp {
|
||||
|
||||
/// Each cell of a stamp must have a tile handle and it may optionally have
|
||||
/// the handle of a brush cell where the tile was taken from.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Reflect)]
|
||||
pub struct StampElement {
|
||||
/// The stamp cell's tile handle
|
||||
pub handle: TileDefinitionHandle,
|
||||
|
||||
@@ -2118,6 +2118,10 @@ impl ResourceData for TileSet {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// An alias for `Resource<TileSet>`.
|
||||
|
||||
@@ -585,7 +585,7 @@ impl TileSetUpdate {
|
||||
/// A stamp element plus the transformation of the [`Stamp`] where the element is taken from,
|
||||
/// allowing the stamp element itself to be later transformed before it is applied to a tile map,
|
||||
/// tile set, or brush.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Reflect)]
|
||||
pub struct RotTileHandle {
|
||||
/// The transformation of the element.
|
||||
pub transform: OrthoTransformation,
|
||||
|
||||
@@ -334,6 +334,7 @@ pub struct ScriptContext<'a, 'b, 'c> {
|
||||
/// # };
|
||||
/// #
|
||||
/// #[derive(Visit, Reflect, Default, Debug)]
|
||||
/// #[reflect(non_cloneable)]
|
||||
/// struct Game {
|
||||
/// player_name: String,
|
||||
/// }
|
||||
@@ -751,6 +752,10 @@ impl Reflect for Script {
|
||||
fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
|
||||
self.instance.deref_mut().as_list_mut(func)
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Script {
|
||||
|
||||
@@ -126,7 +126,7 @@ where
|
||||
#[derive(Debug, PartialEq, Visit, Clone)]
|
||||
pub struct BehaviorTree<B>
|
||||
where
|
||||
B: Clone,
|
||||
B: Clone + 'static,
|
||||
{
|
||||
nodes: Pool<BehaviorNode<B>>,
|
||||
root: Handle<BehaviorNode<B>>,
|
||||
|
||||
@@ -14,7 +14,7 @@ repository = "https://github.com/FyroxEngine/Fyrox"
|
||||
rust-version = "1.86"
|
||||
|
||||
[dependencies]
|
||||
rectutils = "0.3.0"
|
||||
rectutils = "0.4.0"
|
||||
nalgebra = { version = "0.33", features = ["bytemuck"] }
|
||||
arrayvec = "0.7.4"
|
||||
num-traits = "0.2.18"
|
||||
|
||||
@@ -93,7 +93,7 @@ pub struct UntypedBuiltInResource {
|
||||
/// };
|
||||
/// use std::{error::Error, path::Path};
|
||||
///
|
||||
/// #[derive(TypeUuidProvider, Default, Debug, Visit, Reflect)]
|
||||
/// #[derive(TypeUuidProvider, Default, Debug, Clone, Visit, Reflect)]
|
||||
/// #[type_uuid(id = "00d036bb-fbed-47f7-94e3-b3fce93dee17")]
|
||||
/// struct MyResource {
|
||||
/// some_data: String,
|
||||
@@ -111,6 +111,10 @@ pub struct UntypedBuiltInResource {
|
||||
/// fn can_be_saved(&self) -> bool {
|
||||
/// false
|
||||
/// }
|
||||
///
|
||||
/// fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
/// Some(Box::new(self.clone()))
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn register_built_in_resource(resource_manager: &ResourceManager) {
|
||||
|
||||
@@ -112,7 +112,7 @@ mod test {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, Reflect, Visit)]
|
||||
#[derive(Debug, Default, Clone, Reflect, Visit)]
|
||||
struct Stub {}
|
||||
|
||||
impl ResourceData for Stub {
|
||||
@@ -127,6 +127,10 @@ mod test {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeUuidProvider for Stub {
|
||||
|
||||
@@ -96,6 +96,10 @@ pub trait ResourceData: Debug + Visit + Send + Reflect {
|
||||
/// resource type supports saving, for example there might be temporary resource type that is
|
||||
/// used only at runtime which does not need saving at all.
|
||||
fn can_be_saved(&self) -> bool;
|
||||
|
||||
/// Tries to clone the resource data. This method can return `None` if the underlying type is
|
||||
/// non-cloneable.
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>>;
|
||||
}
|
||||
|
||||
/// Extension trait for a resource data of a particular type, which adds additional functionality,
|
||||
@@ -159,10 +163,7 @@ where
|
||||
///
|
||||
/// Default state of the resource will be [`ResourceState::Ok`] with `T::default`.
|
||||
#[derive(Debug, Reflect)]
|
||||
pub struct Resource<T>
|
||||
where
|
||||
T: TypedResourceData,
|
||||
{
|
||||
pub struct Resource<T: Debug> {
|
||||
untyped: UntypedResource,
|
||||
#[reflect(hidden)]
|
||||
phantom: PhantomData<T>,
|
||||
@@ -409,10 +410,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for Resource<T>
|
||||
where
|
||||
T: TypedResourceData,
|
||||
{
|
||||
impl<T: Debug> Clone for Resource<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
@@ -696,7 +694,7 @@ mod tests {
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Visit, Reflect, TypeUuidProvider)]
|
||||
#[derive(Serialize, Deserialize, Default, Debug, Clone, Visit, Reflect, TypeUuidProvider)]
|
||||
#[type_uuid(id = "241d14c7-079e-4395-a63c-364f0fc3e6ea")]
|
||||
struct MyData {
|
||||
data: u32,
|
||||
@@ -741,6 +739,10 @@ mod tests {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
struct MyDataLoader {}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
//! docs for more info.
|
||||
|
||||
pub use crate::builtin::*;
|
||||
use crate::state::ResourceDataWrapper;
|
||||
use crate::{
|
||||
constructor::ResourceConstructorContainer,
|
||||
core::{
|
||||
@@ -737,7 +738,7 @@ impl ResourceManagerState {
|
||||
assert!(mutex_guard.kind.is_external());
|
||||
|
||||
mutex_guard.state.commit(ResourceState::Ok {
|
||||
data,
|
||||
data: ResourceDataWrapper(data),
|
||||
resource_uuid,
|
||||
});
|
||||
|
||||
@@ -947,7 +948,7 @@ mod test {
|
||||
};
|
||||
use std::{error::Error, fs::File, time::Duration};
|
||||
|
||||
#[derive(Debug, Default, Reflect, Visit)]
|
||||
#[derive(Debug, Default, Clone, Reflect, Visit)]
|
||||
struct Stub {}
|
||||
|
||||
impl TypeUuidProvider for Stub {
|
||||
@@ -968,6 +969,10 @@ mod test {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl ResourceLoader for Stub {
|
||||
|
||||
+175
-7
@@ -26,7 +26,9 @@ use crate::{
|
||||
manager::ResourceManager,
|
||||
ResourceData, ResourceLoadError,
|
||||
};
|
||||
use fyrox_core::reflect::ReflectHandle;
|
||||
use fyrox_core::warn;
|
||||
use std::any::{Any, TypeId};
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
@@ -75,6 +77,168 @@ impl LoadError {
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub struct ResourceDataWrapper(pub Box<dyn ResourceData>);
|
||||
|
||||
impl Reflect for ResourceDataWrapper {
|
||||
fn source_path() -> &'static str
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
file!()
|
||||
}
|
||||
|
||||
fn derived_types() -> &'static [TypeId]
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
&[]
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Reflect::try_clone_box(&*self.0)
|
||||
}
|
||||
|
||||
fn query_derived_types(&self) -> &'static [TypeId] {
|
||||
self.deref().query_derived_types()
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &'static str {
|
||||
self.deref().type_name()
|
||||
}
|
||||
|
||||
fn doc(&self) -> &'static str {
|
||||
self.deref().doc()
|
||||
}
|
||||
|
||||
fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
|
||||
self.deref().fields_ref(func)
|
||||
}
|
||||
|
||||
fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
|
||||
self.deref_mut().fields_mut(func)
|
||||
}
|
||||
|
||||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
|
||||
self.deref().as_any(func)
|
||||
}
|
||||
|
||||
fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
|
||||
self.deref_mut().as_any_mut(func)
|
||||
}
|
||||
|
||||
fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
|
||||
self.deref().as_reflect(func)
|
||||
}
|
||||
|
||||
fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
|
||||
self.deref_mut().as_reflect_mut(func)
|
||||
}
|
||||
|
||||
fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
|
||||
self.deref_mut().set(value)
|
||||
}
|
||||
|
||||
fn assembly_name(&self) -> &'static str {
|
||||
env!("CARGO_PKG_NAME")
|
||||
}
|
||||
|
||||
fn type_assembly_name() -> &'static str
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
env!("CARGO_PKG_NAME")
|
||||
}
|
||||
|
||||
fn set_field(
|
||||
&mut self,
|
||||
field: &str,
|
||||
value: Box<dyn Reflect>,
|
||||
func: &mut dyn FnMut(Result<Box<dyn Reflect>, Box<dyn Reflect>>),
|
||||
) {
|
||||
self.deref_mut().set_field(field, value, func)
|
||||
}
|
||||
|
||||
fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
|
||||
self.deref().field(name, func)
|
||||
}
|
||||
|
||||
fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
|
||||
self.deref_mut().field_mut(name, func)
|
||||
}
|
||||
|
||||
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
|
||||
self.deref().as_array(func)
|
||||
}
|
||||
|
||||
fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
|
||||
self.deref_mut().as_array_mut(func)
|
||||
}
|
||||
|
||||
fn as_list(&self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
|
||||
self.deref().as_list(func)
|
||||
}
|
||||
|
||||
fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
|
||||
self.deref_mut().as_list_mut(func)
|
||||
}
|
||||
|
||||
fn as_inheritable_variable(
|
||||
&self,
|
||||
func: &mut dyn FnMut(Option<&dyn ReflectInheritableVariable>),
|
||||
) {
|
||||
self.deref().as_inheritable_variable(func)
|
||||
}
|
||||
|
||||
fn as_inheritable_variable_mut(
|
||||
&mut self,
|
||||
func: &mut dyn FnMut(Option<&mut dyn ReflectInheritableVariable>),
|
||||
) {
|
||||
self.deref_mut().as_inheritable_variable_mut(func)
|
||||
}
|
||||
|
||||
fn as_hash_map(&self, func: &mut dyn FnMut(Option<&dyn ReflectHashMap>)) {
|
||||
self.deref().as_hash_map(func)
|
||||
}
|
||||
|
||||
fn as_hash_map_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHashMap>)) {
|
||||
self.deref_mut().as_hash_map_mut(func)
|
||||
}
|
||||
|
||||
fn as_handle(&self, func: &mut dyn FnMut(Option<&dyn ReflectHandle>)) {
|
||||
self.deref().as_handle(func)
|
||||
}
|
||||
|
||||
fn as_handle_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHandle>)) {
|
||||
self.deref_mut().as_handle_mut(func)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ResourceDataWrapper {
|
||||
type Target = dyn ResourceData;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for ResourceDataWrapper {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut *self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for ResourceDataWrapper {
|
||||
fn clone(&self) -> Self {
|
||||
Self(ResourceData::try_clone_box(&*self.0).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
/// Resource could be in three possible states (a small state machine):
|
||||
///
|
||||
/// 1. Pending - it is loading or queued for loading.
|
||||
@@ -101,7 +265,7 @@ impl LoadError {
|
||||
/// to get the UUID earlier: the UUID is stored in a metadata file which exists only if the resource
|
||||
/// is present. It is somewhat possible to get a UUID when a resource is failed to load, but not in
|
||||
/// 100% cases.
|
||||
#[derive(Debug, Reflect)]
|
||||
#[derive(Debug, Clone, Reflect)]
|
||||
pub enum ResourceState {
|
||||
/// Resource is loading from external resource or in the queue to load.
|
||||
Pending {
|
||||
@@ -127,7 +291,7 @@ pub enum ResourceState {
|
||||
/// Unique id of the resource.
|
||||
resource_uuid: Uuid,
|
||||
/// Actual data of the resource.
|
||||
data: Box<dyn ResourceData>,
|
||||
data: ResourceDataWrapper,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -185,7 +349,7 @@ impl ResourceState {
|
||||
|
||||
*self = Self::Ok {
|
||||
resource_uuid,
|
||||
data: instance,
|
||||
data: ResourceDataWrapper(instance),
|
||||
};
|
||||
} else {
|
||||
return Err(VisitError::User(format!(
|
||||
@@ -235,7 +399,7 @@ impl ResourceState {
|
||||
pub fn new_ok<T: ResourceData>(resource_uuid: Uuid, data: T) -> Self {
|
||||
Self::Ok {
|
||||
resource_uuid,
|
||||
data: Box::new(data),
|
||||
data: ResourceDataWrapper(Box::new(data)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +408,7 @@ impl ResourceState {
|
||||
pub fn new_ok_untyped(resource_uuid: Uuid, data: Box<dyn ResourceData>) -> Self {
|
||||
Self::Ok {
|
||||
resource_uuid,
|
||||
data,
|
||||
data: ResourceDataWrapper(data),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +458,7 @@ impl ResourceState {
|
||||
pub fn commit_ok<T: ResourceData>(&mut self, resource_uuid: Uuid, data: T) {
|
||||
self.commit(ResourceState::Ok {
|
||||
resource_uuid,
|
||||
data: Box::new(data),
|
||||
data: ResourceDataWrapper(Box::new(data)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -318,7 +482,7 @@ mod test {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, Reflect, Visit)]
|
||||
#[derive(Debug, Default, Clone, Reflect, Visit)]
|
||||
struct Stub {}
|
||||
|
||||
impl ResourceData for Stub {
|
||||
@@ -333,6 +497,10 @@ mod test {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeUuidProvider for Stub {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
//! A module for untyped resources. See [`UntypedResource`] docs for more info.
|
||||
|
||||
use crate::state::ResourceDataWrapper;
|
||||
use crate::{
|
||||
core::{
|
||||
math::curve::Curve, parking_lot::Mutex, reflect::prelude::*, uuid, uuid::Uuid,
|
||||
@@ -154,7 +155,7 @@ impl Display for ResourceKind {
|
||||
|
||||
/// Header of a resource, it contains a common data about the resource, such as its data type uuid,
|
||||
/// its kind, etc.
|
||||
#[derive(Reflect, Debug)]
|
||||
#[derive(Reflect, Clone, Debug)]
|
||||
pub struct ResourceHeader {
|
||||
/// Kind of the resource. See [`ResourceKind`] for more info.
|
||||
pub kind: ResourceKind,
|
||||
@@ -214,7 +215,7 @@ impl Visit for ResourceHeader {
|
||||
instance.visit("Details", &mut region)?;
|
||||
|
||||
self.state = ResourceState::Ok {
|
||||
data: instance,
|
||||
data: ResourceDataWrapper(instance),
|
||||
// The old format does not contain an uuid.
|
||||
resource_uuid: Uuid::nil(),
|
||||
};
|
||||
@@ -609,6 +610,10 @@ mod test {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(*self))
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeUuidProvider for Stub {
|
||||
@@ -660,7 +665,7 @@ mod test {
|
||||
let mut r = UntypedResource(Arc::new(Mutex::new(ResourceHeader {
|
||||
kind: ResourceKind::External,
|
||||
state: ResourceState::Ok {
|
||||
data: Box::new(stub),
|
||||
data: ResourceDataWrapper(Box::new(stub)),
|
||||
resource_uuid: Uuid::new_v4(),
|
||||
},
|
||||
old_format_path: None,
|
||||
|
||||
@@ -36,6 +36,7 @@ pub mod camera;
|
||||
/// # };
|
||||
/// #
|
||||
/// # #[derive(Visit, Reflect, Debug)]
|
||||
/// # #[reflect(non_cloneable)]
|
||||
/// # struct Game;
|
||||
/// #
|
||||
/// # impl Plugin for Game {
|
||||
|
||||
@@ -51,7 +51,7 @@ use std::time::Duration;
|
||||
use super::SoundBufferResourceLoadError;
|
||||
|
||||
/// Samples container.
|
||||
#[derive(Debug, Default, Visit, Reflect)]
|
||||
#[derive(Debug, Default, Visit, Clone, Reflect)]
|
||||
pub struct Samples(pub Vec<f32>);
|
||||
|
||||
impl Deref for Samples {
|
||||
@@ -69,7 +69,7 @@ impl DerefMut for Samples {
|
||||
}
|
||||
|
||||
/// Generic sound buffer that contains decoded samples and allows random access.
|
||||
#[derive(Debug, Default, Visit, Reflect)]
|
||||
#[derive(Debug, Clone, Default, Visit, Reflect)]
|
||||
pub struct GenericBuffer {
|
||||
/// Interleaved decoded samples (mono sounds: L..., stereo sounds: LR...)
|
||||
/// For streaming buffers it contains only small part of decoded data
|
||||
|
||||
@@ -239,6 +239,7 @@ impl std::error::Error for SoundBufferResourceLoadError {}
|
||||
|
||||
/// Sound buffer is a data source for sound sources. See module documentation for more info.
|
||||
#[derive(Debug, Visit, Reflect)]
|
||||
#[reflect(non_cloneable)]
|
||||
pub enum SoundBuffer {
|
||||
/// General-purpose buffer, usually contains all the data and allows random
|
||||
/// access to samples. It is also used to make streaming buffer via composition.
|
||||
@@ -357,4 +358,8 @@ impl ResourceData for SoundBuffer {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ use std::{
|
||||
|
||||
/// Streaming buffer for long sounds. Does not support random access.
|
||||
#[derive(Debug, Default, Visit, Reflect)]
|
||||
#[reflect(non_cloneable)]
|
||||
pub struct StreamingBuffer {
|
||||
pub(crate) generic: GenericBuffer,
|
||||
/// Count of sources that share this buffer, it is important to keep only one
|
||||
|
||||
@@ -203,7 +203,7 @@ impl HrtfRenderer {
|
||||
|
||||
/// Wrapper for [`HrirSphere`] to be able to use it in the resource manager, that will handle async resource
|
||||
/// loading automatically.
|
||||
#[derive(Reflect, Default, Visit)]
|
||||
#[derive(Reflect, Default, Clone, Visit)]
|
||||
pub struct HrirSphereResourceData {
|
||||
#[reflect(hidden)]
|
||||
#[visit(skip)]
|
||||
@@ -234,6 +234,10 @@ impl ResourceData for HrirSphereResourceData {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Resource loader for [`HrirSphereResource`].
|
||||
|
||||
@@ -345,6 +345,10 @@ impl ResourceData for Texture {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for Texture {
|
||||
|
||||
@@ -43,7 +43,7 @@ use std::{
|
||||
|
||||
pub mod loader;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FontGlyph {
|
||||
pub bitmap_top: f32,
|
||||
pub bitmap_left: f32,
|
||||
@@ -56,6 +56,7 @@ pub struct FontGlyph {
|
||||
}
|
||||
|
||||
/// Page is a storage for rasterized glyphs.
|
||||
#[derive(Clone)]
|
||||
pub struct Page {
|
||||
pub pixels: Vec<u8>,
|
||||
pub texture: Option<UntypedResource>,
|
||||
@@ -75,7 +76,7 @@ impl Debug for Page {
|
||||
|
||||
/// Atlas is a storage for glyphs of a particular size, each atlas could have any number of pages to
|
||||
/// store the rasterized glyphs.
|
||||
#[derive(Default, Debug)]
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct Atlas {
|
||||
pub glyphs: Vec<FontGlyph>,
|
||||
pub char_map: FxHashMap<char, usize>,
|
||||
@@ -210,7 +211,7 @@ impl Atlas {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Reflect, Visit)]
|
||||
#[derive(Default, Clone, Debug, Reflect, Visit)]
|
||||
#[reflect(hide_all)]
|
||||
pub struct Font {
|
||||
#[visit(skip)]
|
||||
@@ -235,6 +236,10 @@ impl ResourceData for Font {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Debug)]
|
||||
|
||||
@@ -795,7 +795,7 @@ impl PropertyEditorDefinitionContainer {
|
||||
|
||||
pub fn register_inheritable_styleable_inspectable<T>(&self)
|
||||
where
|
||||
T: Reflect + FieldValue,
|
||||
T: Reflect + FieldValue + Clone + PartialEq,
|
||||
{
|
||||
assert!(self
|
||||
.insert(InspectablePropertyEditorDefinition::<T>::new())
|
||||
@@ -829,7 +829,13 @@ impl PropertyEditorDefinitionContainer {
|
||||
|
||||
pub fn register_inheritable_styleable_enum<T, E: Debug>(&self)
|
||||
where
|
||||
T: InspectableEnum + FieldValue + VariantNames + AsRef<str> + FromStr<Err = E> + Debug,
|
||||
T: InspectableEnum
|
||||
+ FieldValue
|
||||
+ VariantNames
|
||||
+ AsRef<str>
|
||||
+ FromStr<Err = E>
|
||||
+ Debug
|
||||
+ PartialEq,
|
||||
{
|
||||
assert!(self
|
||||
.insert(EnumPropertyEditorDefinition::<T>::new())
|
||||
|
||||
+5
-1
@@ -338,7 +338,7 @@ use fyrox_core::pool::{BorrowAs, ErasedHandle};
|
||||
use fyrox_resource::untyped::ResourceKind;
|
||||
pub use fyrox_texture as texture;
|
||||
|
||||
#[derive(Default, Reflect, Debug)]
|
||||
#[derive(Default, Clone, Reflect, Debug)]
|
||||
pub(crate) struct RcUiNodeHandleInner {
|
||||
handle: Handle<UiNode>,
|
||||
#[reflect(hidden)]
|
||||
@@ -3548,6 +3548,10 @@ impl ResourceData for UserInterface {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
pub mod test {
|
||||
|
||||
@@ -35,7 +35,7 @@ use fyrox_core::visitor::error::VisitError;
|
||||
|
||||
/// A wrapper for widget pool record that allows to define custom visit method to have full
|
||||
/// control over instantiation process at deserialization.
|
||||
#[derive(Debug, Default, Reflect)]
|
||||
#[derive(Debug, Clone, Default, Reflect)]
|
||||
pub struct WidgetContainer(Option<UiNode>);
|
||||
|
||||
fn read_widget(name: &str, visitor: &mut Visitor) -> Result<UiNode, VisitError> {
|
||||
|
||||
@@ -355,4 +355,8 @@ impl Reflect for UiNode {
|
||||
fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
|
||||
self.0.deref_mut().field_mut(name, func)
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,8 @@ lazy_static! {
|
||||
/// the style and why do we need to store the value as well? The answer is flexibility. In this
|
||||
/// approach style becomes not necessary and the value can be hardcoded. Also, the values of such
|
||||
/// properties can be updated individually.
|
||||
#[derive(Clone, Debug, Default, Reflect)]
|
||||
#[derive(Clone, Debug, Reflect, Default)]
|
||||
#[reflect(bounds = "T: Reflect + Clone")]
|
||||
pub struct StyledProperty<T> {
|
||||
/// Property value.
|
||||
pub property: T,
|
||||
@@ -252,7 +253,7 @@ impl<T: Visit> Visit for StyledProperty<T> {
|
||||
/// ui.set_style(StyleResource::new_embedded(style));
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Visit, Reflect, Default, Debug, TypeUuidProvider)]
|
||||
#[derive(Visit, Reflect, Clone, Default, Debug, TypeUuidProvider)]
|
||||
#[type_uuid(id = "38a63b49-d765-4c01-8fb5-202cc43d607e")]
|
||||
pub struct Style {
|
||||
parent: Option<StyleResource>,
|
||||
|
||||
@@ -96,6 +96,10 @@ impl ResourceData for Style {
|
||||
fn can_be_saved(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
|
||||
Some(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
/// A loader for style resource.
|
||||
|
||||
@@ -91,7 +91,7 @@ pub static DATA_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
data_dir
|
||||
});
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Reflect, Debug)]
|
||||
#[derive(Default, Serialize, Deserialize, Reflect, Clone, Debug)]
|
||||
pub struct SettingsData {
|
||||
#[serde(default = "default_open_ide_command")]
|
||||
#[reflect(
|
||||
@@ -203,7 +203,7 @@ impl Settings {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Project {
|
||||
pub manifest_path: PathBuf,
|
||||
pub name: String,
|
||||
|
||||
Reference in New Issue
Block a user