Skip to main content

unity_native_plugin/
interface.rs

1use std::sync::OnceLock;
2use unity_native_plugin_sys::*;
3
4pub trait UnityInterface {
5    fn get_interface_guid() -> UnityInterfaceGUID;
6    fn new(interface: *const IUnityInterface) -> Self;
7}
8
9static UNITY_INTERFACES: OnceLock<UnityInterfaces> = OnceLock::new();
10
11pub struct UnityInterfaces {
12    interfaces: *mut unity_native_plugin_sys::IUnityInterfaces,
13}
14
15// maybe thread safety
16unsafe impl Send for UnityInterfaces {}
17unsafe impl Sync for UnityInterfaces {}
18
19impl UnityInterfaces {
20    pub fn get() -> &'static UnityInterfaces {
21        UNITY_INTERFACES.get().unwrap()
22    }
23
24    pub fn set_native_unity_interfaces(interfaces: *mut unity_native_plugin_sys::IUnityInterfaces) {
25        if !interfaces.is_null() {
26            let unity_interfaces = UnityInterfaces { interfaces };
27            let _ = UNITY_INTERFACES.set(unity_interfaces);
28        }
29    }
30
31    pub fn interface<T: UnityInterface>(&self) -> Option<T> {
32        unsafe {
33            if let Some(intf) = (&*self.interfaces).GetInterfaceSplit {
34                let guid = T::get_interface_guid();
35                let r = intf(guid.m_GUIDHigh, guid.m_GUIDLow);
36                if !r.is_null() {
37                    return Some(T::new(r));
38                }
39            }
40            None
41        }
42    }
43}