aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/cli/cmd/edit.rs20
-rw-r--r--src/client/cli/cmd/read.rs17
-rw-r--r--src/client/cli/cmd/write.rs4
-rw-r--r--src/client/map/mod.rs30
-rw-r--r--src/net/cargo.rs4
-rw-r--r--src/stable_vec.rs2
-rw-r--r--src/world/mod.rs17
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> {