Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: Rustlib & Sun subsystem in Rust #6537

Draft
wants to merge 20 commits into
base: master220
Choose a base branch
from
Prev Previous commit
Next Next commit
plan b
  • Loading branch information
Antoonij committed Feb 16, 2025
commit d67f74f31d907791f2be82ba29b2b2d3992fb259
2 changes: 1 addition & 1 deletion code/modules/power/solar.dm
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@
autostart = TRUE // Automatically search for connected devices

/obj/machinery/power/solar_control/Initialize(mapload, obj/structure/computerframe)
SSsun.add_solar(src)
connect_to_network()
setup()

. = ..()
Expand Down
26 changes: 9 additions & 17 deletions rust/src/subsystem/sun/api.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,42 @@
use super::statics::SUN;
use super::sun::Sun;
use byondapi::value::ByondValue;

#[byondapi::bind]
pub fn sun_subsystem_initialize() -> eyre::Result<ByondValue> {
let mut sun = SUN.lock().unwrap();
sun.initialize()
Sun::initialize()
}

#[byondapi::bind]
pub fn sun_subsystem_fire() -> eyre::Result<ByondValue> {
let mut sun = SUN.lock().unwrap();
sun.update_position()
Sun::update_position()
}

#[byondapi::bind]
pub fn get_sun_angle() -> eyre::Result<ByondValue> {
let sun = SUN.lock().unwrap();
sun.get_angle()
Sun::get_angle()
}

#[byondapi::bind]
pub fn add_solar(solar: ByondValue) -> eyre::Result<ByondValue> {
let mut sun = SUN.lock().unwrap();
sun.add_solar(solar)
Sun::add_solar(solar)
}

#[byondapi::bind]
pub fn remove_solar(solar: ByondValue) -> eyre::Result<ByondValue> {
let mut sun = SUN.lock().unwrap();
sun.remove_solar(solar)
Sun::remove_solar(solar)
}

#[byondapi::bind]
pub fn get_solars() -> eyre::Result<ByondValue> {
let sun = SUN.lock().unwrap();
sun.get_solars()
Sun::get_solars()
}

#[byondapi::bind]
pub fn get_dy() -> eyre::Result<ByondValue> {
let sun = SUN.lock().unwrap();
sun.get_dy()
Sun::get_dy()
}

#[byondapi::bind]
pub fn get_dx() -> eyre::Result<ByondValue> {
let sun = SUN.lock().unwrap();
sun.get_dx()
Sun::get_dx()
}
10 changes: 7 additions & 3 deletions rust/src/subsystem/sun/statics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use super::sun::Sun;
use std::sync::Mutex;
use byondapi::value::ByondValue;
use std::sync::RwLock;

pub static SUN: Mutex<Sun> = Mutex::new(Sun::default());
pub static RATE: RwLock<f32> = RwLock::new(0.0);
pub static DX: RwLock<f32> = RwLock::new(0.0);
pub static DY: RwLock<f32> = RwLock::new(0.0);
pub static SOLARS: RwLock<Vec<ByondValue>> = RwLock::new(Vec::new());
pub static ANGLE: RwLock<f32> = RwLock::new(0.0);
149 changes: 91 additions & 58 deletions rust/src/subsystem/sun/sun.rs
Original file line number Diff line number Diff line change
@@ -1,115 +1,148 @@
use super::statics::*;
use byondapi::value::ByondValue;
use rand::Rng;

pub struct Sun {
pub rate: f32,
pub dx: f32,
pub dy: f32,
pub solars: Vec<ByondValue>,
pub angle: f32,
}
pub struct Sun {}

