diff --git a/src/core_ffi/CMakeLists.txt b/src/core_ffi/CMakeLists.txt index d28d493..36cdeab 100644 --- a/src/core_ffi/CMakeLists.txt +++ b/src/core_ffi/CMakeLists.txt @@ -20,8 +20,9 @@ if (KLSK_RUST_FFI) else() # just for IDE highlight add_library(klotski_rust - rust_ffi/adapter/common_code.cc - rust_ffi/target/cxxbridge/rust_ffi/src/common_code.rs.cc + rust_ffi/adapter/short_code.cc + rust_ffi/adapter/common_code.cc + rust_ffi/target/cxxbridge/rust_ffi/src/bridge.rs.cc ) target_include_directories(klotski_rust PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(klotski_rust PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/rust_ffi/target/cxxbridge) diff --git a/src/core_ffi/rust_ffi/adapter/common_code.cc b/src/core_ffi/rust_ffi/adapter/common_code.cc index dfe4343..973689a 100644 --- a/src/core_ffi/rust_ffi/adapter/common_code.cc +++ b/src/core_ffi/rust_ffi/adapter/common_code.cc @@ -4,7 +4,6 @@ #include using klotski::codec::RawCode; -using klotski::codec::ShortCode; using klotski::codec::CommonCode; using klotski::mover::MaskMover; @@ -13,15 +12,15 @@ using klotski::ffi::RsShortCode; using klotski::ffi::RsCommonCode; // TODO: it seems that cxx.rs not support `std::optional` -uint64_t klotski::ffi::common_code_from_str(rust::Str s) { - std::string_view sv {s.data(), s.length()}; +uint64_t klotski::ffi::common_code_from_str(const rust::Str s) { + const std::string_view sv {s.data(), s.length()}; if (const auto ret = CommonCode::from_string(sv); ret.has_value()) { return ret.value().unwrap(); } return 0x10FFFFFFFF; // return invalid value for now } -bool klotski::ffi::common_code_check(uint64_t val) { +bool klotski::ffi::common_code_check(const uint64_t val) { return CommonCode::check(val); } diff --git a/src/core_ffi/rust_ffi/adapter/short_code.cc b/src/core_ffi/rust_ffi/adapter/short_code.cc new file mode 100644 index 0000000..45b0836 --- /dev/null +++ b/src/core_ffi/rust_ffi/adapter/short_code.cc @@ -0,0 +1,32 @@ +#include "rust_ffi/include/short_code.h" + +#include + +using klotski::codec::ShortCode; + +using klotski::ffi::RsShortCode; +using klotski::ffi::RsCommonCode; + +bool klotski::ffi::short_code_check(const uint32_t val) { + return ShortCode::check(val); +} + +uint32_t klotski::ffi::short_code_from_str(const rust::Str s) { + const std::string_view sv {s.data(), s.length()}; + if (const auto ret = ShortCode::from_string(sv); ret.has_value()) { + return ret.value().unwrap(); + } + return 0xFFFFFFFF; // return invalid value for now +} + +rust::String RsShortCode::to_string() const noexcept { + return ShortCode::unsafe_create(code).to_string(); +} + +RsCommonCode RsShortCode::to_common_code() const noexcept { + return {ShortCode::unsafe_create(code).to_common_code().unwrap()}; +} + +void klotski::ffi::short_code_speed_up(const bool fast_mode) { + ShortCode::speed_up(fast_mode); +} diff --git a/src/core_ffi/rust_ffi/build.rs b/src/core_ffi/rust_ffi/build.rs index 1931ac0..c4a7ccc 100644 --- a/src/core_ffi/rust_ffi/build.rs +++ b/src/core_ffi/rust_ffi/build.rs @@ -13,7 +13,6 @@ use cxx_build::CFG; fn main() { let dst = cmake::Config::new("klotski") - // .build_target("klotski_core") .define("CARGO_BUILD:BOOL", "ON") .define("KLSK_ENABLE_TESTING:BOOL", "OFF") .define("KLSK_ENABLE_BENCHMARK:BOOL", "OFF") @@ -23,17 +22,19 @@ fn main() { CFG.include_prefix = "rust_ffi"; - cxx_build::bridge("src/common_code.rs") + cxx_build::bridge("src/bridge.rs") + .file("adapter/short_code.cc") .file("adapter/common_code.cc") + .include("klotski/src/core") .flag("-std=c++23") .flag("-fno-rtti") .flag("-fno-exceptions") - .include("klotski/src/core") .compile("klotski"); println!("cargo:rustc-link-search=native={}", dst.display()); println!("cargo:rustc-link-lib=static=klotski_core"); + println!("cargo:rerun-if-changed=src/bridge.rs"); + println!("cargo:rerun-if-changed=adapter/short_code.cc"); println!("cargo:rerun-if-changed=adapter/common_code.cc"); - println!("cargo:rerun-if-changed=src/common_code.rs"); } diff --git a/src/core_ffi/rust_ffi/include/common_code.h b/src/core_ffi/rust_ffi/include/common_code.h index 4a004c2..eb54c1c 100644 --- a/src/core_ffi/rust_ffi/include/common_code.h +++ b/src/core_ffi/rust_ffi/include/common_code.h @@ -1,11 +1,3 @@ #pragma once -#include "rust_ffi/src/common_code.rs.h" - -namespace klotski::ffi { - -bool common_code_check(uint64_t val); - -uint64_t common_code_from_str(rust::Str s); - -} // namespace klotski::ffi +#include "interface.h" diff --git a/src/core_ffi/rust_ffi/include/interface.h b/src/core_ffi/rust_ffi/include/interface.h new file mode 100644 index 0000000..35362e8 --- /dev/null +++ b/src/core_ffi/rust_ffi/include/interface.h @@ -0,0 +1,17 @@ +#pragma once + +#include "rust_ffi/src/bridge.rs.h" + +namespace klotski::ffi { + +bool short_code_check(uint32_t val); + +bool common_code_check(uint64_t val); + +uint32_t short_code_from_str(rust::Str s); + +uint64_t common_code_from_str(rust::Str s); + +void short_code_speed_up(bool fast_mode); + +} // namespace klotski::ffi diff --git a/src/core_ffi/rust_ffi/include/short_code.h b/src/core_ffi/rust_ffi/include/short_code.h new file mode 100644 index 0000000..eb54c1c --- /dev/null +++ b/src/core_ffi/rust_ffi/include/short_code.h @@ -0,0 +1,3 @@ +#pragma once + +#include "interface.h" diff --git a/src/core_ffi/rust_ffi/src/common_code.rs b/src/core_ffi/rust_ffi/src/bridge.rs similarity index 59% rename from src/core_ffi/rust_ffi/src/common_code.rs rename to src/core_ffi/rust_ffi/src/bridge.rs index 3434876..f0d5f8e 100644 --- a/src/core_ffi/rust_ffi/src/common_code.rs +++ b/src/core_ffi/rust_ffi/src/bridge.rs @@ -45,11 +45,22 @@ mod ffi { } unsafe extern "C++" { - // include!("rust_ffi/include/short_code.h"); + include!("rust_ffi/include/short_code.h"); - // fn short_code_from_str(s: &str) -> RsShortCode; + /// only for internal use + fn short_code_check(val: u32) -> bool; + + /// only for internal use + fn short_code_from_str(s: &str) -> u32; + + /// Convert ShortCode to string form. + fn to_string(self: &RsShortCode) -> String; - // TODO: speed_up interface + /// Convert ShortCode to CommonCode. + fn to_common_code(self: &RsShortCode) -> RsCommonCode; + + /// Build the conversion index for ShortCode. + fn short_code_speed_up(fast_mode: bool); } } @@ -63,12 +74,12 @@ impl CommonCode { } /// Create CommonCode without any check. - pub fn unsafe_create(code: u64) -> CommonCode { - CommonCode { code } + pub fn unsafe_create(code: u64) -> Self { + Self { code } } /// Create CommonCode with validity check. - pub fn create(code: u64) -> Option { + pub fn create(code: u64) -> Option { if Self::check(code) { return Some(Self::unsafe_create(code)); } @@ -76,12 +87,12 @@ impl CommonCode { } /// Get the original u64 code. - pub fn unwrap(self: &CommonCode) -> u64 { + pub fn unwrap(self: &Self) -> u64 { self.code } /// Create CommonCode from string form. - pub fn from_string(s: &str) -> Option { + pub fn from_string(s: &str) -> Option { let val = ffi::common_code_from_str(s); if val < 0x10_FFFF_FFFF { return Some(Self::unsafe_create(val)); @@ -90,6 +101,44 @@ impl CommonCode { } } +impl ShortCode { + /// Check the validity of the original ShortCode. + pub fn check(code: u32) -> bool { + ffi::short_code_check(code) + } + + /// Create ShortCode without any check. + pub fn unsafe_create(code: u32) -> Self { + Self { code } + } + + /// Create ShortCode with validity check. + pub fn create(code: u32) -> Option { + if Self::check(code) { + return Some(Self::unsafe_create(code)); + } + None + } + + /// Get the original u32 code. + pub fn unwrap(self: &Self) -> u32 { + self.code + } + + /// Create ShortCode from string form. + pub fn from_string(s: &str) -> Option { + let val = ffi::short_code_from_str(s); + if val != 0xFFFF_FFFF { + return Some(Self::unsafe_create(val)); + } + None + } + + pub fn speed_up(fast_mode: bool) { + ffi::short_code_speed_up(fast_mode) + } +} + impl PartialEq for CommonCode { fn eq(&self, other: &Self) -> bool { self.code == other.code diff --git a/src/core_ffi/rust_ffi/src/main.rs b/src/core_ffi/rust_ffi/src/main.rs index 09d6a14..c5cc900 100644 --- a/src/core_ffi/rust_ffi/src/main.rs +++ b/src/core_ffi/rust_ffi/src/main.rs @@ -1,8 +1,24 @@ -mod common_code; +mod bridge; -use common_code::CommonCode; +use bridge::ShortCode; +use bridge::CommonCode; -fn main() { +fn short_code_demo() { + ShortCode::speed_up(false); + ShortCode::speed_up(true); + + assert!(ShortCode::check(4091296)); + let code = ShortCode::create(4091296).unwrap(); + assert_eq!(code, ShortCode::from_string("4WVE1").unwrap()); + assert_eq!(code, ShortCode::create(4091296).unwrap()); + + println!("code: {:?}", code.unwrap()); + println!("string: {}", code.to_string()); + + println!("common_code: {:?}", code.to_common_code()); +} + +fn common_code_demo() { assert!(CommonCode::check(0x1A9BF0C00)); let code = CommonCode::create(0x1A9BF0C00).unwrap(); assert_eq!(code, CommonCode::from_string("1A9BF0C").unwrap()); @@ -23,3 +39,11 @@ fn main() { println!("next_cases: {:?}", code.next_cases()); } + +fn main() { + println!("----------------------------------------------------------------"); + short_code_demo(); + println!("----------------------------------------------------------------"); + common_code_demo(); + println!("----------------------------------------------------------------"); +}