proper exiting of conversation branches

This commit is contained in:
yuni 2024-04-13 20:59:55 +02:00
parent e7df698225
commit 5bc76a3e2f

View file

@ -135,14 +135,15 @@ impl ChatDB {
return None;
}
// returns false if the advanced pointer is out of bounds
// 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();
if len == 0 {
return false;
return true; // out of bounds
}
chat.position[len - 1] += 1;
let mut popped = false;
while chat.position.len() > 0 {
dbg!(&chat.position);
dbg!(self.at(chat.id, &chat.position));
@ -150,6 +151,7 @@ impl ChatDB {
None => {
dbg!("Pop.");
chat.position.pop();
popped = true;
if chat.position.len() > 0 {
let index = chat.position.len() - 1;
chat.position[index] += 1;
@ -161,10 +163,9 @@ impl ChatDB {
}
}
if chat.position.len() == 0 {
// out of bounds, return false.
return false;
return true; // out of bounds
}
return true;
return popped;
}
// Note that this (intentionally) may result in a pointer that's out of bounds.
@ -199,8 +200,7 @@ impl ChatDB {
}
}
None => {
// Out of bounds.
return None;
return None; // Out of bounds.
}
_ => {
error!("Could not handle YAML value {value:?}");
@ -216,6 +216,9 @@ impl ChatDB {
return result;
}
pub fn process_value(&self, chat: &mut Chat, event: &mut EventWriter<ChatEvent>) {
}
pub fn advance_chat(&self, chat: &mut Chat, event: &mut EventWriter<ChatEvent>) {
event.send(ChatEvent::DespawnAllChoices);
let conv = &self.0.get(chat.id);
@ -223,42 +226,44 @@ impl ChatDB {
return;
}
// Handle next entry in the chat list
let mut is_skipping_through = false;
if !self.advance_pointer(chat) {
event.send(ChatEvent::SpawnMessage("Disconnected.".to_string()));
event.send(ChatEvent::DespawnAllChats);
return;
}
else if let Some(_) = self.search_choice(self.at(chat.id, &chat.position).as_ref()) {
is_skipping_through = true;
}
else if let Some(Value::String(message)) = self.at(chat.id, &chat.position) {
event.send(ChatEvent::SpawnMessage(message.to_string()));
// Handle this entry in the chat list
let current_item = self.at(chat.id, &chat.position);
let mut add_choices = true;
match current_item {
Some(Value::String(message)) => {
event.send(ChatEvent::SpawnMessage(message.to_string()));
}
Some(Value::Mapping(message)) => {
if let Some(_) = self.search_choice(Some(&Value::Mapping(message))) {
add_choices = false;
}
}
None => {
event.send(ChatEvent::SpawnMessage("Disconnected.".to_string()));
event.send(ChatEvent::DespawnAllChats);
}
_ => {
error!("Can't handle YAML value {current_item:?}");
}
}
// Check if the immediately following entries are choices
let mut pos = chat.position.clone();
self.pointer_lookahead(&mut pos);
let mut key: usize = 0;
loop {
if is_skipping_through /*|| pos[0] >= conv.len()*/ { // TODO: out of bounds checking
break;
}
dbg!(&pos);
dbg!(self.at(chat.id, &pos));
let choice = self.search_choice(self.at(chat.id, &pos).as_ref());
dbg!(&choice);
if let Some((choice, _)) = choice {
let mut goto: Vec<usize> = pos.clone();
// Move on to next entry
let mut finished_branch = self.advance_pointer(chat);
// Add choices, if available
if add_choices {
let mut key: usize = 0;
while let Some((choice, _)) =
self.search_choice(self.at(chat.id, &chat.position).as_ref()) {
if finished_branch {
break;
}
let mut goto: Vec<usize> = chat.position.clone();
goto.push(0);
event.send(ChatEvent::SpawnChoice(choice, key, goto));
key += 1;
finished_branch = self.advance_pointer(chat);
}
else {
break;
}
self.pointer_lookahead(&mut pos);
}
}
}