use crate::env::{Env, RenderFrame, RenderMode, ResetResult, StepResult};
use crate::error::Result;
use crate::space::BoundedSpace;
#[derive(Debug)]
pub struct ClipAction<E>
where
E: Env<Act = Vec<f32>, ActSpace = BoundedSpace>,
{
env: E,
}
impl<E> ClipAction<E>
where
E: Env<Act = Vec<f32>, ActSpace = BoundedSpace>,
{
#[must_use]
pub const fn new(env: E) -> Self {
Self { env }
}
#[must_use]
pub const fn inner(&self) -> &E {
&self.env
}
#[must_use]
pub const fn inner_mut(&mut self) -> &mut E {
&mut self.env
}
#[must_use]
pub fn into_inner(self) -> E {
self.env
}
fn clip(&self, action: &[f32]) -> Vec<f32> {
let space = self.env.action_space();
action
.iter()
.zip(space.low.iter().zip(space.high.iter()))
.map(|(&a, (&lo, &hi))| a.clamp(lo, hi))
.collect()
}
}
impl<E> Env for ClipAction<E>
where
E: Env<Act = Vec<f32>, ActSpace = BoundedSpace>,
{
type Obs = E::Obs;
type Act = Vec<f32>;
type ObsSpace = E::ObsSpace;
type ActSpace = BoundedSpace;
fn step(&mut self, action: &Vec<f32>) -> Result<StepResult<Self::Obs>> {
let clipped = self.clip(action);
self.env.step(&clipped)
}
fn reset(&mut self, seed: Option<u64>) -> Result<ResetResult<Self::Obs>> {
self.env.reset(seed)
}
fn render(&mut self) -> Result<RenderFrame> {
self.env.render()
}
fn close(&mut self) {
self.env.close();
}
fn observation_space(&self) -> &Self::ObsSpace {
self.env.observation_space()
}
fn action_space(&self) -> &BoundedSpace {
self.env.action_space()
}
fn render_mode(&self) -> &RenderMode {
self.env.render_mode()
}
}