aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/editor.rs28
-rw-r--r--src/client/map/icon_mark.rs5
-rw-r--r--src/client/map/mod.rs29
-rw-r--r--src/client/map/wall_mark.rs6
-rw-r--r--src/server/mod.rs54
-rw-r--r--src/world/mod.rs50
6 files changed, 160 insertions, 12 deletions
diff --git a/src/client/editor.rs b/src/client/editor.rs
index e416339..fb271d4 100644
--- a/src/client/editor.rs
+++ b/src/client/editor.rs
@@ -168,12 +168,32 @@ impl Editor {
fn poll_net(&mut self) {
while let Some(cargo) = self.server().next_packet() {
match cargo {
- Cargo::SetRoom((id, new_room)) => {
- if let Some(mark) = self.map.get_room_mut(id) {
- mark.set_room(new_room);
- } else {
+ Cargo::SetRoom((id, new_room)) => match self.map.get_room_mut(id) {
+ Some(mark) => mark.set_room(new_room),
+ None => {
self.map.add_room(id, new_room);
}
+ },
+ Cargo::SetIcon((id, new_icon)) => match self.map.get_icon_mut(id) {
+ Some(mark) => mark.set_icon(new_icon),
+ None => {
+ self.map.add_icon(id, new_icon);
+ }
+ },
+ Cargo::SetWall((id, new_wall)) => match self.map.get_wall_mut(id) {
+ Some(mark) => mark.set_wall(new_wall),
+ None => {
+ self.map.add_wall(id, new_wall);
+ }
+ },
+ Cargo::ClearAll => self.map.clear(),
+ Cargo::Remove(id) => {
+ self.map.remove(id);
+ }
+ Cargo::AddMapData(_) => unimplemented!(),
+ Cargo::UpdateMapData(_) => unimplemented!(),
+ Cargo::AddIcon(_) | Cargo::AddRoom(_) | Cargo::AddWall(_) => {
+ error!("Packet is only valid in Client -> Server direction")
}
other => error!("Unknown packet received: {:?}", other),
}
diff --git a/src/client/map/icon_mark.rs b/src/client/map/icon_mark.rs
index 39fd554..02ed501 100644
--- a/src/client/map/icon_mark.rs
+++ b/src/client/map/icon_mark.rs
@@ -45,6 +45,11 @@ impl IconMark {
textures,
}
}
+
+ /// Set the inner icon this icon mark is referencing.
+ pub fn set_icon(&mut self, icon: Icon) {
+ self.icon = icon;
+ }
}
impl Mappable for IconMark {
diff --git a/src/client/map/mod.rs b/src/client/map/mod.rs
index 9589e59..7a0613c 100644
--- a/src/client/map/mod.rs
+++ b/src/client/map/mod.rs
@@ -16,7 +16,7 @@ pub use wall_mark::*;
use crate::client::Transform;
use crate::stable_vec::StableVec;
-use crate::world::{Room, Wall, World};
+use crate::world::{Icon, Room, Wall, World};
use icon_texture_manager::IconTextureManager;
use raylib::drawing::RaylibDrawHandle;
use raylib::{RaylibHandle, RaylibThread};
@@ -92,9 +92,11 @@ impl Map {
}
/// Add an icon with a specific id. May fail if there already is an entity with that id.
- pub fn add_icon(&mut self, id: usize, icon: IconMark) -> bool {
+ pub fn add_icon(&mut self, id: usize, icon: Icon) -> bool {
if self.used_ids.try_insert(id, ()).is_ok() {
- self.icons.try_insert(id, icon).unwrap();
+ self.icons
+ .try_insert(id, IconMark::from_icon(icon, self.icon_renderer.clone()))
+ .unwrap();
true
} else {
error!("Unable to add icon. Id already in use.");
@@ -162,6 +164,14 @@ impl Map {
)
}
+ /// Remove all items from the map.
+ pub fn clear(&mut self) {
+ self.rooms.clear();
+ self.walls.clear();
+ self.icons.clear();
+ self.used_ids.clear();
+ }
+
/// Get the rooms of this map.
pub fn rooms(&self) -> &StableVec<RoomMark> {
&self.rooms
@@ -175,11 +185,19 @@ impl Map {
pub fn walls(&self) -> &StableVec<WallMark> {
&self.walls
}
+ /// Get a wall with the given id mutably, in case it exists.
+ pub fn get_wall_mut(&mut self, id: usize) -> Option<&mut WallMark> {
+ self.walls.get_mut(id)
+ }
/// Get the icons of this map.
pub fn icons(&self) -> &StableVec<IconMark> {
&self.icons
}
+ /// Get an icon with the given id mutably, in case it exists.
+ pub fn get_icon_mut(&mut self, id: usize) -> Option<&mut IconMark> {
+ self.icons.get_mut(id)
+ }
/// Replace the internal map data with the data of the world provided.
/// (Load and replace)
@@ -199,10 +217,7 @@ 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.clone(), self.icon_renderer.clone()),
- );
+ self.add_icon(*id, i.clone());
}
for (id, r) in world.rooms().iter() {
self.add_room(*id, r.clone());
diff --git a/src/client/map/wall_mark.rs b/src/client/map/wall_mark.rs
index c51af9d..76ac03b 100644
--- a/src/client/map/wall_mark.rs
+++ b/src/client/map/wall_mark.rs
@@ -32,6 +32,12 @@ impl WallMark {
}
}
+ /// Set the internal wall of this wall mark.
+ pub fn set_wall(&mut self, wall: Wall) {
+ // XXX: Rounded edges??
+ self.wall = wall;
+ }
+
/// Get the internal data for serialisation
pub fn data(&self) -> &Wall {
&self.wall
diff --git a/src/server/mod.rs b/src/server/mod.rs
index fe208ad..7f94453 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -50,7 +50,59 @@ fn start(conn_man: ConnectionManager<Cargo>) -> JoinHandle<()> {
let room_id = world.push_room(room.clone());
conn_man.broadcast(Cargo::SetRoom((room_id, room)));
}
- other => error!("Unknown packet received from `{}`: {:?}", user, other),
+ Cargo::AddIcon(icon) => {
+ let icon_id = world.push_icon(icon.clone());
+ conn_man.broadcast(Cargo::SetIcon((icon_id, icon)));
+ }
+ Cargo::AddWall(wall) => {
+ let wall_id = world.push_wall(wall.clone());
+ conn_man.broadcast(Cargo::SetWall((wall_id, wall)));
+ }
+ Cargo::SetRoom((id, new)) => {
+ if let Some(old) = world.get_room_mut(id) {
+ *old = new;
+ } else {
+ error!(
+ "Unable to change room. Room with id `{}` does not exist.",
+ id
+ );
+ }
+ }
+ Cargo::SetIcon((id, new)) => {
+ if let Some(old) = world.get_icon_mut(id) {
+ *old = new;
+ } else {
+ error!(
+ "Unable to change icon. Icon with id `{}` does not exist.",
+ id
+ );
+ }
+ }
+ Cargo::SetWall((id, new)) => {
+ if let Some(old) = world.get_wall_mut(id) {
+ *old = new;
+ } else {
+ error!(
+ "Unable to change wall. Wall with id `{}` does not exist.",
+ id
+ );
+ }
+ }
+ Cargo::ClearAll => {
+ world.clear();
+ conn_man.broadcast(Cargo::ClearAll);
+ }
+ Cargo::Remove(id) => {
+ if world.remove(id) {
+ conn_man.broadcast(Cargo::Remove(id));
+ } else {
+ error!("Unable to remove item. No item with id `{}` found.", id);
+ }
+ }
+ Cargo::ApplyMatrix((_id, _matrix)) => unimplemented!(),
+ Cargo::AddMapData(_) | Cargo::UpdateMapData(_) => {
+ error!("This packet is not allowed in the client -> server direction");
+ }
}
}
})
diff --git a/src/world/mod.rs b/src/world/mod.rs
index a72031d..9ddd9e9 100644
--- a/src/world/mod.rs
+++ b/src/world/mod.rs
@@ -44,6 +44,32 @@ impl World {
}
}
+ /// Remove all items from the world, leaving it empty.
+ pub fn clear(&mut self) {
+ self.rooms.clear();
+ self.walls.clear();
+ self.icons.clear();
+ self.used_ids.clear();
+ }
+
+ /// Remove the item with the given id. Returns `false` in case no item with
+ /// such an id existed in the first place.
+ pub fn remove(&mut self, id: usize) -> bool {
+ if self.used_ids.remove(id).is_none() {
+ return false;
+ }
+
+ if self.rooms.remove(id).is_some() {
+ true
+ } else if self.walls.remove(id).is_some() {
+ true
+ } else if self.icons.remove(id).is_some() {
+ true
+ } else {
+ panic!("used_ids and the actual ids are out of sync")
+ }
+ }
+
/// 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.
@@ -127,16 +153,40 @@ impl World {
pub fn icons(&self) -> &StableVec<Icon> {
&self.icons
}
+ /// Get an icon mutably.
+ pub fn get_icon_mut(&mut self, id: usize) -> Option<&mut Icon> {
+ self.icons.get_mut(id)
+ }
/// Get all rooms of the world.
pub fn rooms(&self) -> &StableVec<Room> {
&self.rooms
}
+ /// Get a room mutably.
+ pub fn get_room_mut(&mut self, id: usize) -> Option<&mut Room> {
+ self.rooms.get_mut(id)
+ }
/// Get all walls of the world.
pub fn walls(&self) -> &StableVec<Wall> {
&self.walls
}
+ /// Get a wall mutably.
+ pub fn get_wall_mut(&mut self, id: usize) -> Option<&mut Wall> {
+ self.walls.get_mut(id)
+ }
+
+ pub fn get_mut(&mut self, id: usize) -> Option<&mut dyn Component> {
+ if let Some(c) = self.rooms.get_mut(id) {
+ Some(c as &mut dyn Component)
+ } else if let Some(c) = self.walls.get_mut(id) {
+ Some(c as &mut dyn Component)
+ } else if let Some(c) = self.icons.get_mut(id) {
+ Some(c as &mut dyn Component)
+ } else {
+ None
+ }
+ }
}
impl Default for World {