implement goto token in chats
This commit is contained in:
parent
9176caa372
commit
fbc6dea13e
57
src/chat.rs
57
src/chat.rs
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue