use crate::core::{Env, StepResult};
use super::Wrapper;
pub struct TimeLimit<E: Env> {
env: E,
max_episode_steps: usize,
current_step: usize,
}
impl<E: Env> TimeLimit<E> {
pub fn new(env: E, max_episode_steps: usize) -> Self {
Self {
env,
max_episode_steps,
current_step: 0,
}
}
pub fn steps_remaining(&self) -> usize {
self.max_episode_steps.saturating_sub(self.current_step)
}
pub fn max_steps(&self) -> usize {
self.max_episode_steps
}
pub fn current_step(&self) -> usize {
self.current_step
}
}
impl<E: Env> Env for TimeLimit<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) -> StepResult<Self::Observation> {
let mut result = self.env.step(action);
self.current_step += 1;
if self.current_step >= self.max_episode_steps && !result.terminated {
result.truncated = true;
}
result
}
fn reset(&mut self, seed: Option<u64>, options: Self::ResetOptions) -> Self::Observation {
self.current_step = 0;
self.env.reset(seed, options)
}
fn action_space(&self) -> &Self::ActionSpace {
self.env.action_space()
}
fn observation_space(&self) -> &Self::ObservationSpace {
self.env.observation_space()
}
fn close(&mut self) {
self.env.close();
}
}
impl<E: Env> Wrapper for TimeLimit<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
}
}