two way communications

This commit is contained in:
WanderingPenwing 2024-03-11 17:45:10 +01:00
parent ce2992f524
commit 454047661c

View file

@ -3,8 +3,14 @@ use serenity::{
model::{channel::Message, gateway::Ready}, model::{channel::Message, gateway::Ready},
prelude::*, prelude::*,
}; };
use serenity::model::prelude::GuildId;
use std::sync::mpsc; use std::sync::mpsc;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;
use std::thread;
use std::sync::Arc;
use crate::postman; use crate::postman;
use crate::discord_structure; use crate::discord_structure;
@ -12,8 +18,11 @@ mod token;
const HELP_MESSAGE: &str = "Hello there, Human! I am a messenger for the wandering penwing."; const HELP_MESSAGE: &str = "Hello there, Human! I am a messenger for the wandering penwing.";
const HELP_COMMAND: &str = "!jiji"; const HELP_COMMAND: &str = "!jiji";
const PACKET_REFRESH : u64 = 500;
struct Handler; struct Handler {
is_loop_running: AtomicBool,
}
#[async_trait] #[async_trait]
@ -30,7 +39,59 @@ impl EventHandler for Handler {
} }
async fn ready(&self, context: Context, ready: Ready) { async fn ready(&self, context: Context, ready: Ready) {
println!("{} is connected!", ready.user.name); println!("bot : {} is connected!", ready.user.name);
}
async fn cache_ready(&self, context: Context, _guilds: Vec<GuildId>) {
println!("bot : cache built successfully!");
let context = Arc::new(context);
if !self.is_loop_running.load(Ordering::Relaxed) {
// We have to clone the Arc, as it gets moved into the new thread.
let context1 = Arc::clone(&context);
// tokio::spawn creates a new green thread that can run in parallel with the rest of
// the application.
tokio::spawn(async move {
get_guilds(&context1).await;
});
let context2 = Arc::clone(&context);
tokio::spawn(async move {
loop {
check_packets(&context2).await;
thread::sleep(Duration::from_millis(PACKET_REFRESH));
}
});
// Now that the loop is running, we set the bool to true
self.is_loop_running.swap(true, Ordering::Relaxed);
}
}
}
async fn check_packets(context: &Context) {
if let Some(receiver_mutex) = context.data.read().await.get::<postman::Receiver>() {
if let Ok(receiver) = receiver_mutex.lock() {
while let Ok(packet) = receiver.try_recv() {
match packet {
postman::Packet::FetchChannels(guild_id) => {
println!("bot : fetch channels request received : '{}'", guild_id);
}
_ => {
println!("bot : unhandled packet");
}
}
}
} else {
println!("bot : failed to lock receiver");
}
} else {
println!("bot : failed to retrieve receiver");
}
}
async fn get_guilds(context: &Context) {
let guilds = context.cache.guilds().await; let guilds = context.cache.guilds().await;
if let Some(sender) = context.data.read().await.get::<postman::Sender>() { if let Some(sender) = context.data.read().await.get::<postman::Sender>() {
@ -48,13 +109,14 @@ impl EventHandler for Handler {
} else { } else {
println!("bot : failed to retrieve sender"); println!("bot : failed to retrieve sender");
} }
}
} }
pub async fn start_discord_bot(sender: mpsc::Sender<postman::Packet>, receiver: Mutex<mpsc::Receiver<postman::Packet>>) { pub async fn start_discord_bot(sender: mpsc::Sender<postman::Packet>, receiver: Mutex<mpsc::Receiver<postman::Packet>>) {
println!("bot : connection process started..."); println!("bot : connection process started...");
let maybe_client = Client::builder(token::TOKEN) let maybe_client = Client::builder(token::TOKEN)
.event_handler(Handler) .event_handler(Handler {
is_loop_running: AtomicBool::new(false),
})
.type_map_insert::<postman::Sender>(sender) .type_map_insert::<postman::Sender>(sender)
.type_map_insert::<postman::Receiver>(receiver) .type_map_insert::<postman::Receiver>(receiver)
.await .await