use objc2::runtime::AnyClass;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TouchPhase {
Began,
Moved,
Ended,
}
#[must_use]
pub fn fnv1a_64(bytes: &[u8]) -> u64 {
let mut h: u64 = 0xcbf2_9ce4_8422_2325;
for &b in bytes {
h ^= u64::from(b);
h = h.wrapping_mul(0x0000_0100_0000_01b3);
}
h
}
pub unsafe fn ivar_offset(cls: &AnyClass, name: &core::ffi::CStr) -> usize {
unsafe extern "C" {
fn class_getInstanceVariable(
cls: *const AnyClass,
name: *const core::ffi::c_char,
) -> *mut core::ffi::c_void;
fn ivar_getOffset(ivar: *mut core::ffi::c_void) -> isize;
}
unsafe {
let ivar = class_getInstanceVariable(core::ptr::from_ref::<AnyClass>(cls), name.as_ptr());
assert!(!ivar.is_null(), "ivar {name:?} not registered");
let off = ivar_getOffset(ivar);
usize::try_from(off).expect("non-negative ivar offset")
}
}
#[cfg(test)]
mod tests {
use super::fnv1a_64;
#[test]
fn fnv1a_64_known_vectors() {
assert_eq!(fnv1a_64(b""), 0xcbf2_9ce4_8422_2325);
assert_eq!(fnv1a_64(b"a"), 0xaf63_dc4c_8601_ec8c);
}
}