refactor(vm+frontend): better logging, fix slot serialization
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -659,6 +659,7 @@ dependencies = [
|
||||
"serde_with",
|
||||
"stationeers_data",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"tracing-wasm",
|
||||
"tsify",
|
||||
"wasm-bindgen",
|
||||
@@ -694,6 +695,8 @@ dependencies = [
|
||||
"js-sys",
|
||||
"tokio",
|
||||
"tower-lsp",
|
||||
"tracing",
|
||||
"tracing-wasm",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
|
||||
@@ -113,16 +113,22 @@ impl VM {
|
||||
|
||||
/// Take ownership of an iterable that produces (prefab hash, ObjectTemplate) pairs and build a prefab
|
||||
/// database
|
||||
#[tracing::instrument(skip(db))]
|
||||
pub fn import_template_database(
|
||||
self: &Rc<Self>,
|
||||
db: impl IntoIterator<Item = (i32, ObjectTemplate)>,
|
||||
) {
|
||||
tracing::info!("importing new template database");
|
||||
self.template_database
|
||||
.borrow_mut()
|
||||
.replace(db.into_iter().collect());
|
||||
}
|
||||
|
||||
/// Take ownership of an iterable that produces (reagent id, Reagent) pairs and build a reagent
|
||||
/// database
|
||||
#[tracing::instrument(skip(db))]
|
||||
pub fn import_reagent_database(self: &Rc<Self>, db: impl IntoIterator<Item = (u8, Reagent)>) {
|
||||
tracing::info!("importing new reagent database");
|
||||
self.reagent_database
|
||||
.borrow_mut()
|
||||
.replace(db.into_iter().collect());
|
||||
@@ -192,6 +198,7 @@ impl VM {
|
||||
/// Add an number of object to the VM state using Frozen Object structs.
|
||||
/// See also `add_objects_frozen`
|
||||
/// Returns the built objects' IDs
|
||||
#[tracing::instrument(skip(frozen_objects))]
|
||||
pub fn add_objects_frozen(
|
||||
self: &Rc<Self>,
|
||||
frozen_objects: impl IntoIterator<Item = FrozenObject>,
|
||||
@@ -249,6 +256,7 @@ impl VM {
|
||||
/// current database.
|
||||
/// Errors if the object can not be built do to a template error
|
||||
/// Returns the built object's ID
|
||||
#[tracing::instrument]
|
||||
pub fn add_object_frozen(self: &Rc<Self>, frozen: FrozenObject) -> Result<ObjectID, VMError> {
|
||||
let mut transaction = VMTransaction::new(self);
|
||||
|
||||
@@ -295,6 +303,7 @@ impl VM {
|
||||
}
|
||||
|
||||
/// Creates a new network adn return it's ID
|
||||
#[tracing::instrument]
|
||||
pub fn add_network(self: &Rc<Self>) -> ObjectID {
|
||||
let next_id = self.network_id_space.borrow_mut().next();
|
||||
self.networks.borrow_mut().insert(
|
||||
@@ -322,6 +331,7 @@ impl VM {
|
||||
///
|
||||
/// Iterates over all objects borrowing them mutably, never call unless VM is not currently
|
||||
/// stepping or you'll get reborrow panics
|
||||
#[tracing::instrument]
|
||||
pub fn change_device_id(
|
||||
self: &Rc<Self>,
|
||||
old_id: ObjectID,
|
||||
@@ -385,6 +395,7 @@ impl VM {
|
||||
|
||||
/// Set program code if it's valid
|
||||
/// Object Id is the programmable Id or the circuit holder's id
|
||||
#[tracing::instrument]
|
||||
pub fn set_code(self: &Rc<Self>, id: ObjectID, code: &str) -> Result<bool, VMError> {
|
||||
let obj = self
|
||||
.objects
|
||||
@@ -420,6 +431,7 @@ impl VM {
|
||||
|
||||
/// Set program code and translate invalid lines to Nop, collecting errors
|
||||
/// Object Id is the programmable Id or the circuit holder's id
|
||||
#[tracing::instrument]
|
||||
pub fn set_code_invalid(self: &Rc<Self>, id: ObjectID, code: &str) -> Result<bool, VMError> {
|
||||
let obj = self
|
||||
.objects
|
||||
@@ -455,6 +467,7 @@ impl VM {
|
||||
|
||||
/// Get program code
|
||||
/// Object Id is the programmable Id or the circuit holder's id
|
||||
#[tracing::instrument]
|
||||
pub fn get_code(self: &Rc<Self>, id: ObjectID) -> Result<String, VMError> {
|
||||
let obj = self
|
||||
.objects
|
||||
@@ -488,6 +501,7 @@ impl VM {
|
||||
|
||||
/// Get a vector of any errors compiling the source code
|
||||
/// Object Id is the programmable Id or the circuit holder's id
|
||||
#[tracing::instrument]
|
||||
pub fn get_compile_errors(self: &Rc<Self>, id: ObjectID) -> Result<Vec<ICError>, VMError> {
|
||||
let obj = self
|
||||
.objects
|
||||
@@ -521,6 +535,7 @@ impl VM {
|
||||
|
||||
/// Set register of integrated circuit
|
||||
/// Object Id is the circuit Id or the circuit holder's id
|
||||
#[tracing::instrument]
|
||||
pub fn set_register(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -561,6 +576,7 @@ impl VM {
|
||||
|
||||
/// Set memory at address of object with memory
|
||||
/// Object Id is the memory writable Id or the circuit holder's id
|
||||
#[tracing::instrument]
|
||||
pub fn set_memory(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -610,6 +626,7 @@ impl VM {
|
||||
}
|
||||
|
||||
/// Set logic field on a logicable object
|
||||
#[tracing::instrument]
|
||||
pub fn set_logic_field(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -634,6 +651,7 @@ impl VM {
|
||||
}
|
||||
|
||||
/// Set slot logic filed on device object
|
||||
#[tracing::instrument]
|
||||
pub fn set_slot_logic_field(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -661,6 +679,7 @@ impl VM {
|
||||
self.operation_modified.borrow().clone()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn step_programmable(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -705,6 +724,7 @@ impl VM {
|
||||
}
|
||||
|
||||
/// returns true if executed 128 lines, false if returned early.
|
||||
#[tracing::instrument]
|
||||
pub fn run_programmable(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -816,10 +836,12 @@ impl VM {
|
||||
Err(VMError::NoIC(id))
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn get_object(self: &Rc<Self>, id: ObjectID) -> Option<VMObject> {
|
||||
self.objects.borrow().get(&id).cloned()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn batch_device(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -850,6 +872,7 @@ impl VM {
|
||||
.into_iter()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn get_device_same_network(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -862,6 +885,7 @@ impl VM {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn get_network_channel(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -887,6 +911,7 @@ impl VM {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn set_network_channel(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -913,6 +938,7 @@ impl VM {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn devices_on_same_network(self: &Rc<Self>, ids: &[ObjectID]) -> bool {
|
||||
for net in self.networks.borrow().values() {
|
||||
if net
|
||||
@@ -928,6 +954,7 @@ impl VM {
|
||||
}
|
||||
|
||||
/// return a vector with the device ids the source id can see via it's connected networks
|
||||
#[tracing::instrument]
|
||||
pub fn visible_devices(self: &Rc<Self>, source: ObjectID) -> Vec<ObjectID> {
|
||||
self.networks
|
||||
.borrow()
|
||||
@@ -944,6 +971,7 @@ impl VM {
|
||||
.concat()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn set_pin(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -976,6 +1004,7 @@ impl VM {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn set_device_connection(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -1076,6 +1105,7 @@ impl VM {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn remove_device_from_network(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -1108,6 +1138,7 @@ impl VM {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn set_batch_device_field(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -1129,6 +1160,7 @@ impl VM {
|
||||
.try_collect()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn set_batch_device_slot_field(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -1151,6 +1183,7 @@ impl VM {
|
||||
.try_collect()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn set_batch_name_device_field(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -1173,6 +1206,7 @@ impl VM {
|
||||
.try_collect()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn get_batch_device_field(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -1195,6 +1229,7 @@ impl VM {
|
||||
Ok(LogicBatchMethodWrapper(mode).apply(&samples))
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn get_batch_name_device_field(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -1218,6 +1253,7 @@ impl VM {
|
||||
Ok(LogicBatchMethodWrapper(mode).apply(&samples))
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn get_batch_name_device_slot_field(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -1242,6 +1278,7 @@ impl VM {
|
||||
Ok(LogicBatchMethodWrapper(mode).apply(&samples))
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn get_batch_device_slot_field(
|
||||
self: &Rc<Self>,
|
||||
source: ObjectID,
|
||||
@@ -1265,6 +1302,7 @@ impl VM {
|
||||
Ok(LogicBatchMethodWrapper(mode).apply(&samples))
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn remove_object(self: &Rc<Self>, id: ObjectID) -> Result<(), VMError> {
|
||||
let Some(obj) = self.objects.borrow_mut().remove(&id) else {
|
||||
return Err(VMError::UnknownId(id));
|
||||
@@ -1294,6 +1332,7 @@ impl VM {
|
||||
/// object must already be added to the VM
|
||||
/// does not clean up previous object
|
||||
/// returns the id of any former occupant
|
||||
#[tracing::instrument]
|
||||
pub fn set_slot_occupant(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -1348,6 +1387,7 @@ impl VM {
|
||||
}
|
||||
|
||||
/// returns former occupant id if any
|
||||
#[tracing::instrument]
|
||||
pub fn remove_slot_occupant(
|
||||
self: &Rc<Self>,
|
||||
id: ObjectID,
|
||||
@@ -1368,6 +1408,7 @@ impl VM {
|
||||
Ok(last)
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn freeze_object(self: &Rc<Self>, id: ObjectID) -> Result<FrozenObjectFull, VMError> {
|
||||
let Some(obj) = self.objects.borrow().get(&id).cloned() else {
|
||||
return Err(VMError::UnknownId(id));
|
||||
@@ -1375,6 +1416,7 @@ impl VM {
|
||||
Ok(FrozenObject::freeze_object(&obj, self)?)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(ids))]
|
||||
pub fn freeze_objects(
|
||||
self: &Rc<Self>,
|
||||
ids: impl IntoIterator<Item = ObjectID>,
|
||||
@@ -1389,6 +1431,7 @@ impl VM {
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn freeze_network(self: &Rc<Self>, id: ObjectID) -> Result<FrozenCableNetwork, VMError> {
|
||||
Ok(self
|
||||
.networks
|
||||
@@ -1401,6 +1444,7 @@ impl VM {
|
||||
.into())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(ids))]
|
||||
pub fn freeze_networks(
|
||||
self: &Rc<Self>,
|
||||
ids: impl IntoIterator<Item = ObjectID>,
|
||||
@@ -1420,7 +1464,9 @@ impl VM {
|
||||
.collect::<Result<Vec<FrozenCableNetwork>, VMError>>()
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn save_vm_state(self: &Rc<Self>) -> Result<FrozenVM, VMError> {
|
||||
tracing::trace!("saving vm state");
|
||||
Ok(FrozenVM {
|
||||
objects: self
|
||||
.objects
|
||||
@@ -1449,7 +1495,9 @@ impl VM {
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub fn restore_vm_state(self: &Rc<Self>, state: FrozenVM) -> Result<(), VMError> {
|
||||
tracing::trace!("restoring vm state from {:?}", &state);
|
||||
let mut transaction_network_id_space = IdSpace::new();
|
||||
transaction_network_id_space
|
||||
.use_ids(&state.networks.iter().map(|net| net.id).collect_vec())?;
|
||||
@@ -1624,6 +1672,7 @@ impl VMTransaction {
|
||||
}
|
||||
|
||||
pub fn finalize(&mut self) -> Result<(), VMError> {
|
||||
tracing::trace!("finalizing vm transaction: {:?}", &self);
|
||||
for (child, (slot, parent)) in &self.object_parents {
|
||||
let child_obj = self
|
||||
.objects
|
||||
|
||||
@@ -27,6 +27,7 @@ thiserror = "1.0.61"
|
||||
serde_derive = "1.0.203"
|
||||
serde_json = "1.0.117"
|
||||
tracing-wasm = "0.2.1"
|
||||
tracing = "0.1.40"
|
||||
|
||||
[features]
|
||||
default = ["console_error_panic_hook"]
|
||||
|
||||
@@ -18,7 +18,7 @@ use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
use stationeers_data::{
|
||||
enums::script::{LogicSlotType, LogicType},
|
||||
templates::ObjectTemplate,
|
||||
templates::{ObjectTemplate, Reagent},
|
||||
};
|
||||
|
||||
use std::{collections::BTreeMap, rc::Rc};
|
||||
@@ -60,6 +60,18 @@ impl IntoIterator for TemplateDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Tsify)]
|
||||
#[tsify(into_wasm_abi, from_wasm_abi)]
|
||||
pub struct ReagentDatabase(BTreeMap<u8, Reagent>);
|
||||
|
||||
impl IntoIterator for ReagentDatabase {
|
||||
type Item = (u8, Reagent);
|
||||
type IntoIter = std::collections::btree_map::IntoIter<u8, Reagent>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Tsify)]
|
||||
#[tsify(into_wasm_abi, from_wasm_abi)]
|
||||
pub struct FrozenObjects(Vec<FrozenObjectFull>);
|
||||
@@ -115,7 +127,7 @@ pub fn parse_value<'a, T: serde::Deserialize<'a>>(
|
||||
let mut track = serde_path_to_error::Track::new();
|
||||
let path = serde_path_to_error::Deserializer::new(jd, &mut track);
|
||||
let mut fun = |path: serde_ignored::Path| {
|
||||
log!("Found ignored key: {path}");
|
||||
tracing::warn!("Found ignored key: {path}");
|
||||
};
|
||||
serde_ignored::deserialize(path, &mut fun).map_err(|e| {
|
||||
eyre::eyre!(
|
||||
@@ -125,6 +137,7 @@ pub fn parse_value<'a, T: serde::Deserialize<'a>>(
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[wasm_bindgen]
|
||||
impl VMRef {
|
||||
#[wasm_bindgen(constructor)]
|
||||
@@ -137,6 +150,11 @@ impl VMRef {
|
||||
self.vm.import_template_database(db);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "importReagentDatabase")]
|
||||
pub fn import_reagent_database(&self, db: ReagentDatabase) {
|
||||
self.vm.import_reagent_database(db);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "importTemplateDatabaseSerdeWasm")]
|
||||
pub fn import_template_database_serde_wasm(&self, db: JsValue) -> Result<(), JsError> {
|
||||
let parsed_db: BTreeMap<i32, ObjectTemplate> =
|
||||
@@ -480,6 +498,6 @@ pub fn init() -> VMRef {
|
||||
utils::set_panic_hook();
|
||||
tracing_wasm::set_as_global_default();
|
||||
let vm = VMRef::new();
|
||||
log!("Hello from ic10emu!");
|
||||
tracing::info!("Hello from ic10emu!");
|
||||
vm
|
||||
}
|
||||
|
||||
@@ -11,12 +11,3 @@ pub fn set_panic_hook() {
|
||||
web_sys::console::log_1(&"Panic hook set...".into());
|
||||
}
|
||||
}
|
||||
|
||||
extern crate web_sys;
|
||||
|
||||
// A macro to provide `println!(..)`-style syntax for `console.log` logging.
|
||||
macro_rules! log {
|
||||
( $( $t:tt )* ) => {
|
||||
web_sys::console::log_1(&format!( $( $t )* ).into());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ wasm-bindgen-futures = { version = "0.4.42", features = [
|
||||
wasm-streams = "0.4"
|
||||
# web-tree-sitter-sys = "1.3"
|
||||
ic10lsp = { git = "https://github.com/Ryex/ic10lsp.git", branch = "wasm" }
|
||||
tracing-wasm = "0.2.1"
|
||||
tracing = "0.1.40"
|
||||
# ic10lsp = { path = "../../ic10lsp" }
|
||||
|
||||
[package.metadata.wasm-pack.profile.dev]
|
||||
|
||||
@@ -30,8 +30,9 @@ impl ServerConfig {
|
||||
#[wasm_bindgen]
|
||||
pub async fn serve(config: ServerConfig) -> Result<(), JsValue> {
|
||||
console_error_panic_hook::set_once();
|
||||
tracing_wasm::set_as_global_default();
|
||||
|
||||
web_sys::console::log_1(&"server::serve".into());
|
||||
tracing::trace!("server::serv error:");
|
||||
|
||||
let ServerConfig {
|
||||
into_server,
|
||||
@@ -51,6 +52,7 @@ pub async fn serve(config: ServerConfig) -> Result<(), JsValue> {
|
||||
})
|
||||
.map_err(|err| {
|
||||
web_sys::console::log_2(&"server::input Error: ".into(), &err);
|
||||
tracing::error!("server::input error: {:?}", &err);
|
||||
|
||||
std::io::Error::from(std::io::ErrorKind::Other)
|
||||
})
|
||||
@@ -67,7 +69,7 @@ pub async fn serve(config: ServerConfig) -> Result<(), JsValue> {
|
||||
});
|
||||
Server::new(input, output, messages).serve(service).await;
|
||||
|
||||
web_sys::console::log_1(&"server::serve ic10lsp started".into());
|
||||
tracing::info!("server::serve ic10lsp started");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -174,11 +174,14 @@ impl From<HumanTemplate> for ObjectTemplate {
|
||||
}
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct HumanTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub species: Species,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
}
|
||||
|
||||
@@ -420,6 +423,7 @@ pub struct StructureTemplate {
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct StructureSlotsTemplate {
|
||||
@@ -429,9 +433,12 @@ pub struct StructureSlotsTemplate {
|
||||
pub thermal_info: Option<ThermalInfo>,
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct StructureLogicTemplate {
|
||||
@@ -442,9 +449,12 @@ pub struct StructureLogicTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct StructureLogicDeviceTemplate {
|
||||
@@ -455,10 +465,13 @@ pub struct StructureLogicDeviceTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub device: DeviceInfo,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct StructureLogicDeviceConsumerTemplate {
|
||||
@@ -469,6 +482,8 @@ pub struct StructureLogicDeviceConsumerTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub device: DeviceInfo,
|
||||
pub consumer_info: ConsumerInfo,
|
||||
@@ -476,6 +491,7 @@ pub struct StructureLogicDeviceConsumerTemplate {
|
||||
pub fabricator_info: Option<FabricatorInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct StructureLogicDeviceMemoryTemplate {
|
||||
@@ -486,11 +502,14 @@ pub struct StructureLogicDeviceMemoryTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub device: DeviceInfo,
|
||||
pub memory: MemoryInfo,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct StructureCircuitHolderTemplate {
|
||||
@@ -501,10 +520,13 @@ pub struct StructureCircuitHolderTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub device: DeviceInfo,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct StructureLogicDeviceConsumerMemoryTemplate {
|
||||
@@ -515,6 +537,8 @@ pub struct StructureLogicDeviceConsumerMemoryTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub device: DeviceInfo,
|
||||
pub consumer_info: ConsumerInfo,
|
||||
@@ -534,6 +558,7 @@ pub struct ItemTemplate {
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemSlotsTemplate {
|
||||
@@ -543,9 +568,12 @@ pub struct ItemSlotsTemplate {
|
||||
pub thermal_info: Option<ThermalInfo>,
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemConsumerTemplate {
|
||||
@@ -555,10 +583,13 @@ pub struct ItemConsumerTemplate {
|
||||
pub thermal_info: Option<ThermalInfo>,
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub consumer_info: ConsumerInfo,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemLogicTemplate {
|
||||
@@ -569,9 +600,12 @@ pub struct ItemLogicTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemLogicMemoryTemplate {
|
||||
@@ -582,10 +616,13 @@ pub struct ItemLogicMemoryTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub memory: MemoryInfo,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemCircuitHolderTemplate {
|
||||
@@ -596,9 +633,12 @@ pub struct ItemCircuitHolderTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemSuitTemplate {
|
||||
@@ -608,10 +648,13 @@ pub struct ItemSuitTemplate {
|
||||
pub thermal_info: Option<ThermalInfo>,
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub suit_info: SuitInfo,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemSuitLogicTemplate {
|
||||
@@ -622,10 +665,13 @@ pub struct ItemSuitLogicTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub suit_info: SuitInfo,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
|
||||
pub struct ItemSuitCircuitHolderTemplate {
|
||||
@@ -636,6 +682,8 @@ pub struct ItemSuitCircuitHolderTemplate {
|
||||
#[cfg_attr(feature = "tsify", tsify(optional))]
|
||||
pub internal_atmo_info: Option<InternalAtmoInfo>,
|
||||
pub logic: LogicInfo,
|
||||
#[serde_as(as = "BTreeMap<DisplayFromStr, _>")]
|
||||
#[cfg_attr(feature = "tsify", tsify(type = "Map<string, SlotInfo>"))]
|
||||
pub slots: BTreeMap<u32, SlotInfo>,
|
||||
pub suit_info: SuitInfo,
|
||||
pub memory: MemoryInfo,
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"dbutils",
|
||||
"Depressurising",
|
||||
"deviceslength",
|
||||
"dodgerblue",
|
||||
"endpos",
|
||||
"getd",
|
||||
"Hardsuit",
|
||||
@@ -72,6 +73,7 @@
|
||||
"jetpack",
|
||||
"Keybind",
|
||||
"labelledby",
|
||||
"lawngreen",
|
||||
"lbns",
|
||||
"leeoniya",
|
||||
"logicable",
|
||||
@@ -136,6 +138,7 @@
|
||||
"VMIC",
|
||||
"VMUI",
|
||||
"vstack",
|
||||
"whitesmoke",
|
||||
"whos"
|
||||
],
|
||||
"flagWords": [],
|
||||
|
||||
@@ -9,6 +9,7 @@ import { IC10Editor } from "../editor";
|
||||
import { Session } from "../session";
|
||||
import { VirtualMachine } from "../virtualMachine";
|
||||
import { openFile, saveFile } from "../utils";
|
||||
import * as log from "log";
|
||||
|
||||
import "../virtualMachine/ui";
|
||||
import "./save";
|
||||
@@ -103,8 +104,8 @@ export class App extends BaseElement {
|
||||
<app-nav appVer=${this.appVersion} gitVer=${this.gitVer} buildDate=${this.buildDate} ></app-nav>
|
||||
<div class="app-body">
|
||||
${until(
|
||||
mainBody,
|
||||
html`
|
||||
mainBody,
|
||||
html`
|
||||
<div class="w-full h-full place-content-center">
|
||||
<div class="w-full h-fit justify-center">
|
||||
<p class="mt-auto mr-auto ml-auto w-fit text-2xl">
|
||||
@@ -115,7 +116,7 @@ export class App extends BaseElement {
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
<session-share-dialog></session-share-dialog>
|
||||
<save-dialog></save-dialog>
|
||||
@@ -138,7 +139,7 @@ export class App extends BaseElement {
|
||||
const saved = JSON.parse(seenVersionsStr);
|
||||
seenVersions = saved;
|
||||
} catch (e) {
|
||||
console.log("error pulling seen versions", e);
|
||||
log.error("error pulling seen versions", e);
|
||||
}
|
||||
}
|
||||
const ourVer = `${this.appVersion}_${this.gitVer}_${this.buildDate}`;
|
||||
@@ -155,7 +156,7 @@ export class App extends BaseElement {
|
||||
const saved = JSON.parse(seenVersionsStr);
|
||||
seenVersions.concat(saved);
|
||||
} catch (e) {
|
||||
console.log("error pulling seen versions", e);
|
||||
log.error("error pulling seen versions", e);
|
||||
}
|
||||
}
|
||||
const unique = new Set(seenVersions);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { HTMLTemplateResult, html, css } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "components";
|
||||
import * as log from "log";
|
||||
|
||||
import SlMenuItem from "@shoelace-style/shoelace/dist/components/menu-item/menu-item.js";
|
||||
|
||||
@@ -213,7 +214,7 @@ export class Nav extends BaseElement {
|
||||
`;
|
||||
}
|
||||
|
||||
firstUpdated(): void {}
|
||||
firstUpdated(): void { }
|
||||
|
||||
_menuClickHandler(e: CustomEvent) {
|
||||
const item = e.detail.item as SlMenuItem;
|
||||
@@ -248,7 +249,7 @@ export class Nav extends BaseElement {
|
||||
this.dispatchEvent(new CustomEvent("app-changelog", { bubbles: true }));
|
||||
break;
|
||||
default:
|
||||
console.log("Unknown main menu item", item.value);
|
||||
log.debug("Unknown main menu item", item.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { html, css} from "lit";
|
||||
import { customElement, query, state } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "components";
|
||||
import { SessionDB } from "sessionDB";
|
||||
import * as log from "log";
|
||||
|
||||
import SlInput from "@shoelace-style/shoelace/dist/components/input/input.js";
|
||||
import { repeat } from "lit/directives/repeat.js";
|
||||
@@ -256,7 +257,7 @@ export class SaveDialog extends BaseElement {
|
||||
async _handleSaveButtonClick(_e: CustomEvent) {
|
||||
const name = this.saveInput.value;
|
||||
const app = await window.App.get();
|
||||
console.log(app);
|
||||
log.debug(app);
|
||||
await app.session.saveLocal(name);
|
||||
this.saveDialog.hide();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { isSome } from "utils";
|
||||
export type PrefabName = keyof typeof prefabDatabase.prefabs;
|
||||
export type Prefab<K extends PrefabName> = typeof prefabDatabase.prefabs[K]
|
||||
export type ReagentName = keyof typeof prefabDatabase.reagents;
|
||||
export type ReagentHash = (typeof prefabDatabase.reagents)[ReagentName]["Hash"]
|
||||
export type ReagentHash = (typeof prefabDatabase.reagents)[ReagentName]["hash"]
|
||||
export type NetworkChannels = [number, number, number, number, number, number, number, number]
|
||||
|
||||
export const validCircuitPrefabsNames = ["ItemIntegratedCircuit10"] as const;
|
||||
@@ -25,7 +25,7 @@ export interface ObjectFromTemplateOptions<K extends PrefabName> {
|
||||
obj: ObjectID,
|
||||
slot: number,
|
||||
} : never,
|
||||
slots?: Prefab<K> extends { slots: readonly unknown[] } ? Record<number, {
|
||||
slots?: Prefab<K> extends { slots: {} } ? Record<number, {
|
||||
quantity: number,
|
||||
occupant: ObjectID
|
||||
}> : never,
|
||||
@@ -102,7 +102,7 @@ export function objectFromTemplate<K extends PrefabName>(
|
||||
}
|
||||
if (isSome(options?.reagents)) {
|
||||
frozen.obj_info.reagents = new Map(Object.entries(options.reagents).map(([reagent, value]: [ReagentName, number]) => {
|
||||
return [prefabDatabase.reagents[reagent].Hash, value]
|
||||
return [prefabDatabase.reagents[reagent].hash, value]
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Mode as TextMode } from "ace-builds/src-noconflict/mode-text";
|
||||
|
||||
export async function setupLspWorker() {
|
||||
// Create a web worker
|
||||
let worker = new Worker(new URL("./lspWorker.ts", import.meta.url));
|
||||
let worker = new Worker(new URL("./lspWorker.ts", import.meta.url), { name: "ic10lsp-Worker" });
|
||||
|
||||
const loaded = (w: Worker) =>
|
||||
new Promise((r) => w.addEventListener("message", r, { once: true }));
|
||||
|
||||
@@ -40,6 +40,8 @@ import { VirtualMachine } from "virtualMachine";
|
||||
import { isSome } from "utils";
|
||||
import { Session } from "session";
|
||||
|
||||
import * as log from "log";
|
||||
|
||||
interface SessionStateExtension {
|
||||
state?: {
|
||||
errorMarkers?: Ace.MarkerGroup;
|
||||
@@ -108,7 +110,7 @@ export class IC10Editor extends BaseElement {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
console.log("constructing editor");
|
||||
log.trace("constructing editor");
|
||||
|
||||
window.Editor = this;
|
||||
}
|
||||
@@ -158,7 +160,7 @@ export class IC10Editor extends BaseElement {
|
||||
async firstUpdated() {
|
||||
await this.setupApp();
|
||||
|
||||
console.log("editor firstUpdated");
|
||||
log.trace("editor firstUpdated");
|
||||
if (!ace.require("ace/ext/language_tools")) {
|
||||
await import("ace-builds/src-noconflict/ext-language_tools");
|
||||
}
|
||||
@@ -608,7 +610,7 @@ export class IC10Editor extends BaseElement {
|
||||
const temp = Object.assign({}, this.settings, saved);
|
||||
Object.assign(this.settings, temp);
|
||||
} catch (e) {
|
||||
console.log("error loading editor settings", e);
|
||||
log.error("error loading editor settings", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ServerConfig, serve } from "ic10lsp_wasm";
|
||||
|
||||
import * as log from "log";
|
||||
|
||||
export const encoder = new TextEncoder();
|
||||
export const decoder = new TextDecoder();
|
||||
|
||||
@@ -120,9 +122,7 @@ export class AsyncStreamQueueUint8Array
|
||||
|
||||
async next(): Promise<IteratorResult<Uint8Array>> {
|
||||
const done = false;
|
||||
// console.log(`AsyncStream(${this.tag}) waiting for message`)
|
||||
const value = await this.dequeue();
|
||||
// console.log(`AsyncStream(${this.tag}) got message`, decoder.decode(value))
|
||||
return { done, value };
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ function sendClient(data: any) {
|
||||
async function listen() {
|
||||
let contentLength: number | null = null;
|
||||
let buffer = new Uint8Array();
|
||||
console.log("Worker: listening for lsp messages...");
|
||||
log.trace("Worker: listening for lsp messages...");
|
||||
for await (const bytes of serverMsgStream) {
|
||||
buffer = Bytes.append(Uint8Array, buffer, bytes);
|
||||
let waitingForFullContent = false;
|
||||
@@ -236,18 +236,18 @@ async function listen() {
|
||||
|
||||
try {
|
||||
const message = JSON.parse(delimited);
|
||||
console.log(
|
||||
log.debug(
|
||||
"Lsp Message:",
|
||||
`| This Loop: ${messagesThisLoop} |`,
|
||||
message,
|
||||
);
|
||||
postMessage(message);
|
||||
} catch (e) {
|
||||
console.log("Error parsing Lsp Message:", e);
|
||||
log.error("Error parsing Lsp Message:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log("Worker: lsp message queue done?");
|
||||
log.debug("Worker: lsp message queue done?");
|
||||
}
|
||||
|
||||
listen();
|
||||
@@ -255,9 +255,9 @@ listen();
|
||||
postMessage("ready");
|
||||
|
||||
onmessage = function (e) {
|
||||
console.log("Client Message:", e.data);
|
||||
log.debug("Client Message:", e.data);
|
||||
sendClient(e.data);
|
||||
};
|
||||
|
||||
console.log("Starting LSP...");
|
||||
log.trace("Starting LSP...");
|
||||
start();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { prompt as ace_prompt } from "ace-builds/src-noconflict/ext-prompt"
|
||||
|
||||
console.log(ace_prompt);
|
||||
|
||||
function prompt(editor: { cmdLine: { setTheme: (arg0: string) => void; }; }, message: any, options: any, callback: any) {
|
||||
ace_prompt(editor, message, options, callback);
|
||||
if (editor.cmdLine) {
|
||||
|
||||
51
www/src/ts/log.ts
Normal file
51
www/src/ts/log.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
export function logHeaderFormatting(msg: string, style: string, origin: string,): string[] {
|
||||
return [
|
||||
`%c${msg}%c ${origin}%c`,
|
||||
style,
|
||||
"color: gray; font-style: italic",
|
||||
"color: inherit"
|
||||
];
|
||||
}
|
||||
|
||||
declare var WorkerGlobalScope: {
|
||||
prototype: any;
|
||||
new(): any;
|
||||
};
|
||||
|
||||
export function getOrigin(framesUp: number = 1) {
|
||||
const origin = new Error().stack.split('\n')[framesUp + 1];
|
||||
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
|
||||
const workerName = self.name ?? "worker"
|
||||
return `(worker: ${workerName})|${origin}`;
|
||||
} else {
|
||||
return origin;
|
||||
}
|
||||
}
|
||||
|
||||
export function error(...args: any[]): void {
|
||||
const header = logHeaderFormatting("ERROR", "color: red; background: #444", getOrigin());
|
||||
console.error(...header, ...args)
|
||||
}
|
||||
|
||||
export function warn(...args: any[]): void {
|
||||
const header = logHeaderFormatting("WARN", "color: orange; background: #444", getOrigin());
|
||||
console.warn(...header, ...args)
|
||||
}
|
||||
|
||||
export function info(...args: any[]): void {
|
||||
const header = logHeaderFormatting("INFO", "color: whitesmoke; background: #444", getOrigin());
|
||||
console.info(...header, ...args)
|
||||
}
|
||||
|
||||
export function debug(...args: any[]): void {
|
||||
const header = logHeaderFormatting("DEBUG", "color: lawngreen; background: #444", getOrigin());
|
||||
console.debug(...header, ...args)
|
||||
}
|
||||
|
||||
export function trace(...args: any[]): void {
|
||||
const header = logHeaderFormatting("TRACE", "color: dodgerblue; background: #444", getOrigin());
|
||||
console.log(...header, ...args)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
toJson,
|
||||
} from "./utils";
|
||||
|
||||
import * as log from "log";
|
||||
|
||||
import * as presets from "./presets";
|
||||
import { computed, signal, Signal } from "@lit-labs/preact-signals";
|
||||
import { SessionDB } from "sessionDB";
|
||||
@@ -97,7 +99,7 @@ export class Session extends TypedEventTarget<SessionEventMap, typeof EventTarge
|
||||
const fragment = base64url_encode(c_bytes);
|
||||
window.history.replaceState(null, "", `#${fragment}`);
|
||||
} catch (e) {
|
||||
console.log("Error compressing content fragment:", e);
|
||||
log.error("Error compressing content fragment:", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -144,7 +146,7 @@ export class Session extends TypedEventTarget<SessionEventMap, typeof EventTarge
|
||||
} else if ("vm" in data && "activeIC" in data) {
|
||||
this.load(data as SessionDB.CurrentDBVmState);
|
||||
} else {
|
||||
console.log("Bad session data:", data);
|
||||
log.error("Bad session data:", data);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -280,11 +282,11 @@ function guessFormat(bytes: ArrayBuffer): CompressionFormat {
|
||||
async function decompressFragment(c_bytes: ArrayBuffer) {
|
||||
try {
|
||||
const format = guessFormat(c_bytes);
|
||||
console.log("Decompressing fragment with:", format);
|
||||
log.info("Decompressing fragment with:", format);
|
||||
const bytes = await decompress(c_bytes, format);
|
||||
return bytes;
|
||||
} catch (e) {
|
||||
console.log("Error decompressing content fragment:", e);
|
||||
log.error("Error decompressing content fragment:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Ace } from "ace-builds";
|
||||
import { TransferHandler } from "comlink";
|
||||
import * as log from "log";
|
||||
|
||||
export function isSome<T>(object: T | null | undefined): object is T {
|
||||
return typeof object !== "undefined" && object !== null;
|
||||
@@ -230,7 +231,7 @@ export function makeRequest(opts: {
|
||||
export async function saveFile(content: BlobPart) {
|
||||
const blob = new Blob([content], { type: "text/plain" });
|
||||
if (typeof window.showSaveFilePicker !== "undefined") {
|
||||
console.log("Saving via FileSystem API");
|
||||
log.info("Saving via FileSystem API");
|
||||
try {
|
||||
const saveHandle = await window.showSaveFilePicker({
|
||||
types: [
|
||||
@@ -247,10 +248,10 @@ export async function saveFile(content: BlobPart) {
|
||||
await ws.write(blob);
|
||||
await ws.close();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log.error(e);
|
||||
}
|
||||
} else {
|
||||
console.log("saving file via hidden link event");
|
||||
log.info("saving file via hidden link event");
|
||||
var a = document.createElement("a");
|
||||
const date = new Date().valueOf().toString(16);
|
||||
a.download = `code_${date}.ic10`;
|
||||
@@ -261,7 +262,7 @@ export async function saveFile(content: BlobPart) {
|
||||
|
||||
export async function openFile(editor: Ace.Editor) {
|
||||
if (typeof window.showOpenFilePicker !== "undefined") {
|
||||
console.log("opening file via FileSystem Api");
|
||||
log.info("opening file via FileSystem Api");
|
||||
try {
|
||||
const [fileHandle] = await window.showOpenFilePicker();
|
||||
const file = await fileHandle.getFile();
|
||||
@@ -269,16 +270,16 @@ export async function openFile(editor: Ace.Editor) {
|
||||
const session = editor.getSession();
|
||||
session.setValue(contents);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
log.error(e);
|
||||
}
|
||||
} else {
|
||||
console.log("opening file via hidden input event");
|
||||
log.info("opening file via hidden input event");
|
||||
let input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = ".txt,.ic10,.mips,text/*";
|
||||
input.onchange = (_) => {
|
||||
const files = Array.from(input.files!);
|
||||
console.log(files);
|
||||
log.trace(files);
|
||||
const file = files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
|
||||
@@ -15,6 +15,8 @@ import { repeat } from "lit/directives/repeat.js";
|
||||
import { Connection } from "ic10emu_wasm";
|
||||
import { createRef, ref, Ref } from "lit/directives/ref.js";
|
||||
|
||||
import * as log from "log";
|
||||
|
||||
export type CardTab = "fields" | "slots" | "reagents" | "networks" | "pins";
|
||||
|
||||
@customElement("vm-device-card")
|
||||
@@ -119,7 +121,7 @@ export class VMDeviceCard extends VMObjectMixin(BaseElement) {
|
||||
|
||||
onImageErr(e: Event) {
|
||||
this.image_err = true;
|
||||
console.log("Image load error", e);
|
||||
log.error("Image load error", e);
|
||||
}
|
||||
|
||||
thisIsActiveIc = computed(() => {
|
||||
@@ -327,7 +329,7 @@ export class VMDeviceCard extends VMObjectMixin(BaseElement) {
|
||||
});
|
||||
|
||||
const connectionSelectRef = this.getConnectionSelectRef(index);
|
||||
selectOptions.subscribe(() => {this.forceSelectUpdate(connectionSelectRef)})
|
||||
selectOptions.subscribe(() => { this.forceSelectUpdate(connectionSelectRef) })
|
||||
|
||||
connNet.subscribe((net) => {
|
||||
if (isSome(connectionSelectRef.value)) {
|
||||
|
||||
@@ -82,8 +82,8 @@ export class VMSlotAddDialog extends VMObjectMixin(BaseElement) {
|
||||
const obj = this.vm.value?.state.getObject(this.objectIDSignal.value).value;
|
||||
if (isSome(obj)) {
|
||||
const template = obj.template;
|
||||
const slot = "slots" in template ? template.slots[this.slotIndex.value] : null;
|
||||
const typ = slot?.typ;
|
||||
const slot = "slots" in template ? template.slots.get(this.slotIndex.value.toString()) : null;
|
||||
const typ = typeof slot === "object" && "Direct" in slot ? slot.Direct.class : null;
|
||||
|
||||
if (typeof typ === "string" && typ !== "None") {
|
||||
filtered = Array.from(Object.values(this.items.value)).filter(
|
||||
|
||||
@@ -151,8 +151,7 @@ export class VmObjectTemplate extends VMObjectMixin(
|
||||
).map(
|
||||
(slot, _index) =>
|
||||
({
|
||||
typ: slot.class
|
||||
,
|
||||
typ: typeof slot === "object" && "Direct" in slot ? slot.Direct.class : null,
|
||||
quantity: 0,
|
||||
}) as SlotTemplate,
|
||||
);
|
||||
|
||||
@@ -28,6 +28,8 @@ import {
|
||||
import { getJsonContext } from "./jsonErrorUtils";
|
||||
import { VMState } from "./state";
|
||||
|
||||
import * as log from "log";
|
||||
|
||||
export interface VirtualMachineEventMap {
|
||||
"vm-template-db-loaded": CustomEvent<TemplateDatabase>;
|
||||
"vm-objects-update": CustomEvent<number[]>;
|
||||
@@ -62,11 +64,11 @@ class VirtualMachine extends TypedEventTarget<VirtualMachineEventMap, typeof Eve
|
||||
|
||||
async setupVM() {
|
||||
|
||||
this.vmWorker = new Worker(new URL("./vmWorker.ts", import.meta.url));
|
||||
this.vmWorker = new Worker(new URL("./vmWorker.ts", import.meta.url), { name: "ic10emu-Worker"});
|
||||
const loaded = (w: Worker) =>
|
||||
new Promise((r) => w.addEventListener("message", r, { once: true }));
|
||||
await Promise.all([loaded(this.vmWorker)]);
|
||||
console.info("VM Worker loaded");
|
||||
log.info("VM Worker loaded");
|
||||
const vm = Comlink.wrap<VMRef>(this.vmWorker);
|
||||
this.ic10vm = vm;
|
||||
this.state.vm.value = await this.ic10vm.saveVMState();
|
||||
@@ -133,11 +135,11 @@ class VirtualMachine extends TypedEventTarget<VirtualMachineEventMap, typeof Eve
|
||||
|
||||
handleVmError(err: Error, args: { context?: string, jsonContext?: string, trace?: boolean } = {}) {
|
||||
const message = args.context ? `Error in Virtual Machine {${args.context}}` : "Error in Virtual Machine";
|
||||
console.log(message, err);
|
||||
log.error(message, err);
|
||||
if (args.jsonContext != null) {
|
||||
const jsonTypeError = err.message.match(jsonErrorRegex)
|
||||
if (jsonTypeError) {
|
||||
console.log(
|
||||
log.debug(
|
||||
"Json Error context",
|
||||
getJsonContext(
|
||||
parseInt(jsonTypeError.groups["errorLine"]),
|
||||
@@ -307,14 +309,14 @@ class VirtualMachine extends TypedEventTarget<VirtualMachineEventMap, typeof Eve
|
||||
|
||||
setupTemplateDatabase(db: TemplateDatabase) {
|
||||
this.state.templateDB.value = db;
|
||||
console.log("Loaded Template Database", this.state.templateDB.value);
|
||||
log.debug("Loaded Template Database", this.state.templateDB.value);
|
||||
this.dispatchCustomEvent("vm-template-db-loaded", this.state.templateDB.value);
|
||||
}
|
||||
|
||||
async addObjectFrozen(frozen: FrozenObject): Promise<ObjectID | undefined> {
|
||||
let id = undefined;
|
||||
try {
|
||||
console.log("adding device", frozen);
|
||||
log.trace("adding device", frozen);
|
||||
id = await this.ic10vm.addObjectFrozen(frozen);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
@@ -329,7 +331,7 @@ class VirtualMachine extends TypedEventTarget<VirtualMachineEventMap, typeof Eve
|
||||
): Promise<ObjectID[] | undefined> {
|
||||
let ids = undefined;
|
||||
try {
|
||||
console.log("adding devices", frozenObjects);
|
||||
log.trace("adding devices", frozenObjects);
|
||||
ids = await this.ic10vm.addObjectsFrozen(frozenObjects);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
@@ -357,7 +359,7 @@ class VirtualMachine extends TypedEventTarget<VirtualMachineEventMap, typeof Eve
|
||||
quantity: number,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
console.log("setting slot occupant", frozen);
|
||||
log.trace("setting slot occupant", frozen);
|
||||
await this.ic10vm.setSlotOccupant(id, index, frozen, quantity);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
@@ -384,7 +386,7 @@ class VirtualMachine extends TypedEventTarget<VirtualMachineEventMap, typeof Eve
|
||||
|
||||
async restoreVMState(state: FrozenVM) {
|
||||
try {
|
||||
console.info("Restoring VM State from", state);
|
||||
log.info("Restoring VM State from", state);
|
||||
await this.ic10vm.restoreVMState(state);
|
||||
} catch (e) {
|
||||
this.handleVmError(e, { jsonContext: JSON.stringify(state) });
|
||||
|
||||
@@ -2,6 +2,8 @@ import { computed, ReadonlySignal, signal, Signal } from "@lit-labs/preact-signa
|
||||
import { Class, Connection, FrozenCableNetwork, FrozenObject, FrozenVM, ICInfo, ICState, LineError, LogicField, LogicSlotType, LogicType, ObjectID, Operand, Slot, TemplateDatabase } from "ic10emu_wasm";
|
||||
import { isSome, structuralEqual } from "utils";
|
||||
|
||||
import * as log from "log";
|
||||
|
||||
|
||||
export interface ObjectSlotInfo {
|
||||
parent: ObjectID;
|
||||
@@ -232,7 +234,7 @@ export class VMState {
|
||||
const s = computed((): number => {
|
||||
const obj = this.getObject(id).value;
|
||||
const template = obj?.template;
|
||||
return isSome(template) && "slots" in template ? template.slots.length : 0
|
||||
return isSome(template) && "slots" in template ? template.slots.size : 0
|
||||
});
|
||||
this.signalCacheSet(key, s);
|
||||
return s;
|
||||
@@ -248,13 +250,15 @@ export class VMState {
|
||||
const obj = this.getObject(id).value;
|
||||
const info = obj?.obj_info.slots.get(index);
|
||||
const template = obj?.template;
|
||||
const slotTemplate = isSome(template) && "slots" in template ? template.slots[index] : null;
|
||||
const slotTemplate = isSome(template) && "slots" in template ? template.slots.get(index.toString()) : null;
|
||||
const name = typeof slotTemplate === "object" && "Direct" in slotTemplate ? slotTemplate.Direct.name : slotTemplate?.Proxy.name;
|
||||
const typ = typeof slotTemplate === "object" && "Direct" in slotTemplate ? slotTemplate.Direct.class : null;
|
||||
if (isSome(obj)) {
|
||||
const next = {
|
||||
parent: obj?.obj_info.id,
|
||||
index,
|
||||
name: slotTemplate?.name,
|
||||
typ: slotTemplate?.typ,
|
||||
name,
|
||||
typ,
|
||||
quantity: info?.quantity,
|
||||
occupant: info?.id
|
||||
}
|
||||
@@ -713,7 +717,7 @@ export class VMState {
|
||||
} else if (this.programHolderIds.value?.includes(id)) {
|
||||
return this.getObject(id).value?.obj_info.source_code ?? null;
|
||||
} else {
|
||||
console.error(`(objectId: ${id}) does not refer to a object with a known program interface`)
|
||||
log.error(`(objectId: ${id}) does not refer to a object with a known program interface`)
|
||||
return null;
|
||||
}
|
||||
})
|
||||
@@ -735,7 +739,7 @@ export class VMState {
|
||||
} else if (this.programHolderIds.value?.includes(id)) {
|
||||
ic = this.getObject(id).value ?? null;
|
||||
} else {
|
||||
console.error(`(objectId: ${id}) does not refer to a object with a known program interface`)
|
||||
log.error(`(objectId: ${id}) does not refer to a object with a known program interface`)
|
||||
return null;
|
||||
}
|
||||
const errors = ic?.obj_info.compile_errors?.flatMap((error): LineError[] => {
|
||||
|
||||
@@ -1,42 +1,78 @@
|
||||
import { VMRef, init } from "ic10emu_wasm";
|
||||
import type {
|
||||
TemplateDatabase,
|
||||
Reagent,
|
||||
ObjectTemplate,
|
||||
} from "ic10emu_wasm";
|
||||
|
||||
import * as Comlink from "comlink";
|
||||
|
||||
import * as log from "log";
|
||||
|
||||
import prefabDatabase from "../database/prefabDatabase";
|
||||
import { comlinkSpecialJsonTransferHandler } from "utils";
|
||||
|
||||
Comlink.transferHandlers.set("SpecialJson", comlinkSpecialJsonTransferHandler);
|
||||
|
||||
console.info("Processing Json prefab Database ", prefabDatabase);
|
||||
|
||||
const vm: VMRef = init();
|
||||
|
||||
|
||||
const start_time = performance.now();
|
||||
const template_database = new Map(
|
||||
Object.entries(prefabDatabase.prefabsByHash).map(([hash, prefabName]) => [
|
||||
parseInt(hash),
|
||||
prefabDatabase.prefabs[prefabName],
|
||||
]),
|
||||
) as TemplateDatabase;
|
||||
console.info("Loading Prefab Template Database into VM", template_database);
|
||||
try {
|
||||
// vm.importTemplateDatabase(template_database);
|
||||
vm.importTemplateDatabase(template_database);
|
||||
const now = performance.now();
|
||||
const time_elapsed = (now - start_time) / 1000;
|
||||
console.info(`Prefab Template Database loaded in ${time_elapsed} seconds`);
|
||||
} catch (e) {
|
||||
if ("stack" in e) {
|
||||
console.error("Error importing template database:", e.toString(), e.stack);
|
||||
} else {
|
||||
console.error("Error importing template database:", e.toString());
|
||||
log.info("Processing Json Database", prefabDatabase);
|
||||
{
|
||||
const start_time = performance.now();
|
||||
const template_database = new Map(
|
||||
Object.entries(prefabDatabase.prefabsByHash).map(([hash, prefabName]) => [
|
||||
parseInt(hash),
|
||||
prefabDatabase.prefabs[prefabName] as ObjectTemplate,
|
||||
]),
|
||||
);
|
||||
log.info("Loading Prefab Template Database into VM", template_database);
|
||||
|
||||
try {
|
||||
vm.importTemplateDatabase(template_database);
|
||||
const now = performance.now();
|
||||
const time_elapsed = (now - start_time) / 1000;
|
||||
log.info(`Prefab Template Database loaded in ${time_elapsed} seconds`);
|
||||
} catch (e) {
|
||||
if ("stack" in e) {
|
||||
log.error("Error importing template database:", e.toString(), e.stack);
|
||||
} else {
|
||||
log.error("Error importing template database:", e.toString());
|
||||
}
|
||||
}
|
||||
console.info(JSON.stringify(template_database));
|
||||
}
|
||||
|
||||
{
|
||||
const start_time = performance.now();
|
||||
const reagent_database = new Map(
|
||||
Object.entries(prefabDatabase.reagents).map(([_name, entry]) => [
|
||||
entry.id,
|
||||
{
|
||||
id: entry.id satisfies number,
|
||||
name: entry.name satisfies string,
|
||||
hash: entry.hash satisfies number,
|
||||
unit: entry.unit satisfies string,
|
||||
is_organic: entry.is_organic satisfies boolean,
|
||||
sources: new Map(Object.entries(entry.sources))
|
||||
} satisfies Reagent
|
||||
])
|
||||
)
|
||||
log.info("Loading Reagent Database into VM", reagent_database);
|
||||
|
||||
try {
|
||||
vm.importReagentDatabase(reagent_database);
|
||||
const now = performance.now();
|
||||
const time_elapsed = (now - start_time) / 1000;
|
||||
log.info(`Prefab Reagent Database loaded in ${time_elapsed} seconds`);
|
||||
} catch (e) {
|
||||
if ("stack" in e) {
|
||||
log.error("Error importing reagent database:", e.toString(), e.stack);
|
||||
} else {
|
||||
log.error("Error importing reagent database:", e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
postMessage("ready");
|
||||
|
||||
Comlink.expose(vm);
|
||||
|
||||
Reference in New Issue
Block a user