diff --git a/src/core/botmodules.rs b/src/core/botmodules.rs index 5b725b8..a752ad5 100644 --- a/src/core/botmodules.rs +++ b/src/core/botmodules.rs @@ -31,13 +31,16 @@ use std::sync::Arc; use casual_logger::Log; use chrono::DateTime; -use chrono::Duration; +// use chrono::Duration; use chrono::Local; use tokio::sync::RwLock; use async_trait::async_trait; use tokio::task::JoinHandle; +use tokio::time::Instant; +use tokio::time::{sleep, Duration}; + use crate::core::bot_actions::actions_util; use crate::core::bot_actions::ExecBodyParams; use crate::core::botinstance::{BotInstance, Channel,ChangeResult}; @@ -572,8 +575,9 @@ impl BotActionTrait for Listener { } } - -enum RoutineAttr { +// #[derive(Debug, PartialEq, Eq, Hash, Clone)] +#[derive(PartialEq, Eq, Hash)] +pub enum RoutineAttr { DelayedStart, ScheduledStart(DateTime), // Scheduled Date (if any) after which, if not started, may trigger LoopDuration(Duration), // How long to wait between iterations @@ -610,16 +614,17 @@ enum RoutineAttr { // #[derive(Debug)] pub struct Routine { - // pub name : String , + pub name : String , module : BotModule , // from() can determine this if passed parents_params // pub channel : Option , // Routines generally run by Channel ; but can be left None channel : Channel , // Requiring some channel context exec_body: bot_actions::actions_util::ExecBody, - parent_params : Option , + // parent_params : Option , + parent_params : ExecBodyParams , join_handle : Option> , - complete_iterations : i64 , - remaining_iterations : i64 , start_time : Option> , + complete_iterations : i64 , + remaining_iterations : Option , routine_attr : Vec , } @@ -628,16 +633,37 @@ impl Routine { // Constructor pub fn from( - _module : BotModule , - _channel : Channel, - _exec_body : bot_actions::actions_util::ExecBody , - _parent_params : Option - ) -> Result { + name : String , + module : BotModule , + channel : Channel, + routine_attr : Vec , + exec_body : bot_actions::actions_util::ExecBody , + // parent_params : Option + parent_params : ExecBodyParams + // ) -> Result { + ) -> Result { // [ ] Validation is made against parent_params // to ensure those params don't conflict // conlicts would throw an error + // parent_params.unwrap(). + + if routine_attr.contains(&RoutineAttr::RunOnce) { + return Ok(Routine { + name , + module , + channel , + exec_body , + parent_params , + join_handle : None , + start_time : None , + complete_iterations : 0 , + remaining_iterations : None , + routine_attr : routine_attr + }) ; + } + Err("NOT IMPLEMENTED".to_string()) } @@ -652,16 +678,95 @@ impl Routine { Err("NOT IMPLEMENTED".to_string()) } - - pub fn start(&self) -> Result + pub async fn start(self) -> Result { // [ ] Asyncio Spawn likely around here // [ ] & Assigns self.join_handle + + let self_rw = Arc::new(RwLock::new(self)); + let mut self_wr_lock = self_rw.write().await; + + if self_wr_lock.routine_attr.contains(&RoutineAttr::RunOnce) { + self_wr_lock.remaining_iterations = Some(1); + + fn innerhelper(self_rw : Arc>) -> Option> { + Some( + tokio::spawn(async move { + + + let mut self_wr_lock = self_rw.write().await; + let mut remainingiter = self_wr_lock.remaining_iterations.unwrap(); + + + + botlog::trace( + format!( + "[TRACE][Routine Started] {} in {}", + self_wr_lock.name,self_wr_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_wr_lock.module + )), + Some(&self_wr_lock.parent_params.msg), + ); + + self_wr_lock.start_time = Some(chrono::offset::Local::now()); + + + // Loop iteration + while remainingiter > 1 { + + // execution body + self_wr_lock.loopbody().await; + + // end of loop iteration + remainingiter -= 1; + { + self_wr_lock.remaining_iterations = Some(remainingiter); + self_wr_lock.complete_iterations += 1; + } + + } + + botlog::trace( + format!( + "[TRACE][Routine Completed] {} in {}", + self_wr_lock.name,self_wr_lock.channel.0 + ) + .as_str(), + Some(format!( + "Routine > start() > (In Tokio Spawn) > {:?}", + self_wr_lock.module + )), + Some(&self_wr_lock.parent_params.msg), + ); + + + })) + } + + self_wr_lock.join_handle = innerhelper(self_rw.clone()) ; + return Ok("Successfully Started Routine".to_string()); + } + + + + Err("NOT IMPLEMENTED".to_string()) } + + async fn loopbody(&self) + { + (self.exec_body)( + self.parent_params.clone() + ).await; + } + pub fn stop(&self) -> Result { Err("NOT IMPLEMENTED".to_string())