use wasm_bindgen::prelude::*;
use crate::{
algorithmen::{
Algorithmen3DBinPackaging,
AlgorithmenError,
},
bin::Bin,
items::{
Item,
ItemsPlaced,
},
second_algorithmen::SecondAlgorithmen,
vector::Vector3,
};
fn to_js_error(e: AlgorithmenError) -> JsError {
JsError::new(&e.to_string())
}
#[wasm_bindgen]
#[derive(Clone, Copy)]
pub struct BinSpec {
id: i32,
x: u32,
y: u32,
z: u32,
max_weight: u32,
weight_currently: u32,
}
#[wasm_bindgen]
impl BinSpec {
#[wasm_bindgen(constructor)]
pub fn new(id: i32, x: u32, y: u32, z: u32, max_weight: u32, weight_currently: u32) -> BinSpec {
Self {
id,
x,
y,
z,
max_weight,
weight_currently,
}
}
#[wasm_bindgen(getter)]
pub fn x(&self) -> u32 {
self.x
}
#[wasm_bindgen(getter)]
pub fn y(&self) -> u32 {
self.y
}
#[wasm_bindgen(getter)]
pub fn z(&self) -> u32 {
self.z
}
#[wasm_bindgen(getter)]
pub fn max_weight(&self) -> u32 {
self.max_weight
}
#[wasm_bindgen(getter)]
pub fn weight_currently(&self) -> u32 {
self.weight_currently
}
}
impl From<BinSpec> for Bin {
fn from(b: BinSpec) -> Self {
Bin::new(
b.id,
Vector3::new(b.x, b.y, b.z),
b.max_weight,
b.weight_currently,
)
}
}
#[wasm_bindgen]
#[derive(Clone, Copy)]
pub struct ItemSpec {
id: i32,
x: u32,
y: u32,
z: u32,
weight: u32,
order: u32,
}
#[wasm_bindgen]
impl ItemSpec {
#[wasm_bindgen(constructor)]
pub fn new(id: i32, x: u32, y: u32, z: u32, weight: u32, order: u32) -> ItemSpec {
Self {
id,
x,
y,
z,
weight,
order,
}
}
#[wasm_bindgen(getter)]
pub fn x(&self) -> u32 {
self.x
}
#[wasm_bindgen(getter)]
pub fn y(&self) -> u32 {
self.y
}
#[wasm_bindgen(getter)]
pub fn z(&self) -> u32 {
self.z
}
#[wasm_bindgen(getter)]
pub fn weight(&self) -> u32 {
self.weight
}
#[wasm_bindgen(getter)]
pub fn order(&self) -> u32 {
self.order
}
}
impl From<ItemSpec> for Item {
fn from(i: ItemSpec) -> Self {
Item::new(i.id, Vector3::new(i.x, i.y, i.z), i.weight, i.order)
}
}
#[wasm_bindgen]
pub struct CalcResult {
pub x: u32,
pub y: u32,
pub z: u32,
pub size_x: u32,
pub size_y: u32,
pub size_z: u32,
pub ignore: usize,
}
#[wasm_bindgen]
impl CalcResult {
#[wasm_bindgen(constructor)]
pub fn new(x: u32, y: u32, z: u32, size_x: u32, size_y: u32, size_z: u32) -> Self {
Self {
x,
y,
z,
size_x,
size_y,
size_z,
ignore: 0,
}
}
#[wasm_bindgen]
pub fn center_point(&self) -> Center {
let x = (self.x + self.size_x) / 2;
let y = (self.y + self.size_y) / 2;
let z = (self.z + self.size_z) / 2;
Center::new(x, y, z)
}
}
#[wasm_bindgen]
pub struct Center {
pub x: u32,
pub y: u32,
pub z: u32,
}
impl Center {
pub fn new(x: u32, y: u32, z: u32) -> Self {
Self { x, y, z }
}
}
impl From<ItemsPlaced> for CalcResult {
fn from(value: ItemsPlaced) -> Self {
Self {
x: value.position.x,
y: value.position.y,
z: value.position.z,
size_x: value.item.size_cube.x,
size_y: value.item.size_cube.y,
size_z: value.item.size_cube.z,
ignore: 0,
}
}
}
#[wasm_bindgen]
pub struct AlgorithmenFirstWasm {
inner: SecondAlgorithmen,
}
#[wasm_bindgen]
impl AlgorithmenFirstWasm {
#[wasm_bindgen]
pub fn create(input: Vec<ItemSpec>, bin: BinSpec) -> Result<AlgorithmenFirstWasm, JsError> {
let items: Vec<Item> = input.into_iter().map(Into::into).collect();
let bin: Bin = bin.into();
let inner = SecondAlgorithmen::create_algorithmen(items, bin)?;
Ok(Self { inner })
}
#[wasm_bindgen]
pub fn add_item(&mut self, input: Vec<ItemSpec>) -> Result<(), JsError> {
let items: Vec<Item> = input.into_iter().map(Into::into).collect();
self.inner.add_item(items).map_err(to_js_error)
}
#[wasm_bindgen]
pub fn remove_item(&mut self, input: Vec<ItemSpec>) -> Result<(), JsError> {
let items: Vec<Item> = input.into_iter().map(Into::into).collect();
self.inner
.remove_item(items)
.map_err(|_| JsError::new(&format!("Removed item from algorithmen failed")))
}
#[wasm_bindgen]
pub fn space_left(&self) -> u32 {
self.inner.space_left()
}
#[wasm_bindgen]
pub fn calculate(self) -> Result<Vec<CalcResult>, JsError> {
let sorted = self.inner.calculate().map_err(to_js_error)?;
let ignore = sorted.removed_items.len();
let output: Vec<CalcResult> = sorted
.items
.into_iter()
.map(|x| CalcResult::from(x))
.map(|mut x| {
x.ignore = ignore;
x
})
.collect();
Ok(output)
}
}