use super::session::Mailbox;
use crate::session::SendUIMessage;
use actix::WrapFuture;
use actix::{AsyncContext, Handler, Message};
use benthic_protocol::messages::ui::land_update::LandUpdate;
use benthic_protocol::messages::ui::{skybox_update::SkyboxUpdate, ui_messages::UIMessage};
use log::error;
use log::info;
use log::warn;
use metaverse_environment::layer_handler::handle_layer;
use metaverse_environment::sim_time::fetch_environment_time;
use metaverse_messages::http::capabilities::Capability;
use metaverse_messages::udp::environment::layer_data::LayerData;
use std::time::Duration;
#[derive(Message)]
#[rtype(result = "()")]
pub struct HandleSimulatorViewerTimeMessage {
pub seconds_since_start: u64,
pub sun_phase: f32,
pub seconds_per_day: u32,
pub seconds_per_year: u32,
}
#[cfg(feature = "environment")]
impl Handler<HandleSimulatorViewerTimeMessage> for Mailbox {
type Result = ();
fn handle(
&mut self,
msg: HandleSimulatorViewerTimeMessage,
ctx: &mut Self::Context,
) -> Self::Result {
if let Some(session) = &mut self.session {
let region = &mut session.region_data;
if msg.seconds_since_start <= region.last_time_update {
info!("Received out of order SimulatorViewerTimeMessage");
return;
}
ctx.address().do_send(SendUIMessage {
ui_message: UIMessage::new_skybox_update(SkyboxUpdate {
sun_phase: msg.sun_phase,
}),
});
}
}
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct FetchEnvironmentEvent {}
impl Handler<FetchEnvironmentEvent> for Mailbox {
type Result = ();
fn handle(&mut self, msg: FetchEnvironmentEvent, ctx: &mut Self::Context) -> Self::Result {
let Some(session) = self.session.as_ref() else {
return;
};
if session.capability_urls.is_empty() {
warn!("Capabilities not ready yet. Queueing Environment fetch...");
ctx.notify_later(msg, Duration::from_secs(1));
return;
}
let capability_url = {
session
.capability_urls
.get(&Capability::ExtEnvironment)
.cloned()
};
ctx.spawn(
async move {
match fetch_environment_time(&capability_url).await {
Ok(_) => {}
Err(e) => error!("{:?}", e),
}
}
.into_actor(self),
);
}
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct HandleLayerData {
pub layer_data: LayerData,
}
impl Handler<HandleLayerData> for Mailbox {
type Result = ();
fn handle(&mut self, msg: HandleLayerData, ctx: &mut Self::Context) -> Self::Result {
let Some(session) = self.session.as_mut() else {
return;
};
match handle_layer(msg.layer_data, session) {
Ok(paths) => {
for path in paths {
ctx.address().do_send(SendUIMessage {
ui_message: UIMessage::new_land_update(LandUpdate { path }),
});
}
}
Err(e) => {
error!("{:?}", e);
}
};
}
}