use crate::{BehaviorNode, Context, NodeStatus};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::time::{Duration, Instant};
#[derive(Debug)]
pub struct TimerNode {
duration: Duration,
start_time: Option<Instant>,
}
#[derive(Debug, Serialize, Deserialize)]
struct TimerConfig {
duration_secs: f64,
}
impl TimerNode {
pub fn from_json(config: Value) -> anyhow::Result<Self> {
let cfg: TimerConfig = serde_json::from_value(config)?;
Ok(Self {
duration: Duration::from_secs_f64(cfg.duration_secs),
start_time: None,
})
}
}
#[async_trait]
impl BehaviorNode for TimerNode {
async fn tick(&mut self, _ctx: &Context) -> anyhow::Result<NodeStatus> {
let now = Instant::now();
if self.start_time.is_none() {
self.start_time = Some(now);
}
if now.duration_since(self.start_time.unwrap()) >= self.duration {
Ok(NodeStatus::Success)
} else {
Ok(NodeStatus::Running)
}
}
async fn reset(&mut self) -> anyhow::Result<()> {
self.start_time = None;
Ok(())
}
fn name(&self) -> &str {
"TimerNode"
}
}
#[derive(Debug)]
pub struct IdleNode;
impl IdleNode {
pub fn from_json(_config: Value) -> anyhow::Result<Self> {
Ok(Self)
}
}
#[async_trait]
impl BehaviorNode for IdleNode {
async fn tick(&mut self, _ctx: &Context) -> anyhow::Result<NodeStatus> {
Ok(NodeStatus::Success)
}
fn name(&self) -> &str {
"IdleNode"
}
}
#[derive(Debug)]
pub struct PauseNode {
duration: Duration,
start_time: Option<Instant>,
}
#[derive(Debug, Serialize, Deserialize)]
struct PauseConfig {
duration_secs: f64,
}
impl PauseNode {
pub fn from_json(config: Value) -> anyhow::Result<Self> {
let cfg: PauseConfig = serde_json::from_value(config)?;
Ok(Self {
duration: Duration::from_secs_f64(cfg.duration_secs),
start_time: None,
})
}
}
#[async_trait]
impl BehaviorNode for PauseNode {
async fn tick(&mut self, _ctx: &Context) -> anyhow::Result<NodeStatus> {
let now = Instant::now();
if self.start_time.is_none() {
self.start_time = Some(now);
tracing::debug!("PauseNode: starting pause for {:?}", self.duration);
}
if now.duration_since(self.start_time.unwrap()) >= self.duration {
tracing::debug!("PauseNode: pause complete");
Ok(NodeStatus::Success)
} else {
Ok(NodeStatus::Running)
}
}
async fn reset(&mut self) -> anyhow::Result<()> {
self.start_time = None;
Ok(())
}
fn name(&self) -> &str {
"PauseNode"
}
}