problem scenario with some test modules

This commit is contained in:
ModulatingForce 2023-12-28 06:02:55 -05:00
parent a697f1d477
commit 4184527d19
5 changed files with 296 additions and 160 deletions

View file

@ -145,7 +145,10 @@ impl Chat {
pub struct BotInstance { pub struct BotInstance<F>
where
F: std::future::Future + ?Sized,
{
prefix : char, prefix : char,
bot_channel : ChType, bot_channel : ChType,
//pub client : TwitchIRCClient<TCPTransport<TLS>,StaticLoginCredentials>, //pub client : TwitchIRCClient<TCPTransport<TLS>,StaticLoginCredentials>,
@ -153,7 +156,7 @@ pub struct BotInstance {
// pub ratelimiters : HashMap<ChType,RateLimiter>, // used to limit messages sent per channel // pub ratelimiters : HashMap<ChType,RateLimiter>, // used to limit messages sent per channel
pub chat : Chat, pub chat : Chat,
// botmodules : HashMap<ModType,Vec<EnType>>, // botmodules : HashMap<ModType,Vec<EnType>>,
pub botmodules : ModulesManager, pub botmodules : ModulesManager<F>,
twitch_oauth : String, twitch_oauth : String,
pub bot_channels : Vec<ChType>, pub bot_channels : Vec<ChType>,
/*bot_commands : Vec[BotCommand], /*bot_commands : Vec[BotCommand],
@ -163,10 +166,18 @@ pub struct BotInstance {
// identity : identitymodule, // identity : identitymodule,
} }
impl BotInstance {
pub fn init() -> BotInstance { impl<F> BotInstance<F>
where
F: std::future::Future + 'static,
{
pub fn init() -> BotInstance<F>
where
F: std::future::Future + 'static,
{
dotenv().ok(); dotenv().ok();
let login_name = env::var("login_name").unwrap().to_owned(); let login_name = env::var("login_name").unwrap().to_owned();
@ -237,6 +248,53 @@ impl BotInstance {
b b
} }
pub async fn runner(mut self) -> () {
let join_handle = tokio::spawn(async move {
while let Some(message) = self.incoming_messages.recv().await {
// Below can be used to debug if I want to capture all messages
// println!("Received message: {:?}", message);
match message {
ServerMessage::Notice(msg) => {
if let Some(chnl) = msg.channel_login {
println!("NOTICE : (#{}) {}", chnl, msg.message_text);
}
}
ServerMessage::Privmsg(msg) => {
println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
println!("Privmsg section");
// b.listener_main_prvmsg(&msg);
self.listener_main_prvmsg(&msg).await;
// - BotCommand listener should likely need to be called within the above
},
ServerMessage::Whisper(msg) => {
println!("(w) {}: {}", msg.sender.name, msg.message_text);
},
ServerMessage::Join(msg) => {
println!("JOINED: {}", msg.channel_login);
},
ServerMessage::Part(msg) => {
println!("PARTED: {}", msg.channel_login);
},
_ => {}
}
}
});
join_handle.await.unwrap();
}
pub async fn run(mut self) -> () { pub async fn run(mut self) -> () {
@ -341,3 +399,21 @@ impl BotInstance {
// ======================================
// ======================================
// ======================================
// ======================================
// UNIT TEST MODULES
#[cfg(test)]
mod tests {
fn always() {
assert_eq!(1,1);
}
}

View file

@ -59,33 +59,72 @@ pub enum ModStatusType {
// pub use EnType::Enabled; // pub use EnType::Enabled;
#[derive(Debug)] #[derive(Debug)]
pub enum BotAction { pub enum BotAction<F>
C(BotCommand), where
L(Listener), F: std::future::Future + ?Sized,
{
//C(BotCommand),
L(Listener<F>),
R(Routine), R(Routine),
} }
pub trait BotActionTrait { pub trait BotActionTrait<F>
where
F: std::future::Future,
{
// async fn execute(&self,m:&mut BotInstance,n:&PrivmsgMessage); // async fn execute(&self,m:&mut BotInstance,n:&PrivmsgMessage);
// fn add_to_bot(self, bot:BotInstance) -> Result<String,Box<dyn Error>>; // fn add_to_bot(self, bot:BotInstance) -> Result<String,Box<dyn Error>>;
fn add_to_bot(self, bot:BotInstance); fn add_to_bot(self, bot:BotInstance<F>);
fn add_to_modmgr(self, modmgr:&mut ModulesManager); fn add_to_modmgr(self, modmgr:&mut ModulesManager<F>);
} }
#[derive(Debug)] // #[derive(Debug)]
pub struct BotCommand { // pub struct BotCommand {
pub module : ModType, // pub module : ModType,
pub command : String, // command call name // pub command : String, // command call name
pub alias : Vec<String>, // String of alternative names // pub alias : Vec<String>, // String of alternative names
// bot_prefix : char, // although should be global? // // bot_prefix : char, // although should be global?
exec_body : fn(&BotInstance,&PrivmsgMessage), // exec_body : fn(&BotInstance<F>,&PrivmsgMessage),
pub help : String, // pub help : String,
} // }
impl BotCommand { // impl BotCommand {
// pub fn add_to_bot(self, bot:BotInstance) { // // pub fn add_to_bot(self, bot:BotInstance) {
// // // let mut mgr = bot.botmodules;
// // // let nmod = self.module.clone();
// // // mgr.add_botaction(nmod, BotAction::C(self));
// // let mut mgr = bot.botmodules;
// // //let nmod = self.module.clone();
// // // mgr.add_botaction(self.module.clone(), BotAction::C(self));
// // self.add_to_modmgr(&mut mgr);
// // }
// // pub fn add_to_modmgr(self, modmgr:&mut ModulesManager) {
// // // // let mut mgr = bot.botmodules;
// // // // let nmod = self.module.clone();
// // // // mgr.add_botaction(nmod, BotAction::C(self));
// // // let mut mgr = modmgr;
// // // //let nmod = self.module.clone();
// // // mgr.add_botaction(self.module.clone(), BotAction::C(self));
// // // let mut mgr = modmgr;
// // // //let nmod = self.module.clone();
// // modmgr.add_botaction(self.module.clone(), BotAction::C(self));
// // }
// }
// impl BotActionTrait for BotCommand {
// // fn add_to_bot(&self) -> Result<String,Box<dyn Error>> {
// // println!("Calling Add to Bot");
// // Ok(String::from("Hello"))
// // }
// fn add_to_bot(self, bot:BotInstance) {
// // let mut mgr = bot.botmodules; // // let mut mgr = bot.botmodules;
// // let nmod = self.module.clone(); // // let nmod = self.module.clone();
// // mgr.add_botaction(nmod, BotAction::C(self)); // // mgr.add_botaction(nmod, BotAction::C(self));
@ -96,8 +135,7 @@ impl BotCommand {
// self.add_to_modmgr(&mut mgr); // self.add_to_modmgr(&mut mgr);
// } // }
// fn add_to_modmgr<F>(self, modmgr:&mut ModulesManager<F>) {
// pub fn add_to_modmgr(self, modmgr:&mut ModulesManager) {
// // // let mut mgr = bot.botmodules; // // // let mut mgr = bot.botmodules;
// // // let nmod = self.module.clone(); // // // let nmod = self.module.clone();
// // // mgr.add_botaction(nmod, BotAction::C(self)); // // // mgr.add_botaction(nmod, BotAction::C(self));
@ -109,80 +147,66 @@ impl BotCommand {
// modmgr.add_botaction(self.module.clone(), BotAction::C(self)); // modmgr.add_botaction(self.module.clone(), BotAction::C(self));
// } // }
// // => 12.23 - MF: NOTE : The exec body is defined ad module level , not this core level
} // // fn exec_body(&self,m:&BotInstance,n:&PrivmsgMessage){
// // // => 12.23 - [ ] #todo requires field
// // // (&self.exec)(String::from("Hello from BotAction Trait"))
// // //self.exec_body(m,n)
// // }
impl BotActionTrait for BotCommand { // // fn execute(&self,m:&mut BotInstance,n:&PrivmsgMessage){
// fn add_to_bot(&self) -> Result<String,Box<dyn Error>> { // // // => 12.23 - [ ] #todo requires field
// println!("Calling Add to Bot"); // // // (&self.exec)(String::from("Hello from BotAction Trait"))
// Ok(String::from("Hello")) // // //self.exec_body(m,n)
// // (self.exec_body)(m,n)
// // }
// } // }
fn add_to_bot(self, bot:BotInstance) {
// let mut mgr = bot.botmodules;
// let nmod = self.module.clone();
// mgr.add_botaction(nmod, BotAction::C(self));
let mut mgr = bot.botmodules;
//let nmod = self.module.clone();
// mgr.add_botaction(self.module.clone(), BotAction::C(self));
self.add_to_modmgr(&mut mgr); // #[derive(Debug)]
} // pub struct Listener {
// pub module : ModType,
fn add_to_modmgr(self, modmgr:&mut ModulesManager) { // pub name : String,
// // let mut mgr = bot.botmodules; // pub exec_body : fn(&mut BotInstance,&PrivmsgMessage) ,
// // let nmod = self.module.clone(); // pub help : String
// // mgr.add_botaction(nmod, BotAction::C(self));
// let mut mgr = modmgr;
// //let nmod = self.module.clone();
// mgr.add_botaction(self.module.clone(), BotAction::C(self));
// let mut mgr = modmgr;
// //let nmod = self.module.clone();
modmgr.add_botaction(self.module.clone(), BotAction::C(self));
}
// => 12.23 - MF: NOTE : The exec body is defined ad module level , not this core level
// fn exec_body(&self,m:&BotInstance,n:&PrivmsgMessage){
// // => 12.23 - [ ] #todo requires field
// // (&self.exec)(String::from("Hello from BotAction Trait"))
// //self.exec_body(m,n)
// } // }
// fn execute(&self,m:&mut BotInstance,n:&PrivmsgMessage){
// // => 12.23 - [ ] #todo requires field
// // (&self.exec)(String::from("Hello from BotAction Trait"))
// //self.exec_body(m,n)
// (self.exec_body)(m,n)
// }
}
#[derive(Debug)] #[derive(Debug)]
pub struct Listener { pub struct Listener<F: ?Sized>
where
F: std::future::Future,
{
pub module : ModType, pub module : ModType,
pub name : String, pub name : String,
pub exec_body : fn(&mut BotInstance,&PrivmsgMessage) , //pub exec_body : fn(&mut BotInstance,&PrivmsgMessage) ,
pub exec_body : fn(&mut Box<BotInstance<F>>,&PrivmsgMessage) -> F ,
pub help : String pub help : String
} }
impl Listener { impl<F> Listener<F>
where
F: std::future::Future,
{
async fn execute(&self,m:&mut BotInstance,n:&PrivmsgMessage){ async fn execute(&self,m:&mut Box<BotInstance<F>>,n:&PrivmsgMessage){
// => 12.23 - [ ] #todo requires field // => 12.23 - [ ] #todo requires field
// (&self.exec)(String::from("Hello from BotAction Trait")) // (&self.exec)(String::from("Hello from BotAction Trait"))
//self.exec_body(m,n) //self.exec_body(m,n)
(self.exec_body)(m,n) (self.exec_body)(m,n).await;
} }
} }
impl BotActionTrait for Listener { impl<F> BotActionTrait<F> for Listener<F>
where
F: std::future::Future,
{
// fn add_to_bot(&self) -> Result<String,Box<dyn Error>> { // fn add_to_bot(&self) -> Result<String,Box<dyn Error>> {
// println!("Calling Add to Bot"); // println!("Calling Add to Bot");
// Ok(String::from("Hello")) // Ok(String::from("Hello"))
// } // }
fn add_to_bot(self, bot:BotInstance) { fn add_to_bot(self, bot:BotInstance<F>) {
// let mut mgr = bot.botmodules; // let mut mgr = bot.botmodules;
// let nmod = self.module.clone(); // let nmod = self.module.clone();
// mgr.add_botaction(nmod, BotAction::C(self)); // mgr.add_botaction(nmod, BotAction::C(self));
@ -193,7 +217,7 @@ impl BotActionTrait for Listener {
self.add_to_modmgr(&mut mgr); self.add_to_modmgr(&mut mgr);
} }
fn add_to_modmgr(self, modmgr:&mut ModulesManager) { fn add_to_modmgr(self, modmgr:&mut ModulesManager<F>) {
// // let mut mgr = bot.botmodules; // // let mut mgr = bot.botmodules;
// // let nmod = self.module.clone(); // // let nmod = self.module.clone();
// // mgr.add_botaction(nmod, BotAction::C(self)); // // mgr.add_botaction(nmod, BotAction::C(self));
@ -237,14 +261,20 @@ struct Routine {}
#[derive(Debug)] #[derive(Debug)]
pub struct ModulesManager { pub struct ModulesManager<F: ?Sized>
where
F: std::future::Future,
{
statusdb: HashMap<ModType,Vec<ModStatusType>>, statusdb: HashMap<ModType,Vec<ModStatusType>>,
botactions: HashMap<ModType,Vec<BotAction>>, botactions: HashMap<ModType,Vec<BotAction<F>>>,
} }
impl ModulesManager { impl<F> ModulesManager<F>
where
F: std::future::Future,
{
pub fn init() -> ModulesManager { pub fn init() -> ModulesManager<F> {
// initializes the modulers manager // initializes the modulers manager
// Ideally, this should have added known modules based on // Ideally, this should have added known modules based on
@ -341,7 +371,7 @@ impl ModulesManager {
println!(">> Modules Manager : End of Init"); println!(">> Modules Manager : End of Init");
println!(">> Modules Manager : {:?}",mgr); //println!(">> Modules Manager : {:?}",mgr);
mgr mgr
} }
@ -371,7 +401,7 @@ impl ModulesManager {
} }
pub fn add_botaction(&mut self, in_module:ModType, in_action:BotAction ) -> () { pub fn add_botaction(&mut self, in_module:ModType, in_action:BotAction<F> ) -> () {
/* /*
adds a BotAction to the Modules Manager - This will require a BotModule passed as well adds a BotAction to the Modules Manager - This will require a BotModule passed as well
This will including the logic of a valid add This will including the logic of a valid add
@ -399,7 +429,10 @@ impl ModulesManager {
// - If BotAction to Add is a BotCommand , In Module Manager DB (botactions), // - If BotAction to Add is a BotCommand , In Module Manager DB (botactions),
// Check All Other BotAction Command Names & Aliases to ensure they don't conflict // Check All Other BotAction Command Names & Aliases to ensure they don't conflict
fn find_conflict_module(mgr:& ModulesManager, act:& BotAction) -> Option<ModType> { fn find_conflict_module<F>(mgr:& ModulesManager<F>, act:& BotAction<F>) -> Option<ModType>
where
F: std::future::Future,
{
// Some(BotModule(String::from("GambaCore"))) // Some(BotModule(String::from("GambaCore")))
@ -412,70 +445,70 @@ impl ModulesManager {
// BotAction::R(r) => None, // BotAction::R(r) => None,
// } // }
if let BotAction::C(incmd) = act { // if let BotAction::C(incmd) = act {
// let n = & mgr.botactions; // // let n = & mgr.botactions;
let d = &mgr.botactions; // let d = &mgr.botactions;
for (module,moduleactions) in d { // for (module,moduleactions) in d {
for modact in moduleactions.iter() { // for modact in moduleactions.iter() {
if let BotAction::C(dbcmd) = &modact { // if let BotAction::C(dbcmd) = &modact {
// At this point, there is an command incmd and looked up dbcmd // // At this point, there is an command incmd and looked up dbcmd
// [x] check if given botcommand c.command:String conflicts with any in botactions // // [x] check if given botcommand c.command:String conflicts with any in botactions
if incmd.command.to_lowercase() == dbcmd.command.to_lowercase() { // if incmd.command.to_lowercase() == dbcmd.command.to_lowercase() {
// Returning State - with the identified module // // Returning State - with the identified module
// return Some((module.clone(),BotAction::C(*dbcmd.clone()))); // // return Some((module.clone(),BotAction::C(*dbcmd.clone())));
// return Some(incmd); // for some reason I keep getting issues // // return Some(incmd); // for some reason I keep getting issues
//return Some(BotModule(String::from("GambaCore"))); // works // //return Some(BotModule(String::from("GambaCore"))); // works
return Some(module.clone()); // works // return Some(module.clone()); // works
// return Some(dbcmd.clone()); // // return Some(dbcmd.clone());
} // }
for a in &dbcmd.alias { // for a in &dbcmd.alias {
if incmd.command.to_lowercase() == a.to_lowercase() { // if incmd.command.to_lowercase() == a.to_lowercase() {
// Returning State - with the identified module // // Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd))); // // return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works // return Some(module.clone()); // works
} // }
} // }
// [x] Then do the same check except for each c.alias // // [x] Then do the same check except for each c.alias
for inalias in &incmd.alias { // for inalias in &incmd.alias {
if inalias.to_lowercase() == dbcmd.command.to_lowercase() { // if inalias.to_lowercase() == dbcmd.command.to_lowercase() {
// Returning State - with the identified module // // Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd))); // // return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works // return Some(module.clone()); // works
} // }
for a in &dbcmd.alias { // for a in &dbcmd.alias {
if inalias.to_lowercase() == a.to_lowercase() { // if inalias.to_lowercase() == a.to_lowercase() {
// Returning State - with the identified module // // Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd))); // // return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works // return Some(module.clone()); // works
} // }
} // }
} // }
} // }
} // }
} // }
// return Some(BotModule(String::from("GambaCore"))) // // return Some(BotModule(String::from("GambaCore")))
} // }
// for all other scenarios (e.g., Listener, Routine), find no conflicts // for all other scenarios (e.g., Listener, Routine), find no conflicts
@ -488,7 +521,8 @@ impl ModulesManager {
// panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , probmod ); // panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , probmod );
// } // }
match find_conflict_module(&self, &in_action) { match find_conflict_module(&self, &in_action) {
Some(c) => panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , c ), // Some(c) => panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , c ),
Some(c) => panic!("ERROR: Could not add module; there was a conflict with existing module {:?}", c ),
None => (), None => (),
} }
@ -508,7 +542,7 @@ impl ModulesManager {
modactions.push(in_action); modactions.push(in_action);
println!(">> Modules Manager : Called Add bot Action"); println!(">> Modules Manager : Called Add bot Action");
println!(">> Modules Manager : {:?}",&self); //println!(">> Modules Manager : {:?}",&self);
(); ();
} }

View file

@ -17,14 +17,17 @@
pub mod core; pub mod core;
pub mod modules; pub mod modules;
use std::process::Output;
use crate::core::botinstance::BotInstance; use crate::core::botinstance::BotInstance;
#[tokio::main] #[tokio::main]
pub async fn main() { pub async fn main() {
let bot = BotInstance::init(); let bot:BotInstance<dyn std::future::Future<Output = ()>> = BotInstance::init();
//let bot = BotInstance::init();
bot.run().await; bot.runner().await;
} }

View file

@ -19,7 +19,10 @@ mod experiments;
// [ ] init() function that accepts bot instance - this is passed to init() on submodules // [ ] init() function that accepts bot instance - this is passed to init() on submodules
pub fn init(mgr:&mut ModulesManager) -> () { pub fn init<F>(mgr:&mut ModulesManager<F>) -> ()
where
F: std::future::Future,
{
// Modules initializer loads modules into the bot // Modules initializer loads modules into the bot
// this is achieved by calling submodules that also have fn init() defined // this is achieved by calling submodules that also have fn init() defined

View file

@ -12,12 +12,15 @@
// mod crate::modules; // mod crate::modules;
//use crate::modules; //use crate::modules;
use crate::core::botmodules::{ModulesManager,BotCommand,Listener,BotModule,BotActionTrait}; use crate::core::botmodules::{ModulesManager,Listener,BotModule,BotActionTrait};
use crate::core::botinstance::BotInstance; use crate::core::botinstance::BotInstance;
use twitch_irc::message::PrivmsgMessage; use twitch_irc::message::PrivmsgMessage;
pub fn init(mgr:&mut ModulesManager) -> () { pub fn init<F>(mgr:&mut ModulesManager<F>) -> ()
where
F: std::future::Future,
{
// BotCommand { // BotCommand {
@ -55,7 +58,24 @@ pub fn init(mgr:&mut ModulesManager) -> () {
// () // ()
// } // }
async fn good_girl(bot:&mut BotInstance,msg:&PrivmsgMessage) { // async fn good_girl<F>(bot:&mut BotInstance<F>,msg:&PrivmsgMessage)
// where
// F: std::future::Future,
// {
// println!("In GoodGirl()");
// println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);
// if msg.sender.name == "ModulatingForce" && msg.message_text.contains("GoodGirl") {
// bot.chat.say_in_reply_to(msg,String::from("GoodGirl")).await;
// }
// }
async fn good_girl<F>(bot:&mut Box<BotInstance<F>>,msg:&PrivmsgMessage)
where
F: std::future::Future,
{
println!("In GoodGirl()"); println!("In GoodGirl()");
println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text); println!("(#{}) {}: {}", msg.channel_login, msg.sender.name, msg.message_text);