use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::PathBuf;
use prost::Message;
use yharnam::*;
const DEFAULT_START_NODE_NAME: &str = "Start";
fn main() -> Result<(), Box<dyn Error>> {
let mut args = env::args();
args.next();
let proto_path = args.next()
.unwrap();
let proto_path = PathBuf::from(proto_path);
let start_node = args.next()
.unwrap_or(DEFAULT_START_NODE_NAME.to_string());
let proto_data = fs::read(&proto_path)?;
let program = Program::decode(&*proto_data)?;
let mut csv_path = proto_path;
csv_path.set_extension("csv");
let mut csv_reader = csv::Reader::from_path(csv_path)?;
let string_table: Vec<LineInfo> = csv_reader.deserialize()
.map(|result| result.unwrap())
.collect();
let mut vm = VirtualMachine::new(program);
if vm.program.nodes.contains_key(&start_node) {
vm.set_node(&start_node);
loop {
match vm.continue_dialogue() {
SuspendReason::Line(line) => {
let text = string_table.iter()
.find(|line_info| line_info.id == line.id)
.map(|line_info| &line_info.text);
if let Some(text) = text {
println!("{}", text);
} else {
}
}
SuspendReason::Options(options) => {
println!("== Choose option ==");
for (i, opt) in options.iter().enumerate() {
let text = string_table.iter()
.find(|line_info| line_info.id == opt.line.id)
.map(|line_info| &line_info.text);
if let Some(text) = text {
println!("{}: {}", i, text);
} else {
}
}
let mut selection = String::new();
io::stdin().read_line(&mut selection)?;
let selection: u32 = selection.trim().parse()?;
vm.set_selected_option(selection);
}
SuspendReason::Command(command_text) => {
println!("== Command: {} ==", command_text);
}
SuspendReason::NodeChange { start, end } => {
println!("== Node end: {} ==", end);
println!("== Node start: {} ==", start);
}
SuspendReason::DialogueComplete(last_node) => {
println!("== Node end: {} ==", last_node);
println!("== Dialogue complete ==");
break;
}
}
}
} else {
eprintln!("Could not find start node: {}", DEFAULT_START_NODE_NAME);
}
Ok(())
}