use crate::prelude::*;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TheCodeSandbox {
pub id: Uuid,
#[serde(skip)]
pub packages: FxHashMap<Uuid, TheCodePackage>,
pub objects: FxHashMap<Uuid, TheCodeObject>,
pub items: FxHashMap<Uuid, TheCodeObject>,
pub areas: FxHashMap<Uuid, TheCodeObject>,
pub debug_mode: bool,
#[serde(skip)]
pub aliases: FxHashMap<String, Uuid>,
#[serde(skip)]
pub func_rc: Option<TheValue>,
#[serde(skip)]
pub module_stack: Vec<Uuid>,
#[serde(skip)]
pub codegrid_stack: Vec<Uuid>,
#[serde(skip)]
pub call_stack: Vec<TheCodeFunction>,
#[serde(skip)]
pub debug_modules: FxHashMap<Uuid, TheDebugModule>,
#[serde(skip)]
pub debug_messages: Vec<TheDebugMessage>,
}
impl Default for TheCodeSandbox {
fn default() -> Self {
TheCodeSandbox::new()
}
}
impl TheCodeSandbox {
pub fn new() -> Self {
Self {
id: Uuid::new_v4(),
objects: FxHashMap::default(),
items: FxHashMap::default(),
areas: FxHashMap::default(),
packages: FxHashMap::default(),
debug_mode: false,
aliases: FxHashMap::default(),
func_rc: None,
module_stack: vec![],
call_stack: vec![],
codegrid_stack: vec![],
debug_modules: FxHashMap::default(),
debug_messages: vec![],
}
}
pub fn clear_runtime_states(&mut self) {
self.aliases = FxHashMap::default();
self.func_rc = None;
self.call_stack = vec![];
self.module_stack = vec![];
self.debug_modules = FxHashMap::default();
self.codegrid_stack = vec![];
}
pub fn clear_debug_messages(&mut self) {
self.debug_messages = vec![];
}
pub fn insert_package(&mut self, package: TheCodePackage) {
self.packages.insert(package.id, package);
}
pub fn add_object(&mut self, object: TheCodeObject) {
self.objects.insert(object.id, object);
}
pub fn add_item(&mut self, item: TheCodeObject) {
self.items.insert(item.id, item);
}
pub fn add_area(&mut self, area: TheCodeObject) {
self.areas.insert(area.id, area);
}
pub fn get_package_module_cloned(
&self,
package_id: &Uuid,
codegrid_id: &Uuid,
) -> Option<TheCodeModule> {
if let Some(package) = self.packages.get(package_id) {
if let Some(module) = package.get_function_codegrid(codegrid_id) {
return Some(module.clone());
}
}
None
}
pub fn get_local(&self, name: &String) -> Option<&TheValue> {
if let Some(function) = self.call_stack.last() {
if let Some(var) = function.get_local(name) {
return Some(var);
}
}
None
}
pub fn get_object(&self, name: &String) -> Option<&TheCodeObject> {
if let Some(id) = self.aliases.get(name) {
if let Some(object) = self.objects.get(id) {
return Some(object);
}
}
None
}
pub fn get_object_mut(&mut self, name: &String) -> Option<&mut TheCodeObject> {
if let Some(id) = self.aliases.get(name) {
if let Some(object) = self.objects.get_mut(id) {
return Some(object);
} else if let Some(item) = self.items.get_mut(id) {
return Some(item);
} else if let Some(area) = self.areas.get_mut(id) {
return Some(area);
}
}
None
}
pub fn get_self_mut(&mut self) -> Option<&mut TheCodeObject> {
if let Some(id) = self.aliases.get("self") {
if let Some(object) = self.objects.get_mut(id) {
return Some(object);
} else if let Some(item) = self.items.get_mut(id) {
return Some(item);
} else if let Some(area) = self.areas.get_mut(id) {
return Some(area);
}
}
None
}
pub fn get_target_mut(&mut self) -> Option<&mut TheCodeObject> {
if let Some(id) = self.aliases.get("target") {
if let Some(object) = self.objects.get_mut(id) {
return Some(object);
}
}
None
}
pub fn get_self_area_mut(&mut self) -> Option<&mut TheCodeObject> {
if let Some(id) = self.aliases.get("self") {
if let Some(area) = self.areas.get_mut(id) {
return Some(area);
}
}
None
}
pub fn get_self_item_mut(&mut self) -> Option<&mut TheCodeObject> {
if let Some(id) = self.aliases.get("self") {
if let Some(item) = self.items.get_mut(id) {
return Some(item);
}
}
None
}
pub fn push_current_module(&mut self, module_id: Uuid, codegrid_id: Uuid) {
self.module_stack.push(module_id);
self.codegrid_stack.push(codegrid_id);
let debug_module = TheDebugModule {
codegrid_id,
..TheDebugModule::default()
};
self.debug_modules.insert(module_id, debug_module);
}
pub fn pop_current_module(&mut self) {
self.module_stack.pop();
self.codegrid_stack.pop();
}
pub fn set_debug_value(&mut self, location: (u16, u16), value: (Option<TheValue>, TheValue)) {
if let Some(module_id) = self.module_stack.last() {
if let Some(debug_module) = self.debug_modules.get_mut(module_id) {
debug_module.values.insert(location, value);
}
}
}
pub fn set_debug_executed(&mut self, location: (u16, u16)) {
if let Some(module_id) = self.module_stack.last() {
if let Some(debug_module) = self.debug_modules.get_mut(module_id) {
debug_module.executed.insert(location);
}
}
}
pub fn get_module_debug_module(&self, module_id: Uuid) -> TheDebugModule {
if let Some(dv) = self.debug_modules.get(&module_id) {
dv.clone()
} else {
TheDebugModule::default()
}
}
pub fn get_codegrid_debug_module(&self, entity_id: Uuid) -> TheDebugModule {
for (index, id) in self.codegrid_stack.iter().enumerate() {
if *id == entity_id {
if let Some(module_id) = self.module_stack.get(index) {
if let Some(dv) = self.debug_modules.get(module_id) {
return dv.clone();
}
}
}
}
TheDebugModule::default()
}
pub fn add_debug_message(&mut self, message: String) {
let mut debug_message = TheDebugMessage::new(TheDebugMessageRole::Debug, message);
if let Some(object) = self.get_self_mut() {
if let Some(name) = object.get(&"name".to_string()) {
debug_message.entity = name.describe();
}
}
self.debug_messages.push(debug_message);
}
pub fn from_json(json: &str) -> Self {
serde_json::from_str(json).unwrap_or_default()
}
pub fn to_json(&self) -> String {
serde_json::to_string(&self).unwrap_or_default()
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TheDebugModule {
pub codegrid_id: Uuid,
pub values: FxHashMap<(u16, u16), (Option<TheValue>, TheValue)>,
pub executed: FxHashSet<(u16, u16)>,
}
impl Default for TheDebugModule {
fn default() -> Self {
TheDebugModule::new()
}
}
impl TheDebugModule {
pub fn new() -> Self {
Self {
codegrid_id: Uuid::nil(),
values: FxHashMap::default(),
executed: FxHashSet::default(),
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum TheDebugMessageRole {
Status,
Debug,
Warning,
Error,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TheDebugMessage {
pub role: TheDebugMessageRole,
pub message: String,
pub module: String,
pub entity: String,
}
impl TheDebugMessage {
pub fn new(role: TheDebugMessageRole, message: String) -> Self {
Self {
role,
message,
module: "".to_string(),
entity: "".to_string(),
}
}
}