diff options
| author | 1992414357@qq.com <1992414357@qq.com> | 2025-06-18 02:52:12 +0800 |
|---|---|---|
| committer | 1992414357@qq.com <1992414357@qq.com> | 2025-06-18 02:52:12 +0800 |
| commit | 768e2d50fdbf8a2de8b57e7363cf26d95dbdc015 (patch) | |
| tree | ea4c3f8f5d2683765642dd53c133b859bd280ac3 /core/bindings/lang/clang/src | |
| parent | 37f6816105f165610eca06432b798f99f9d4325a (diff) | |
Finished CBindings
Diffstat (limited to 'core/bindings/lang/clang/src')
| -rw-r--r-- | core/bindings/lang/clang/src/data/ngpd_controller.rs | 121 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/data/ngpd_game.rs | 355 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/lib.rs | 1 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/logger_utils.rs | 13 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/service/ngpd_service_types.rs | 4 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/service/ngpd_tcp_service.rs | 68 |
6 files changed, 353 insertions, 209 deletions
diff --git a/core/bindings/lang/clang/src/data/ngpd_controller.rs b/core/bindings/lang/clang/src/data/ngpd_controller.rs index d7f7b96..3c710fb 100644 --- a/core/bindings/lang/clang/src/data/ngpd_controller.rs +++ b/core/bindings/lang/clang/src/data/ngpd_controller.rs @@ -6,7 +6,8 @@ use nogamepads_core::data::controller::controller_runtime::ControllerRuntime; use nogamepads_core::data::message::message_enums::ControlMessage; use nogamepads_core::data::player::player_data::Player; use std::ffi::{c_char, c_double, c_void, CStr}; -use std::sync::{Arc, Mutex}; +use std::ptr::null_mut; +use std::sync::{Arc, Mutex, MutexGuard}; #[repr(C)] pub struct FfiControllerData(*mut c_void); @@ -29,13 +30,11 @@ impl FfiControllerData { /// Bind player to controller #[unsafe(no_mangle)] - #[allow(unsafe_op_in_unsafe_fn)] pub extern "C" fn controller_data_bind_player( controller: *mut FfiControllerData, ffi_player: *mut FfiPlayer ) { - assert!(!controller.is_null(), "ControllerData pointer is null"); - assert!(!ffi_player.is_null(), "FfiPlayer pointer is null"); + if controller.is_null() || ffi_player.is_null() { return; } let ffi_player_ref = unsafe { &*ffi_player }; @@ -52,39 +51,32 @@ impl FfiControllerData { /// Build runtime #[unsafe(no_mangle)] - #[allow(unsafe_op_in_unsafe_fn)] pub extern "C" fn controller_data_build_runtime( controller: *mut FfiControllerData ) -> *mut FfiControllerRuntime { - assert!(!controller.is_null(), "ControllerData pointer is null"); + let controller_inner = unsafe { &mut *((*controller).0 as *mut ControllerData) }; + let arc = controller_inner.runtime_with_borrowed_data(); + let ptr = Arc::into_raw(arc) as *mut c_void; - // Take ownership - let controller_box = unsafe { Box::from_raw(controller) }; - let raw_data = controller_box.0; + let ffi_runtime = Box::new(FfiControllerRuntime { + inner: ptr, + drop_fn: Self::drop_controller_runtime, + }); - // Convert ControllerData - let controller_data: Box<ControllerData> = unsafe { Box::from_raw(raw_data as *mut ControllerData) }; + Box::into_raw(ffi_runtime) + } - // Define custom drop function - extern "C" fn drop_runtime(raw: *mut c_void) { + extern "C" fn drop_controller_runtime(ptr: *mut c_void) { + if !ptr.is_null() { unsafe { - let arc_ptr = raw as *const Arc<Mutex<ControllerRuntime>>; - drop(Arc::from_raw(arc_ptr)); + let _ = Arc::<Mutex<ControllerRuntime>>::from_raw(ptr as *mut _); } } - - // Convert to an FFI-safe structure - let arc_raw = Arc::into_raw(controller_data.runtime()) as *mut c_void; - - Box::into_raw(Box::new(FfiControllerRuntime { - inner: arc_raw, - drop_fn: drop_runtime, - })) } /// Free ControllerData memory #[unsafe(no_mangle)] - pub extern "C" fn controller_data_free(controller: *mut FfiControllerData) { + pub extern "C" fn free_controller_data(controller: *mut FfiControllerData) { if controller.is_null() { return; } @@ -103,6 +95,43 @@ impl FfiControllerData { // ControllerRuntime implementation impl FfiControllerRuntime { + fn operate_controller_runtime( + runtime: *mut FfiControllerRuntime, + callback: fn(guard: &mut MutexGuard<ControllerRuntime>) + ) { + unsafe { + let ffi_runtime = &*runtime; + Arc::increment_strong_count(ffi_runtime.inner); + let arc = Arc::<Mutex<ControllerRuntime>>::from_raw(ffi_runtime.inner as *mut _); + let arc_clone = Arc::clone(&arc); + let _ = Arc::into_raw(arc); + entry_mutex!(arc_clone, |guard| { + callback(guard); + }); + Arc::decrement_strong_count(ffi_runtime.inner); + } + } + + fn operate_controller_runtime_with_return<Input, Result>( + runtime: *mut FfiControllerRuntime, + input: Input, + callback: fn(guard: &mut MutexGuard<ControllerRuntime>, input: Input) -> Option<Result> + ) -> Option<Result> { + unsafe { + let ffi_runtime = &*runtime; + Arc::increment_strong_count(ffi_runtime.inner); + let arc = Arc::<Mutex<ControllerRuntime>>::from_raw(ffi_runtime.inner as *mut _); + let arc_clone = Arc::clone(&arc); + let _ = Arc::into_raw(arc); + let mut result = None; + entry_mutex!(arc_clone, |guard| { + result = callback(guard, input); + }); + Arc::decrement_strong_count(ffi_runtime.inner); + result + } + } + /// Close runtime and exit game #[unsafe(no_mangle)] pub extern "C" fn controller_runtime_close( @@ -112,15 +141,9 @@ impl FfiControllerRuntime { return; } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - - entry_mutex!(arc_ref, |mutex_guard| { - mutex_guard.close(); + Self::operate_controller_runtime(runtime, |guard| { + guard.close(); }); - - // Reconstruct Arc - let _ = Arc::into_raw(arc_ref); } /// Send control message @@ -133,19 +156,12 @@ impl FfiControllerRuntime { return; } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; + let msg = unsafe { ControlMessage::from(control_message.read()) }; - let msg = unsafe { - let boxed_msg = Box::from_raw(control_message); - ControlMessage::from(*boxed_msg) - }; - - entry_mutex!(arc_ref, |mutex_guard| { - mutex_guard.send_message(msg); + Self::operate_controller_runtime_with_return(runtime, msg, |guard, input| { + guard.send_message(input); + Some(()) }); - - let _ = Arc::into_raw(arc_ref); } /// Send text message @@ -257,20 +273,19 @@ impl FfiControllerRuntime { runtime: *mut FfiControllerRuntime ) -> *mut FfiGameMessage { if runtime.is_null() { - return std::ptr::null_mut(); + return null_mut(); } let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; + let arc_ref = unsafe { Arc::from_raw(arc_ptr).clone() }; let result = { - let mut pop_result = None; - - entry_mutex!(arc_ref, |mutex_guard| { - pop_result = mutex_guard.pop(); - }); - - pop_result + Self::operate_controller_runtime_with_return(runtime, (), |guard, _| { + match guard.pop() { + None => { None } + Some(msg) => { Some(msg) } + } + }) }; // Reconstruct Arc @@ -281,7 +296,7 @@ impl FfiControllerRuntime { let ffi_msg = Box::new(FfiGameMessage::from(msg)); Box::into_raw(ffi_msg) } else { - std::ptr::null_mut() + null_mut() } } diff --git a/core/bindings/lang/clang/src/data/ngpd_game.rs b/core/bindings/lang/clang/src/data/ngpd_game.rs index 829c5ed..2892ecc 100644 --- a/core/bindings/lang/clang/src/data/ngpd_game.rs +++ b/core/bindings/lang/clang/src/data/ngpd_game.rs @@ -8,7 +8,6 @@ use nogamepads_core::data::message::message_enums::{ExitReason, GameMessage}; use nogamepads_core::data::player::player_data::Player; use nogamepads_core::service::service_types::ServiceType; use std::ffi::{c_char, c_double, c_void, CStr}; -use std::ptr::null; use std::sync::{Arc, Mutex, MutexGuard}; #[repr(C)] @@ -72,6 +71,68 @@ impl FfiGameData { raw } + /// Add info + #[unsafe(no_mangle)] + pub extern "C" fn game_data_add_info( + data: *mut FfiGameData, + key: *const c_char, + value: *const c_char, + ) -> *mut FfiGameData { + + if data.is_null() || key.is_null() || value.is_null() { + return std::ptr::null_mut(); + } + + let key_str = unsafe { CStr::from_ptr(key) }.to_string_lossy().into_owned(); + let value_str = unsafe { CStr::from_ptr(value) }.to_string_lossy().into_owned(); + + let data_inner = unsafe { &mut *((*data).0 as *mut GameData) }; + data_inner.info(key_str, value_str); + + let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(data)) as *mut _))); + raw + } + + /// Set name info + #[unsafe(no_mangle)] + pub extern "C" fn game_data_set_name_info( + data: *mut FfiGameData, + name: *const c_char, + ) -> *mut FfiGameData { + + if data.is_null() || name.is_null() { + return std::ptr::null_mut(); + } + + let name_str = unsafe { CStr::from_ptr(name) }.to_string_lossy().into_owned(); + + let data_inner = unsafe { &mut *((*data).0 as *mut GameData) }; + data_inner.name(name_str); + + let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(data)) as *mut _))); + raw + } + + /// Set version info + #[unsafe(no_mangle)] + pub extern "C" fn game_data_set_version_info( + data: *mut FfiGameData, + version: *const c_char, + ) -> *mut FfiGameData { + + if data.is_null() || version.is_null() { + return std::ptr::null_mut(); + } + + let version_str = unsafe { CStr::from_ptr(version) }.to_string_lossy().into_owned(); + + let data_inner = unsafe { &mut *((*data).0 as *mut GameData) }; + data_inner.version(version_str); + + let raw = Box::into_raw(Box::new(FfiGameData(Box::into_raw(Box::new(data)) as *mut _))); + raw + } + /// Load data archive #[unsafe(no_mangle)] pub extern "C" fn game_data_load_archive( @@ -104,24 +165,25 @@ impl FfiGameData { return std::ptr::null_mut(); } - let data_inner = unsafe { data.read() }; - let raw_data = data_inner.0; + let data_inner = unsafe { &mut *((*data).0 as *mut GameData) }; - let game_data: Box<GameData> = unsafe { Box::from_raw(raw_data as *mut GameData) }; + let arc = data_inner.runtime_with_borrowed_data(); + let ptr = Arc::into_raw(arc) as *mut c_void; - extern "C" fn drop_runtime(raw: *mut c_void) { + let ffi_runtime = Box::new(FfiGameRuntime { + inner: ptr, + drop_fn: Self::drop_game_runtime, + }); + + Box::into_raw(ffi_runtime) + } + + extern "C" fn drop_game_runtime(ptr: *mut c_void) { + if !ptr.is_null() { unsafe { - let arc_ptr = raw as *const Arc<Mutex<GameRuntime>>; - drop(Arc::from_raw(arc_ptr)); + let _ = Arc::<Mutex<GameRuntime>>::from_raw(ptr as *mut _); } } - - let arc_raw = Arc::into_raw(game_data.runtime()) as *mut c_void; - - Box::into_raw(Box::new(FfiGameRuntime { - inner: arc_raw, - drop_fn: drop_runtime, - })) } /// Free data @@ -183,34 +245,62 @@ impl FfiGameRuntimeArchive { impl FfiGameRuntime { + fn operate_game_runtime( + runtime: *mut FfiGameRuntime, + callback: fn(guard: &mut MutexGuard<GameRuntime>) + ) { + unsafe { + let ffi_runtime = &*runtime; + Arc::increment_strong_count(ffi_runtime.inner); + let arc = Arc::<Mutex<GameRuntime>>::from_raw(ffi_runtime.inner as *mut _); + let arc_clone = Arc::clone(&arc); + let _ = Arc::into_raw(arc); + entry_mutex!(arc_clone, |guard| { + callback(guard); + }); + Arc::decrement_strong_count(ffi_runtime.inner); + } + } + + fn operate_game_runtime_with_return<Input, Result>( + runtime: *mut FfiGameRuntime, + input: Input, + callback: fn(guard: &mut MutexGuard<GameRuntime>, input: Input) -> Option<Result> + ) -> Option<Result> { + unsafe { + let ffi_runtime = &*runtime; + Arc::increment_strong_count(ffi_runtime.inner); + let arc = Arc::<Mutex<GameRuntime>>::from_raw(ffi_runtime.inner as *mut _); + let arc_clone = Arc::clone(&arc); + let _ = Arc::into_raw(arc); + let mut result = None; + entry_mutex!(arc_clone, |guard| { + result = callback(guard, input); + }); + Arc::decrement_strong_count(ffi_runtime.inner); + result + } + } + fn send_message_to( runtime: *mut FfiGameRuntime, player: *const FfiPlayer, - service_type: *mut FfiServiceType, + service_type: FfiServiceType, message: GameMessage, ) { if runtime.is_null() || player.is_null() { return; } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; + let ffi_player_ref = unsafe { &*player }; let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); - let service = unsafe { ServiceType::from(&service_type.read()) }; - entry_mutex!(arc_ref, |mutex_guard| { - mutex_guard.send_game_message(&player.account, message, service); - }); - } - - fn do_on_rt( - runtime: *mut FfiGameRuntime, - do_on: fn(guard: &mut MutexGuard<GameRuntime>) - ) { - if runtime.is_null() { return; } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; + let service = ServiceType::from(&service_type); - entry_mutex!(arc_ref, |mutex_guard| { - do_on(mutex_guard); + Self::operate_game_runtime_with_return( + runtime, + (&player.account, message, service), + |guard, (account, message, service)| { + guard.send_game_message(account, message, service); + Some(()) }); } @@ -220,7 +310,7 @@ impl FfiGameRuntime { runtime: *mut FfiGameRuntime, player: *const FfiPlayer, message: *mut FfiGameMessage, - service_type: *mut FfiServiceType + service_type: FfiServiceType ) { if message.is_null() { return; } let msg = unsafe { GameMessage::from(message.read()) }; @@ -232,7 +322,7 @@ impl FfiGameRuntime { pub extern "C" fn game_runtime_send_text_message( runtime: *mut FfiGameRuntime, player: *const FfiPlayer, - service_type: *mut FfiServiceType, + service_type: FfiServiceType, text: *const c_char ) { let text_str = unsafe { CStr::from_ptr(text) }.to_string_lossy().into_owned().to_string(); @@ -244,7 +334,7 @@ impl FfiGameRuntime { pub extern "C" fn game_runtime_send_event( runtime: *mut FfiGameRuntime, player: *const FfiPlayer, - service_type: *mut FfiServiceType, + service_type: FfiServiceType, key: u8 ) { Self::send_message_to(runtime, player, service_type, GameMessage::EventTrigger(key)); @@ -254,12 +344,13 @@ impl FfiGameRuntime { #[unsafe(no_mangle)] pub extern "C" fn game_runtime_pop_control_event(runtime: *mut FfiGameRuntime) -> *mut FfiControlEvent { if runtime.is_null() { return std::ptr::null_mut(); } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - let mut control_event = None; - entry_mutex!(arc_ref, |mutex_guard| { - control_event = mutex_guard.pop_control_event(); - }); + + let control_event = Self::operate_game_runtime_with_return( + runtime, + (), |guard, _| { + guard.pop_control_event() + }); + match control_event { None => { std::ptr::null_mut() } Some((account, message)) => { @@ -276,13 +367,21 @@ impl FfiGameRuntime { pub extern "C" fn game_runtime_let_exit( runtime: *mut FfiGameRuntime, player: *const FfiPlayer, - service_type: *mut FfiServiceType, - reason: *mut FfiExitReason + service_type: FfiServiceType, + reason: FfiExitReason ) { - if reason.is_null() { return; } - let reason = unsafe { reason.read() }; - let reason_msg = GameMessage::LetExit(ExitReason::from(&reason)); - Self::send_message_to(runtime, player, service_type, reason_msg); + if runtime.is_null() || player.is_null() { return; } + + let ffi_player_ref = unsafe { &*player }; + let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); + + Self::operate_game_runtime_with_return( + runtime, (&player.account, ExitReason::from(&reason), ServiceType::from(&service_type)), + |guard, (account, reason, service)| { + guard.let_account_exit(account, reason, service); + Some(()) + } + ); } /// Kick a player @@ -290,20 +389,20 @@ impl FfiGameRuntime { pub extern "C" fn game_runtime_kick_player( runtime: *mut FfiGameRuntime, player: *const FfiPlayer, - service_type: *mut FfiServiceType + service_type: FfiServiceType ) { - if runtime.is_null() || player.is_null() || service_type.is_null() { return; } + if runtime.is_null() || player.is_null() { return; } let ffi_player_ref = unsafe { &*player }; let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); - let service = unsafe { ServiceType::from(&service_type.read()) }; - if runtime.is_null() { return; } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - mutex_guard.kick_player(&player, service); - }); + Self::operate_game_runtime_with_return( + runtime, (&player, ServiceType::from(&service_type)), + |guard, (player, service)| { + guard.kick_player(player, service); + Some(()) + } + ); } /// Ban a player (And kick) @@ -311,20 +410,20 @@ impl FfiGameRuntime { pub extern "C" fn game_runtime_ban_player( runtime: *mut FfiGameRuntime, player: *const FfiPlayer, - service_type: *mut FfiServiceType + service_type: FfiServiceType ) { - if runtime.is_null() || player.is_null() || service_type.is_null() { return; } + if runtime.is_null() || player.is_null() { return; } let ffi_player_ref = unsafe { &*player }; let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); - let service = unsafe { ServiceType::from(&service_type.read()) }; - if runtime.is_null() { return; } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - mutex_guard.ban_player(&player, service); - }); + Self::operate_game_runtime_with_return( + runtime, (&player, ServiceType::from(&service_type)), + |guard, (player, service)| { + guard.ban_player(player, service); + Some(()) + } + ); } /// Pardon a player @@ -338,19 +437,20 @@ impl FfiGameRuntime { let ffi_player_ref = unsafe { &*player }; let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); - if runtime.is_null() { return; } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - mutex_guard.pardon_player(&player); - }); + Self::operate_game_runtime_with_return( + runtime, &player, + |guard, player| { + guard.pardon_player(player); + Some(()) + } + ); } /// Close runtime #[unsafe(no_mangle)] pub extern "C" fn game_runtime_close(runtime: *mut FfiGameRuntime) { if runtime.is_null() { return; } - Self::do_on_rt(runtime, |guard| { + Self::operate_game_runtime(runtime, |guard| { guard.close_game(); }) } @@ -359,7 +459,7 @@ impl FfiGameRuntime { #[unsafe(no_mangle)] pub extern "C" fn game_runtime_lock(runtime: *mut FfiGameRuntime) { if runtime.is_null() { return; } - Self::do_on_rt(runtime, |guard| { + Self::operate_game_runtime(runtime, |guard| { guard.lock_game(); }) } @@ -368,7 +468,7 @@ impl FfiGameRuntime { #[unsafe(no_mangle)] pub extern "C" fn game_runtime_unlock(runtime: *mut FfiGameRuntime) { if runtime.is_null() { return; } - Self::do_on_rt(runtime, |guard| { + Self::operate_game_runtime(runtime, |guard| { guard.unlock_game(); }) } @@ -377,15 +477,12 @@ impl FfiGameRuntime { #[unsafe(no_mangle)] pub extern "C" fn game_runtime_get_lock_status(runtime: *mut FfiGameRuntime) -> bool { if runtime.is_null() { return false; } - - let mut locked = false; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - locked = mutex_guard.is_game_locked(); + let result = Self::operate_game_runtime_with_return( + runtime, (), + |guard, _| { + Some(guard.is_game_locked()) }); - - locked + result.unwrap_or(false) } /// Get button status of player @@ -400,12 +497,11 @@ impl FfiGameRuntime { let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); let account = player.account; - let mut status = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - status = mutex_guard.control.get_button_status(&account, &key); - }); + let status = Self::operate_game_runtime_with_return( + runtime, (account, key), |guard, (account, key)| { + guard.control.get_button_status(&account, &key) + } + ); match status { None => { FfiButtonStatus { found: false, pressed: false, released: false } } @@ -427,12 +523,11 @@ impl FfiGameRuntime { let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); let account = player.account; - let mut status = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - status = mutex_guard.control.get_axis(&account, &key); - }); + let status = Self::operate_game_runtime_with_return( + runtime, (account, key), |guard, (account, key)| { + guard.control.get_axis(&account, &key) + } + ); match status { None => { FfiAxis { found: false, axis: 0.0 } } @@ -454,12 +549,11 @@ impl FfiGameRuntime { let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); let account = player.account; - let mut status = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - status = mutex_guard.control.get_direction(&account, &key); - }); + let status = Self::operate_game_runtime_with_return( + runtime, (account, key), |guard, (account, key)| { + guard.control.get_direction(&account, &key) + } + ); match status { None => { FfiDirection { found: false, x: 0.0, y: 0.0 } } @@ -474,23 +568,22 @@ impl FfiGameRuntime { pub extern "C" fn game_runtime_get_service_type( runtime: *mut FfiGameRuntime, player: *const FfiPlayer - ) -> *const FfiServiceType { + ) -> FfiServiceType { let ffi_player_ref = unsafe { &*player }; let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); let account = player.account; - let mut service_type = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - service_type = mutex_guard.data.get_service_type(&account); - }); + let service_type = Self::operate_game_runtime_with_return( + runtime, account, |guard, account| { + guard.data.get_service_type(&account) + } + ); match service_type { - None => { null() } + None => { FfiServiceType::BlueTooth } Some(r) => { - Box::into_raw(Box::new(FfiServiceType::from(&r))) + FfiServiceType::from(&r) } } } @@ -506,12 +599,11 @@ impl FfiGameRuntime { let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); let account = player.account; - let mut banned = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - banned = Some(mutex_guard.data.is_account_banned(&account)); - }); + let banned = Self::operate_game_runtime_with_return( + runtime, account, |guard, account| { + Some(guard.data.is_account_banned(&account)) + } + ); match banned { None => { FfiBooleanResult { found: false, result: false } } @@ -532,12 +624,11 @@ impl FfiGameRuntime { let player = Player::try_from(&*ffi_player_ref).unwrap_or_default(); let account = player.account; - let mut online = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - online = Some(mutex_guard.data.is_account_online(&account)); - }); + let online = Self::operate_game_runtime_with_return( + runtime, account, |guard, account| { + Some(guard.data.is_account_online(&account)) + } + ); match online { None => { FfiBooleanResult { found: false, result: false } } @@ -551,12 +642,11 @@ impl FfiGameRuntime { #[unsafe(no_mangle)] pub extern "C" fn game_runtime_get_online_list(runtime: *mut FfiGameRuntime) -> FfiPlayerList { - let mut online_list = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - online_list = Some(mutex_guard.data.online_accounts()); - }); + let online_list = Self::operate_game_runtime_with_return( + runtime, (), |guard, _| { + Some(guard.data.online_accounts()) + } + ); let mut result : Vec<FfiPlayer> = vec![]; if online_list.is_some() { @@ -579,12 +669,11 @@ impl FfiGameRuntime { #[unsafe(no_mangle)] pub extern "C" fn game_runtime_get_banned_list(runtime: *mut FfiGameRuntime) -> FfiPlayerList { - let mut banned_list = None; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::from_raw(arc_ptr) }; - entry_mutex!(arc_ref, |mutex_guard| { - banned_list = Some(mutex_guard.data.banned_accounts()); - }); + let banned_list = Self::operate_game_runtime_with_return( + runtime, (), |guard, _| { + Some(guard.data.banned_accounts()) + } + ); let mut result : Vec<FfiPlayer> = vec![]; if banned_list.is_none() { diff --git a/core/bindings/lang/clang/src/lib.rs b/core/bindings/lang/clang/src/lib.rs index f939758..08da79e 100644 --- a/core/bindings/lang/clang/src/lib.rs +++ b/core/bindings/lang/clang/src/lib.rs @@ -1,3 +1,4 @@ pub mod converter; pub mod data; pub mod service; +pub mod logger_utils; diff --git a/core/bindings/lang/clang/src/logger_utils.rs b/core/bindings/lang/clang/src/logger_utils.rs new file mode 100644 index 0000000..96bd0dc --- /dev/null +++ b/core/bindings/lang/clang/src/logger_utils.rs @@ -0,0 +1,13 @@ +use nogamepads::logger_utils::logger_build; + +#[unsafe(no_mangle)] +pub extern "C" fn enable_logger(level: u8) { + let level_filter = match level { + 0 => log::LevelFilter::Info, + 1 => log::LevelFilter::Debug, + 2 => log::LevelFilter::Trace, + _ => { log::LevelFilter::Info } + }; + + logger_build(level_filter); +}
\ No newline at end of file diff --git a/core/bindings/lang/clang/src/service/ngpd_service_types.rs b/core/bindings/lang/clang/src/service/ngpd_service_types.rs index 8701284..a11c2f1 100644 --- a/core/bindings/lang/clang/src/service/ngpd_service_types.rs +++ b/core/bindings/lang/clang/src/service/ngpd_service_types.rs @@ -2,6 +2,7 @@ use nogamepads_core::service::service_types::ServiceType; #[repr(C)] pub enum FfiServiceType { + Unknown, TCPConnection, BlueTooth, USB, @@ -23,6 +24,9 @@ impl From<&FfiServiceType> for ServiceType { FfiServiceType::TCPConnection => { ServiceType::TCPConnection } FfiServiceType::BlueTooth => { ServiceType::BlueTooth } FfiServiceType::USB => { ServiceType::USB } + _ => { + ServiceType::default() + } } } } diff --git a/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs b/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs index 2c8995c..6e706b5 100644 --- a/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs +++ b/core/bindings/lang/clang/src/service/ngpd_tcp_service.rs @@ -1,13 +1,14 @@ use crate::data::ngpd_controller::FfiControllerRuntime; use crate::data::ngpd_game::FfiGameRuntime; -use nogamepads_core::data::controller::controller_runtime::ControllerRuntime; -use nogamepads_core::data::game::game_runtime::GameRuntime; use nogamepads_core::service::tcp_network::pad_client::pad_client_service::PadClientNetwork; use nogamepads_core::service::tcp_network::pad_server::pad_server_service::PadServerNetwork; +use nogamepads_core::service::tcp_network::utils::tokio_utils::build_tokio_runtime; use std::ffi::{c_char, c_void, CStr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +use std::ptr::null_mut; use std::sync::{Arc, Mutex}; -use nogamepads_core::service::tcp_network::utils::tokio_utils::build_tokio_runtime; +use nogamepads_core::data::controller::controller_runtime::ControllerRuntime; +use nogamepads_core::data::game::game_runtime::GameRuntime; #[repr(C)] pub struct FfiTcpClientService(*mut c_void); @@ -24,16 +25,22 @@ impl FfiTcpClientService { ) -> *mut FfiTcpClientService { if runtime.is_null() { - return std::ptr::null_mut(); + return null_mut(); } - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<ControllerRuntime>> }; - let arc_ref = unsafe { Arc::clone(&*arc_ptr) }; + let runtime_ref = unsafe { &*runtime }; + let data_ptr = runtime_ref.inner as *const Mutex<ControllerRuntime>; + + let arc = unsafe { + let atomic_arc = Arc::from_raw(data_ptr); + Arc::clone(&atomic_arc) + }; - let service = PadClientNetwork::build(Arc::clone(&arc_ref)); - let raw = Box::into_raw(Box::new(FfiTcpClientService(Box::into_raw(Box::new(service)) as *mut _))); + let client = PadClientNetwork::build(arc.clone()); - raw + let client_box = Box::new(client); + let service = FfiTcpClientService(Box::into_raw(client_box) as *mut _); + Box::into_raw(Box::new(service)) } /// Bind ipv4 address @@ -160,12 +167,17 @@ impl FfiTcpClientService { pub extern "C" fn free_tcp_client( service: *mut FfiTcpClientService ) { - if service.is_null() { return; } + if service.is_null() { + return; + } - let service_ptr = service as *mut PadClientNetwork; + let wrapper = unsafe { Box::from_raw(service) }; + let client_ptr = wrapper.0; unsafe { - let _ = Box::from_raw(service_ptr); + if !client_ptr.is_null() { + let _ = Box::from_raw(client_ptr as *mut PadClientNetwork); + } } } } @@ -178,15 +190,23 @@ impl FfiTcpServerService { runtime: *mut FfiGameRuntime, ) -> *mut FfiTcpServerService { - if runtime.is_null() { return std::ptr::null_mut(); } + if runtime.is_null() { + return null_mut(); + } + + let runtime_ref = unsafe { &*runtime }; + let data_ptr = runtime_ref.inner as *const Mutex<GameRuntime>; - let arc_ptr = unsafe { (*runtime).inner as *const Arc<Mutex<GameRuntime>> }; - let arc_ref = unsafe { Arc::clone(&*arc_ptr) }; + let arc = unsafe { + let atomic_arc = Arc::from_raw(data_ptr); + Arc::clone(&atomic_arc) + }; - let service = PadServerNetwork::build(Arc::clone(&arc_ref)); - let raw = Box::into_raw(Box::new(FfiTcpServerService(Box::into_raw(Box::new(service)) as *mut _))); + let server = PadServerNetwork::build(arc.clone()); - raw + let server_box = Box::new(server); + let service = FfiTcpServerService(Box::into_raw(server_box) as *mut _); + Box::into_raw(Box::new(service)) } /// Bind ipv4 address @@ -305,12 +325,14 @@ impl FfiTcpServerService { pub extern "C" fn free_tcp_server( service: *mut FfiTcpServerService ) { - if service.is_null() { return; } - - let service_ptr = service as *mut PadServerNetwork; + if !service.is_null() { + unsafe { + let service = Box::from_raw(service); - unsafe { - let _ = Box::from_raw(service_ptr); + if !service.0.is_null() { + Arc::from_raw(service.0 as *mut _); + } + } } } }
\ No newline at end of file |
