Began adding support for variables

This commit is contained in:
2026-05-24 15:09:59 +01:00
parent 93ca1ea34a
commit 21bf659718
8 changed files with 287 additions and 24 deletions
+92
View File
@@ -206,6 +206,16 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.4.1"
@@ -379,11 +389,13 @@ dependencies = [
name = "happening-client"
version = "0.1.0"
dependencies = [
"home",
"macroquad",
"phf",
"reqwest",
"serde",
"serde_json",
"tokio",
]
[[package]]
@@ -403,6 +415,15 @@ version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "home"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "http"
version = "1.4.0"
@@ -724,6 +745,15 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.29"
@@ -846,6 +876,29 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
name = "parking_lot"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-link",
]
[[package]]
name = "percent-encoding"
version = "2.3.2"
@@ -1047,6 +1100,15 @@ dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
"bitflags 2.11.1",
]
[[package]]
name = "reqwest"
version = "0.13.3"
@@ -1217,6 +1279,12 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "3.7.0"
@@ -1295,6 +1363,16 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
dependencies = [
"errno",
"libc",
]
[[package]]
name = "simd-adler32"
version = "0.3.9"
@@ -1463,11 +1541,25 @@ dependencies = [
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.61.2",
]
[[package]]
name = "tokio-macros"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-rustls"
version = "0.26.4"
+2
View File
@@ -4,8 +4,10 @@ version = "0.1.0"
edition = "2024"
[dependencies]
home = "0.5.12"
macroquad = "0.4.15"
phf = {version="0.13.1",features=["macros"]}
reqwest = {version="0.13.3",features=["blocking","json"]}
serde = {version="1.0.228",features=["derive"]}
serde_json = "1.0.149"
tokio = {version="1.52.3",features=["full"]}
+89 -21
View File
@@ -1,14 +1,24 @@
use macroquad::prelude::*;
use reqwest::*;
use reqwest::blocking;
use std::collections::HashMap;
use phf::phf_map;
use std::{thread, time::Duration};
use std::
{
thread,
time::Duration,
collections::
{
HashMap,
HashSet,
},
process::exit,
};
use serde::
{
Serialize,
Deserialize,
};
use home::home_dir;
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
pub struct Data {
@@ -69,45 +79,92 @@ static POSITIONS: phf::Map<&'static str, [f32;2]> = phf_map! [
async fn main()
{
let mut characters: HashMap<String, (Character, Texture2D)> = HashMap::new();
let mut textures: Vec<(Texture2D, f32, f32, Color)> = Vec::new();
characters.insert("narrator".to_string(), (Character { name: "Narrator".to_string(), ..Default::default() }, Texture2D::empty()));
let mut textures: HashMap<String,(Texture2D, f32, f32, Color)> = HashMap::new();
let mut text: String = String::new();
let mut checking_for_choice: bool = false;
let mut data: Data = next_happening(); // First one should be begin
loop
{
clear_background(RED);
// Get the next character
let data = next_happening();
let character_name: &str = data.character.as_str();
// Add the character to the HashMap if it's not already
if character_name != "" && !characters.contains_key(character_name)
for (name, (texture, x, y, colour)) in &textures
{
let new_character = get_character(character_name).await;
characters.insert(character_name.to_string(), new_character);
draw_texture(&texture, *x, *y, *colour);
}
draw_multiline_text(&text, 50.0,30.0,40.0,None,WHITE);
if !is_any_key_down()
{
next_frame().await;
continue
}
let keys: HashSet<KeyCode> = get_keys_pressed();
if checking_for_choice
{
for key in &keys
{
let keycode = *key as u16;
let length: u16 = data.choices.len() as u16;
println!("key: {key:?} {keycode}");
if keycode > 48 && keycode <= length+48
{
checking_for_choice = false;
println!("Sending POST: {}",keycode-49);
let value = keycode - 49;
send_choice(value);
}
else { continue }
}
}
// Get the next character
data = next_happening();
let character_name: String = data.character.to_lowercase();
// Add the character to the HashMap if it's not already
if character_name != "" && !characters.contains_key(&character_name)
{
println!("Fetching {character_name}");
let new_character = get_character(&character_name).await;
characters.insert(character_name.clone(), new_character);
}
// Matchbox for all the commands
match data.action_type.to_lowercase().as_str()
{
"choice" =>
{
for (index, choice) in data.choices.iter().enumerate()
{
text += format!("\n{}. {}",index+1, choice).as_str();
}
checking_for_choice = true;
},
"output" =>
{
println!("SAYING");
draw_text(characters[character_name].0.name.clone(), 50.0,20.0,40.0,WHITE);
draw_text(data.content.as_str(), 50.0,40.0,30.0,WHITE);
text = format!("{}: {}", characters[&character_name].0.name.clone(),wrap_text(&data.content).as_str());
},
"to" =>
{
let position = POSITIONS.get(&data.content).cloned().unwrap();
let texture = &characters[character_name].1;
textures.push((texture.clone(), position[0], position[1], WHITE)); // Heavy
let texture = &characters[&character_name].1;
textures.insert(character_name.clone(),(texture.clone(), position[0], position[1], WHITE)); // Heavy
}
_ => println!("Unknown action"),
"begin" => (),
"end" => exit(0),
_ => println!("Unknown action, {}", data.action_type),
}
for (texture, x, y, colour) in &textures
{
draw_texture(&texture, *x, *y, *colour);
}
thread::sleep(Duration::from_millis(1000));
next_frame().await;
}
}
fn wrap_text(text: &str) -> String
{
text.chars()
.collect::<Vec<_>>()
.chunks(30)
.map(|chunk| chunk.iter().collect::<String>())
.collect::<Vec<_>>()
.join("\n")
}
fn next_happening()
-> Data
{
@@ -116,6 +173,17 @@ fn next_happening()
data
}
#[tokio::main]
async fn send_choice(index: u16)
{
let client = reqwest::Client::new();
let res = client.post("http://localhost:20264/choice")
.json(&index)
.send()
.await;
}
async fn get_character(name: &str)
-> (Character, Texture2D)
{
@@ -125,7 +193,7 @@ async fn get_character(name: &str)
let skin: Color = Color::from_rgba(skin_colour.red,skin_colour.green,skin_colour.blue,255);
let hair_colour = character.hair_color.clone();
let hair: Color = Color::from_rgba(hair_colour.red,hair_colour.green,hair_colour.blue,255);
let head_path: String = format!("../images/head/{}.png",character.head_shape);
let head_path: String = format!("/home/deadvey/.local/share/happening/images/head/{}.png",character.head_shape);
let head: Texture2D = change_colour(&mut load_image(head_path.as_str()).await.unwrap(), &skin, &hair);
(character, head)
}
+14
View File
@@ -18,6 +18,7 @@ use crate::
mod character_parse;
mod keyword_parse;
mod identifier_parse;
// Parse the tokens in a file
// Returns success or an error string
@@ -66,6 +67,19 @@ pub fn token_parse(
},
};
}
// Identifier
Some(tokenise::Token::Identifier(name)) =>
{
index = match identifier_parse::identifier_parse(index+1,tokens)
{
Ok(increment) => increment,
Err((err,increment)) =>
{
warn!("{err}");
increment
},
};
}
Some(_) =>
{
warn!("Unexpected token");
+29
View File
@@ -0,0 +1,29 @@
use crate::
{
// Internal code
character,
api,
tokenise,
UnwrapOrExit,
//Libs
Mutex,
Arc,
HashMap,
VecDeque,
info,
warn,
debug,
};
#[allow(unused_variables)]
pub fn identifier_parse
(
index: usize,
tokens: &[tokenise::Token],
) -> Result<usize,(String,usize)>
{
let mut sum_index: usize = index;
sum_index += 1;
Ok(sum_index)
}
+59 -3
View File
@@ -7,19 +7,40 @@ use crate::
pub enum Token
{
String(String),
#[allow(dead_code)]
Integer(i64), // idk someone might want to do a big number
#[allow(dead_code)]
Bool(bool),
#[allow(dead_code)]
Operator(Operator),
Keyword(String), // Keywords aren't checked for validity in this stage
#[allow(dead_code)] // This is unused rn, but am going to add it later
Identifier(String),
Bracket((Bracket,usize)), // Stores the index of the matching deliminator
Character(String),
}
#[derive(Debug,Clone,PartialEq, Eq)]
pub enum Bracket
#[derive(Debug,Clone,PartialEq,Eq)]
pub enum Bracket
{
Opening,
Closing,
}
#[derive(Debug, Clone)]
pub enum Operator
{
// Changing a value
Assignment,
Add,
Sub,
// Comparing a value
Comparison,
Greater,
Less,
GreaterOrEqual,
LessOrEqual,
}
pub fn get_string_token(tokens: &[Token], index: usize)
-> Result<String, String>
{
@@ -64,6 +85,29 @@ pub fn tokenise(file_contents: &str)
while index < space_seperated.len()
{
let mut item = space_seperated[index].to_string();
// Operator
let op: Option<Operator> = match item.as_str()
{
"=" => Some(Operator::Assignment),
"+" => Some(Operator::Add),
"-" => Some(Operator::Sub),
"==" => Some(Operator::Comparison),
">" => Some(Operator::Greater),
"<" => Some(Operator::Less),
">=" => Some(Operator::GreaterOrEqual),
"<=" => Some(Operator::LessOrEqual),
_ => None,
};
match op
{
Some(op) =>
{
tokenised_data.push(Token::Operator(op));
index += 1;
continue // skip the rest of this loop
},
None => (),
}
// Characters
if item.starts_with('@')
{
@@ -80,6 +124,18 @@ pub fn tokenise(file_contents: &str)
item = new_item;
tokenised_data.push(Token::String(item));
}
// variable/identifier
else if item.starts_with("$")
{
let mut chars = item.chars();
chars.next();
tokenised_data.push(Token::Identifier(chars.as_str().to_string()));
}
// Integer
else if item.parse::<i64>().is_ok()
{
tokenised_data.push(Token::Integer(item.parse::<i64>().unwrap()));
}
// Labels
else if item.ends_with(':')
{
+2
View File
@@ -1,5 +1,7 @@
@tim says "hello world, it's a good day"
@tim change name "Timothy Fineshooter"
$x = 3
$x + 1
label:
choice "choice numero uno" {
@tim says "super sad"
BIN
View File
Binary file not shown.