diff options
| author | Arne Dußin | 2021-02-03 10:51:08 +0100 |
|---|---|---|
| committer | Arne Dußin | 2021-02-03 10:51:08 +0100 |
| commit | d4c1c7ecb5688ef64f45425d9ac8e7ddeb8e8602 (patch) | |
| tree | 6788d2efc22373d735947ba46d3a3ea3b3b3733c /src | |
| parent | f92e9f6f07b1e3834c2ca58ce3510734819d08e4 (diff) | |
| download | graf_karto-d4c1c7ecb5688ef64f45425d9ac8e7ddeb8e8602.tar.gz graf_karto-d4c1c7ecb5688ef64f45425d9ac8e7ddeb8e8602.zip | |
Fix commands
Commands now operate on the local file system, but on the remote world
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/cli/cmd/edit.rs | 20 | ||||
| -rw-r--r-- | src/client/cli/cmd/read.rs | 17 | ||||
| -rw-r--r-- | src/client/cli/cmd/write.rs | 4 | ||||
| -rw-r--r-- | src/client/map/mod.rs | 30 | ||||
| -rw-r--r-- | src/net/cargo.rs | 4 | ||||
| -rw-r--r-- | src/stable_vec.rs | 2 | ||||
| -rw-r--r-- | src/world/mod.rs | 17 |
7 files changed, 82 insertions, 12 deletions
diff --git a/src/client/cli/cmd/edit.rs b/src/client/cli/cmd/edit.rs index 7a02959..1cfb530 100644 --- a/src/client/cli/cmd/edit.rs +++ b/src/client/cli/cmd/edit.rs @@ -2,8 +2,9 @@ use super::Command; use super::{CmdParseError, FromArgs}; -use crate::client::map::MapData; use crate::client::Editor; +use crate::net::Cargo; +use crate::world::World; use std::path::PathBuf; /// Command to load a file from the disk and replace the current editor contents with it's info. @@ -25,8 +26,8 @@ impl FromArgs for Edit { impl Command for Edit { fn process(&self, editor: &mut Editor) -> Result<String, String> { - let data = match MapData::load_from_file(&self.file) { - Ok(data) => data, + let world = match World::load_from_file(&self.file) { + Ok(world) => world, Err(err) => { return Err(format!( "Unable to read file: {:?}, reason: {:?}", @@ -35,7 +36,18 @@ impl Command for Edit { } }; - editor.map_mut().set_data(data); + // Clear all data from the world, afterwards add all components from the file. + editor.server().send(Cargo::ClearAll); + for (_, icon) in world.icons().iter() { + editor.server().send(Cargo::AddIcon(icon.clone())); + } + for (_, room) in world.rooms().iter() { + editor.server().send(Cargo::AddRoom(room.clone())); + } + for (_, wall) in world.walls().iter() { + editor.server().send(Cargo::AddWall(wall.clone())); + } + Ok(format!("Map data from {:?} loaded.", &self.file)) } } diff --git a/src/client/cli/cmd/read.rs b/src/client/cli/cmd/read.rs index 313530a..3b20308 100644 --- a/src/client/cli/cmd/read.rs +++ b/src/client/cli/cmd/read.rs @@ -3,7 +3,8 @@ use super::Command; use super::{CmdParseError, FromArgs}; use crate::client::Editor; -use crate::map::MapData; +use crate::net::Cargo; +use crate::world::World; use std::path::PathBuf; /// Command to read a file from the system @@ -25,7 +26,7 @@ impl FromArgs for Read { impl Command for Read { fn process(&self, editor: &mut Editor) -> Result<String, String> { - let data = match MapData::load_from_file(&self.file) { + let world = match World::load_from_file(&self.file) { Ok(data) => data, Err(err) => { return Err(format!( @@ -35,7 +36,17 @@ impl Command for Read { } }; - editor.map_mut().add_data(data); + // Send all components of the file to the server. + for (_, icon) in world.icons().iter() { + editor.server().send(Cargo::AddIcon(icon.clone())); + } + for (_, room) in world.rooms().iter() { + editor.server().send(Cargo::AddRoom(room.clone())); + } + for (_, wall) in world.walls().iter() { + editor.server().send(Cargo::AddWall(wall.clone())); + } + Ok(format!( "Map data from {:?} read and added to the current buffer.", &self.file diff --git a/src/client/cli/cmd/write.rs b/src/client/cli/cmd/write.rs index 3114f63..37d5a0a 100644 --- a/src/client/cli/cmd/write.rs +++ b/src/client/cli/cmd/write.rs @@ -25,9 +25,9 @@ impl FromArgs for Write { impl Command for Write { fn process(&self, editor: &mut Editor) -> Result<String, String> { - let data = MapData::extract_data(editor.map()); + let world = editor.map().clone_as_world(); - match data.write_to_file(&self.destination) { + match world.write_to_file(&self.destination) { Ok(_) => Ok(format!( "Successfully wrote contents to `{:?}`", &self.destination diff --git a/src/client/map/mod.rs b/src/client/map/mod.rs index eaab72f..27cafc4 100644 --- a/src/client/map/mod.rs +++ b/src/client/map/mod.rs @@ -20,6 +20,7 @@ use crate::world::{Room, Wall, World}; use icon_texture_manager::IconTextureManager; use raylib::drawing::RaylibDrawHandle; use raylib::{RaylibHandle, RaylibThread}; +use std::ops::Deref; use std::rc::Rc; /// The map containing all map elements that are seen on the screen. @@ -194,7 +195,10 @@ impl Map { /// items with the same id will therefore be ignored and not added. pub fn add_data(&mut self, world: World) { for (id, i) in world.icons().iter() { - self.add_icon(*id, IconMark::from_icon(*i, self.icon_renderer.clone())); + self.add_icon( + *id, + IconMark::from_icon(i.clone(), self.icon_renderer.clone()), + ); } for (id, r) in world.rooms().iter() { self.add_room(*id, r.clone()); @@ -203,4 +207,28 @@ impl Map { self.add_wall(*id, w.clone()); } } + + /// Creates a world from + pub fn clone_as_world(&self) -> World { + let rooms = self + .rooms + .iter() + .map(|(id, mark)| (*id, mark.deref().clone())) + .collect(); + let rooms = StableVec::from_raw_unchecked(rooms); + let icons = self + .icons + .iter() + .map(|(id, mark)| (*id, mark.deref().clone())) + .collect(); + let icons = StableVec::from_raw_unchecked(icons); + let walls = self + .walls + .iter() + .map(|(id, mark)| (*id, mark.deref().clone())) + .collect(); + let walls = StableVec::from_raw_unchecked(walls); + + World::from_raw_unchecked(rooms, walls, icons, self.used_ids.clone()) + } } diff --git a/src/net/cargo.rs b/src/net/cargo.rs index b05944c..34e6bb4 100644 --- a/src/net/cargo.rs +++ b/src/net/cargo.rs @@ -24,7 +24,9 @@ pub enum Cargo { /// Client -> Server: Request to apply the given matrix to the item with the provided id. /// If the matrix cannot be applied to an item with the given id, it will do nothing. ApplyMatrix((usize, Matrix3<f64>)), - /// Client <-> Remove the item with the given id. + /// Client <-> Server: Clear all data from the world. + ClearAll, + /// Client <-> Server: Remove the item with the given id. Remove(usize), /// Server -> Client: Add all of the data additively to the map AddMapData(World), diff --git a/src/stable_vec.rs b/src/stable_vec.rs index 72a1995..c3b8685 100644 --- a/src/stable_vec.rs +++ b/src/stable_vec.rs @@ -7,7 +7,7 @@ use std::slice::IterMut; /// Works like Vec, but with an additional field, where the position information is saved. Does not /// support inserting elements in arbitrary positions, since that may shift the data. Removing data /// in the middle is fine, however. -#[derive(Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct StableVec<T> { data: Vec<(usize, T)>, } diff --git a/src/world/mod.rs b/src/world/mod.rs index 047ca5c..f163269 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -34,6 +34,23 @@ pub struct World { } impl World { + /// Create a world from the raw parts of the world. The components must fit, + /// meaning no id must exist twice and the used ids must correspond to the + /// actually used ids. Use with care. + pub fn from_raw_unchecked( + rooms: StableVec<Room>, + walls: StableVec<Wall>, + icons: StableVec<Icon>, + used_ids: StableVec<()>, + ) -> Self { + Self { + rooms, + walls, + icons, + used_ids, + } + } + /// Load the world data from a file. Fails if the file does not exist or /// cannot be correctly parsed. pub fn load_from_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { |
