diff options
| author | Weicao Mao <1992414357@qq.com> | 2025-06-14 04:35:18 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-14 04:35:18 +0800 |
| commit | f0929789d5e3957082c41534eecd2ebf5dd38163 (patch) | |
| tree | 00692a012dde9ca06ffc725066228157e0e83ec8 /core/bindings | |
| parent | 8a87a67ac7eaed22b3d925b8a2d66e60c3847007 (diff) | |
| parent | f657a9c2056d4e5692ddbc19217b654277300c75 (diff) | |
Merge pull request #1 from CatilGrass/c_bindings
Merge to main
Diffstat (limited to 'core/bindings')
| -rw-r--r-- | core/bindings/c_lang/Cargo.toml | 12 | ||||
| -rw-r--r-- | core/bindings/c_lang/headers/ngpd_player.h | 39 | ||||
| -rw-r--r-- | core/bindings/c_lang/src/data/mod.rs | 1 | ||||
| -rw-r--r-- | core/bindings/c_lang/src/lib.rs | 1 | ||||
| -rw-r--r-- | core/bindings/lang/clang/Cargo.toml | 16 | ||||
| -rw-r--r-- | core/bindings/lang/clang/build.rs | 61 | ||||
| -rw-r--r-- | core/bindings/lang/clang/configures/nogamepads_data.toml | 17 | ||||
| -rw-r--r-- | core/bindings/lang/clang/headers/nogamepads_data.h | 181 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/converter/mod.rs | 1 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/converter/string_converter.rs | 24 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/data/mod.rs | 3 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/data/ngpd_game_info.rs | 109 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/data/ngpd_message.rs | 486 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/data/ngpd_player.rs (renamed from core/bindings/c_lang/src/data/ngpd_player.rs) | 16 | ||||
| -rw-r--r-- | core/bindings/lang/clang/src/lib.rs | 2 |
15 files changed, 908 insertions, 61 deletions
diff --git a/core/bindings/c_lang/Cargo.toml b/core/bindings/c_lang/Cargo.toml deleted file mode 100644 index a0ee61f..0000000 --- a/core/bindings/c_lang/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "nogamepads-c-bindings" -edition = "2024" -version.workspace = true - -[dependencies] -nogamepads-core = { path = "../../../core" } -libc = "0.2.172" - -[lib] -name = "nogamepads_c" -crate-type = ["cdylib"] diff --git a/core/bindings/c_lang/headers/ngpd_player.h b/core/bindings/c_lang/headers/ngpd_player.h deleted file mode 100644 index 00fbe5b..0000000 --- a/core/bindings/c_lang/headers/ngpd_player.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef PLAYER_FFI_H -#define PLAYER_FFI_H - -#include <stdbool.h> -#include <stdint.h> - -typedef struct FfiAccount { - char* id; - char* player_hash; -} FfiAccount; - -typedef struct FfiCustomize { - char* nickname; - int32_t color_hue; - double color_saturation; - double color_value; -} FfiCustomize; - -typedef struct FfiPlayer { - FfiAccount account; - FfiCustomize* customize; -} FfiPlayer; - -#ifdef __cplusplus -extern "C" { -#endif - -FfiPlayer* player_register(const char* id, const char* password); -bool player_check(const FfiPlayer* player, const char* password); -void player_set_nickname(FfiPlayer* player, const char* nickname); -void player_set_hue(FfiPlayer* player, int hue); -void player_set_hsv(FfiPlayer* player, int hue, double saturation, double value); -void player_free(FfiPlayer* player); - -#ifdef __cplusplus -} -#endif - -#endif
\ No newline at end of file diff --git a/core/bindings/c_lang/src/data/mod.rs b/core/bindings/c_lang/src/data/mod.rs deleted file mode 100644 index 32af6d8..0000000 --- a/core/bindings/c_lang/src/data/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod ngpd_player;
\ No newline at end of file diff --git a/core/bindings/c_lang/src/lib.rs b/core/bindings/c_lang/src/lib.rs deleted file mode 100644 index 12e35bb..0000000 --- a/core/bindings/c_lang/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod data;
\ No newline at end of file diff --git a/core/bindings/lang/clang/Cargo.toml b/core/bindings/lang/clang/Cargo.toml new file mode 100644 index 0000000..7359db0 --- /dev/null +++ b/core/bindings/lang/clang/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "nogamepads-c-bindings" +edition = "2024" +version.workspace = true + +build = "build.rs" + +[dependencies] +nogamepads-core = { path = "./../../../../core" } + +[build-dependencies] +cbindgen = "0.29.0" + +[lib] +name = "nogamepads_c" +crate-type = ["cdylib", "rlib"] diff --git a/core/bindings/lang/clang/build.rs b/core/bindings/lang/clang/build.rs new file mode 100644 index 0000000..190501e --- /dev/null +++ b/core/bindings/lang/clang/build.rs @@ -0,0 +1,61 @@ +fn main() { + // Get the project root directory + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); + let root_path = std::path::Path::new(&manifest_dir); + + // Input configuration directory path + let config_dir = root_path.join("configures"); + + // Output directory path (headers folder in the crate directory) + let headers_dir = root_path.join("headers"); + + // Clear existing headers directory (if it exists) + if headers_dir.exists() { + std::fs::remove_dir_all(&headers_dir).expect("Failed to remove headers directory"); + } + + // Create a new headers directory + std::fs::create_dir_all(&headers_dir).expect("Failed to create headers directory"); + + // Find all TOML files in configures directory + let config_files = std::fs::read_dir(&config_dir) + .expect("Failed to read configures directory") + .filter_map(|entry| { + let entry = entry.expect("Failed to read directory entry"); + let path = entry.path(); + if path.is_file() && path.extension().map_or(false, |ext| ext == "toml") { + Some(path) + } else { + None + } + }); + + // Process each configuration file + for config_path in config_files { + // Extract filename without extension + let file_stem = config_path.file_stem() + .and_then(|s| s.to_str()) + .expect("Invalid filename") + .to_string(); + + // Set output file path + let output_file = headers_dir.join(format!("{}.h", file_stem)); + + // Load configuration from current TOML file + let config = cbindgen::Config::from_file(&config_path) + .expect(&format!("Failed to parse configuration: {}", config_path.display())); + + // Generate header file + cbindgen::Builder::new() + .with_crate(&manifest_dir) + .with_config(config) + .generate() + .expect(&format!("Failed to generate header for: {}", config_path.display())) + .write_to_file(&output_file); + } + + // Print rerun instructions + println!("cargo:rerun-if-changed={}", config_dir.display()); + println!("cargo:rerun-if-changed=src/mycode.rs"); + println!("cargo:rerun-if-changed=build.rs"); +}
\ No newline at end of file diff --git a/core/bindings/lang/clang/configures/nogamepads_data.toml b/core/bindings/lang/clang/configures/nogamepads_data.toml new file mode 100644 index 0000000..56d645d --- /dev/null +++ b/core/bindings/lang/clang/configures/nogamepads_data.toml @@ -0,0 +1,17 @@ +language = "C" +include_guard = "NOGAMEPADS_DATA_H" +header = "// Auto generated by cbindgen 0.29.0" +cpp_compat = true + +[parse] +parse_deps = true +include = [ + "string_converter", + + "ngpd_game_info", + "ngpd_message", + "ngpd_player" +] + +[fn] +prefix = "ngpd_data_"
\ No newline at end of file diff --git a/core/bindings/lang/clang/headers/nogamepads_data.h b/core/bindings/lang/clang/headers/nogamepads_data.h new file mode 100644 index 0000000..6d9f1ad --- /dev/null +++ b/core/bindings/lang/clang/headers/nogamepads_data.h @@ -0,0 +1,181 @@ +// Auto generated by cbindgen 0.29.0 + +#ifndef NOGAMEPADS_DATA_H +#define NOGAMEPADS_DATA_H + +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +typedef enum FfiConnectionMessageTag { + Join, + RequestGameInfos, + RequestLayoutConfigure, + RequestSkinPackage, + Ready, + Err, +} FfiConnectionMessageTag; + +typedef enum FfiConnectionResponseMessageTag { + GameInfos, + Deny, + Fail, + Ok, + Welcome, + Err, +} FfiConnectionResponseMessageTag; + +typedef enum FfiControlMessageTag { + Msg, + Pressed, + Released, + Axis, + Dir, + Exit, + Err, + End, +} FfiControlMessageTag; + +typedef enum FfiExitReason { + Exit, + GameOver, + ServerClosed, + YouAreKicked, + YouAreBanned, + Err, +} FfiExitReason; + +typedef enum FfiGameMessageTag { + EventTrigger, + Msg, + LetExit, + Err, + End, +} FfiGameMessageTag; + +typedef enum FfiJoinFailedMessage { + ContainIdenticalPlayer, + PlayerBanned, + GameLocked, + UnknownError, +} FfiJoinFailedMessage; + +typedef struct FfiAccount { + char *id; + char *player_hash; +} FfiAccount; + +typedef struct FfiCustomize { + char *nickname; + int color_hue; + double color_saturation; + double color_value; +} FfiCustomize; + +typedef struct FfiPlayer { + struct FfiAccount account; + struct FfiCustomize *customize; +} FfiPlayer; + +typedef struct FfiKeyAndAxis { + uint8_t key; + double axis; +} FfiKeyAndAxis; + +typedef struct FfiKeyAndDirection { + uint8_t key; + double x; + double y; +} FfiKeyAndDirection; + +typedef union FfiControlMessageUnion { + char *message; + uint8_t key; + struct FfiKeyAndAxis key_and_axis; + struct FfiKeyAndDirection key_and_direction; +} FfiControlMessageUnion; + +typedef struct FfiControlMessage { + enum FfiControlMessageTag tag; + union FfiControlMessageUnion data; +} FfiControlMessage; + +typedef union FfiGameMessageUnion { + uint8_t key; + char *message; + enum FfiExitReason exit_reason; +} FfiGameMessageUnion; + +typedef struct FfiGameMessage { + enum FfiGameMessageTag tag; + union FfiGameMessageUnion data; +} FfiGameMessage; + +typedef union FfiConnectionMessageUnion { + struct FfiPlayer player; +} FfiConnectionMessageUnion; + +typedef struct FfiConnectionMessage { + enum FfiConnectionMessageTag tag; + union FfiConnectionMessageUnion data; +} FfiConnectionMessage; + +typedef struct KeyValuePair { + char *key; + char *value; +} KeyValuePair; + +typedef struct FfiGameInfo { + struct KeyValuePair *data; + uintptr_t len; + uintptr_t cap; +} FfiGameInfo; + +typedef union FfiConnectionResponseMessageUnion { + struct FfiGameInfo game_info; + enum FfiJoinFailedMessage failed_message; +} FfiConnectionResponseMessageUnion; + +typedef struct FfiConnectionResponseMessage { + enum FfiConnectionResponseMessageTag tag; + union FfiConnectionResponseMessageUnion data; +} FfiConnectionResponseMessage; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +ngpd_data_ void free_c_string(char *ptr); + +ngpd_data_ struct FfiPlayer *player_register(const char *id, const char *password); + +ngpd_data_ bool player_check(const struct FfiPlayer *player, const char *password); + +ngpd_data_ void player_set_nickname(struct FfiPlayer *player, const char *nickname); + +ngpd_data_ void player_set_hue(struct FfiPlayer *player, int hue); + +ngpd_data_ void player_set_hsv(struct FfiPlayer *player, int hue, double saturation, double value); + +ngpd_data_ void player_free(struct FfiPlayer *player); + +ngpd_data_ void free_control_message(struct FfiControlMessage msg); + +ngpd_data_ void free_game_message(struct FfiGameMessage msg); + +ngpd_data_ void free_exit_reason(enum FfiExitReason msg); + +ngpd_data_ void free_connection_message(struct FfiConnectionMessage msg); + +ngpd_data_ void free_connection_response_message(struct FfiConnectionResponseMessage msg); + +ngpd_data_ void free_join_failed_message(enum FfiJoinFailedMessage msg); + +ngpd_data_ void free_game_info(struct FfiGameInfo map); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif /* NOGAMEPADS_DATA_H */ diff --git a/core/bindings/lang/clang/src/converter/mod.rs b/core/bindings/lang/clang/src/converter/mod.rs new file mode 100644 index 0000000..86708b0 --- /dev/null +++ b/core/bindings/lang/clang/src/converter/mod.rs @@ -0,0 +1 @@ +pub mod string_converter;
\ No newline at end of file diff --git a/core/bindings/lang/clang/src/converter/string_converter.rs b/core/bindings/lang/clang/src/converter/string_converter.rs new file mode 100644 index 0000000..7345f5a --- /dev/null +++ b/core/bindings/lang/clang/src/converter/string_converter.rs @@ -0,0 +1,24 @@ +use std::ffi::{c_char, CStr, CString}; + +pub unsafe fn str_rs_to_c(content: String) -> *mut c_char { + let c_str = CString::new(content).expect("CString::new failed"); + + c_str.into_raw() +} + +pub unsafe fn str_c_to_rs(content_ptr: *mut c_char) -> String { + let c_str = unsafe { CStr::from_ptr(content_ptr) }; + + c_str.to_str() + .expect("Invalid UTF-8 sequence") + .to_owned() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn free_c_string(ptr: *mut c_char) { + if ptr.is_null() { + return; + } + + let _ = unsafe { CString::from_raw(ptr) }; +}
\ No newline at end of file diff --git a/core/bindings/lang/clang/src/data/mod.rs b/core/bindings/lang/clang/src/data/mod.rs new file mode 100644 index 0000000..c93e7f0 --- /dev/null +++ b/core/bindings/lang/clang/src/data/mod.rs @@ -0,0 +1,3 @@ +pub mod ngpd_player; +pub mod ngpd_message; +mod ngpd_game_info;
\ No newline at end of file diff --git a/core/bindings/lang/clang/src/data/ngpd_game_info.rs b/core/bindings/lang/clang/src/data/ngpd_game_info.rs new file mode 100644 index 0000000..af45758 --- /dev/null +++ b/core/bindings/lang/clang/src/data/ngpd_game_info.rs @@ -0,0 +1,109 @@ +use std::collections::HashMap; +use std::ffi::{CStr, CString}; +use std::os::raw::c_char; + +#[repr(C)] +pub struct KeyValuePair { + key: *mut c_char, + value: *mut c_char, +} + +#[repr(C)] +pub struct FfiGameInfo { + data: *mut KeyValuePair, + len: usize, + cap: usize, +} + +impl From<&HashMap<String, String>> for FfiGameInfo { + fn from(map: &HashMap<String, String>) -> Self { + let mut kv_pairs: Vec<KeyValuePair> = map + .into_iter() + .map(|(k, v)| { + KeyValuePair { + key: CString::new(k.clone()).unwrap().into_raw(), + value: CString::new(v.clone()).unwrap().into_raw(), + } + }) + .collect(); + + let cap = kv_pairs.capacity(); + let len = kv_pairs.len(); + let data_ptr = kv_pairs.as_mut_ptr(); + + std::mem::forget(kv_pairs); + + FfiGameInfo { + data: data_ptr, + len, + cap, + } + } +} + +impl TryFrom<&FfiGameInfo> for HashMap<String, String> { + type Error = String; + + fn try_from(ffi_info: &FfiGameInfo) -> Result<Self, Self::Error> { + if ffi_info.len == 0 { + return Ok(HashMap::new()); + } + + if ffi_info.data.is_null() { + return Err("FfiGameInfo data pointer is null".to_string()); + } + + let kv_slice = unsafe { + std::slice::from_raw_parts(ffi_info.data, ffi_info.len) + }; + + let mut map = HashMap::with_capacity(ffi_info.len); + + for (i, pair) in kv_slice.iter().enumerate() { + if pair.key.is_null() { + return Err(format!("Key pointer is null at index {}", i)); + } + + if pair.value.is_null() { + return Err(format!("Value pointer is null at index {}", i)); + } + + let key_str = unsafe { + CStr::from_ptr(pair.key) + .to_str() + .map_err(|_| "Invalid UTF-8 in key")? + }; + + let value_str = unsafe { + CStr::from_ptr(pair.value) + .to_str() + .map_err(|_| "Invalid UTF-8 in value")? + }; + + map.insert(key_str.to_owned(), value_str.to_owned()); + } + + Ok(map) + } +} + +impl From<&FfiGameInfo> for Option<HashMap<String, String>> { + fn from(ffi_info: &FfiGameInfo) -> Self { + match HashMap::try_from(ffi_info) { + Ok(map) => Some(map), + Err(_) => None, + } + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn free_game_info(map: FfiGameInfo) { + let kv_pairs = unsafe { Vec::from_raw_parts(map.data, map.len, map.cap) }; + + for pair in kv_pairs { + unsafe { + let _ = CString::from_raw(pair.key); + let _ = CString::from_raw(pair.value); + } + } +}
\ No newline at end of file diff --git a/core/bindings/lang/clang/src/data/ngpd_message.rs b/core/bindings/lang/clang/src/data/ngpd_message.rs new file mode 100644 index 0000000..c669299 --- /dev/null +++ b/core/bindings/lang/clang/src/data/ngpd_message.rs @@ -0,0 +1,486 @@ +use crate::converter::string_converter::{str_c_to_rs, str_rs_to_c}; +use crate::data::ngpd_game_info::FfiGameInfo; +use crate::data::ngpd_player::FfiPlayer; +use nogamepads_core::data::message::message_enums::{ConnectionMessage, ConnectionResponseMessage, ControlMessage, ExitReason, GameMessage, JoinFailedMessage}; +use std::mem::ManuallyDrop; +use std::ops::Deref; +use std::os::raw::{c_char, c_double}; + +#[repr(C)] +pub struct FfiControlMessage { + pub tag: FfiControlMessageTag, + pub data: FfiControlMessageUnion +} + +#[repr(C)] +pub enum FfiControlMessageTag { + Msg, Pressed, Released, Axis, Dir, Exit, Err, End +} + +#[repr(C)] +pub union FfiControlMessageUnion { + pub none: (), + pub message: *mut c_char, + pub key: u8, + pub key_and_axis: ManuallyDrop<FfiKeyAndAxis>, + pub key_and_direction: ManuallyDrop<FfiKeyAndDirection>, +} + +#[repr(C)] +pub struct FfiKeyAndAxis { + pub key: u8, + pub axis: c_double +} + +#[repr(C)] +pub struct FfiKeyAndDirection { + pub key: u8, + pub x: c_double, + pub y: c_double +} + +#[repr(C)] +pub struct FfiGameMessage { + pub tag: FfiGameMessageTag, + pub data: FfiGameMessageUnion +} + +#[repr(C)] +pub enum FfiGameMessageTag { + EventTrigger, Msg, LetExit, Err, End +} + +#[repr(C)] +pub union FfiGameMessageUnion { + pub none: (), + pub key: u8, + pub message: *mut c_char, + pub exit_reason: ManuallyDrop<FfiExitReason>, +} + +#[repr(C)] +pub enum FfiExitReason { + Exit, GameOver, ServerClosed, YouAreKicked, YouAreBanned, Err +} + +#[repr(C)] +pub struct FfiConnectionMessage { + pub tag: FfiConnectionMessageTag, + pub data: FfiConnectionMessageUnion +} + +#[repr(C)] +pub enum FfiConnectionMessageTag { + Join, RequestGameInfos, RequestLayoutConfigure, RequestSkinPackage, Ready, Err +} + +#[repr(C)] +pub union FfiConnectionMessageUnion { + pub none: (), + pub player: ManuallyDrop<FfiPlayer> +} + +#[repr(C)] +pub struct FfiConnectionResponseMessage { + pub tag: FfiConnectionResponseMessageTag, + pub data: FfiConnectionResponseMessageUnion +} + +#[repr(C)] +pub enum FfiConnectionResponseMessageTag { + GameInfos, Deny, Fail, Ok, Welcome, Err +} + +#[repr(C)] +pub union FfiConnectionResponseMessageUnion { + pub none: (), + pub game_info: ManuallyDrop<FfiGameInfo>, + pub failed_message: ManuallyDrop<FfiJoinFailedMessage> +} + +#[repr(C)] +pub enum FfiJoinFailedMessage { + ContainIdenticalPlayer, PlayerBanned, GameLocked, UnknownError +} + +impl From<ControlMessage> for FfiControlMessage { + fn from(value: ControlMessage) -> Self { + match value { + ControlMessage::Msg(msg) => unsafe { + FfiControlMessage { + tag: FfiControlMessageTag::Msg, + data: FfiControlMessageUnion { + message: str_rs_to_c(msg), + } + } + } + ControlMessage::Pressed(key) => { + FfiControlMessage { + tag: FfiControlMessageTag::Pressed, + data: FfiControlMessageUnion { + key: key.into() + } + } + } + ControlMessage::Released(key) => { + FfiControlMessage { + tag: FfiControlMessageTag::Released, + data: FfiControlMessageUnion { + key: key.into() + } + } + } + ControlMessage::Axis(key, axis) => { + FfiControlMessage { + tag: FfiControlMessageTag::Axis, + data: FfiControlMessageUnion { + key_and_axis: ManuallyDrop::new(FfiKeyAndAxis { + key: key.into(), + axis: axis.into() + }) + } + } + } + ControlMessage::Dir(key, (x, y)) => { + FfiControlMessage { + tag: FfiControlMessageTag::Axis, + data: FfiControlMessageUnion { + key_and_direction: ManuallyDrop::new(FfiKeyAndDirection { + key: key.into(), + x, y + }) + } + } + } + ControlMessage::Exit => { + FfiControlMessage { + tag: FfiControlMessageTag::Axis, + data: FfiControlMessageUnion { none: () } + } + } + ControlMessage::Err => { + FfiControlMessage { + tag: FfiControlMessageTag::Axis, + data: FfiControlMessageUnion { none: () } + } + } + ControlMessage::End => { + FfiControlMessage { + tag: FfiControlMessageTag::Axis, + data: FfiControlMessageUnion { none: () } + } + } + } + } +} + +impl From<FfiControlMessage> for ControlMessage { + fn from(value: FfiControlMessage) -> Self { + match value.tag { + FfiControlMessageTag::Msg => unsafe { + ControlMessage::Msg(str_c_to_rs(value.data.message)) + } + FfiControlMessageTag::Pressed => unsafe { + ControlMessage::Pressed(value.data.key.into()) + } + FfiControlMessageTag::Released => unsafe { + ControlMessage::Released(value.data.key.into()) + } + FfiControlMessageTag::Axis => { + let value = unsafe { value.data.key_and_axis }; + ControlMessage::Axis(value.key.into(), value.axis.into()) + } + FfiControlMessageTag::Dir => { + let value = unsafe { value.data.key_and_direction }; + ControlMessage::Dir(value.key.into(), (value.x.into(), value.y.into())) + } + FfiControlMessageTag::Exit => { + ControlMessage::Exit + } + FfiControlMessageTag::Err => { + ControlMessage::Err + } + FfiControlMessageTag::End => { + ControlMessage::End + } + } + } +} + +impl From<GameMessage> for FfiGameMessage { + fn from(value: GameMessage) -> Self { + match value { + GameMessage::EventTrigger(key) => { + FfiGameMessage { + tag: FfiGameMessageTag::EventTrigger, + data: FfiGameMessageUnion { + key: key.into() + } + } + } + GameMessage::Msg(msg) => unsafe { + FfiGameMessage { + tag: FfiGameMessageTag::Msg, + data: FfiGameMessageUnion { + message: str_rs_to_c(msg) + } + } + } + GameMessage::LetExit(reason) => { + FfiGameMessage { + tag: FfiGameMessageTag::LetExit, + data: FfiGameMessageUnion { + exit_reason: ManuallyDrop::new(FfiExitReason::from(&reason)) + } + } + } + GameMessage::Err => { + FfiGameMessage { + tag: FfiGameMessageTag::Err, + data: FfiGameMessageUnion { none: () } + } + } + GameMessage::End => { + FfiGameMessage { + tag: FfiGameMessageTag::End, + data: FfiGameMessageUnion { none: () } + } + } + } + } +} + +impl From<FfiGameMessage> for GameMessage { + fn from(value: FfiGameMessage) -> Self { + match value.tag { + FfiGameMessageTag::EventTrigger => unsafe { + GameMessage::EventTrigger(value.data.key.into()) + } + FfiGameMessageTag::Msg => unsafe { + GameMessage::Msg(str_c_to_rs(value.data.message)) + } + FfiGameMessageTag::LetExit => unsafe { + GameMessage::LetExit(value.data.exit_reason.deref().into()) + } + FfiGameMessageTag::Err => { + GameMessage::Err + } + FfiGameMessageTag::End => { + GameMessage::End + } + } + } +} + +impl From<&ExitReason> for FfiExitReason { + fn from(value: &ExitReason) -> Self { + match value { + ExitReason::Exit => { FfiExitReason::Exit } + ExitReason::GameOver => { FfiExitReason::GameOver } + ExitReason::ServerClosed => { FfiExitReason::ServerClosed } + ExitReason::YouAreKicked => { FfiExitReason::YouAreKicked } + ExitReason::YouAreBanned => { FfiExitReason::YouAreBanned } + ExitReason::Err => { FfiExitReason::Err } + } + } +} + +impl From<&FfiExitReason> for ExitReason { + fn from(value: &FfiExitReason) -> Self { + match value { + FfiExitReason::Exit => { ExitReason::Exit } + FfiExitReason::GameOver => { ExitReason::GameOver } + FfiExitReason::ServerClosed => { ExitReason::ServerClosed } + FfiExitReason::YouAreKicked => { ExitReason::YouAreKicked } + FfiExitReason::YouAreBanned => { ExitReason::YouAreBanned } + FfiExitReason::Err => { ExitReason::Err } + } + } +} + +impl From<ConnectionMessage> for FfiConnectionMessage { + fn from(value: ConnectionMessage) -> Self { + match value { + ConnectionMessage::Join(player) => { + let c_player : FfiPlayer = (&player).into(); + FfiConnectionMessage { + tag: FfiConnectionMessageTag::Join, + data: FfiConnectionMessageUnion { + player: ManuallyDrop::new(c_player), + } + } + } + ConnectionMessage::RequestGameInfos => { + FfiConnectionMessage { + tag: FfiConnectionMessageTag::RequestGameInfos, + data: FfiConnectionMessageUnion { none: () } + } + } + ConnectionMessage::RequestLayoutConfigure => { + FfiConnectionMessage { + tag: FfiConnectionMessageTag::RequestLayoutConfigure, + data: FfiConnectionMessageUnion { none: () } + } + } + ConnectionMessage::RequestSkinPackage => { + FfiConnectionMessage { + tag: FfiConnectionMessageTag::RequestSkinPackage, + data: FfiConnectionMessageUnion { none: () } + } + } + ConnectionMessage::Ready => { + FfiConnectionMessage { + tag: FfiConnectionMessageTag::Ready, + data: FfiConnectionMessageUnion { none: () } + } + } + ConnectionMessage::Err => { + FfiConnectionMessage { + tag: FfiConnectionMessageTag::Err, + data: FfiConnectionMessageUnion { none: () } + } + } + } + } +} + +impl From<FfiConnectionMessage> for ConnectionMessage { + fn from(value: FfiConnectionMessage) -> Self { + match value.tag { + FfiConnectionMessageTag::Join => unsafe { + ConnectionMessage::Join(value.data.player.deref().try_into().unwrap_or_default()) + } + FfiConnectionMessageTag::RequestGameInfos => { ConnectionMessage::RequestGameInfos } + FfiConnectionMessageTag::RequestLayoutConfigure => { ConnectionMessage::RequestLayoutConfigure } + FfiConnectionMessageTag::RequestSkinPackage => { ConnectionMessage::RequestSkinPackage } + FfiConnectionMessageTag::Ready => { ConnectionMessage::Ready } + FfiConnectionMessageTag::Err => { ConnectionMessage::Err } + } + } +} + +impl From<ConnectionResponseMessage> for FfiConnectionResponseMessage { + fn from(value: ConnectionResponseMessage) -> Self { + match value { + ConnectionResponseMessage::GameInfos(info) => { + FfiConnectionResponseMessage { + tag: FfiConnectionResponseMessageTag::GameInfos, + data: FfiConnectionResponseMessageUnion { + game_info: ManuallyDrop::new((&info).into()) + } + } + } + ConnectionResponseMessage::Deny(fail) => { + FfiConnectionResponseMessage { + tag: FfiConnectionResponseMessageTag::Deny, + data: FfiConnectionResponseMessageUnion { + failed_message: ManuallyDrop::new((&fail).into()) + } + } + } + ConnectionResponseMessage::Fail(fail) => { + FfiConnectionResponseMessage { + tag: FfiConnectionResponseMessageTag::Fail, + data: FfiConnectionResponseMessageUnion { + failed_message: ManuallyDrop::new((&fail).into()) + } + } + } + ConnectionResponseMessage::Ok => { + FfiConnectionResponseMessage { + tag: FfiConnectionResponseMessageTag::Ok, + data: FfiConnectionResponseMessageUnion { none: () } + } + } + ConnectionResponseMessage::Welcome => { + FfiConnectionResponseMessage { + tag: FfiConnectionResponseMessageTag::Welcome, + data: FfiConnectionResponseMessageUnion { none: () } + } + } + ConnectionResponseMessage::Err => { + FfiConnectionResponseMessage { + tag: FfiConnectionResponseMessageTag::Err, + data: FfiConnectionResponseMessageUnion { none: () } + } + } + } + } +} + +impl From<FfiConnectionResponseMessage> for ConnectionResponseMessage { + fn from(value: FfiConnectionResponseMessage) -> Self { + match value.tag { + FfiConnectionResponseMessageTag::GameInfos => unsafe { + ConnectionResponseMessage::GameInfos(value.data.game_info.deref().try_into().unwrap_or_default()) + } + FfiConnectionResponseMessageTag::Deny => unsafe { + ConnectionResponseMessage::Deny(value.data.failed_message.deref().try_into().unwrap_or_default()) + } + FfiConnectionResponseMessageTag::Fail => unsafe { + ConnectionResponseMessage::Fail(value.data.failed_message.deref().try_into().unwrap_or_default()) + } + FfiConnectionResponseMessageTag::Ok => { + ConnectionResponseMessage::Ok + } + FfiConnectionResponseMessageTag::Welcome => { + ConnectionResponseMessage::Welcome + } + FfiConnectionResponseMessageTag::Err => { + ConnectionResponseMessage::Err + } + } + } +} + +impl From<&JoinFailedMessage> for FfiJoinFailedMessage { + fn from(value: &JoinFailedMessage) -> Self { + match value { + JoinFailedMessage::ContainIdenticalPlayer => { FfiJoinFailedMessage::ContainIdenticalPlayer } + JoinFailedMessage::PlayerBanned => { FfiJoinFailedMessage::PlayerBanned } + JoinFailedMessage::GameLocked => { FfiJoinFailedMessage::GameLocked } + JoinFailedMessage::UnknownError => { FfiJoinFailedMessage::UnknownError } + } + } +} + +impl From<&FfiJoinFailedMessage> for JoinFailedMessage { + fn from(value: &FfiJoinFailedMessage) -> Self { + match value { + FfiJoinFailedMessage::ContainIdenticalPlayer => { JoinFailedMessage::ContainIdenticalPlayer } + FfiJoinFailedMessage::PlayerBanned => { JoinFailedMessage::PlayerBanned } + FfiJoinFailedMessage::GameLocked => { JoinFailedMessage::GameLocked } + FfiJoinFailedMessage::UnknownError => { JoinFailedMessage::UnknownError } + } + } +} + +#[unsafe(no_mangle)] +pub extern "C" fn free_control_message(msg: FfiControlMessage) { + let _ = msg; +} + +#[unsafe(no_mangle)] +pub extern "C" fn free_game_message(msg: FfiGameMessage) { + let _ = msg; +} + +#[unsafe(no_mangle)] +pub extern "C" fn free_exit_reason(msg: FfiExitReason) { + let _ = msg; +} + +#[unsafe(no_mangle)] +pub extern "C" fn free_connection_message(msg: FfiConnectionMessage) { + let _ = msg; +} + +#[unsafe(no_mangle)] +pub extern "C" fn free_connection_response_message(msg: FfiConnectionResponseMessage) { + let _ = msg; +} + +#[unsafe(no_mangle)] +pub extern "C" fn free_join_failed_message(msg: FfiJoinFailedMessage) { + let _ = msg; +}
\ No newline at end of file diff --git a/core/bindings/c_lang/src/data/ngpd_player.rs b/core/bindings/lang/clang/src/data/ngpd_player.rs index 2ab615c..a1a8370 100644 --- a/core/bindings/c_lang/src/data/ngpd_player.rs +++ b/core/bindings/lang/clang/src/data/ngpd_player.rs @@ -32,10 +32,10 @@ impl From<Account> for FfiAccount { } } -impl From<Player> for FfiPlayer { - fn from(player: Player) -> Self { - let account = FfiAccount::from(player.account); - let customize = player.customize.map(|c| { +impl From<&Player> for FfiPlayer { + fn from(player: &Player) -> Self { + let account = FfiAccount::from(player.account.clone()); + let customize = player.clone().customize.map(|c| { Box::into_raw(Box::new(FfiCustomize { nickname: CString::new(c.nickname).unwrap().into_raw(), color_hue: c.color_hue, @@ -79,7 +79,7 @@ pub extern "C" fn player_register(id: *const c_char, password: *const c_char) -> let pass_str = unsafe { CStr::from_ptr(password) }.to_string_lossy(); let player = Player::register(id_str.into_owned(), pass_str.into_owned()); - Box::into_raw(Box::new(FfiPlayer::from(player))) + Box::into_raw(Box::new(FfiPlayer::from(&player))) } #[unsafe(no_mangle)] @@ -98,7 +98,7 @@ pub extern "C" fn player_set_nickname(player: *mut FfiPlayer, nickname: *const c let mut rust_player : Player = unsafe { (&*player).try_into().unwrap() }; rust_player.nickname(&nickname_str); - *unsafe { &mut *player } = FfiPlayer::from(rust_player); + *unsafe { &mut *player } = FfiPlayer::from(&rust_player); } #[unsafe(no_mangle)] @@ -106,7 +106,7 @@ pub extern "C" fn player_set_hue(player: *mut FfiPlayer, hue: c_int) { let mut rust_player : Player = unsafe { (&*player).try_into().unwrap() }; rust_player.hue(hue); - *unsafe { &mut *player } = FfiPlayer::from(rust_player); + *unsafe { &mut *player } = FfiPlayer::from(&rust_player); } #[unsafe(no_mangle)] @@ -116,7 +116,7 @@ pub extern "C" fn player_set_hsv( let mut rust_player : Player = unsafe { (&*player).try_into().unwrap() }; rust_player.hsv(hue, saturation, value); - *unsafe { &mut *player } = FfiPlayer::from(rust_player); + *unsafe { &mut *player } = FfiPlayer::from(&rust_player); } #[unsafe(no_mangle)] diff --git a/core/bindings/lang/clang/src/lib.rs b/core/bindings/lang/clang/src/lib.rs new file mode 100644 index 0000000..9a8fe37 --- /dev/null +++ b/core/bindings/lang/clang/src/lib.rs @@ -0,0 +1,2 @@ +pub mod converter; +pub mod data; |
