Pane creation and signal creation support

main
Shad Amethyst 2 years ago
parent 92180606a1
commit 2597a7e1b7
Signed by: amethyst
GPG Key ID: D970C8DD1D6DEE36

@ -35,11 +35,18 @@ export default function RightPane(props) {
setWorld((world) => { setWorld((world) => {
let [x, y] = settings.selected; let [x, y] = settings.selected;
let full_tile = world.get(x, y); let full_tile = world.get(x, y);
let had_signal = !!full_tile.signal;
if (typeof new_signal === "function") { if (typeof new_signal === "function") {
full_tile.signal = new_signal(full_tile.signal); full_tile.signal = new_signal(full_tile.signal);
} else { } else {
full_tile.signal = new_signal; full_tile.signal = new_signal;
} }
if (full_tile.signal && !had_signal) {
full_tile.state = "Active";
}
world.set(x, y, full_tile); world.set(x, y, full_tile);
return world; return world;
}); });

@ -5,7 +5,7 @@ import Value from "./input/Value.jsx";
import styles from "./RightPane.module.css"; import styles from "./RightPane.module.css";
import input_styles from "./input/input.module.css"; import input_styles from "./input/input.module.css";
import * as stackline from "../stackline-wasm/stackline_wasm.js";
export const DIRECTIONS = [ export const DIRECTIONS = [
"Up", "Up",
@ -17,7 +17,21 @@ export const DIRECTIONS = [
export default function Signal(props) { export default function Signal(props) {
let {signal, setSignal} = props; let {signal, setSignal} = props;
return (<Show when={signal()} fallback={<i class={styles.gray}>No signal</i>}> return (<Show when={signal()} fallback={<>
<i class={styles.gray}>No signal</i>{" "}
<Show when={setSignal}>
<button
class={input_styles.button}
aria-label="Add an empty signal"
title="Add signal"
onClick={() => {
let signal = new stackline.Signal();
setSignal(signal.serialize());
signal.free();
}}
>+</button>
</Show>
</>}>
<div class={styles.indent}> <div class={styles.indent}>
<h3 class={styles.h3}>Direction:</h3> <h3 class={styles.h3}>Direction:</h3>
<Show when={setSignal} fallback={signal()?.direction}> <Show when={setSignal} fallback={signal()?.direction}>

@ -8,6 +8,7 @@ import Orientation from "./input/Orientation.jsx";
import Number from "./input/Number.jsx"; import Number from "./input/Number.jsx";
import Value from "./input/Value.jsx"; import Value from "./input/Value.jsx";
import Bool from "./input/Bool.jsx"; import Bool from "./input/Bool.jsx";
import String from "./input/String.jsx";
import CmpOp from "./input/CmpOp.jsx"; import CmpOp from "./input/CmpOp.jsx";
import ArithOp from "./input/ArithOp.jsx"; import ArithOp from "./input/ArithOp.jsx";
@ -22,6 +23,8 @@ COMPONENTS.set("Int", Number);
COMPONENTS.set("Value", Value); COMPONENTS.set("Value", Value);
COMPONENTS.set("CmpOp", CmpOp); COMPONENTS.set("CmpOp", CmpOp);
COMPONENTS.set("ArithOp", ArithOp); COMPONENTS.set("ArithOp", ArithOp);
COMPONENTS.set("Bool", Bool);
COMPONENTS.set("String", String);
export default function Tile(props) { export default function Tile(props) {
let {full_tile, set_full_tile} = props; let {full_tile, set_full_tile} = props;

Binary file not shown.

@ -13,17 +13,17 @@ use stackline::utils::Direction;
use stackline::world::World as SLWorld; use stackline::world::World as SLWorld;
use stackline::text::TextSurface; use stackline::text::TextSurface;
// TODO: refactor:
// - make everything camelCase
// - clearly separate serialized properties/functions from non-serialized
// - add javascript code to the classes?
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator. // allocator.
#[cfg(feature = "wee_alloc")] #[cfg(feature = "wee_alloc")]
#[global_allocator] #[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen] #[wasm_bindgen]
pub struct World(SLWorld); pub struct World(SLWorld);
@ -459,6 +459,12 @@ impl Signal {
} }
} }
pub fn serialize(&self) -> JsValue {
JsValue::from_serde(&self.0).map_err(|err| {
err!("Error while serializing Signal: {:?}", err);
}).unwrap_or(JsValue::NULL)
}
pub fn push(&mut self, value: JsValue) { pub fn push(&mut self, value: JsValue) {
if let Some(num) = value.as_f64() { if let Some(num) = value.as_f64() {
self.0.push(Value::Number(num)); self.0.push(Value::Number(num));

@ -11,15 +11,14 @@ pub struct TextChar {
impl TextChar { impl TextChar {
#[inline] #[inline]
pub fn new<C1, C2>(ch: char, fg: C1, bg: Option<C2>) -> Self pub fn new<C>(ch: char, fg: C, bg: Option<C>) -> Self
where where
Srgb<u8>: FromColor<C1>, Srgb<u8>: From<C>,
Srgb<u8>: FromColor<C2>,
{ {
Self { Self {
ch, ch,
fg: Srgb::from_color(fg), fg: Srgb::from(fg),
bg: bg.map(|x| Srgb::from_color(x)), bg: bg.map(|x| Srgb::from(x)),
} }
} }

@ -17,7 +17,7 @@ macro_rules! binary_op {
} }
if let Some(coords) = context.offset(signal.direction().into_offset()) { if let Some(coords) = context.offset(signal.direction().into_offset()) {
context.send(coords, signal.direction(), signal).unwrap_or_else(|_| unreachable!()); let _ = context.send(coords, signal.direction(), signal);
} }
} }

@ -145,10 +145,10 @@ impl Tile for StorageCount {
if let Some(target_position) = context.offset(signal.direction().into_offset()) { if let Some(target_position) = context.offset(signal.direction().into_offset()) {
let _ = context.send(target_position, signal.direction(), signal); let _ = context.send(target_position, signal.direction(), signal);
} }
}
if context.state() != State::Idle { if context.state() != State::Idle {
context.next_state(); context.next_state();
}
} }
} }
@ -231,6 +231,56 @@ impl Tile for Stacker {
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Debug {
value: Value,
}
impl Default for Debug {
fn default() -> Self {
Self {
value: Value::Number(0.0)
}
}
}
impl Tile for Debug {
fn update<'b>(&'b mut self, mut context: UpdateContext<'b>) {
if let Some(mut signal) = context.take_signal() {
if let Some(value) = signal.pop() {
self.value = value;
}
}
if context.state() != State::Idle {
context.next_state();
}
}
fn draw(&self, surface: &mut TextSurface, ctx: DrawContext<'_>) {
use palette::Srgb;
let text = format!("\"{}", self.value);
let y = ctx.surface_coords.1;
for (index, c) in text.chars().enumerate() {
let x = ctx.surface_coords.0 + index as i32;
if let (Ok(x), Ok(y)) = (x.try_into(), y.try_into()) {
let textchar = if index == 0 {
TextChar::from_state(c, ctx.state)
} else {
TextChar::new(c, Srgb::new(100, 100, 100), None)
};
surface.set(x, y, textchar);
}
}
}
fn schema(&self) -> TileSchema {
TileSchema::map()
.add("value", TileSchema::value("Stored value", "Value"))
}
}
/// Tries to convert a [`FullTile`] to a [`Store`] /// Tries to convert a [`FullTile`] to a [`Store`]
fn get_store<'a>(full: VecRef<'a, FullTile>) -> Option<VecRef<'a, Store>> { fn get_store<'a>(full: VecRef<'a, FullTile>) -> Option<VecRef<'a, Store>> {
VecRef::try_map(full, |tile| { VecRef::try_map(full, |tile| {

@ -151,6 +151,63 @@ impl Tile for Resistor {
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Fuse {
blown: bool,
orientation: Orientation,
}
impl Default for Fuse {
fn default() -> Self {
Self {
blown: false,
orientation: Orientation::Horizontal,
}
}
}
impl Tile for Fuse {
fn update<'b>(&'b mut self, mut context: UpdateContext<'b>) {
if let Some(signal) = context.take_signal() {
if self.orientation.contains(signal.direction()) {
if !self.blown {
self.blown = true;
if let Some(pos) = context.offset(signal.direction().into_offset()) {
let _ = context.send(pos, signal.direction(), signal);
}
} else {
context.set_state(State::Idle);
}
} else {
self.blown = false;
context.set_state(State::Idle);
}
}
if context.state() != State::Idle {
context.next_state();
}
}
fn draw_simple(&self, ctx: DrawContext) -> TextChar {
let ch = match (self.blown, self.orientation) {
(true, Orientation::Vertical) => '\u{254e}', // Light double dash vertical
(true, Orientation::Horizontal) => '\u{254c}', // Light double dash horizontal
(false, Orientation::Vertical) => '\u{2506}', // Light triple dash vertical
(false, Orientation::Horizontal) => '\u{2504}', // Light triple dash horizontal
_ => ' ',
};
TextChar::from_state(ch, ctx.state)
}
fn schema(&self) -> TileSchema {
TileSchema::map()
.add("blown", TileSchema::value("Is blown", "Bool"))
.add("orientation", TileSchema::value("Orientation", "Orientation|NotAny"))
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;

Loading…
Cancel
Save