mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Began work on new sites
This commit is contained in:
parent
f6e44d2f06
commit
0098086b8f
@ -5,69 +5,175 @@ use std::{
|
|||||||
ops::{Index, IndexMut},
|
ops::{Index, IndexMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: We use u64 to make sure we are consistent across all machines. We
|
pub struct Id<T> {
|
||||||
// assume that usize fits into 8 bytes.
|
idx: u32,
|
||||||
pub struct Id<T>(u64, PhantomData<T>);
|
gen: u32,
|
||||||
|
phantom: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Id<T> {
|
impl<T> Id<T> {
|
||||||
pub fn id(&self) -> u64 { self.0 }
|
pub fn id(&self) -> u64 { self.idx as u64 | ((self.gen as u64) << 32) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Copy for Id<T> {}
|
impl<T> Copy for Id<T> {}
|
||||||
impl<T> Clone for Id<T> {
|
impl<T> Clone for Id<T> {
|
||||||
fn clone(&self) -> Self { Self(self.0, PhantomData) }
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
idx: self.idx,
|
||||||
|
gen: self.gen,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl<T> Eq for Id<T> {}
|
impl<T> Eq for Id<T> {}
|
||||||
impl<T> PartialEq for Id<T> {
|
impl<T> PartialEq for Id<T> {
|
||||||
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
|
fn eq(&self, other: &Self) -> bool { self.idx == other.idx && self.gen == other.gen }
|
||||||
}
|
}
|
||||||
impl<T> fmt::Debug for Id<T> {
|
impl<T> fmt::Debug for Id<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "Id<{}>({})", std::any::type_name::<T>(), self.0)
|
write!(f, "Id<{}>({}, {})", std::any::type_name::<T>(), self.idx, self.gen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T> hash::Hash for Id<T> {
|
impl<T> hash::Hash for Id<T> {
|
||||||
fn hash<H: hash::Hasher>(&self, h: &mut H) { self.0.hash(h); }
|
fn hash<H: hash::Hasher>(&self, h: &mut H) {
|
||||||
|
self.idx.hash(h);
|
||||||
|
self.gen.hash(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Entry<T> {
|
||||||
|
gen: u32,
|
||||||
|
item: Option<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Store<T> {
|
pub struct Store<T> {
|
||||||
items: Vec<T>,
|
entries: Vec<Entry<T>>,
|
||||||
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Default for Store<T> {
|
impl<T> Default for Store<T> {
|
||||||
fn default() -> Self { Self { items: Vec::new() } }
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
entries: Vec::new(),
|
||||||
|
len: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Store<T> {
|
impl<T> Store<T> {
|
||||||
|
pub fn contains(&self, id: Id<T>) -> bool {
|
||||||
|
self.entries
|
||||||
|
.get(id.idx as usize)
|
||||||
|
.map(|e| e.gen == id.gen)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self, id: Id<T>) -> &T {
|
pub fn get(&self, id: Id<T>) -> &T {
|
||||||
// NOTE: Safe conversion, because it came from usize.
|
let entry = self.entries
|
||||||
self.items.get(id.0 as usize).unwrap()
|
.get(id.idx as usize)
|
||||||
|
.unwrap();
|
||||||
|
if entry.gen == id.gen {
|
||||||
|
entry.item.as_ref().unwrap()
|
||||||
|
} else {
|
||||||
|
panic!("Stale ID used to access store entry");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut(&mut self, id: Id<T>) -> &mut T {
|
pub fn get_mut(&mut self, id: Id<T>) -> &mut T {
|
||||||
// NOTE: Safe conversion, because it came from usize.
|
let entry = self.entries
|
||||||
self.items.get_mut(id.0 as usize).unwrap()
|
.get_mut(id.idx as usize)
|
||||||
|
.unwrap();
|
||||||
|
if entry.gen == id.gen {
|
||||||
|
entry.item.as_mut().unwrap()
|
||||||
|
} else {
|
||||||
|
panic!("Stale ID used to access store entry");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ids(&self) -> impl Iterator<Item = Id<T>> {
|
pub fn ids(&self) -> impl Iterator<Item = Id<T>> + '_ {
|
||||||
(0..self.items.len()).map(|i| Id(i as u64, PhantomData))
|
self.iter().map(|(id, _)| id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn values(&self) -> impl Iterator<Item = &T> { self.items.iter() }
|
pub fn values(&self) -> impl Iterator<Item = &T> + '_ {
|
||||||
|
self.iter().map(|(_, item)| item)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> { self.items.iter_mut() }
|
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> + '_ {
|
||||||
|
self.iter_mut().map(|(_, item)| item)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = (Id<T>, &T)> { self.ids().zip(self.values()) }
|
pub fn iter(&self) -> impl Iterator<Item = (Id<T>, &T)> + '_ {
|
||||||
|
self.entries
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(move |(idx, entry)| {
|
||||||
|
Some(Id {
|
||||||
|
idx: idx as u32,
|
||||||
|
gen: entry.gen,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}).zip(entry.item.as_ref())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (Id<T>, &mut T)> {
|
pub fn iter_mut(&mut self) -> impl Iterator<Item = (Id<T>, &mut T)> + '_ {
|
||||||
self.ids().zip(self.values_mut())
|
self.entries
|
||||||
|
.iter_mut()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(move |(idx, entry)| {
|
||||||
|
Some(Id {
|
||||||
|
idx: idx as u32,
|
||||||
|
gen: entry.gen,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}).zip(entry.item.as_mut())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, item: T) -> Id<T> {
|
pub fn insert(&mut self, item: T) -> Id<T> {
|
||||||
// NOTE: Assumes usize fits into 8 bytes.
|
if self.len < self.entries.len() {
|
||||||
let id = Id(self.items.len() as u64, PhantomData);
|
// TODO: Make this more efficient with a lookahead system
|
||||||
self.items.push(item);
|
let (idx, entry) = self.entries
|
||||||
id
|
.iter_mut()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, e)| e.item.is_none())
|
||||||
|
.unwrap();
|
||||||
|
entry.item = Some(item);
|
||||||
|
assert!(entry.gen < u32::MAX);
|
||||||
|
entry.gen += 1;
|
||||||
|
Id {
|
||||||
|
idx: idx as u32,
|
||||||
|
gen: entry.gen,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert!(self.entries.len() < (u32::MAX - 1) as usize);
|
||||||
|
let id = Id {
|
||||||
|
idx: self.entries.len() as u32,
|
||||||
|
gen: 0,
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
self.entries.push(Entry {
|
||||||
|
gen: 0,
|
||||||
|
item: Some(item),
|
||||||
|
});
|
||||||
|
self.len += 1;
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, id: Id<T>) -> Option<T> {
|
||||||
|
if let Some(item) = self.entries
|
||||||
|
.get_mut(id.idx as usize)
|
||||||
|
.and_then(|e| if e.gen == id.gen {
|
||||||
|
e.item.take()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
{
|
||||||
|
self.len -= 1;
|
||||||
|
Some(item)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
world/examples/site.rs
Normal file
3
world/examples/site.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
todo!();
|
||||||
|
}
|
@ -24,6 +24,7 @@ pub mod pathfinding;
|
|||||||
pub mod sim;
|
pub mod sim;
|
||||||
pub mod sim2;
|
pub mod sim2;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
|
pub mod site2;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
|
@ -88,7 +88,8 @@ pub fn simulate(index: &mut Index, world: &mut WorldSim) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(index: &mut Index, _world: &mut WorldSim, dt: f32) {
|
pub fn tick(index: &mut Index, _world: &mut WorldSim, dt: f32) {
|
||||||
for site in index.sites.ids() {
|
let site_ids = index.sites.ids().collect::<Vec<_>>();
|
||||||
|
for site in site_ids {
|
||||||
tick_site_economy(index, site, dt);
|
tick_site_economy(index, site, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
world/src/site2/mod.rs
Normal file
15
world/src/site2/mod.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
mod tile;
|
||||||
|
mod plot;
|
||||||
|
|
||||||
|
use vek::*;
|
||||||
|
use common::store::{Store, Id};
|
||||||
|
use crate::util::Grid;
|
||||||
|
use self::{
|
||||||
|
tile::TileGrid,
|
||||||
|
plot::Plot,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Site {
|
||||||
|
grid: TileGrid,
|
||||||
|
plot: Store<Plot>,
|
||||||
|
}
|
12
world/src/site2/plot.rs
Normal file
12
world/src/site2/plot.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
use vek::*;
|
||||||
|
|
||||||
|
pub struct Plot {
|
||||||
|
kind: PlotKind,
|
||||||
|
center_tpos: Vec2<i32>,
|
||||||
|
units: Vec2<Vec2<i8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum PlotKind {
|
||||||
|
Path,
|
||||||
|
House { height: i32 },
|
||||||
|
}
|
49
world/src/site2/tile.rs
Normal file
49
world/src/site2/tile.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
const TILE_SIZE: u32 = 7;
|
||||||
|
const ZONE_SIZE: u32 = 16;
|
||||||
|
const ZONE_RADIUS: u32 = 16;
|
||||||
|
const TILE_RADIUS: u32 = ZONE_SIZE * ZONE_RADIUS;
|
||||||
|
const MAX_BLOCK_RADIUS: u32 = TILE_SIZE * TILE_RADIUS;
|
||||||
|
|
||||||
|
pub struct TileGrid {
|
||||||
|
zones: Grid<Option<Grid<Option<Tile>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TileGrid {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
zones: Grid::populate_from(Vec2::broadcast(ZONE_RADIUS as i32 * 2 + 1), |_| None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, tpos: Vec2<i32>) -> Option<&Tile> {
|
||||||
|
let tpos = tpos + TILE_RADIUS as i32;
|
||||||
|
self.zones
|
||||||
|
.get(tpos)
|
||||||
|
.and_then(|zone| zone.as_ref()?.get(tpos.map(|e| e.rem_euclid(ZONE_SIZE as i32))))
|
||||||
|
.and_then(|tile| tile.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self, tpos: Vec2<i32>) -> Option<&mut Tile> {
|
||||||
|
let tpos = tpos + TILE_RADIUS as i32;
|
||||||
|
self.zones
|
||||||
|
.get_mut(tpos)
|
||||||
|
.and_then(|zone| zone
|
||||||
|
.get_or_insert_with(|| Grid::populate_from(Vec2::broadcast(ZONE_RADIUS as i32 * 2 + 1), |_| None))
|
||||||
|
.get_mut(tpos.map(|e| e.rem_euclid(ZONE_SIZE as i32)))
|
||||||
|
.map(|tile| tile.get_or_insert_with(|| Tile::empty())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Tile {
|
||||||
|
plot: Option<Id<Plot>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tile {
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Self {
|
||||||
|
plot: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user