use async_trait::async_trait;
pub use rlmesh_proto::env::v1::{
CloseResponse, RenderRequest, RenderResponse, ResetRequest, ResetResponse, StepRequest,
StepResponse,
};
use rlmesh_spaces::{EnvContract, spaces::SpaceSpec};
use crate::error::{EnvError, EnvErrorCode};
#[async_trait]
pub trait Environment: Send + Sync {
fn observation_space(&self) -> &SpaceSpec;
fn action_space(&self) -> &SpaceSpec;
fn num_envs(&self) -> usize;
fn env_contract(&self) -> &EnvContract;
async fn reset(&mut self, req: ResetRequest) -> Result<ResetResponse, EnvError>;
async fn reset_subset(&mut self, req: ResetRequest) -> Result<ResetResponse, EnvError> {
if req.env_indices.is_empty() {
self.reset(req).await
} else {
Err(EnvError::new(
EnvErrorCode::Internal,
format!(
"partial reset of sub-envs {:?} is not supported by this environment. \
Per-lane reset is only available for an env that implements reset_subset. \
Use NEXT_STEP autoreset (the env resets done lanes itself), run with \
num_envs == 1, or ensure all lanes terminate on the same step so the whole \
vector resets together.",
req.env_indices
),
))
}
}
async fn step(&mut self, req: StepRequest) -> Result<StepResponse, EnvError>;
async fn render(&mut self, req: RenderRequest) -> Result<RenderResponse, EnvError>;
async fn close(&mut self) -> Result<CloseResponse, EnvError>;
}