spatialos-sdk 0.1.5

High-level SDK built around spatialos-sys
use spatialos::schema::ComponentData;
use spatialos::schema::ComponentUpdate;
use spatialos::worker::component_vtable::ComponentVtable;
use spatialos::worker::ComponentDataHandle;
use spatialos::worker::ComponentId;
use spatialos::worker::ComponentUpdateHandle;
use spatialos::private_exports::Schema_ComponentData;
use spatialos::private_exports::Schema_ComponentUpdate;
use std::os::raw::c_void;

pub trait Component: Sized {
    type Data: Clone;
    type Update: Clone;

    const ID: ComponentId;

    fn component_data_deserialize(
        component_id: ComponentId,
        user_data: *mut c_void,
        source: ComponentData,
    ) -> Self::Data;

    fn component_data_serialize(
        component_id: ComponentId,
        user_data: *mut c_void,
        handle: &mut Self::Data,
    ) -> ComponentData;

    fn component_update_deserialize(
        component_id: ComponentId,
        user_data: *mut c_void,
        source: ComponentUpdate,
    ) -> Self::Update;

    fn component_update_serialize(
        component_id: ComponentId,
        user_data: *mut c_void,
        handle: &mut Self::Update,
    ) -> ComponentUpdate;

    fn component_update_free(
        component_id: ComponentId,
        user_data: *mut c_void,
        handle: Self::Update,
    );

    fn component_update_copy(
        component_id: ComponentId,
        user_data: *mut c_void,
        handle: &Self::Update,
    ) -> Self::Update;

    fn get_vtable() -> ComponentVtable {
        ComponentVtable {
            component_id: Self::ID,
            user_data: std::ptr::null_mut(),
            command_request_free: None,
            command_request_copy: None,
            command_request_deserialize: None,
            command_request_serialize: None,
            command_response_free: None,
            command_response_copy: None,
            command_response_deserialize: None,
            command_response_serialize: None,
            component_data_free: Some(component_data_free::<Self>),
            component_data_copy: Some(component_data_copy::<Self>),
            component_data_deserialize: Some(component_data_deserialize::<Self>),
            component_data_serialize: Some(component_data_serialize::<Self>),
            component_update_free: Some(component_update_free::<Self>),
            component_update_copy: Some(component_update_copy::<Self>),
            component_update_deserialize: Some(component_update_deserialize::<Self>),
            component_update_serialize: Some(component_update_serialize::<Self>),
        }
    }
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_data_deserialize<T: Component>(
    component_id: ComponentId,
    user_data: *mut c_void,
    source: *mut Schema_ComponentData,
    handle_out: *mut *mut ComponentDataHandle,
) -> u8 {
    assert_eq!(component_id, T::ID);
    let source = source.into();
    let new_data = Box::new(T::component_data_deserialize(
        component_id,
        user_data,
        source,
    ));
    *(handle_out as *mut *mut T::Data) = Box::into_raw(new_data);
    1
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_data_serialize<T: Component>(
    component_id: ComponentId,
    user_data: *mut c_void,
    handle: *mut ComponentDataHandle,
    target_out: *mut *mut Schema_ComponentData,
) {
    assert_eq!(component_id, T::ID);
    let handle = handle as *mut T::Data;
    let mut data = Box::from_raw(handle);
    let component_data = T::component_data_serialize(component_id, user_data, &mut *data).into();
    *target_out = component_data;
    Box::into_raw(data);
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_update_deserialize<T: Component>(
    component_id: ComponentId,
    _: *mut c_void,
    _source: *mut Schema_ComponentUpdate,
    _handle_out: *mut *mut ComponentUpdateHandle,
) -> u8 {
    assert_eq!(component_id, T::ID);
    unimplemented!()
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_update_serialize<T: Component>(
    component_id: ComponentId,
    _: *mut c_void,
    _handle: *mut ComponentUpdateHandle,
    _target_out: *mut *mut Schema_ComponentUpdate,
) {
    assert_eq!(component_id, T::ID);
    unimplemented!()
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_data_copy<T: Component>(
    component_id: ComponentId,
    _: *mut c_void,
    handle: *mut ComponentDataHandle,
) -> *mut ComponentDataHandle {
    assert_eq!(component_id, T::ID);
    let handle = handle as *mut T::Data;
    let ptr = Box::from_raw(handle);
    let new_data = ptr.clone();
    Box::into_raw(ptr);
    Box::into_raw(new_data) as *mut ComponentDataHandle
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_data_free<T: Component>(
    component_id: ComponentId,
    _: *mut c_void,
    handle: *mut ComponentDataHandle,
) {
    assert_eq!(component_id, T::ID);
    Box::from_raw(handle);
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_update_free<T: Component>(
    component_id: ComponentId,
    user_data: *mut c_void,
    handle: *mut ComponentUpdateHandle,
) {
    assert_eq!(component_id, T::ID);
    let handle = handle as *mut T::Update;
    let handle = Box::from_raw(handle);
    T::component_update_free(component_id, user_data, *handle)
}

/// You shouldn't have to call this function yourself
///
/// # Safety
///
/// This function is used as part of a FFI connection with Improbable's C SDK
/// It must be marked unsafe to be on par with the C interface
pub unsafe extern "C" fn component_update_copy<T: Component>(
    component_id: ComponentId,
    user_data: *mut c_void,
    handle: *mut ComponentUpdateHandle,
) -> *mut ComponentUpdateHandle {
    assert_eq!(component_id, T::ID);
    let handle = handle as *mut T::Update;
    let ptr = Box::from_raw(handle);
    let new_data = Box::new(T::component_update_copy(component_id, user_data, &*ptr));

    Box::into_raw(ptr);
    Box::into_raw(new_data) as *mut ComponentDataHandle
}