diff --git a/readme.md b/readme.md index 55aa65f..769ba75 100644 --- a/readme.md +++ b/readme.md @@ -119,7 +119,7 @@ pub async fn main() { let mut bot = Bot::new(); /* load the Module */ - bot.load_module(custom_mod::new()); + bot.load_module(custom_mod::new()).await; /* Run the bot */ bot.run().await; diff --git a/src/bin/fun_bot.rs b/src/bin/fun_bot.rs index 27c67a0..4f119ce 100644 --- a/src/bin/fun_bot.rs +++ b/src/bin/fun_bot.rs @@ -26,11 +26,11 @@ pub async fn main() { let mut bot = Bot::new(); /* 1. Load the module into the bot */ - bot.load_module(funbot_objs::create_module()); + bot.load_module(funbot_objs::create_module()).await; /* 2. Load Custom Modules */ - bot.load_module(guest_badge::create_module()); - bot.load_module(pyramid::create_module()); + bot.load_module(guest_badge::create_module()).await; + bot.load_module(pyramid::create_module()).await; /* 3. Run the bot */ bot.run().await; diff --git a/src/bin/simple_module.rs b/src/bin/simple_module.rs index f9e7bec..77bd5da 100644 --- a/src/bin/simple_module.rs +++ b/src/bin/simple_module.rs @@ -26,7 +26,7 @@ pub async fn main() { let mut bot = Bot::new(); /* load the Module */ - bot.load_module(custom_mod::new()); + bot.load_module(custom_mod::new()).await; /* Run the bot */ bot.run().await; diff --git a/src/botcore/bot.rs b/src/botcore/bot.rs index 1a54cc6..f1a8798 100644 --- a/src/botcore/bot.rs +++ b/src/botcore/bot.rs @@ -141,13 +141,11 @@ impl Bot while let Some(message) = in_msgs_lock.recv().await { - - + for listener in &(*bot).listeners { let a = listener.clone(); - if a.cond_triggered(bot.clone(),message.clone()) { - + if a.cond_triggered(bot.clone(),message.clone()).await { let _ = listener.execute_fn(bot.clone(),message.clone()).await; } } @@ -160,8 +158,6 @@ impl Bot // dbg!(cache_lock.clone()); drop(cache_lock); - // let a = bot.clone(); - // dbg!(bot.get_message_cache()); for cmd in &(*bot).commands { @@ -192,7 +188,7 @@ impl Bot for listener in module.get_listeners() { let a = listener.clone(); - if a.cond_triggered(bot.clone(),message.clone()) && a.cond_async_triggered(bot.clone(), message.clone()).await { + if a.cond_triggered(bot.clone(),message.clone()).await { let _ = listener.execute_fn(bot.clone(),message.clone()).await; } diff --git a/src/botcore/bot_objects.rs b/src/botcore/bot_objects.rs index cca0423..d5ae5b2 100644 --- a/src/botcore/bot_objects.rs +++ b/src/botcore/bot_objects.rs @@ -7,7 +7,7 @@ use std::future::Future; use std::pin::Pin; use std::sync::Arc; -use twitch_irc::message::ServerMessage; +use twitch_irc::message::{PrivmsgMessage, ServerMessage}; use super::bot::Bot; @@ -25,6 +25,21 @@ pub type ExecBody = Box< dyn Fn(Arc<Bot>,ServerMessage) -> Pin<Box<dyn Future<Output = Result<String,String>> + Send>> + Send + Sync, >; +/// used to store async execution functions. Primarily used for `Command` +/// +/// call this to store execution functions in `Commands` +/// +/// # example +/// ``` +/// /* 2. Define exec callback */ +/// async fn execbody(bot:Arc<Bot>,message:ServerMessage) -> Result<String,String> { +/// /* do smth */ +/// } +/// +/// /* 3. Set Command flags */ +/// cmd.set_exec_fn(execution_async(execbody)); +/// ``` +/// pub fn execution_async<T>(f: fn(Arc<Bot>,ServerMessage) -> T) -> ExecBody where T: Future<Output = Result<String,String>> + Send + 'static, @@ -32,11 +47,24 @@ where Box::new(move |a,b| Box::pin(f(a,b))) } -pub type TrigBody = Box< - dyn Fn(Arc<Bot>,ServerMessage) -> Pin<Box<dyn Future<Output = bool> + Send>> + Send + Sync, +pub type CommandTrigger = Box< + dyn Fn(Arc<Bot>,PrivmsgMessage) -> Pin<Box<dyn Future<Output = bool> + Send>> + Send + Sync, >; -pub fn condition_async<T>(f: fn(Arc<Bot>,ServerMessage) -> T) -> TrigBody +/// used to store async trigger condition callback functions. Primarily used for `Command` +/// +/// # example +/// ``` +/// /* 2. Define condition callback */ +/// async fn condition01(bot:Arc<Bot>,message:ServerMessage) -> bool { +/// /* do smth */ +/// } +/// +/// /* 3. Set Command flags */ +/// cmd.set_custom_cond_async(command_condition_async(condition01)); +/// ``` +/// +pub fn command_condition_async<T>(f: fn(Arc<Bot>,PrivmsgMessage) -> T) -> CommandTrigger where T: Future<Output = bool> + Send + 'static, { @@ -44,6 +72,30 @@ where } +pub type ListenerTrigger = Box< + dyn Fn(Arc<Bot>,ServerMessage) -> Pin<Box<dyn Future<Output = bool> + Send>> + Send + Sync, +>; + +/// used to store async trigger condition callback functions. Primarily used for `Listener` +/// +/// # example +/// ``` +/// /* 2. Define condition callback */ +/// async fn condition01(bot:Arc<Bot>,message:ServerMessage) -> bool { +/// /* do smth */ +/// } +/// +/// /* 3. Set Command flags */ +/// cmd.set_custom_cond_async(listener_condition_async(condition01)); +/// ``` +/// +pub fn listener_condition_async<T>(f: fn(Arc<Bot>,ServerMessage) -> T) -> ListenerTrigger +where + T: Future<Output = bool> + Send + 'static, +{ + Box::new(move |a,b| Box::pin(f(a,b))) +} + /// collection of functions to create built in objects diff --git a/src/botcore/bot_objects/command.rs b/src/botcore/bot_objects/command.rs index 3314347..001ac31 100644 --- a/src/botcore/bot_objects/command.rs +++ b/src/botcore/bot_objects/command.rs @@ -2,9 +2,9 @@ use std::sync::Arc; use twitch_irc::message::{PrivmsgMessage, ServerMessage}; -use crate::{botcore::{bot::Bot, bot_objects::condition_async}, execution_async, Badge}; +use crate::{botcore::bot::Bot, command_condition_async, execution_async, Badge}; -use super::{ExecBody, TrigBody}; +use super::{CommandTrigger, ExecBody}; /// Bot `Command` that stores trigger condition callback and a execution functon /// @@ -23,12 +23,13 @@ pub struct Command commands : Vec<String>, exec_fn : Arc<ExecBody>, min_badge : Badge, + /// only admins can run - default : `true` admin_only : bool, - /// admin role overrides channel badgen- default : false + /// admin role overrides channel badge - default : `false` admin_override : bool, prefix : String, custom_cond_fn : fn(Arc<Bot>,PrivmsgMessage) -> bool, - custom_cond_async : Arc<TrigBody>, + custom_cond_async : Arc<CommandTrigger>, } impl Command @@ -45,7 +46,7 @@ impl Command async fn execbody(_:Arc<Bot>,_:ServerMessage) -> Result<String,String> { Result::Ok("success".to_string()) } - async fn condition01(_:Arc<Bot>,_:ServerMessage) -> bool { true } + async fn condition01(_:Arc<Bot>,_:PrivmsgMessage) -> bool { true } Command { commands , @@ -55,11 +56,11 @@ impl Command admin_only : true, admin_override : false , custom_cond_fn : |_:Arc<Bot>,_:PrivmsgMessage| true, - custom_cond_async : Arc::new(condition_async(condition01)), + custom_cond_async : Arc::new(command_condition_async(condition01)), } } - /// set a trigger conditin callback that returns true if the command should trigger + /// set a trigger condition callback that returns true if the command should trigger pub fn set_custom_cond_fn(&mut self,cond_fn: fn(Arc<Bot>,PrivmsgMessage) -> bool) { self.custom_cond_fn = cond_fn; } @@ -83,7 +84,7 @@ impl Command /// cmd.set_custom_cond_async(condition_async(condition01)); /// ``` /// - pub fn set_custom_cond_async(&mut self,condition:TrigBody ) { + pub fn set_custom_cond_async(&mut self,condition:CommandTrigger ) { self.custom_cond_async = Arc::new(condition); } @@ -181,8 +182,8 @@ impl Command } } - fn custom_cond_ok(cmd:&Command,bot:Arc<Bot>,message:PrivmsgMessage) -> bool { - (cmd.custom_cond_fn)(bot,message) + async fn custom_cond_ok(cmd:&Command,bot:Arc<Bot>,message:PrivmsgMessage) -> bool { + (cmd.custom_cond_fn)(bot.clone(),message.clone()) && (cmd.custom_cond_async)(bot,message).await } // dbg!(msg.clone()); @@ -196,7 +197,7 @@ impl Command cmd_called(self, bot.clone(), msg.clone()) && caller_badge_ok(self, bot.clone(), msg.clone()).await && admin_only_ok(self, bot.clone(), msg.clone()) && - custom_cond_ok(self, bot, msg) + custom_cond_ok(self, bot, msg).await } diff --git a/src/botcore/bot_objects/listener.rs b/src/botcore/bot_objects/listener.rs index cc170df..af96cf7 100644 --- a/src/botcore/bot_objects/listener.rs +++ b/src/botcore/bot_objects/listener.rs @@ -2,9 +2,9 @@ use std::sync::Arc; use twitch_irc::message::ServerMessage; -use crate::{botcore::bot_objects::condition_async, execution_async, Bot}; +use crate::{execution_async, listener_condition_async, Bot}; -use super::{ExecBody, TrigBody}; +use super::{ExecBody, ListenerTrigger}; /// Bot `Listener`` that stores trigger condition callback and a execution functon /// @@ -15,7 +15,7 @@ pub struct Listener /// trigger condition trigger_cond_fn : fn(Arc<Bot>,ServerMessage) -> bool, /// trigger condition for async - trigger_cond_async : Arc<TrigBody> , + trigger_cond_async : Arc<ListenerTrigger> , /// execution body exec_fn : Arc<ExecBody>, } @@ -31,7 +31,7 @@ impl Listener async fn condition01(_:Arc<Bot>,_:ServerMessage) -> bool { true } Listener { trigger_cond_fn : |_:Arc<Bot>,_:ServerMessage| false, - trigger_cond_async : Arc::new(condition_async(condition01)), + trigger_cond_async : Arc::new(listener_condition_async(condition01)), exec_fn : Arc::new(execution_async(execbody)), } } @@ -59,7 +59,7 @@ impl Listener /// listener.set_trigger_cond_async(condition_async(condition01)); /// ``` /// - pub fn set_trigger_cond_async(&mut self,condition:TrigBody ) { + pub fn set_trigger_cond_async(&mut self,condition:ListenerTrigger ) { self.trigger_cond_async = Arc::new(condition); } @@ -85,14 +85,9 @@ impl Listener } /// checks if the trigger condition is met - pub fn cond_triggered(&self,bot:Arc<Bot>,msg:ServerMessage) -> bool { - (self.trigger_cond_fn)(bot,msg) - } - - /// executes the listeners executon body - pub async fn cond_async_triggered(&self,bot:Arc<Bot>,msg:ServerMessage) -> bool { - // (self.exec_fn)(bot,msg) - (self.trigger_cond_async)(bot,msg).await + pub async fn cond_triggered(&self,bot:Arc<Bot>,msg:ServerMessage) -> bool { + let list = Arc::new(self); + (list.trigger_cond_fn)(bot.clone(),msg.clone()) && (list.trigger_cond_async)(bot,msg).await } /// executes the listeners executon body diff --git a/src/custom_mods/pyramid.rs b/src/custom_mods/pyramid.rs index de633bb..fcc9da2 100644 --- a/src/custom_mods/pyramid.rs +++ b/src/custom_mods/pyramid.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Mutex}; use twitch_irc::message::{PrivmsgMessage, ServerMessage}; -use crate::{condition_async, Badge, Bot, Command, Listener, Module}; +use crate::{listener_condition_async, Badge, Bot, Command, Listener, Module}; /// pyramid module /// @@ -52,7 +52,7 @@ fn create_pyramid_detector() -> Listener { } /* 3. Set a trigger condition function for listener */ - listener.set_trigger_cond_async(condition_async(condition01)); + listener.set_trigger_cond_async(listener_condition_async(condition01)); /* 4. Define an async fn callback execution */ diff --git a/src/lib.rs b/src/lib.rs index 7981025..67e89ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -203,7 +203,8 @@ pub mod botcore; pub mod custom_mods; pub use crate::botcore::bot::Bot; pub use crate::botcore::bot_objects::execution_async; -pub use crate::botcore::bot_objects::condition_async; +pub use crate::botcore::bot_objects::command_condition_async; +pub use crate::botcore::bot_objects::listener_condition_async; pub use crate::botcore::bot_objects::listener::Listener; pub use crate::botcore::bot_objects::command::Command; pub use crate::botcore::modules::Module;