#[cfg(not(feature = "std"))]
pub mod connector_no_std;
#[cfg(feature = "std")]
pub mod connector_std;
#[cfg(not(feature = "std"))]
pub mod socket_no_std;
#[cfg(feature = "std")]
pub mod socket_std;
#[cfg(not(feature = "std"))]
pub mod error_no_std;
pub mod connector_data;
pub mod dispatch;
pub mod message;
pub mod protocol;
#[cfg(not(feature = "std"))]
use embassy_time::Instant;
use crate::{
Arc, ConstString, Mutex,
behavior_data::BehaviorData,
behavior_state::BehaviorState,
tree::{
observer::groot2::{connector_data::Groot2ConnectorData, protocol::Groot2TransitionInfo},
tree::BehaviorTree,
},
};
const FLAG_MORE: u8 = 0x01;
const FLAG_LONG: u8 = 0x02;
const FLAG_COMMAND: u8 = 0x04;
const GREETING_SIZE: usize = 64;
const READY_BODY: &[u8] = &[
0x05, b'R', b'E', b'A', b'D', b'Y', 0x0b, b'S', b'o', b'c', b'k', b'e', b't', b'-', b'T', b'y', b'p', b'e', 0x00, 0x00,
0x00, 0x03, b'R', b'E', b'P',
];
const TRANSITION_SIZE: u32 = 100;
pub const GROOT_STATE: &str = "groot_state";
fn timestamp() -> u64 {
#[cfg(not(feature = "std"))]
{
Instant::now().as_micros()
}
#[cfg(feature = "std")]
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::expect_used)]
{
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("Time went backwards")
.as_micros() as u64
}
}
pub fn build_greeting(is_server: bool) -> [u8; GREETING_SIZE] {
let mut g = [0u8; GREETING_SIZE];
g[0] = 0xff;
g[1..9].copy_from_slice(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
g[9] = 0x7f;
g[10] = 0x03;
g[11] = 0x01;
g[12..16].copy_from_slice(b"NULL");
g[32] = u8::from(is_server);
g
}
pub fn attach_groot_callback(tree: &mut BehaviorTree, shared: Arc<Mutex<Groot2ConnectorData>>) {
let id: ConstString = GROOT_STATE.into();
let shared = shared;
for element in tree.iter_mut() {
let shared_clone = shared.clone();
let callback = move |behavior: &BehaviorData, new_state: &mut BehaviorState| {
if behavior.state() != *new_state {
if behavior.uid() != 0 {
let state = if *new_state == BehaviorState::Idle {
behavior.state() as u8 + 10
} else {
*new_state as u8
};
let mut shared_guard = shared_clone.lock();
let uid = behavior.uid().to_le_bytes();
let index = 3 * ((behavior.uid() - 1) as usize);
shared_guard.state_buffer[index] = uid[0];
shared_guard.state_buffer[index + 1] = uid[1];
shared_guard.state_buffer[index + 2] = state;
if shared_guard.recording {
let info = Groot2TransitionInfo::new(timestamp(), behavior.uid(), *new_state);
if shared_guard.transitions_buffer.is_empty() {
shared_guard.transitions = 0;
} else if shared_guard.transitions >= TRANSITION_SIZE {
shared_guard.transitions_buffer.pop_front();
} else {
shared_guard.transitions += 1;
}
shared_guard.transitions_buffer.push_back(info);
}
drop(shared_guard);
}
}
};
element.add_pre_state_change_callback(id.clone(), callback);
}
}