mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
Remove Rust test
This commit is contained in:
parent
9efea584a0
commit
4cdff21b54
296
spine-c/tests/rust-wasm/Cargo.lock
generated
296
spine-c/tests/rust-wasm/Cargo.lock
generated
@ -1,296 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 4
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "1.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bindgen"
|
|
||||||
version = "0.70.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cexpr",
|
|
||||||
"clang-sys",
|
|
||||||
"itertools",
|
|
||||||
"log",
|
|
||||||
"prettyplease",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"regex",
|
|
||||||
"rustc-hash",
|
|
||||||
"shlex",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "2.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.2.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
|
|
||||||
dependencies = [
|
|
||||||
"shlex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cexpr"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
|
||||||
dependencies = [
|
|
||||||
"nom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clang-sys"
|
|
||||||
version = "1.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
|
||||||
dependencies = [
|
|
||||||
"glob",
|
|
||||||
"libc",
|
|
||||||
"libloading",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "either"
|
|
||||||
version = "1.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glob"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.174"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libloading"
|
|
||||||
version = "0.8.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"windows-targets",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.4.27"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.7.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "prettyplease"
|
|
||||||
version = "0.2.35"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.95"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-automata",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-automata"
|
|
||||||
version = "0.4.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.8.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-hash"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "shlex"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "spine-c-wasm-test"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"bindgen",
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "2.0.104"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-ident",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-ident"
|
|
||||||
version = "1.0.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.53.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_gnullvm",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "spine-c-wasm-test"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["cdylib"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
cc = "1.0"
|
|
||||||
bindgen = "0.70"
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
# Spine-C Rust WASM Test
|
|
||||||
|
|
||||||
A minimal test demonstrating Rust FFI with spine-c, proving the no-cpprt workflow for WASM compilation.
|
|
||||||
|
|
||||||
## What This Does
|
|
||||||
|
|
||||||
This test:
|
|
||||||
1. Loads a Spine atlas with texture callbacks (`spine_atlas_load_callback`)
|
|
||||||
2. Loads binary skeleton data (`spine_skeleton_data_load_binary`)
|
|
||||||
3. Creates a skeleton instance (`spine_skeleton_create`)
|
|
||||||
4. Runs basic skeleton operations (`spine_skeleton_setup_pose`, `spine_skeleton_update_world_transform_1`)
|
|
||||||
5. Reads skeleton position (`spine_skeleton_get_x/y`)
|
|
||||||
6. Cleans up all resources including atlas disposal with texture callbacks
|
|
||||||
|
|
||||||
## Build Process
|
|
||||||
|
|
||||||
The build script compiles:
|
|
||||||
- spine-cpp with no-cpprt variant (eliminates C++ standard library)
|
|
||||||
- spine-c wrapper (provides C-compatible FFI)
|
|
||||||
- Generates complete Rust FFI bindings via bindgen from spine-c.h
|
|
||||||
- Links everything into a single Rust executable/library
|
|
||||||
|
|
||||||
**Full API Coverage**: Bindgen automatically generates Rust bindings for the entire spine-c API, exposing all public functions without manual FFI maintenance.
|
|
||||||
|
|
||||||
spine-c/spine-cpp only rely on libc for `malloc`, `free` and various math functions, which can be easily stubbed on any target platform.
|
|
||||||
|
|
||||||
This proves Rust projects can use Spine without C++ stdlib dependencies, enabling WASM compilation via Rust toolchain instead of Emscripten.
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
- `src/lib.rs` - Rust FFI test calling spine-c functions via bindgen-generated bindings
|
|
||||||
- `build.rs` - Compiles spine-cpp-no-cpprt + spine-c via cc crate, generates FFI bindings with bindgen
|
|
||||||
- Test data: `../../../examples/spineboy/export/spineboy-*` (atlas, skeleton, texture)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo test -- --nocapture # Run test with debug output
|
|
||||||
cargo build # Build native
|
|
||||||
cargo build --target wasm32-unknown-unknown # Build WASM
|
|
||||||
```
|
|
||||||
|
|
||||||
**Status**: Fully working. Test executable: 1.8 MB. All spine-c functionality operational including atlas disposal.
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let target = env::var("TARGET").unwrap();
|
|
||||||
let is_wasm = target.starts_with("wasm32");
|
|
||||||
|
|
||||||
// Build spine-cpp with no-cpprt variant
|
|
||||||
let spine_cpp_dir = PathBuf::from("../../../spine-cpp");
|
|
||||||
let spine_c_dir = PathBuf::from("../..");
|
|
||||||
|
|
||||||
let mut cpp_build = cc::Build::new();
|
|
||||||
cpp_build
|
|
||||||
.cpp(true)
|
|
||||||
.include(spine_cpp_dir.join("include"))
|
|
||||||
.include(spine_c_dir.join("include"))
|
|
||||||
.include(spine_c_dir.join("src"))
|
|
||||||
.flag("-std=c++11");
|
|
||||||
|
|
||||||
// Always avoid C++ runtime (consistent with no-cpprt approach)
|
|
||||||
cpp_build
|
|
||||||
.flag("-fno-exceptions")
|
|
||||||
.flag("-fno-rtti");
|
|
||||||
|
|
||||||
// Always avoid C++ runtime (consistent with no-cpprt approach)
|
|
||||||
cpp_build.flag("-nostdlib++");
|
|
||||||
|
|
||||||
// Tell cc crate linker to not link libc++
|
|
||||||
cpp_build.flag_if_supported("-Wl,-undefined,dynamic_lookup");
|
|
||||||
cpp_build.cpp_link_stdlib(None);
|
|
||||||
|
|
||||||
if is_wasm {
|
|
||||||
// For WASM, we may need additional setup, but let's first try without extra flags
|
|
||||||
// The target is already handled by cc-rs when building for wasm32-unknown-unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spine-cpp source files (no-cpprt variant = all sources + no-cpprt.cpp)
|
|
||||||
let spine_cpp_src = spine_cpp_dir.join("src");
|
|
||||||
for entry in std::fs::read_dir(&spine_cpp_src).unwrap() {
|
|
||||||
let entry = entry.unwrap();
|
|
||||||
let path = entry.path();
|
|
||||||
if path.extension().map_or(false, |ext| ext == "cpp") {
|
|
||||||
cpp_build.file(&path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spine-cpp subdirectories
|
|
||||||
for subdir in &["spine", "spine-c", "utils"] {
|
|
||||||
let subdir_path = spine_cpp_src.join(subdir);
|
|
||||||
if subdir_path.exists() {
|
|
||||||
for entry in std::fs::read_dir(&subdir_path).unwrap() {
|
|
||||||
let entry = entry.unwrap();
|
|
||||||
let path = entry.path();
|
|
||||||
if path.extension().map_or(false, |ext| ext == "cpp") {
|
|
||||||
cpp_build.file(&path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spine-c generated sources
|
|
||||||
let spine_c_generated = spine_c_dir.join("src/generated");
|
|
||||||
for entry in std::fs::read_dir(&spine_c_generated).unwrap() {
|
|
||||||
let entry = entry.unwrap();
|
|
||||||
let path = entry.path();
|
|
||||||
if path.extension().map_or(false, |ext| ext == "cpp") {
|
|
||||||
cpp_build.file(&path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add spine-c extensions
|
|
||||||
cpp_build.file(spine_c_dir.join("src/extensions.cpp"));
|
|
||||||
|
|
||||||
// Add no-cpprt.cpp for C++ runtime stubs
|
|
||||||
cpp_build.file(spine_cpp_dir.join("src/no-cpprt.cpp"));
|
|
||||||
|
|
||||||
cpp_build.compile("spine");
|
|
||||||
|
|
||||||
// Generate bindings with bindgen
|
|
||||||
let bindings = bindgen::Builder::default()
|
|
||||||
.header("../../include/spine-c.h")
|
|
||||||
.clang_arg("-I../../include")
|
|
||||||
.clang_arg("-I../../../spine-cpp/include")
|
|
||||||
.clang_arg("-I../../src")
|
|
||||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
|
||||||
.generate()
|
|
||||||
.expect("Unable to generate bindings");
|
|
||||||
|
|
||||||
let out_path = std::path::PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
||||||
bindings
|
|
||||||
.write_to_file(out_path.join("bindings.rs"))
|
|
||||||
.expect("Couldn't write bindings!");
|
|
||||||
|
|
||||||
// Link libraries - no C++ stdlib since we're using no-cpprt variant
|
|
||||||
// The no-cpprt.cpp provides minimal runtime stubs
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=../../spine-cpp/src");
|
|
||||||
println!("cargo:rerun-if-changed=../../src");
|
|
||||||
println!("cargo:rerun-if-changed=../../include/spine-c.h");
|
|
||||||
}
|
|
||||||
@ -1,185 +0,0 @@
|
|||||||
use std::ffi::{CStr, CString};
|
|
||||||
use std::os::raw::{c_char, c_float, c_int, c_void};
|
|
||||||
|
|
||||||
// Include the generated bindings
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
|
||||||
|
|
||||||
// Headless texture loader functions with debug prints
|
|
||||||
extern "C" fn headless_texture_loader(path: *const c_char) -> *mut c_void {
|
|
||||||
unsafe {
|
|
||||||
let path_str = if !path.is_null() {
|
|
||||||
CStr::from_ptr(path).to_string_lossy()
|
|
||||||
} else {
|
|
||||||
"NULL".into()
|
|
||||||
};
|
|
||||||
println!("DEBUG: texture_loader called with path: {}", path_str);
|
|
||||||
|
|
||||||
let ptr = std::alloc::alloc(std::alloc::Layout::from_size_align(8, 8).unwrap());
|
|
||||||
println!("DEBUG: texture_loader returning: {:?}", ptr);
|
|
||||||
ptr as *mut c_void
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" fn headless_texture_unloader(texture: *mut c_void) -> () {
|
|
||||||
println!("DEBUG: texture_unloader called with texture: {:?}", texture);
|
|
||||||
|
|
||||||
if !texture.is_null() && texture as usize > 1 {
|
|
||||||
unsafe {
|
|
||||||
println!("DEBUG: deallocating texture: {:?}", texture);
|
|
||||||
std::alloc::dealloc(texture as *mut u8, std::alloc::Layout::from_size_align(8, 8).unwrap());
|
|
||||||
println!("DEBUG: texture deallocation completed");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println!("DEBUG: skipping deallocation (null or invalid pointer)");
|
|
||||||
}
|
|
||||||
println!("DEBUG: texture_unloader returning");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn test_spine_basic() -> c_int {
|
|
||||||
unsafe {
|
|
||||||
println!("Starting spine test...");
|
|
||||||
spine_bone_set_y_down(false);
|
|
||||||
println!("Set y_down...");
|
|
||||||
|
|
||||||
// Load real spineboy atlas data
|
|
||||||
let atlas_file = std::fs::read_to_string("../../../examples/spineboy/export/spineboy-pma.atlas")
|
|
||||||
.expect("Failed to read atlas file");
|
|
||||||
let atlas_data = CString::new(atlas_file).unwrap();
|
|
||||||
let atlas_dir = CString::new("../../../examples/spineboy/export/").unwrap();
|
|
||||||
|
|
||||||
println!("About to load atlas...");
|
|
||||||
let atlas = spine_atlas_load_callback(
|
|
||||||
atlas_data.as_ptr(),
|
|
||||||
atlas_dir.as_ptr(),
|
|
||||||
Some(headless_texture_loader),
|
|
||||||
Some(headless_texture_unloader),
|
|
||||||
);
|
|
||||||
println!("Atlas loaded: {:?}", atlas);
|
|
||||||
|
|
||||||
if atlas.is_null() {
|
|
||||||
println!("Atlas is null!");
|
|
||||||
return 1; // Failed to load atlas
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load real spineboy skeleton data (binary format like the C test)
|
|
||||||
println!("Reading skeleton file...");
|
|
||||||
let skeleton_file = std::fs::read("../../../examples/spineboy/export/spineboy-pro.skel")
|
|
||||||
.expect("Failed to read skeleton file");
|
|
||||||
println!("Skeleton file size: {} bytes", skeleton_file.len());
|
|
||||||
let skeleton_path = CString::new("../../../examples/spineboy/export/spineboy-pro.skel").unwrap();
|
|
||||||
|
|
||||||
println!("About to call spine_skeleton_data_load_binary...");
|
|
||||||
let result = spine_skeleton_data_load_binary(atlas, skeleton_file.as_ptr(), skeleton_file.len() as i32, skeleton_path.as_ptr());
|
|
||||||
println!("spine_skeleton_data_load_binary returned: {:?}", result);
|
|
||||||
|
|
||||||
if result.is_null() {
|
|
||||||
println!("Result is null!");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("About to call spine_skeleton_data_result_get_data...");
|
|
||||||
println!("Result pointer: {:?}", result);
|
|
||||||
println!("Result is null: {}", result.is_null());
|
|
||||||
|
|
||||||
// Try to read the error first to see if result is valid
|
|
||||||
println!("Checking if result has error...");
|
|
||||||
let error_ptr = spine_skeleton_data_result_get_error(result);
|
|
||||||
println!("Error check completed. Error ptr: {:?}", error_ptr);
|
|
||||||
|
|
||||||
if !error_ptr.is_null() {
|
|
||||||
let error_str = CStr::from_ptr(error_ptr);
|
|
||||||
println!("Found error: {:?}", error_str);
|
|
||||||
spine_skeleton_data_result_dispose(result);
|
|
||||||
spine_atlas_dispose(atlas);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("No error found, getting skeleton data...");
|
|
||||||
let skeleton_data = spine_skeleton_data_result_get_data(result);
|
|
||||||
|
|
||||||
if skeleton_data.is_null() {
|
|
||||||
let error = spine_skeleton_data_result_get_error(result);
|
|
||||||
if !error.is_null() {
|
|
||||||
let error_str = CStr::from_ptr(error);
|
|
||||||
eprintln!("Skeleton data error: {:?}", error_str);
|
|
||||||
}
|
|
||||||
spine_skeleton_data_result_dispose(result);
|
|
||||||
spine_atlas_dispose(atlas);
|
|
||||||
return 2; // Failed to load skeleton data
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Skeleton data is valid: {:?}", skeleton_data);
|
|
||||||
// Test skeleton creation immediately
|
|
||||||
println!("Creating skeleton...");
|
|
||||||
let skeleton = spine_skeleton_create(skeleton_data);
|
|
||||||
println!("Skeleton create returned: {:?}", skeleton);
|
|
||||||
if skeleton.is_null() {
|
|
||||||
spine_skeleton_data_result_dispose(result);
|
|
||||||
spine_atlas_dispose(atlas);
|
|
||||||
return 3; // Failed to create skeleton
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test basic operations
|
|
||||||
println!("Calling spine_skeleton_setup_pose...");
|
|
||||||
spine_skeleton_setup_pose(skeleton);
|
|
||||||
println!("Setup pose completed");
|
|
||||||
|
|
||||||
println!("Calling spine_skeleton_update_world_transform_1...");
|
|
||||||
spine_skeleton_update_world_transform_1(skeleton, 1); // SPINE_PHYSICS_UPDATE = 1
|
|
||||||
println!("Update world transform completed");
|
|
||||||
|
|
||||||
println!("Getting skeleton position...");
|
|
||||||
let x = spine_skeleton_get_x(skeleton);
|
|
||||||
println!("Got x: {}", x);
|
|
||||||
let y = spine_skeleton_get_y(skeleton);
|
|
||||||
println!("Got y: {}", y);
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
println!("Disposing skeleton...");
|
|
||||||
spine_skeleton_dispose(skeleton);
|
|
||||||
println!("Skeleton disposed");
|
|
||||||
|
|
||||||
println!("Disposing skeleton data result...");
|
|
||||||
spine_skeleton_data_result_dispose(result);
|
|
||||||
println!("Skeleton data result disposed");
|
|
||||||
|
|
||||||
// Test atlas disposal to get proper crash backtrace
|
|
||||||
println!("About to call spine_atlas_dispose - crash expected...");
|
|
||||||
spine_atlas_dispose(atlas);
|
|
||||||
println!("Atlas disposal completed successfully");
|
|
||||||
|
|
||||||
// Verify we got reasonable values
|
|
||||||
println!("Verifying values...");
|
|
||||||
if x.is_finite() && y.is_finite() {
|
|
||||||
println!("SUCCESS! Test completed successfully");
|
|
||||||
0 // Success
|
|
||||||
} else {
|
|
||||||
println!("FAILED! Invalid values");
|
|
||||||
4 // Invalid values
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WASM export for web testing
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
mod wasm {
|
|
||||||
use super::*;
|
|
||||||
use std::os::raw::c_int;
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn run_spine_test() -> c_int {
|
|
||||||
test_spine_basic()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_spine_basic_works() {
|
|
||||||
let result = test_spine_basic();
|
|
||||||
assert_eq!(result, 0, "Spine basic test should succeed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Spine-C WASM Test
|
|
||||||
#
|
|
||||||
# Tests spine-c + spine-cpp-no-cpprt compilation to WASM via Rust FFI
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Change to test directory
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
# Source logging utilities
|
|
||||||
source ../../../formatters/logging/logging.sh
|
|
||||||
|
|
||||||
log_title "Spine-C WASM Test"
|
|
||||||
|
|
||||||
# Check if Rust is installed
|
|
||||||
if ! command -v cargo > /dev/null 2>&1; then
|
|
||||||
log_fail "Cargo not found - install Rust toolchain"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if WASM target is installed
|
|
||||||
log_action "Checking WASM target"
|
|
||||||
if RUSTUP_OUTPUT=$(rustup target list --installed 2>&1); then
|
|
||||||
if echo "$RUSTUP_OUTPUT" | grep -q "wasm32-unknown-unknown"; then
|
|
||||||
log_ok
|
|
||||||
else
|
|
||||||
log_detail "Installing wasm32-unknown-unknown target"
|
|
||||||
if rustup target add wasm32-unknown-unknown > /dev/null 2>&1; then
|
|
||||||
log_ok
|
|
||||||
else
|
|
||||||
log_fail
|
|
||||||
log_detail "Failed to install WASM target"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_fail
|
|
||||||
log_detail "Could not check rustup targets"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build native version first (for comparison)
|
|
||||||
log_action "Building native version"
|
|
||||||
if BUILD_OUTPUT=$(cargo build 2>&1); then
|
|
||||||
log_ok
|
|
||||||
else
|
|
||||||
log_fail
|
|
||||||
log_error_output "$BUILD_OUTPUT"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test native version
|
|
||||||
log_action "Testing native version"
|
|
||||||
if TEST_OUTPUT=$(cargo test 2>&1); then
|
|
||||||
log_ok
|
|
||||||
else
|
|
||||||
log_fail
|
|
||||||
log_error_output "$TEST_OUTPUT"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build WASM version
|
|
||||||
log_action "Building WASM version"
|
|
||||||
if WASM_BUILD_OUTPUT=$(cargo build --target wasm32-unknown-unknown 2>&1); then
|
|
||||||
log_ok
|
|
||||||
else
|
|
||||||
log_fail
|
|
||||||
log_error_output "$WASM_BUILD_OUTPUT"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check WASM output
|
|
||||||
WASM_FILE="target/wasm32-unknown-unknown/debug/spine_c_wasm_test.wasm"
|
|
||||||
if [ -f "$WASM_FILE" ]; then
|
|
||||||
log_action "Analyzing WASM output"
|
|
||||||
WASM_SIZE=$(du -h "$WASM_FILE" | cut -f1)
|
|
||||||
log_ok
|
|
||||||
log_detail "WASM file size: $WASM_SIZE"
|
|
||||||
|
|
||||||
# Check for C++ runtime dependencies (should be minimal)
|
|
||||||
if command -v wasm-objdump > /dev/null 2>&1; then
|
|
||||||
log_detail "WASM imports:"
|
|
||||||
wasm-objdump -x "$WASM_FILE" | grep -A 20 "Import\[" | head -20 || true
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_fail "WASM file not found: $WASM_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test with wasmtime if available
|
|
||||||
if command -v wasmtime > /dev/null 2>&1; then
|
|
||||||
log_action "Testing with wasmtime"
|
|
||||||
# Create a simple test runner
|
|
||||||
cat > test_runner.wat << 'EOF'
|
|
||||||
(module
|
|
||||||
(import "spine" "run_spine_test" (func $run_spine_test (result i32)))
|
|
||||||
(func (export "_start")
|
|
||||||
(call $run_spine_test)
|
|
||||||
(if (i32.ne (i32.const 0))
|
|
||||||
(then unreachable))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
EOF
|
|
||||||
|
|
||||||
if wasmtime test_runner.wat --invoke _start 2>/dev/null; then
|
|
||||||
log_ok
|
|
||||||
else
|
|
||||||
log_detail "Wasmtime test skipped (expected - needs proper test harness)"
|
|
||||||
fi
|
|
||||||
rm -f test_runner.wat
|
|
||||||
else
|
|
||||||
log_detail "Wasmtime not available - skipping runtime test"
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_summary "✓ WASM compilation successful"
|
|
||||||
log_detail "This proves spine-cpp-no-cpprt can be used from Rust and compiled to WASM"
|
|
||||||
Loading…
x
Reference in New Issue
Block a user