fish_lib/game/services/
weather_service.rs1use crate::config::ConfigInterface;
2use crate::data::location_data::LocationData;
3use crate::game::errors::resource::GameResourceError;
4use crate::game::errors::GameResult;
5use crate::game::systems::weather_system::config::WeatherSystemConfig;
6use crate::game::systems::weather_system::weather::Weather;
7use crate::game::systems::weather_system::WeatherSystem;
8use chrono::DateTime;
9use chrono_tz::Tz;
10use std::collections::HashMap;
11use std::sync::Arc;
12
13pub trait WeatherServiceInterface: Send + Sync {
14 fn get_weather(
15 &self,
16 location_data: Arc<LocationData>,
17 time: DateTime<Tz>,
18 ) -> GameResult<Weather>;
19 fn get_current_weather(&self, location_data: Arc<LocationData>) -> GameResult<Weather>;
20}
21
22pub struct WeatherService {
23 time_multiplier: f32,
24 weather_systems: HashMap<i32, WeatherSystem>,
26}
27
28impl WeatherService {
29 pub fn new(config: Arc<dyn ConfigInterface>) -> Self {
30 let mut systems = HashMap::new();
31 config
32 .locations()
33 .iter()
34 .for_each(|(location_id, location_data)| {
35 let config = WeatherSystemConfig::builder()
36 .with_location_data(location_data.clone())
37 .build();
38 let system = WeatherSystem::new(config);
39 systems.insert(*location_id, system);
40 });
41
42 Self {
43 time_multiplier: config.settings().time_speed_multiplier,
44 weather_systems: systems,
45 }
46 }
47}
48
49impl WeatherServiceInterface for WeatherService {
50 fn get_weather(
51 &self,
52 location_data: Arc<LocationData>,
53 time: DateTime<Tz>,
54 ) -> GameResult<Weather> {
55 let location_id = location_data.id;
56 self.weather_systems
57 .get(&location_id)
58 .map(|system| system.get_weather(time, self.time_multiplier))
59 .ok_or_else(|| GameResourceError::location_not_found(location_id).into())
60 }
61
62 fn get_current_weather(&self, location_data: Arc<LocationData>) -> GameResult<Weather> {
63 let time_now = location_data.get_local_time();
64 self.get_weather(location_data, time_now)
65 }
66}