Skip to main content

spine_sys/
lib.rs

1#![deny(clippy::all, clippy::pedantic)]
2#![allow(dead_code, clippy::module_name_repetitions, clippy::must_use_candidate)]
3
4use atlas::AtlasPage;
5use std::ffi::CStr;
6use std::{os::raw::c_char, path::Path};
7use thiserror::Error;
8
9pub mod ffi;
10
11pub mod animation;
12pub mod atlas;
13pub mod enums;
14pub mod skeleton;
15
16mod spine_ptr;
17use spine_ptr::*;
18
19#[derive(Debug, Error)]
20pub enum SpineError {
21    #[error("LOL")]
22    FailLoadAtlas(String),
23    #[error("{}", 0)]
24    FailLoadSkeleton(String),
25}
26
27#[allow(clippy::mut_mut)]
28#[no_mangle]
29extern "C" fn _spAtlasPage_createTexture(
30    atlas_page_ptr: *mut ffi::spAtlasPage,
31    path: *const std::os::raw::c_char,
32) {
33    std::panic::catch_unwind(|| {
34        let path = unsafe { CStr::from_ptr(path).to_str().unwrap().to_owned() };
35
36        let mut atlas_page = AtlasPage {
37            inner: SpineMutPtr::new(atlas_page_ptr, None),
38        };
39
40        let atlas_object_ptr = unsafe { (*atlas_page.inner.as_mut().atlas).rendererObject };
41        //let atlas_page_object_ptr = atlas_page.inner.as_mut().rendererObject;
42
43        if !atlas_object_ptr.is_null() {
44            let closure: &mut &mut dyn FnMut(&AtlasPage, &Path) -> u32 =
45                unsafe { &mut *(atlas_object_ptr as *mut _) };
46
47            atlas_page.set_texture_id(closure(&atlas_page, Path::new(&path)));
48        }
49    })
50    .unwrap_or_else(|e| println!("ERROR: {:?}", e));
51}
52
53#[no_mangle]
54extern "C" fn _spAtlasPage_disposeTexture(atlas: *mut ffi::spAtlasPage) {
55    std::panic::catch_unwind(|| {
56        let _atlas_page = AtlasPage {
57            inner: SpineMutPtr::new(atlas, None),
58        };
59
60        // TODO: no-op?
61    })
62    .unwrap_or_else(|e| println!("ERROR: {:?}", e));
63}
64
65#[no_mangle]
66unsafe extern "C" fn _spUtil_readFile(path: *const c_char, length: *mut i32) -> *mut c_char {
67    std::panic::catch_unwind(|| ffi::_spReadFile(path, length)).unwrap_or_else(|e| {
68        println!("ERROR: {:?}", e);
69        std::ptr::null_mut()
70    })
71}
72
73#[cfg(test)]
74pub(crate) mod tests {
75    use std::path::PathBuf;
76
77    pub struct TestCase {
78        name: &'static str,
79        atlas: &'static str,
80        binary: &'static str,
81        json: &'static str,
82        path: &'static str,
83    }
84    impl TestCase {
85        pub fn name(&self) -> &str {
86            self.name
87        }
88
89        pub fn atlas(&self) -> PathBuf {
90            PathBuf::from(self.path).join(self.atlas)
91        }
92
93        pub fn binary(&self) -> PathBuf {
94            PathBuf::from(self.path).join(self.binary)
95        }
96
97        pub fn json(&self) -> PathBuf {
98            PathBuf::from(self.path).join(self.json)
99        }
100    }
101
102    pub const TEST_CASES: &[TestCase] = &[TestCase {
103        name: "dragon",
104        atlas: "dragon.atlas",
105        binary: "dragon-ess.skel",
106        json: "dragon-ess.json",
107        path: "../spine-example/examples/dragon/export",
108    }];
109}