use crate::{
core::Env,
spaces::{Bounded, BoxSpace},
};
pub trait AsBoxBounds<B: Bounded> {
fn bounds(&self) -> (&B, &B);
}
impl<B: Bounded> AsBoxBounds<B> for BoxSpace<B> {
fn bounds(&self) -> (&B, &B) {
(&self.low, &self.high)
}
}
pub trait Wrapper: Env {
type Inner: Env;
fn inner(&self) -> &Self::Inner;
fn inner_mut(&mut self) -> &mut Self::Inner;
fn into_inner(self) -> Self::Inner;
}
#[macro_export]
macro_rules! delegate_env {
($wrapper:ident < $e:ident >, $field:ident) => {
impl<$e: $crate::core::Env> $crate::core::Env for $wrapper<$e> {
type Action = $e::Action;
type Observation = $e::Observation;
type ActionSpace = $e::ActionSpace;
type ObservationSpace = $e::ObservationSpace;
type ResetOptions = $e::ResetOptions;
fn step(
&mut self,
action: Self::Action,
) -> $crate::core::StepResult<Self::Observation> {
self.$field.step(action)
}
fn reset(
&mut self,
seed: Option<u64>,
options: Self::ResetOptions,
) -> Self::Observation {
self.$field.reset(seed, options)
}
fn action_space(&self) -> &Self::ActionSpace {
self.$field.action_space()
}
fn observation_space(&self) -> &Self::ObservationSpace {
self.$field.observation_space()
}
fn close(&mut self) {
self.$field.close();
}
}
};
}
mod autoreset;
mod clip_action;
mod clip_reward;
mod flatten_observation;
mod normalize_observation;
mod normalize_reward;
mod order_enforcing;
mod record_episode_statistics;
mod rescale_action;
mod time_limit;
mod transform_action;
mod transform_observation;
mod transform_reward;
pub use autoreset::Autoreset;
pub use clip_action::ClipAction;
pub use clip_reward::ClipReward;
pub use flatten_observation::FlattenObservation;
pub use normalize_observation::NormalizeObservation;
pub use normalize_reward::NormalizeReward;
pub use order_enforcing::OrderEnforcing;
pub use record_episode_statistics::RecordEpisodeStatistics;
pub use rescale_action::RescaleAction;
pub use time_limit::TimeLimit;
pub use transform_action::TransformAction;
pub use transform_observation::TransformObservation;
pub use transform_reward::TransformReward;
#[cfg(test)]
mod tests {
use super::*;
struct Passthrough<E: crate::core::Env> {
env: E,
}
crate::delegate_env!(Passthrough<E>, env);
impl<E: crate::core::Env> Wrapper for Passthrough<E> {
type Inner = E;
fn inner(&self) -> &E {
&self.env
}
fn inner_mut(&mut self) -> &mut E {
&mut self.env
}
fn into_inner(self) -> E {
self.env
}
}
#[test]
fn delegate_env_macro_compiles_and_delegates() {
use crate::core::{Env, Flatten};
use crate::envs::classical_control::cartpole::CartPoleEnv;
let env = CartPoleEnv::new();
let mut w = Passthrough { env };
let obs = w.reset(Some(42), None);
let result = w.step(1_i64);
assert_eq!(obs.flatten().len(), 4);
assert!(result.reward >= 0.0);
}
}