device templates exist now
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -588,6 +588,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde-wasm-bindgen 0.6.5",
|
"serde-wasm-bindgen 0.6.5",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
|
"strum",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tsify",
|
"tsify",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
|||||||
@@ -449,8 +449,8 @@ impl Network {
|
|||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
pub struct Prefab {
|
pub struct Prefab {
|
||||||
name: String,
|
pub name: String,
|
||||||
hash: i32,
|
pub hash: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Prefab {
|
impl Prefab {
|
||||||
@@ -481,7 +481,7 @@ pub struct DeviceTemplate {
|
|||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub prefab_name: Option<String>,
|
pub prefab_name: Option<String>,
|
||||||
pub slots: Vec<SlotTemplate>,
|
pub slots: Vec<SlotTemplate>,
|
||||||
pub reagents: HashMap<ReagentMode, HashMap<i32, f64>>,
|
// pub reagents: HashMap<ReagentMode, HashMap<i32, f64>>,
|
||||||
pub connections: Vec<Connection>,
|
pub connections: Vec<Connection>,
|
||||||
pub fields: HashMap<LogicType, LogicField>,
|
pub fields: HashMap<LogicType, LogicField>,
|
||||||
}
|
}
|
||||||
@@ -1089,7 +1089,8 @@ impl VM {
|
|||||||
name_hash,
|
name_hash,
|
||||||
prefab: template.prefab_name.map(|name| Prefab::new(&name)),
|
prefab: template.prefab_name.map(|name| Prefab::new(&name)),
|
||||||
slots,
|
slots,
|
||||||
reagents: template.reagents,
|
// reagents: template.reagents,
|
||||||
|
reagents: HashMap::new(),
|
||||||
ic,
|
ic,
|
||||||
connections: template.connections,
|
connections: template.connections,
|
||||||
fields,
|
fields,
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ serde_with = "3.7.0"
|
|||||||
tsify = { version = "0.4.5", default-features = false, features = ["js", "wasm-bindgen"] }
|
tsify = { version = "0.4.5", default-features = false, features = ["js", "wasm-bindgen"] }
|
||||||
thiserror = "1.0.58"
|
thiserror = "1.0.58"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
ic10emu = { path = "../ic10emu" }
|
||||||
|
strum = { version = "0.26.2"}
|
||||||
|
itertools = "0.12.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["console_error_panic_hook"]
|
default = ["console_error_panic_hook"]
|
||||||
console_error_panic_hook = ["dep:console_error_panic_hook"]
|
console_error_panic_hook = ["dep:console_error_panic_hook"]
|
||||||
|
|||||||
@@ -5,18 +5,59 @@ use std::{
|
|||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
let dest_path = Path::new(&out_dir).join("ts_types.rs");
|
let dest_path = Path::new(&out_dir).join("ts_types.rs");
|
||||||
let output_file = File::create(dest_path).unwrap();
|
let output_file = File::create(dest_path).unwrap();
|
||||||
let mut writer = BufWriter::new(&output_file);
|
let mut writer = BufWriter::new(&output_file);
|
||||||
|
|
||||||
|
let mut ts_types: String = String::new();
|
||||||
|
|
||||||
|
let lt_tsunion: String = Itertools::intersperse(
|
||||||
|
ic10emu::grammar::generated::LogicType::iter().map(|lt| format!("\"{}\"", lt.as_ref())),
|
||||||
|
"\n | ".to_owned(),
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
let lt_tstype = format!("\nexport type LogicType = {};", lt_tsunion);
|
||||||
|
ts_types.push_str(<_tstype);
|
||||||
|
|
||||||
|
let slt_tsunion: String = Itertools::intersperse(
|
||||||
|
ic10emu::grammar::generated::SlotLogicType::iter().map(|slt| format!("\"{}\"", slt.as_ref())),
|
||||||
|
"\n | ".to_owned(),
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
let slt_tstype = format!("\nexport type SlotLogicType = {};", slt_tsunion);
|
||||||
|
ts_types.push_str(&slt_tstype);
|
||||||
|
|
||||||
|
let bm_tsunion: String = Itertools::intersperse(
|
||||||
|
ic10emu::grammar::generated::BatchMode::iter().map(|bm| format!("\"{}\"", bm.as_ref())),
|
||||||
|
"\n | ".to_owned(),
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
let bm_tstype = format!("\nexport type BatchMode = {};", bm_tsunion);
|
||||||
|
ts_types.push_str(&bm_tstype);
|
||||||
|
|
||||||
|
let rm_tsunion: String = Itertools::intersperse(
|
||||||
|
ic10emu::grammar::generated::ReagentMode::iter().map(|rm| format!("\"{}\"", rm.as_ref())),
|
||||||
|
"\n | ".to_owned(),
|
||||||
|
)
|
||||||
|
.collect();
|
||||||
|
let rm_tstype = format!("\nexport type ReagentMode = {};", rm_tsunion);
|
||||||
|
ts_types.push_str(&rm_tstype);
|
||||||
|
|
||||||
let infile = Path::new("src/types.ts");
|
let infile = Path::new("src/types.ts");
|
||||||
let contents = fs::read_to_string(infile).unwrap();
|
let contents = fs::read_to_string(infile).unwrap();
|
||||||
|
|
||||||
|
ts_types.push('\n');
|
||||||
|
ts_types.push_str(&contents);
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
&mut writer,
|
&mut writer,
|
||||||
"#[wasm_bindgen(typescript_custom_section)]\n\
|
"#[wasm_bindgen(typescript_custom_section)]\n\
|
||||||
const TYPES: &'static str = r#\"{contents}\"#;
|
const TYPES: &'static str = r#\"{ts_types}\"#;
|
||||||
"
|
"
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
mod utils;
|
mod utils;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use ic10emu::grammar::{LogicType, SlotLogicType};
|
use ic10emu::{grammar::{LogicType, SlotLogicType}, DeviceTemplate};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use types::{Registers, Stack};
|
use types::{Registers, Stack};
|
||||||
|
|
||||||
@@ -55,18 +55,18 @@ impl DeviceRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(getter, js_name = "nameHash")]
|
#[wasm_bindgen(getter, js_name = "nameHash")]
|
||||||
pub fn name_hash(&self) -> Option<f64> {
|
pub fn name_hash(&self) -> Option<i32> {
|
||||||
self.device.borrow().name_hash
|
self.device.borrow().name_hash
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(getter, js_name = "prefabName")]
|
#[wasm_bindgen(getter, js_name = "prefabName")]
|
||||||
pub fn prefab_name(&self) -> Option<String> {
|
pub fn prefab_name(&self) -> Option<String> {
|
||||||
self.device.borrow().prefab_name.clone()
|
self.device.borrow().prefab.as_ref().map(|prefab| prefab.name.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(getter, js_name = "prefabHash")]
|
#[wasm_bindgen(getter, js_name = "prefabHash")]
|
||||||
pub fn prefab_hash(&self) -> Option<i32> {
|
pub fn prefab_hash(&self) -> Option<i32> {
|
||||||
self.device.borrow().prefab_hash
|
self.device.borrow().prefab.as_ref().map(|prefab| prefab.hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(getter, skip_typescript)]
|
#[wasm_bindgen(getter, skip_typescript)]
|
||||||
@@ -351,6 +351,12 @@ impl VM {
|
|||||||
Ok(self.vm.borrow_mut().add_device(network)?)
|
Ok(self.vm.borrow_mut().add_device(network)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_name = "addDeviceFromTemplate", skip_typescript)]
|
||||||
|
pub fn add_device_from_template(&self, template: JsValue) -> Result<u32, JsError> {
|
||||||
|
let template: DeviceTemplate = serde_wasm_bindgen::from_value(template)?;
|
||||||
|
Ok(self.vm.borrow_mut().add_device_from_template(template)?)
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(js_name = "getDevice")]
|
#[wasm_bindgen(js_name = "getDevice")]
|
||||||
pub fn get_device(&self, id: u32) -> Option<DeviceRef> {
|
pub fn get_device(&self, id: u32) -> Option<DeviceRef> {
|
||||||
let device = self.vm.borrow().get_device(id);
|
let device = self.vm.borrow().get_device(id);
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ export interface LogicField {
|
|||||||
field_type: FieldType;
|
field_type: FieldType;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
export type Fields = Map<string, LogicField>;
|
export type LogicFields = Map<LogicType, LogicField>;
|
||||||
|
export type SlotLogicFields = Map<SlotLogicType, LogicField>;
|
||||||
|
|
||||||
export type SlotType =
|
export type SlotType =
|
||||||
| "AccessCard"
|
| "AccessCard"
|
||||||
@@ -46,12 +47,12 @@ export interface SlotOccupant {
|
|||||||
readonly quantity: number;
|
readonly quantity: number;
|
||||||
readonly max_quantity: number;
|
readonly max_quantity: number;
|
||||||
readonly damage: number;
|
readonly damage: number;
|
||||||
readonly fields: Fields;
|
readonly fields: SlotLogicFields;
|
||||||
}
|
}
|
||||||
export interface Slot {
|
export interface Slot {
|
||||||
readonly typ: SlotType;
|
readonly typ: SlotType;
|
||||||
readonly occupant: SlotOccupant | undefined;
|
readonly occupant: SlotOccupant | undefined;
|
||||||
readonly fields: Fields;
|
readonly fields: SlotLogicFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Reagents = Map<string, Map<number, number>>;
|
export type Reagents = Map<string, Map<number, number>>;
|
||||||
@@ -80,10 +81,10 @@ export type DeviceSpec = {
|
|||||||
};
|
};
|
||||||
readonly connection: number | undefined;
|
readonly connection: number | undefined;
|
||||||
};
|
};
|
||||||
export type LogicType = { readonly LogicType: string };
|
export type OperandLogicType = { readonly LogicType: string };
|
||||||
export type SlotLogicType = { readonly SlotLogicType: string };
|
export type OperandSlotLogicType = { readonly SlotLogicType: string };
|
||||||
export type BatchMode = { readonly BatchMode: string };
|
export type OperandBatchMode = { readonly BatchMode: string };
|
||||||
export type ReagentMode = { readonly ReagentMode: string };
|
export type OperandReagentMode = { readonly ReagentMode: string };
|
||||||
export type Identifier = { readonly Identifier: { name: string } };
|
export type Identifier = { readonly Identifier: { name: string } };
|
||||||
|
|
||||||
export type NumberFloat = { readonly Float: number };
|
export type NumberFloat = { readonly Float: number };
|
||||||
@@ -106,10 +107,10 @@ export type Operand =
|
|||||||
| RegisterSpec
|
| RegisterSpec
|
||||||
| DeviceSpec
|
| DeviceSpec
|
||||||
| NumberOperand
|
| NumberOperand
|
||||||
| LogicType
|
| OperandLogicType
|
||||||
| SlotLogicType
|
| OperandSlotLogicType
|
||||||
| BatchMode
|
| OperandBatchMode
|
||||||
| ReagentMode
|
| OperandReagentMode
|
||||||
| Identifier;
|
| Identifier;
|
||||||
|
|
||||||
export type Alias = RegisterSpec | DeviceSpec;
|
export type Alias = RegisterSpec | DeviceSpec;
|
||||||
@@ -141,7 +142,7 @@ export interface Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DeviceRef {
|
export interface DeviceRef {
|
||||||
readonly fields: Fields;
|
readonly fields: LogicFields;
|
||||||
readonly slots: Slot[];
|
readonly slots: Slot[];
|
||||||
readonly reagents: Reagents;
|
readonly reagents: Reagents;
|
||||||
readonly connections: Connection[];
|
readonly connections: Connection[];
|
||||||
@@ -149,5 +150,29 @@ export interface DeviceRef {
|
|||||||
readonly defines?: Defines | undefined;
|
readonly defines?: Defines | undefined;
|
||||||
readonly pins?: Pins;
|
readonly pins?: Pins;
|
||||||
readonly program?: Program;
|
readonly program?: Program;
|
||||||
getSlotFields(slot: number): Fields;
|
getSlotFields(slot: number): SlotLogicFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlotOccupantTemplate {
|
||||||
|
id?: number;
|
||||||
|
fields: { [key in SlotLogicType]?: LogicField };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlotTemplate {
|
||||||
|
typ: SlotType;
|
||||||
|
occupant?: SlotOccupantTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceTemplate {
|
||||||
|
id?: number;
|
||||||
|
name?: string;
|
||||||
|
prefab_name?: string;
|
||||||
|
slots: SlotTemplate[];
|
||||||
|
// reagents: { [key: string]: float}
|
||||||
|
connections: Connection[];
|
||||||
|
fields: { [key in LogicType]?: LogicField };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VM {
|
||||||
|
addDeviceFromTemplate(template: DeviceTemplate): number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export class IC10Editor extends BaseElement {
|
|||||||
};
|
};
|
||||||
sessions: Map<number, Ace.EditSession>;
|
sessions: Map<number, Ace.EditSession>;
|
||||||
|
|
||||||
@state() active_session: number = 0;
|
@state() active_session: number = 1;
|
||||||
|
|
||||||
active_line_markers: Map<number, number | null> = new Map();
|
active_line_markers: Map<number, number | null> = new Map();
|
||||||
languageProvider?: LanguageProvider;
|
languageProvider?: LanguageProvider;
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export class Session extends EventTarget {
|
|||||||
this._programs = new Map();
|
this._programs = new Map();
|
||||||
this._errors = new Map();
|
this._errors = new Map();
|
||||||
this._save_timeout = undefined;
|
this._save_timeout = undefined;
|
||||||
this._activeIC = 0;
|
this._activeIC = 1;
|
||||||
this._activeLines = new Map();
|
this._activeLines = new Map();
|
||||||
this.loadFromFragment();
|
this.loadFromFragment();
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ export class Session extends EventTarget {
|
|||||||
async loadFromFragment() {
|
async loadFromFragment() {
|
||||||
const fragment = window.location.hash.slice(1);
|
const fragment = window.location.hash.slice(1);
|
||||||
if (fragment === "demo") {
|
if (fragment === "demo") {
|
||||||
this._programs = new Map([[0, demoCode]]);
|
this._programs = new Map([[1, demoCode]]);
|
||||||
this._fireOnLoad();
|
this._fireOnLoad();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ export class Session extends EventTarget {
|
|||||||
const data = getJson(txt);
|
const data = getJson(txt);
|
||||||
if (data === null) {
|
if (data === null) {
|
||||||
// backwards compatible
|
// backwards compatible
|
||||||
this._programs = new Map([[0, txt]]);
|
this._programs = new Map([[1, txt]]);
|
||||||
this, this._fireOnLoad();
|
this, this._fireOnLoad();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { property, state } from "lit/decorators.js";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
DeviceRef,
|
DeviceRef,
|
||||||
Fields,
|
LogicFields,
|
||||||
Reagents,
|
Reagents,
|
||||||
Slot,
|
Slot,
|
||||||
Connection,
|
Connection,
|
||||||
@@ -25,7 +25,7 @@ export declare class VMDeviceMixinInterface {
|
|||||||
name: string | null;
|
name: string | null;
|
||||||
nameHash: number | null;
|
nameHash: number | null;
|
||||||
prefabName: string | null;
|
prefabName: string | null;
|
||||||
fields: Fields;
|
fields: LogicFields;
|
||||||
slots: Slot[];
|
slots: Slot[];
|
||||||
reagents: Reagents;
|
reagents: Reagents;
|
||||||
connections: Connection[];
|
connections: Connection[];
|
||||||
@@ -53,7 +53,7 @@ export const VMDeviceMixin = <T extends Constructor<LitElement>>(
|
|||||||
@state() accessor name: string | null = null;
|
@state() accessor name: string | null = null;
|
||||||
@state() accessor nameHash: number | null = null;
|
@state() accessor nameHash: number | null = null;
|
||||||
@state() accessor prefabName: string | null;
|
@state() accessor prefabName: string | null;
|
||||||
@state() accessor fields: Fields;
|
@state() accessor fields: LogicFields;
|
||||||
@state() accessor slots: Slot[];
|
@state() accessor slots: Slot[];
|
||||||
@state() accessor reagents: Reagents;
|
@state() accessor reagents: Reagents;
|
||||||
@state() accessor connections: Connection[];
|
@state() accessor connections: Connection[];
|
||||||
|
|||||||
Reference in New Issue
Block a user