Clean up Bevy <-> JS interface

This commit is contained in:
Danny McGee
2023-10-14 10:15:04 -04:00
parent dd5bcdb66c
commit 45dd5a9bd0
2 changed files with 35 additions and 53 deletions
+26 -44
View File
@@ -1,6 +1,7 @@
import { on } from "@storyteller/framework"; import { on } from "@storyteller/framework";
import * as studio from "@storyteller/studio"; import * as studio from "@storyteller/studio";
import { TransformSpace, ViewportSize } from "@storyteller/studio"; import { TransformSpace, ViewportSize } from "@storyteller/studio";
import { match } from "@storyteller/utility";
import { LitElement, html, unsafeCSS } from "lit"; import { LitElement, html, unsafeCSS } from "lit";
import { customElement, state } from "lit/decorators.js"; import { customElement, state } from "lit/decorators.js";
@@ -9,12 +10,12 @@ import "./help.element";
import "./icon.element"; import "./icon.element";
import styles from "./app.element.scss?inline"; import styles from "./app.element.scss?inline";
import { match } from "@storyteller/utility";
// FIXME: Figure out how to generate the correct code from `wasm_bindgen` // FIXME: Figure out how to generate the correct code from `wasm_bindgen`
enum TransformType { enum TransformType {
TRANSLATE = 0b0001, TRANSLATE = 0b0001,
ROTATE = 0b0010, ROTATE = 0b0010,
SCALE = 0b0100,
} }
@customElement("app-root") @customElement("app-root")
@@ -23,11 +24,8 @@ export class AppElement extends LitElement {
@state() showHelp = false; @state() showHelp = false;
@state() transformSpace: "local"|"world" = "local"; @state() transformSpace = TransformSpace.Local;
@state() transformType = TransformType.ROTATE | TransformType.TRANSLATE;
@state() translateGizmoEnabled = true;
@state() rotateGizmoEnabled = true;
@state() scaleGizmoEnabled = false;
#studioCanvas?: HTMLCanvasElement | null; #studioCanvas?: HTMLCanvasElement | null;
@@ -49,54 +47,36 @@ export class AppElement extends LitElement {
onSpaceChange(event: InputEvent): void { onSpaceChange(event: InputEvent): void {
const { value } = event.target as HTMLInputElement; const { value } = event.target as HTMLInputElement;
if (value === this.transformSpace) const space = match (value, {
return; "local": () => TransformSpace.Local,
"world": () => TransformSpace.World,
match (value, {
"local": () => studio.setTransformSpace(TransformSpace.Local),
"world": () => studio.setTransformSpace(TransformSpace.World),
_: () => { _: () => {
console.warn(`Unknown transform space: "${value}"`); throw new Error(`Unknown transform space: "${value}"`);
return;
} }
}); });
this.transformSpace = value as "local"|"world"; this.transformSpace = space;
studio.setTransformSpace(space);
} }
onGizmoToggled(event: InputEvent): void { onGizmoToggled(event: InputEvent): void {
const { name, checked } = event.target as HTMLInputElement; const { name, checked } = event.target as HTMLInputElement;
match (name, { const flag = match (name, {
"translate": () => { "translate": () => TransformType.TRANSLATE,
if (this.translateGizmoEnabled === checked) "rotate": () => TransformType.ROTATE,
return; "scale": () => TransformType.SCALE,
this.translateGizmoEnabled = checked;
},
"rotate": () => {
if (this.rotateGizmoEnabled === checked)
return;
this.rotateGizmoEnabled = checked;
},
"scale": () => {
if (this.scaleGizmoEnabled === checked)
return;
this.scaleGizmoEnabled = checked;
},
_: () => { _: () => {
console.warn(`Unknown gizmo name: "${name}"`); throw new Error(`Unknown gizmo name: "${name}"`);
return;
} }
}); });
let transform = 0; if (checked) {
if (this.translateGizmoEnabled) transform |= TransformType.TRANSLATE; this.transformType |= flag;
if (this.rotateGizmoEnabled) transform |= TransformType.ROTATE; } else {
// TODO: Scale? this.transformType &= ~flag;
}
studio.setInteractionTransform(transform); studio.setTransformType(this.transformType);
} }
#initStudio(): HTMLCanvasElement | null { #initStudio(): HTMLCanvasElement | null {
@@ -121,7 +101,7 @@ export class AppElement extends LitElement {
<input type="radio" <input type="radio"
name="transform-space" name="transform-space"
value="local" value="local"
checked ?checked=${this.transformSpace === TransformSpace.Local}
@input=${this.onSpaceChange} @input=${this.onSpaceChange}
/> />
</label> </label>
@@ -130,6 +110,7 @@ export class AppElement extends LitElement {
<input type="radio" <input type="radio"
name="transform-space" name="transform-space"
value="world" value="world"
?checked=${this.transformSpace === TransformSpace.World}
@input=${this.onSpaceChange} @input=${this.onSpaceChange}
/> />
</label> </label>
@@ -139,7 +120,7 @@ export class AppElement extends LitElement {
<sts-icon icon="up-down-left-right">Translate</sts-icon> <sts-icon icon="up-down-left-right">Translate</sts-icon>
<input type="checkbox" <input type="checkbox"
name="translate" name="translate"
checked ?checked=${this.transformType & TransformType.TRANSLATE}
@input=${this.onGizmoToggled} @input=${this.onGizmoToggled}
/> />
</label> </label>
@@ -147,7 +128,7 @@ export class AppElement extends LitElement {
<sts-icon icon="rotate">Rotate</sts-icon> <sts-icon icon="rotate">Rotate</sts-icon>
<input type="checkbox" <input type="checkbox"
name="rotate" name="rotate"
checked ?checked=${this.transformType & TransformType.ROTATE}
@input=${this.onGizmoToggled} @input=${this.onGizmoToggled}
/> />
</label> </label>
@@ -155,6 +136,7 @@ export class AppElement extends LitElement {
<sts-icon icon="scale">Scale</sts-icon> <sts-icon icon="scale">Scale</sts-icon>
<input type="checkbox" <input type="checkbox"
name="scale" name="scale"
?checked=${this.transformType & TransformType.SCALE}
disabled disabled
/> />
</label> </label>
+9 -9
View File
@@ -96,22 +96,22 @@ pub mod wasm {
use super::{InteractionMode, SelectionChannel, SelectionMode, TransformSpace, TransformType}; use super::{InteractionMode, SelectionChannel, SelectionMode, TransformSpace, TransformType};
static SELECT_MODE_BUF: WasmMessageBuffer<SelectionChannel> = WasmMessageBuffer::new(); static SELECT_MODE_BUF: WasmMessageBuffer<SelectionChannel> = WasmMessageBuffer::new();
static INTERACTION_TRANSFORM_BUF: WasmMessageBuffer<TransformType> = WasmMessageBuffer::new(); static TRANSFORM_TYPE_BUF: WasmMessageBuffer<TransformType> = WasmMessageBuffer::new();
static INTERACTION_SPACE_BUF: WasmMessageBuffer<TransformSpace> = WasmMessageBuffer::new(); static TRANSFORM_SPACE_BUF: WasmMessageBuffer<TransformSpace> = WasmMessageBuffer::new();
#[wasm_bindgen(js_name = setSelectionMode)] #[wasm_bindgen(js_name = setSelectionMode)]
pub fn set_selection_mode(mode: SelectionChannel) { pub fn set_selection_mode(mode: SelectionChannel) {
wasm::write_message!(SELECT_MODE_BUF, mode); wasm::write_message!(SELECT_MODE_BUF, mode);
} }
#[wasm_bindgen(js_name = setInteractionTransform)] #[wasm_bindgen(js_name = setTransformType)]
pub fn set_interaction_transform(flags: u8) { pub fn set_transform_type(flags: u8) {
wasm::write_message!(INTERACTION_TRANSFORM_BUF, TransformType(flags)); wasm::write_message!(TRANSFORM_TYPE_BUF, TransformType(flags));
} }
#[wasm_bindgen(js_name = setTransformSpace)] #[wasm_bindgen(js_name = setTransformSpace)]
pub fn set_transform_space(space: TransformSpace) { pub fn set_transform_space(space: TransformSpace) {
wasm::write_message!(INTERACTION_SPACE_BUF, space); wasm::write_message!(TRANSFORM_SPACE_BUF, space);
} }
pub(super) fn update_selection_mode(mut selection_mode: ResMut<SelectionMode>) { pub(super) fn update_selection_mode(mut selection_mode: ResMut<SelectionMode>) {
@@ -121,10 +121,10 @@ pub mod wasm {
} }
pub(super) fn update_interaction_mode(mut interaction_mode: ResMut<InteractionMode>) { pub(super) fn update_interaction_mode(mut interaction_mode: ResMut<InteractionMode>) {
wasm::read_buffer!(INTERACTION_TRANSFORM_BUF, transform => { wasm::read_buffer!(TRANSFORM_TYPE_BUF, ttype => {
interaction_mode.transform = transform; interaction_mode.transform = ttype;
}); });
wasm::read_buffer!(INTERACTION_SPACE_BUF, space => { wasm::read_buffer!(TRANSFORM_SPACE_BUF, space => {
interaction_mode.space = space; interaction_mode.space = space;
}); });
} }