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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::mem;
use std::ptr;

use wrap::*;
use common::math::Vec2;
use super::Shape;

wrap_shape! {
    ffi::EdgeShape => EdgeShape
    < ffi::EdgeShape_as_shape
    > ffi::Shape_as_edge_shape
}

impl EdgeShape {
    pub fn new() -> Self {
        unsafe { EdgeShape::from_ffi(ffi::EdgeShape_new()) }
    }

    pub fn new_with(v1: &Vec2, v2: &Vec2) -> Self {
        let mut s = Self::new();
        s.set(v1, v2);
        s
    }

    pub fn set(&mut self, v1: &Vec2, v2: &Vec2) {
        unsafe { ffi::EdgeShape_set(self.mut_ptr(), v1, v2) }
    }

    pub fn v1(&self) -> Vec2 {
        unsafe { ffi::EdgeShape_get_v1(self.ptr()) }
    }

    pub fn set_v1(&mut self, v1: Vec2) {
        unsafe { ffi::EdgeShape_set_v1(self.mut_ptr(), v1) }
    }

    pub fn v2(&self) -> Vec2 {
        unsafe { ffi::EdgeShape_get_v2(self.ptr()) }
    }

    pub fn set_v2(&mut self, v2: Vec2) {
        unsafe { ffi::EdgeShape_set_v2(self.mut_ptr(), v2) }
    }

    pub fn v0(&self) -> Option<Vec2> {
        unsafe {
            let mut v0 = mem::MaybeUninit::uninit();
            if ffi::EdgeShape_get_v0(self.ptr(), &mut *v0.as_mut_ptr()) {
                Some(v0.assume_init())
            } else {
                None
            }
        }
    }

    pub fn set_v0(&mut self, v0: Option<Vec2>) {
        let ptr = v0.as_ref().map(|v0| v0 as *const _).unwrap_or(ptr::null());
        unsafe { ffi::EdgeShape_set_v0(self.mut_ptr(), ptr) }
    }

    pub fn v3(&self) -> Option<Vec2> {
        unsafe {
            let mut v3 = mem::MaybeUninit::uninit();
            if ffi::EdgeShape_get_v3(self.ptr(), &mut *v3.as_mut_ptr()) {
                Some(v3.assume_init())
            } else {
                None
            }
        }
    }

    pub fn set_v3(&mut self, v3: Option<Vec2>) {
        let ptr = v3.as_ref().map(|v3| v3 as *const _).unwrap_or(ptr::null());
        unsafe { ffi::EdgeShape_set_v0(self.mut_ptr(), ptr) }
    }
}

impl Drop for EdgeShape {
    fn drop(&mut self) {
        unsafe { ffi::EdgeShape_drop(self.mut_ptr()) }
    }
}

#[doc(hidden)]
pub mod ffi {
    pub use collision::shapes::ffi::Shape;
    use common::math::Vec2;

    pub enum EdgeShape {}

    extern "C" {
        pub fn EdgeShape_new() -> *mut EdgeShape;
        pub fn EdgeShape_drop(slf: *mut EdgeShape);
        pub fn EdgeShape_as_shape(slf: *mut EdgeShape) -> *mut Shape;
        pub fn Shape_as_edge_shape(slf: *mut Shape) -> *mut EdgeShape;
        pub fn EdgeShape_set(slf: *mut EdgeShape, v1: *const Vec2, v2: *const Vec2);
        pub fn EdgeShape_get_v1(slf: *const EdgeShape) -> Vec2;
        pub fn EdgeShape_set_v1(slf: *mut EdgeShape, v1: Vec2);
        pub fn EdgeShape_get_v2(slf: *const EdgeShape) -> Vec2;
        pub fn EdgeShape_set_v2(slf: *mut EdgeShape, v2: Vec2);
        pub fn EdgeShape_get_v0(slf: *const EdgeShape, v0: &mut Vec2) -> bool;
        pub fn EdgeShape_set_v0(slf: *mut EdgeShape, v0: *const Vec2);
        pub fn EdgeShape_get_v3(slf: *const EdgeShape, v3: &mut Vec2) -> bool;
        pub fn EdgeShape_set_v3(slf: *mut EdgeShape, v3: *const Vec2);
    }
}