use crate::{Region, TermShare};
use stakker::Core;
pub struct Tile {
pub(crate) share: Option<TermShare>,
pub(crate) genr: u64,
pub(crate) oy: i32,
pub(crate) ox: i32,
pub(crate) sy: i32,
pub(crate) sx: i32,
}
impl Tile {
pub fn new() -> Self {
Self {
share: None,
genr: 0,
oy: 0,
ox: 0,
sy: 0,
sx: 0,
}
}
pub fn size(&self) -> (i32, i32) {
(self.sy, self.sx)
}
pub fn sy(&self) -> i32 {
self.sy
}
pub fn sx(&self) -> i32 {
self.sx
}
pub fn split_x(self, x: i32) -> (Self, Self) {
let x = x.clamp(0, self.sx);
(
Self {
share: self.share.clone(),
genr: self.genr,
oy: self.oy,
ox: self.ox,
sy: self.sy,
sx: x,
},
Self {
share: self.share,
genr: self.genr,
oy: self.oy,
ox: self.ox + x,
sy: self.sy,
sx: self.sx - x,
},
)
}
pub fn split_xx(self, x0: i32, x1: i32) -> (Self, Self, Self) {
let (t01, t2) = self.split_x(x1);
let (t0, t1) = t01.split_x(x0);
(t0, t1, t2)
}
pub fn split_y(self, y: i32) -> (Self, Self) {
let y = y.clamp(0, self.sy);
(
Self {
share: self.share.clone(),
genr: self.genr,
oy: self.oy,
ox: self.ox,
sy: y,
sx: self.sx,
},
Self {
share: self.share,
genr: self.genr,
oy: self.oy + y,
ox: self.ox,
sy: self.sy - y,
sx: self.sx,
},
)
}
pub fn split_yy(self, y0: i32, y1: i32) -> (Self, Self, Self) {
let (t01, t2) = self.split_y(y1);
let (t0, t1) = t01.split_y(y0);
(t0, t1, t2)
}
pub fn full<'a>(&'a mut self, core: &'a mut Core) -> Option<Region<'a>> {
if let Some(ref mut ts) = self.share {
let (oy, ox, sy, sx) = (self.oy, self.ox, self.sy, self.sx);
ts.output(core).get_local_page(self.genr).map(|mut r| {
r.region_inplace(oy, ox, sy, sx);
r
})
} else {
None
}
}
pub fn region<'a>(
&'a mut self,
core: &'a mut Core,
y: i32,
x: i32,
sy: i32,
sx: i32,
) -> Option<Region<'a>> {
if let Some(ref mut ts) = self.share {
let (self_oy, self_ox, self_sy, self_sx) = (self.oy, self.ox, self.sy, self.sx);
ts.output(core).get_local_page(self.genr).map(|mut r| {
r.region_inplace(self_oy, self_ox, self_sy, self_sx);
r.region_inplace(y, x, sy, sx);
r
})
} else {
None
}
}
}
impl Default for Tile {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for Tile {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Tile")
.field("genr", &self.genr)
.field("oy", &self.oy)
.field("ox", &self.ox)
.field("sy", &self.sy)
.field("sx", &self.sx)
.finish()
}
}