implement goto token in chats

This commit is contained in:
yuni 2024-04-13 22:43:41 +02:00
parent 9176caa372
commit fbc6dea13e

View file

@ -19,8 +19,10 @@ pub const TOKEN_IF: &str = "if";
pub const TOKEN_GOTO: &str = "goto";
pub const TOKEN_LABEL: &str = "label";
pub const TOKEN_SCRIPT: &str = "script";
pub const TOKEN_GOTO_EXIT: &str = "EXIT";
pub const NAME_FALLBACK: &str = "Unknown";
pub const MAX_BRANCH_DEPTH: usize = 64;
pub const CHOICE_TIMER: f64 = 40.0 * settings::DEFAULT_CHAT_SPEED as f64;
pub const LETTERS_PER_SECOND: f32 = 17.0;
@ -168,6 +170,48 @@ impl ChatDB {
return None;
}
fn search_label_recursively(&self, sequence: &Value, label: &String, mut pos: ChatPos) -> Option<ChatPos> {
if pos.len() > MAX_BRANCH_DEPTH {
return None;
}
if let Some(vector) = sequence.as_sequence() {
for (index, item) in vector.iter().enumerate() {
match item {
Value::String(_) => {}
Value::Mapping(map) => {
for (key, value) in map {
if let Some(key) = key.as_str() {
if key == TOKEN_LABEL {
if value == label {
pos.push(index);
return Some(pos);
}
}
}
if value.is_sequence() {
pos.push(index);
if let Some(result) = self.search_label_recursively(
value, label, pos.clone()) {
return Some(result)
}
pos.pop();
}
}
}
_ => {}
}
}
}
return None;
}
fn search_label(&self, chat_id: usize, label: &String) -> Option<ChatPos> {
if label == TOKEN_GOTO_EXIT {
return Some(vec![]);
}
return self.search_label_recursively(&self.0[chat_id], label, vec![]);
}
// returns true if we reached the end of a branch and possibly popped the position stack
fn advance_pointer(&self, chat: &mut Chat) -> bool {
let len = chat.position.len();
@ -178,8 +222,6 @@ impl ChatDB {
let mut popped = false;
while chat.position.len() > 0 {
dbg!(&chat.position);
dbg!(self.at(chat.id, &chat.position));
match self.at(chat.id, &chat.position) {
None => {
chat.position.pop();
@ -276,7 +318,16 @@ impl ChatDB {
}
(Some(TOKEN_SET), _) => {}
(Some(TOKEN_IF), _) => {}
(Some(TOKEN_GOTO), _) => {}
(Some(TOKEN_GOTO), Value::String(label)) => {
match self.search_label(chat.id, &label) {
Some(pos) => {
chat.position = pos;
}
None => {
error!("Could not find goto label {label}!");
}
}
}
(Some(TOKEN_SCRIPT), Value::String(script)) => {
event.send(ChatEvent::RunScript(script));
}