use std::sync::{Arc, Mutex};
pub struct EngineState {
rotation: Arc<Mutex<f32>>,
pub(crate) input_state: Arc<Mutex<crate::input::InputState>>,
}
impl Clone for EngineState {
fn clone(&self) -> Self {
Self {
rotation: self.rotation.clone(),
input_state: self.input_state.clone(),
}
}
}
impl EngineState {
pub fn new() -> Self {
Self {
rotation: Arc::new(Mutex::new(0.0)),
input_state: Arc::new(Mutex::new(crate::input::InputState::new())),
}
}
pub fn set_rotation(&self, angle: f32) {
if let Ok(mut rot) = self.rotation.lock() {
*rot = angle;
}
}
pub fn get_rotation(&self) -> f32 {
self.rotation.lock().map(|r| *r).unwrap_or(0.0)
}
pub fn is_key_pressed(&self, key_code: u32) -> bool {
if let Ok(input) = self.input_state.lock() {
if let Some(code) = crate::input::u32_to_key_code(key_code) {
return input.is_key_pressed(code);
}
}
false
}
pub fn get_mouse_position(&self) -> (f32, f32) {
if let Ok(input) = self.input_state.lock() {
return input.mouse_position();
}
(0.0, 0.0)
}
pub fn get_mouse_delta(&self) -> (f32, f32) {
if let Ok(input) = self.input_state.lock() {
return input.mouse_delta();
}
(0.0, 0.0)
}
}
static mut ENGINE_STATE_PTR: *mut EngineState = std::ptr::null_mut();
#[no_mangle]
pub extern "C" fn engine_register_state_ptr(ptr: *mut EngineState) {
unsafe {
ENGINE_STATE_PTR = ptr;
}
}
#[no_mangle]
pub extern "C" fn engine_set_rotation_callback(angle: f32) {
unsafe {
if !ENGINE_STATE_PTR.is_null() {
(*ENGINE_STATE_PTR).set_rotation(angle);
}
}
}
#[no_mangle]
pub extern "C" fn engine_get_rotation_callback() -> f32 {
unsafe {
if !ENGINE_STATE_PTR.is_null() {
(*ENGINE_STATE_PTR).get_rotation()
} else {
0.0
}
}
}
#[no_mangle]
pub extern "C" fn engine_is_key_pressed(key_code: u32) -> bool {
unsafe {
if !ENGINE_STATE_PTR.is_null() {
(*ENGINE_STATE_PTR).is_key_pressed(key_code)
} else {
false
}
}
}
#[no_mangle]
pub extern "C" fn engine_get_mouse_x() -> f32 {
unsafe {
if !ENGINE_STATE_PTR.is_null() {
(*ENGINE_STATE_PTR).get_mouse_position().0
} else {
0.0
}
}
}
#[no_mangle]
pub extern "C" fn engine_get_mouse_y() -> f32 {
unsafe {
if !ENGINE_STATE_PTR.is_null() {
(*ENGINE_STATE_PTR).get_mouse_position().1
} else {
0.0
}
}
}
#[no_mangle]
pub extern "C" fn engine_get_mouse_delta_x() -> f32 {
unsafe {
if !ENGINE_STATE_PTR.is_null() {
(*ENGINE_STATE_PTR).get_mouse_delta().0
} else {
0.0
}
}
}
#[no_mangle]
pub extern "C" fn engine_get_mouse_delta_y() -> f32 {
unsafe {
if !ENGINE_STATE_PTR.is_null() {
(*ENGINE_STATE_PTR).get_mouse_delta().1
} else {
0.0
}
}
}
static mut CAMERA_PTR: *mut crate::camera::Camera = std::ptr::null_mut();
#[no_mangle]
pub extern "C" fn engine_register_camera_ptr(ptr: *mut crate::camera::Camera) {
unsafe {
CAMERA_PTR = ptr;
eprintln!("DEBUG: engine_register_camera_ptr called with ptr: {:p}", ptr);
}
}
#[no_mangle]
pub extern "C" fn engine_camera_set_position(x: f32, y: f32, z: f32) {
unsafe {
if !CAMERA_PTR.is_null() {
(*CAMERA_PTR).set_position(x, y, z);
}
}
}
#[no_mangle]
pub extern "C" fn engine_camera_set_rotation(pitch: f32, yaw: f32) {
unsafe {
if !CAMERA_PTR.is_null() {
(*CAMERA_PTR).set_rotation(pitch, yaw);
}
}
}
#[no_mangle]
pub extern "C" fn engine_camera_translate(dx: f32, dy: f32, dz: f32) {
unsafe {
if CAMERA_PTR.is_null() {
eprintln!("DEBUG: CAMERA_PTR is null in engine_camera_translate!");
return;
}
(*CAMERA_PTR).translate(dx, dy, dz);
}
}
#[no_mangle]
pub extern "C" fn engine_camera_set_fov(fov: f32) {
unsafe {
if !CAMERA_PTR.is_null() {
(*CAMERA_PTR).set_fov(fov);
}
}
}
pub fn init_bridge() -> EngineState {
let state = EngineState::new();
let state_ptr = Box::leak(Box::new(EngineState {
rotation: state.rotation.clone(),
input_state: state.input_state.clone(),
}));
unsafe {
ENGINE_STATE_PTR = state_ptr;
}
state
}
pub fn get_rotation(state: &EngineState) -> f32 {
state.get_rotation()
}