skia_safe/interop/
cpp.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#![allow(unused)]
use crate::prelude::safer;
use sb::TraitObject;
use skia_bindings as sb;
use std::{marker::PhantomData, mem};

/// A sink / receiver for array data that is copied from C++ to a Rust [`Vec`].
#[derive(Debug)]
pub struct VecSink<'a, T> {
    sink: sb::VecSink<T>,
    pd: PhantomData<&'a mut Vec<T>>,
}

impl<T: 'static> VecSink<'_, T> {
    /// Create a new sink that calls back into the closure given.
    pub fn new(v: &mut dyn FnMut(&[T])) -> VecSink<T> {
        VecSink {
            sink: sb::VecSink {
                fn_trait: unsafe { mem::transmute::<&mut dyn FnMut(&[T]), TraitObject>(v) },
                set_fn: Some(Self::set_fn),
                _phantom_0: PhantomData,
            },
            pd: PhantomData,
        }
    }

    pub fn new_mut(v: &mut dyn FnMut(&mut [T])) -> VecSink<T> {
        VecSink {
            sink: sb::VecSink {
                fn_trait: unsafe { mem::transmute::<&mut dyn FnMut(&mut [T]), TraitObject>(v) },
                set_fn: Some(Self::set_fn_mut),
                _phantom_0: PhantomData,
            },
            pd: PhantomData,
        }
    }

    pub fn native_mut(&mut self) -> &mut sb::VecSink<T> {
        &mut self.sink
    }

    unsafe extern "C" fn set_fn(ptr: *mut T, len: usize, rust_fn: TraitObject) {
        let rust_fn: &mut dyn FnMut(&[T]) = mem::transmute(rust_fn);
        (rust_fn)(safer::from_raw_parts(ptr, len));
    }

    unsafe extern "C" fn set_fn_mut(ptr: *mut T, len: usize, rust_fn: TraitObject) {
        let rust_fn: &mut dyn FnMut(&mut [T]) = mem::transmute(rust_fn);
        (rust_fn)(safer::from_raw_parts_mut(ptr, len));
    }
}

#[derive(Debug)]
pub struct Sink<'a, T> {
    sink: sb::Sink<T>,
    pd: PhantomData<&'a mut T>,
}

impl<T: 'static> Sink<'_, T> {
    /// Create a new sink that calls back into the closure given.
    pub fn new(v: &mut dyn FnMut(&T)) -> Sink<T> {
        Sink {
            sink: sb::Sink {
                fn_trait: unsafe { mem::transmute::<&mut dyn FnMut(&T), TraitObject>(v) },
                set_fn: Some(Self::set_fn),
                _phantom_0: PhantomData,
            },
            pd: PhantomData,
        }
    }

    pub fn native_mut(&mut self) -> &mut sb::Sink<T> {
        &mut self.sink
    }

    unsafe extern "C" fn set_fn(ptr: *const T, rust_fn: TraitObject) {
        let rust_fn: &mut dyn FnMut(&T) = mem::transmute(rust_fn);
        (rust_fn)(&*ptr);
    }
}