polished up a bit and got the index offset working

This commit is contained in:
2026-04-30 12:42:47 +01:00
parent 660f7cad7e
commit 800bee13da
5 changed files with 84 additions and 48 deletions
Binary file not shown.
+44 -12
View File
@@ -7,7 +7,6 @@ use std::
use log:: use log::
{ {
info, info,
trace,
warn, warn,
debug, debug,
}; };
@@ -20,34 +19,67 @@ mod api;
#[tokio::main] #[tokio::main]
async fn main() async fn main()
{ {
// For debugging
env_logger::init(); env_logger::init();
// Tx and Rx allow you to pass data between threads
let (tx,rx) = mpsc::channel(); let (tx,rx) = mpsc::channel();
// Initialise the data strcut that will be sent out during API GET requests
let data_to_send = Arc::new(Mutex::new(api::DataToSend let data_to_send = Arc::new(Mutex::new(api::DataToSend
{ {
action_type: "initialise".to_string(), action_type: "begin".to_string(),
content: "".to_string(), content: "".to_string(),
character: "".to_string(), character: "".to_string(),
})); }));
let data = Arc::clone(&data_to_send);
// setup the api stuff //
// Make clones of the data Arc for the two processes
let data_clone1 = Arc::clone(&data_to_send);
let tx_clone = tx.clone(); let tx_clone = tx.clone();
// Spawn a thread for warp // Spawn a thread for warp api server
tokio::spawn( tokio::spawn(
async move { async move {
api::api_process(data, tx_clone).await; api::api_process(data_clone1, tx_clone).await;
}); });
debug!("and continue");
// setup the parsing stuff //
// Setup the characters hashmap which will store each character in it as a Character struct
let mut characters = HashMap::<String, character::Character>::new(); let mut characters = HashMap::<String, character::Character>::new();
let file_contents: String = fs::read_to_string("stories/story.ha").unwrap();
// Split the file contents into tokens // Read the file and split it into tokens
let file_contents: String = fs::read_to_string("stories/story.ha") // TODO make this a command line argument
.unwrap_or_else(|err|
{
eprintln!("Failed to read file: {}", err);
std::process::exit(2);
});
let tokens: Vec<&str> = file_contents let tokens: Vec<&str> = file_contents
.split_whitespace() .split_whitespace()
.collect(); .collect();
let data_clone2 = Arc::clone(&data_to_send);
// Run the parsing process // Run the parsing process
let data_clone = Arc::clone(&data_to_send); match parsing::token_parse(&tokens, &mut characters, data_clone2, &rx).await
match parsing::token_parse(&tokens, &mut characters, data_clone, &rx).await
{ {
Ok(()) => info!("Program exited successfully"), // Exit with error or success
Err(error) => eprintln!("{}", error), Ok(()) =>
{
info!("Program exited successfully");
let mut data = data_to_send.lock().unwrap();
data.action_type = String::from("end");
data.content = String::new();
data.character = String::new();
// Manually unlock the mutex
std::mem::drop(data);
let _ = rx.recv(); // Wait for the client to respond
std::process::exit(0);
},
Err(error) =>
{
eprintln!("{}", error);
std::process::exit(1);
},
} }
} }
+31 -32
View File
@@ -1,6 +1,4 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::time::Duration;
use std::thread;
mod strings; mod strings;
use crate:: use crate::
{ {
@@ -32,9 +30,8 @@ pub async fn token_parse(
loop loop
{ {
// If the client hasn't responded then continue (after a short pause) // If the client hasn't responded then continue (after a short pause)
if rx.try_recv().is_err() if rx.recv().is_err()
{ {
thread::sleep(Duration::from_millis(300));
continue continue
} }
// Get the next token // Get the next token
@@ -52,17 +49,19 @@ pub async fn token_parse(
let new_character = character::Character::new(character_name.clone()); let new_character = character::Character::new(character_name.clone());
characters.insert(character_name.clone(),new_character); characters.insert(character_name.clone(),new_character);
} }
println!("Doing something with a character: {}", character_name); info!("Doing something with a character: {}", character_name);
// The index is incremented to after the character's instructions // The index is incremented to after the character's instructions
index += match character_parse(index+1, &tokens, character_name, &mut characters, &data_to_send, &rx).await index += match character_parse(index+1, &tokens, character_name, &mut characters, &data_to_send, &rx).await
{ {
Ok(increment) => increment, Ok(increment) => increment,
Err(error) => return Err(error), Err(error) => return Err(error),
} };
continue
} }
// Miscelleneous instructions // Miscelleneous instructions
if token.to_lowercase() == "end" if token.to_lowercase() == "end"
{ {
info!("END command, exiting");
return Ok(()) // quit return Ok(()) // quit
} }
index += 1; index += 1;
@@ -80,35 +79,35 @@ async fn character_parse
) -> Result<usize,String> ) -> Result<usize,String>
{ {
let mut sum_index: usize = index; let mut sum_index: usize = index;
loop // Ensure the index is valid (the index is not beyond the vector)
let token = tokens
.get(sum_index)
.ok_or_else(|| "File reached termination point".to_string())?;
match token.to_lowercase().as_str()
{ {
// Ensure the index is valid (the index is not beyond the vector) // The character is saying something, so grab the text and pass it
let token = tokens // to the client
.get(sum_index) "says" =>
.ok_or_else(|| "File reached termination point".to_string())?;
match token.to_lowercase().as_str()
{ {
// The character is saying something, so grab the text and pass it info!("SAYS command with character {}", character_name);
// to the client match strings::extract_quoted(&tokens[sum_index+1..]) // TODO increment to after the string
"says" =>
{ {
match strings::extract_quoted(&tokens[sum_index+1..]) // TODO increment to after the string Some((output_string, counter)) =>
{ {
Some(output_string) => debug!("{}", output_string);
{ sum_index += counter;
debug!("{}", output_string); let mut data = data_to_send.lock().unwrap();
let mut data = data_to_send.lock().unwrap(); data.action_type = String::from("output");
data.action_type = String::from("output"); data.content = output_string;
data.content = output_string; data.character = character_name.clone();
data.character = character_name.clone(); },
}, None => return Err(String::from("Unable to read string")),
None => return Err(String::from("Unable to read string")), }
} },
}, // Catch all condition, if the instruction is unrecognised as a
// Catch all condition, if the instruction is unrecognised as a // character command
// character command _ => return Err(String::from(format!("Invalid command: {}", token))),
_ => return Err(String::from(format!("Invalid command: {}", token))),
}
sum_index += 1;
} }
sum_index += 1;
Ok(sum_index)
} }
+7 -3
View File
@@ -1,8 +1,11 @@
pub fn extract_quoted(parts: &[&str]) -> Option<String> { // TODO also return a number to increment by pub fn extract_quoted(parts: &[&str]) -> Option<(String, usize)> {
let mut vec_string = Vec::new(); let mut vec_string = Vec::new();
let mut counter: usize = 0;
for part in parts for part in parts
{ {
if part.chars().next_back().unwrap() == '"' counter += 1;
// End of the string
if part.chars().next_back().unwrap() == '"' // TODO allow for backslashes and '
{ {
vec_string.push(*part); vec_string.push(*part);
let final_string: String = vec_string.join(" "); let final_string: String = vec_string.join(" ");
@@ -13,8 +16,9 @@ pub fn extract_quoted(parts: &[&str]) -> Option<String> { // TODO also return a
final_string.chars() final_string.chars()
.count() - 2) .count() - 2)
.collect(); .collect();
return Some(final_string); return Some((final_string, counter));
} }
// Otherwise just add this to the list
else else
{ {
vec_string.push(*part); vec_string.push(*part);
+2 -1
View File
@@ -1 +1,2 @@
@tim says "hello to all the world" @tim says "hello world, it's a good day"
END