fixed terrain layer deletion from inspector

This commit is contained in:
Dmitry
2022-08-07 18:22:33 +03:00
parent c4f5db5429
commit c8a6d0761a
3 changed files with 73 additions and 41 deletions
+33 -26
View File
@@ -1,33 +1,43 @@
use crate::{
scene::commands::{make_set_node_property_command, terrain::AddTerrainLayerCommandConstructor},
scene::commands::{
make_set_node_property_command,
terrain::{AddTerrainLayerCommand, DeleteTerrainLayerCommand},
},
SceneCommand,
};
use fyrox::{
core::pool::Handle,
fxhash::FxHashMap,
gui::inspector::PropertyChanged,
gui::inspector::{CollectionChanged, FieldKind, PropertyChanged},
scene::{node::Node, terrain::Terrain},
};
use std::any::TypeId;
/// A set of constructors for special cases, when simple reflection is not enough.
pub trait CommandConstructor {
fn make_command(&self, handle: Handle<Node>, node: &mut Node) -> SceneCommand;
}
pub struct SceneNodePropertyChangedHandler {
unique_handlers: FxHashMap<String, Box<dyn CommandConstructor>>,
}
pub struct SceneNodePropertyChangedHandler;
impl SceneNodePropertyChangedHandler {
pub fn new() -> Self {
let mut unique_handlers = FxHashMap::<String, Box<dyn CommandConstructor>>::default();
unique_handlers.insert(
Terrain::LAYERS.to_string(),
Box::new(AddTerrainLayerCommandConstructor),
);
Self { unique_handlers }
fn try_get_command(
&self,
args: &PropertyChanged,
handle: Handle<Node>,
node: &mut Node,
) -> Option<SceneCommand> {
// Terrain is special and have its own commands for specific properties.
if args.path() == Terrain::LAYERS && args.owner_type_id == TypeId::of::<Terrain>() {
match args.value {
FieldKind::Collection(ref collection_changed) => match **collection_changed {
CollectionChanged::Add(_) => Some(SceneCommand::new(
AddTerrainLayerCommand::new(handle, node.as_terrain()),
)),
CollectionChanged::Remove(index) => Some(SceneCommand::new(
DeleteTerrainLayerCommand::new(handle, index),
)),
CollectionChanged::ItemChanged { .. } => None,
},
_ => None,
}
} else {
None
}
}
}
@@ -37,11 +47,8 @@ impl SceneNodePropertyChangedHandler {
args: &PropertyChanged,
handle: Handle<Node>,
node: &mut Node,
) -> Option<SceneCommand> {
if let Some(constructor) = self.unique_handlers.get(&args.path()) {
Some(constructor.make_command(handle, node))
} else {
Some(make_set_node_property_command(handle, args))
}
) -> SceneCommand {
self.try_get_command(args, handle, node)
.unwrap_or_else(|| make_set_node_property_command(handle, args))
}
}
+3 -3
View File
@@ -153,7 +153,7 @@ impl Inspector {
inspector,
property_editors,
needs_sync: true,
node_property_changed_handler: SceneNodePropertyChangedHandler::new(),
node_property_changed_handler: SceneNodePropertyChangedHandler,
warning_text,
}
}
@@ -317,11 +317,11 @@ impl Inspector {
.iter()
.filter_map(|&node_handle| {
if scene.graph.is_valid_handle(node_handle) {
self.node_property_changed_handler.handle(
Some(self.node_property_changed_handler.handle(
args,
node_handle,
&mut scene.graph[node_handle],
)
))
} else {
None
}
+37 -12
View File
@@ -1,7 +1,4 @@
use crate::{
command::Command, create_terrain_layer_material, inspector::handlers::node::CommandConstructor,
scene::commands::SceneContext, SceneCommand,
};
use crate::{command::Command, create_terrain_layer_material, scene::commands::SceneContext};
use fyrox::{
core::pool::Handle,
scene::{node::Node, terrain::Layer, terrain::Terrain},
@@ -13,14 +10,6 @@ pub struct AddTerrainLayerCommand {
layer: Option<Layer>,
}
pub struct AddTerrainLayerCommandConstructor;
impl CommandConstructor for AddTerrainLayerCommandConstructor {
fn make_command(&self, handle: Handle<Node>, node: &mut Node) -> SceneCommand {
SceneCommand::new(AddTerrainLayerCommand::new(handle, node.as_terrain()))
}
}
impl AddTerrainLayerCommand {
pub fn new(terrain_handle: Handle<Node>, terrain: &Terrain) -> Self {
Self {
@@ -50,6 +39,42 @@ impl Command for AddTerrainLayerCommand {
}
}
#[derive(Debug)]
pub struct DeleteTerrainLayerCommand {
terrain: Handle<Node>,
layer: Option<Layer>,
index: usize,
}
impl DeleteTerrainLayerCommand {
pub fn new(terrain: Handle<Node>, index: usize) -> Self {
Self {
terrain,
layer: Default::default(),
index,
}
}
}
impl Command for DeleteTerrainLayerCommand {
fn name(&mut self, _context: &SceneContext) -> String {
"Delete Terrain Layer".to_owned()
}
fn execute(&mut self, context: &mut SceneContext) {
self.layer = Some(
context.scene.graph[self.terrain]
.as_terrain_mut()
.remove_layer(self.index),
);
}
fn revert(&mut self, context: &mut SceneContext) {
let terrain = context.scene.graph[self.terrain].as_terrain_mut();
terrain.insert_layer(self.layer.take().unwrap(), self.index);
}
}
#[derive(Debug)]
pub struct ModifyTerrainHeightCommand {
terrain: Handle<Node>,