impl Sun {
pub const fn default() -> Self {
Sun {
rate: 0.0,
dx: 0.0,
dy: 0.0,
solars: Vec::new(),
angle: 0.0,
}
}

pub fn initialize(&mut self) -> eyre::Result<ByondValue> {
pub fn initialize() -> eyre::Result<ByondValue> {
let mut rng = rand::thread_rng();

let angle = rng.gen_range(0.0..=360.0);
let mut rate = rng.gen_range(0.5..=2.0);

if rng.gen_bool(0.5) {
rate = -rate;
}

self.rate = rate;
self.angle = angle;
{
let mut rate_lock = RATE
.write()
.map_err(|_| eyre::eyre!("Failed to lock RATE"))?;
let mut angle_lock = ANGLE
.write()
.map_err(|_| eyre::eyre!("Failed to lock ANGLE"))?;

self.setup_solars()?;
Ok(ByondValue::null())
}
*rate_lock = rate;
*angle_lock = angle;
}

pub fn update_position(&mut self) -> eyre::Result<ByondValue> {
let new_angle = (360.0 + self.angle + self.rate * 6.0) % 360.0;
Self::setup_solars()?;
Ok(ByondValue::from(true))
}

self.angle = new_angle;
pub fn update_position() -> eyre::Result<ByondValue> {
let new_angle = {
let angle_read = ANGLE
.read()
.map_err(|_| eyre::eyre!("Failed to lock ANGLE"))?;
let rate_read = RATE
.read()
.map_err(|_| eyre::eyre!("Failed to lock RATE"))?;

(360.0 + *angle_read + *rate_read * 6.0) % 360.0
};

{
let mut angle_write = ANGLE
.write()
.map_err(|_| eyre::eyre!("Failed to lock ANGLE"))?;
*angle_write = new_angle;
}

let sin = new_angle.to_radians().sin();
let cos = new_angle.to_radians().cos();

let sin_abs = sin.abs();
let cos_abs = cos.abs();

if sin_abs < cos_abs {
self.dx = sin / cos_abs;
self.dy = cos / cos_abs;
} else {
self.dx = sin / sin_abs;
self.dy = cos / sin_abs;
let dx = sin / if sin_abs < cos_abs { cos_abs } else { sin_abs };
let dy = cos / if sin_abs < cos_abs { cos_abs } else { sin_abs };

{
let mut dx_write = DX.write().map_err(|_| eyre::eyre!("Failed to lock DX"))?;
let mut dy_write = DY.write().map_err(|_| eyre::eyre!("Failed to lock DY"))?;

*dx_write = dx;
*dy_write = dy;
}

self.update_solars()?;
Ok(ByondValue::null())
Self::update_solars()?;
Ok(ByondValue::from(true))
}

pub fn setup_solars(&self) -> eyre::Result<ByondValue> {
for solar in &self.solars {
solar.call("setup", &[])?;
pub fn setup_solars() -> eyre::Result<ByondValue> {
let solars_lock = SOLARS
.read()
.map_err(|_| eyre::eyre!("Failed to lock SOLARS"))?;

for solar in solars_lock.iter() {
solar
.call("setup", &[])
.map_err(|_| eyre::eyre!("Failed to setup solar"))?;
}

Ok(ByondValue::from(true))
}

pub fn update_solars(&mut self) -> eyre::Result<ByondValue> {
self.solars.retain(|solar| {
pub fn update_solars() -> eyre::Result<ByondValue> {
let mut solars_lock = SOLARS
.write()
.map_err(|_| eyre::eyre!("Failed to lock SOLARS"))?;

solars_lock.retain(|solar| {
solar.read_var("powernet").unwrap_or_default().is_null()
|| solar.call("update", &[]).is_ok()
});

Ok(ByondValue::from(true))
}

pub fn add_solar(&mut self, solar: ByondValue) -> eyre::Result<ByondValue> {
if self.solars.contains(&solar) {
return Ok(ByondValue::from(false));
}
pub fn add_solar(solar: ByondValue) -> eyre::Result<ByondValue> {
let mut solars_lock = SOLARS
.write()
.map_err(|_| eyre::eyre!("Failed to lock SOLARS"))?;

self.solars.push(solar);
solars_lock.push(solar);
Ok(ByondValue::from(true))
}

pub fn remove_solar(&mut self, solar: ByondValue) -> eyre::Result<ByondValue> {
self.solars.retain(|&element| element != solar);
pub fn remove_solar(solar: ByondValue) -> eyre::Result<ByondValue> {
let mut solars_lock = SOLARS
.write()
.map_err(|_| eyre::eyre!("Failed to lock SOLARS"))?;

solars_lock.retain(|element| element != &solar);
Ok(ByondValue::from(true))
}

pub fn get_dy(&self) -> eyre::Result<ByondValue> {
Ok(ByondValue::from(self.dy))
pub fn get_dy() -> eyre::Result<ByondValue> {
let dy_lock = DY.read().map_err(|_| eyre::eyre!("Failed to lock DY"))?;
Ok(ByondValue::from(*dy_lock))
}

pub fn get_dx(&self) -> eyre::Result<ByondValue> {
Ok(ByondValue::from(self.dx))
pub fn get_dx() -> eyre::Result<ByondValue> {
let dx_lock = DX.read().map_err(|_| eyre::eyre!("Failed to lock DX"))?;
Ok(ByondValue::from(*dx_lock))
}

pub fn get_solars(&self) -> eyre::Result<ByondValue> {
pub fn get_angle() -> eyre::Result<ByondValue> {
let angle_lock = ANGLE
.read()
.map_err(|_| eyre::eyre!("Failed to lock ANGLE"))?;

Ok(ByondValue::from(*angle_lock))
}

pub fn get_solars() -> eyre::Result<ByondValue> {
let solars_lock = SOLARS
.read()
.map_err(|_| eyre::eyre!("Failed to lock SOLARS"))?;

let mut byond_list = ByondValue::new_list()?;

for solar in &self.solars {
for solar in &*solars_lock {
byond_list.push_list(solar.clone())?;
}

Ok(byond_list)
}

pub fn get_angle(&self) -> eyre::Result<ByondValue> {
Ok(ByondValue::from(self.angle))
}
}
Loading