WIP: Basic Routine Functionality #40

Draft
modulatingforce wants to merge 23 commits from routines-functionality into master
2 changed files with 124 additions and 102 deletions
Showing only changes of commit 669b2da871 - Show all commits

View file

@ -5,11 +5,12 @@ use tokio::sync::RwLock;
use crate::core::botinstance::BotInstance;
use super::{botinstance::Channel, botmodules::{BotAction, BotModule}, identity::ChatBadge};
use super::{botinstance::Channel, botmodules::{BotAction, BotModule, Routine}, identity::ChatBadge};
pub type BotAR = Arc<RwLock<BotInstance>>;
pub type ActAR = Arc<RwLock<BotAction>>;
pub type RoutineAR = Arc<RwLock<Routine>>;
#[derive(Clone)]
pub struct ExecBodyParams {

View file

@ -25,6 +25,8 @@ const OF_CMD_CHANNEL:Channel = Channel(String::new());
use core::panic;
use std::borrow::Borrow;
use std::borrow::BorrowMut;
use std::collections::HashMap;
use std::sync::Arc;
@ -51,6 +53,8 @@ use crate::core::bot_actions;
use std::hash::{Hash, Hasher};
use super::bot_actions::ActAR;
use super::bot_actions::RoutineAR;
use super::identity::ChatBadge;
@ -617,7 +621,7 @@ pub struct Routine {
pub channel : Channel , // Requiring some channel context
exec_body: bot_actions::actions_util::ExecBody,
parent_params : ExecBodyParams ,
pub join_handle : Option<Arc<RwLock<JoinHandle<()>>>> ,
pub join_handle : Option<Arc<RwLock<JoinHandle<RoutineAR>>>> ,
start_time : Option<DateTime<Local>> ,
complete_iterations : i64 ,
remaining_iterations : Option<i64> ,
@ -685,121 +689,138 @@ impl Routine {
/*
GENERAL LOGIC
UMBRELLA ROUTINE LOGIC
1. Create a loop scenario based on routine_attr such as RunOnce
2. Run the loop depending on how the Routine is setup
START LOGIC :
1. Ideally validate the routineattr that they're not a problem scenario (However, this should have been validated At Setup)
a. Extra helper validation function though would help in case the attributes were changes between setup
2. Use these attributes only in Critical areas of the loop logic to determine changes in Loop logic
*/
// Use the following to stop the function from going any further if not implemented
if !trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) {
botlog::trace(
format!(
"[ERROR][Routine Feature NOT IMPLEMENTED] {} in {}",
trg_routine_ar.read().await.name,
trg_routine_ar.read().await.channel.0
)
.as_str(),
Some(format!(
"Routine > start() > (In Tokio Spawn) > {:?}",
trg_routine_ar.read().await.module
)),
Some(&trg_routine_ar.read().await.parent_params.msg),
);
Log::flush();
return Err("NOT IMPLEMENTED".to_string())
}
if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) {
async fn runonce_innerhelper(inroutine : Arc<RwLock<Routine>>) -> JoinHandle<()> {
botlog::trace(
"innerhelper() started",
Some(format!(
"Routine > start() > (In Tokio Spawn)",
)),
Some(&inroutine.read().await.parent_params.msg),
);
Log::flush();
return tokio::spawn(async move {
botlog::trace(
">> Within Spawn",
Some(format!(
"Routine > start() > (In Tokio Spawn)",
)),
Some(&inroutine.read().await.parent_params.msg),
);
Log::flush();
{
let mut a = inroutine.write().await;
a.start_time = Some(chrono::offset::Local::now());
a.complete_iterations += 1;
if let Some(i) = a.remaining_iterations{
if i > 0 {
a.remaining_iterations = Some(i-1)
} else {
// do nothing for now
// [ ] If this was in a loop, please validate this
}
}
}
// execution body
inroutine.read().await.loopbody().await;
botlog::trace(
format!(
"[TRACE][Routine Completed] {} in {}",
inroutine.read().await.name,
inroutine.read().await.channel.0
)
.as_str(),
Some(format!(
"Routine > start() > (In Tokio Spawn) > {:?}",
inroutine.read().await.module
)),
Some(&inroutine.read().await.parent_params.msg),
);
botlog::trace(
format!(
"[TRACE][Routine Completed][Routine Header Test] {} in {} > Completed Iterations : {}",
inroutine.read().await.name,
inroutine.read().await.channel.0 ,
inroutine.read().await.complete_iterations,
)
.as_str(),
Some(format!(
"Routine > start() > (In Tokio Spawn) > {:?}",
inroutine.read().await.module
)),
Some(&inroutine.read().await.parent_params.msg),
);
Log::flush();
})
}
{
trg_routine_ar.write().await.join_handle = Some(Arc::new(RwLock::new(runonce_innerhelper(trg_routine_ar.clone()).await)));
}
return Ok(trg_routine_ar);
}
let trg_routine_arout = Arc::clone(&trg_routine_ar);
botlog::trace(
format!(
"[ERROR][Routine NOT IMPLEMENTED] {} in {}",
trg_routine_ar.read().await.name,
trg_routine_ar.read().await.channel.0
)
.as_str(),
Some(format!(
"Routine > start() > (In Tokio Spawn) > {:?}",
trg_routine_ar.read().await.module
"innerhelper() started",
Some(format!(
"Routine > start() > (In Tokio Spawn)",
)),
Some(&trg_routine_ar.read().await.parent_params.msg),
);
Log::flush();
Err("NOT IMPLEMENTED".to_string())
// Spawn the task
let join_handle = tokio::spawn(async move {
botlog::trace(
">> Within Spawn",
Some(format!(
"Routine > start() > (In Tokio Spawn)",
)),
Some(&trg_routine_ar.read().await.parent_params.msg),
);
Log::flush();
{ // Prior to Loop that calls Custom Routine Execution Body
let mut a = trg_routine_ar.write().await;
a.start_time = Some(chrono::offset::Local::now());
}
loop { // Routine loop
// execution body
trg_routine_ar.read().await.loopbody().await;
{ // End of Loop iteration
let mut a = trg_routine_ar.write().await;
a.complete_iterations += 1;
if let Some(i) = a.remaining_iterations {
if i > 0 { a.remaining_iterations = Some(i-1) ; }
}
}
// End of Loop Validation
if trg_routine_ar.read().await.routine_attr.contains(&RoutineAttr::RunOnce) {
if trg_routine_ar.read().await.complete_iterations > 0 { break; }
}
}
botlog::trace(
format!(
"[TRACE][Routine Completed] {} in {}",
trg_routine_ar.read().await.name,
trg_routine_ar.read().await.channel.0
)
.as_str(),
Some(format!(
"Routine > start() > (In Tokio Spawn) > {:?}",
trg_routine_ar.read().await.module
)),
Some(&trg_routine_ar.read().await.parent_params.msg),
);
botlog::trace(
format!(
"[TRACE][Routine Completed][Routine Header Test] {} in {} > Completed Iterations : {}",
trg_routine_ar.read().await.name,
trg_routine_ar.read().await.channel.0 ,
trg_routine_ar.read().await.complete_iterations,
)
.as_str(),
Some(format!(
"Routine > start() > (In Tokio Spawn) > {:?}",
trg_routine_ar.read().await.module
)),
Some(&trg_routine_ar.read().await.parent_params.msg),
);
Log::flush();
trg_routine_ar
});
trg_routine_arout.write().await.join_handle = Some(Arc::new(RwLock::new(join_handle)));
// }
return Ok(trg_routine_arout);
}