aboutsummaryrefslogtreecommitdiff
path: root/core/bindings/lang/clang/src
diff options
context:
space:
mode:
author1992414357@qq.com <1992414357@qq.com>2025-06-18 02:52:12 +0800
committer1992414357@qq.com <1992414357@qq.com>2025-06-18 02:52:12 +0800
commit768e2d50fdbf8a2de8b57e7363cf26d95dbdc015 (patch)
treeea4c3f8f5d2683765642dd53c133b859bd280ac3 /core/bindings/lang/clang/src
parent37f6816105f165610eca06432b798f99f9d4325a (diff)
Finished CBindings
Diffstat (limited to 'core/bindings/lang/clang/src')
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_controller.rs121
-rw-r--r--core/bindings/lang/clang/src/data/ngpd_game.rs355
-rw-r--r--core/bindings/lang/clang/src/lib.rs1
-rw-r--r--core/bindings/lang/clang/src/logger_utils.rs13
-rw-r--r--core/bindings/lang/clang/src/service/ngpd_service_types.rs4
-rw-r--r--core/bindings/lang/clang/src/service/ngpd_tcp_service.rs68
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