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
use wrap::*;
use common::math::Vec2;
use super::Shape;

wrap_shape! {
    ffi::PolygonShape => PolygonShape
    < ffi::PolygonShape_as_shape
    > ffi::Shape_as_polygon_shape
}

impl PolygonShape {
    pub fn new() -> Self {
        unsafe { PolygonShape::from_ffi(ffi::PolygonShape_new()) }
    }

    pub fn set(&mut self, points: &[Vec2]) {
        unsafe { ffi::PolygonShape_set(self.mut_ptr(), points.as_ptr(), points.len() as i32) }
    }

    pub fn set_as_box(&mut self, hw: f32, hh: f32) {
        unsafe { ffi::PolygonShape_set_as_box(self.mut_ptr(), hw, hh) }
    }

    pub fn set_as_oriented_box(&mut self, hw: f32, hh: f32, center: &Vec2, angle: f32) {
        unsafe { ffi::PolygonShape_set_as_oriented_box(self.mut_ptr(), hw, hh, center, angle) }
    }
    
    pub fn new_with(points: &[Vec2]) -> Self {
        let mut s = Self::new();
        s.set(points);
        s
    }
    
    pub fn new_box(hw: f32, hh: f32) -> Self {
        let mut s = Self::new();
        s.set_as_box(hw, hh);
        s
    }
    
    pub fn new_oriented_box(hw: f32, hh: f32, center: &Vec2, angle: f32) -> Self {
        let mut s = Self::new();
        s.set_as_oriented_box(hw, hh, center, angle);
        s
    }

    pub fn vertex_count(&self) -> i32 {
        unsafe { ffi::PolygonShape_get_vertex_count(self.ptr()) }
    }

    pub fn vertex<'a>(&'a self, index: i32) -> &'a Vec2 {
        unsafe {
            &*ffi::PolygonShape_get_vertex(self.ptr(), index) // Comes from a C++ &
        }
    }

    pub fn validate(&self) -> bool {
        unsafe { ffi::PolygonShape_validate(self.ptr()) }
    }
}

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

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

    pub enum PolygonShape {}

    extern "C" {
        pub fn PolygonShape_new() -> *mut PolygonShape;
        pub fn PolygonShape_drop(slf: *mut PolygonShape);
        pub fn PolygonShape_as_shape(slf: *mut PolygonShape) -> *mut Shape;
        pub fn Shape_as_polygon_shape(slf: *mut Shape) -> *mut PolygonShape;
        pub fn PolygonShape_set(slf: *mut PolygonShape, points: *const Vec2, count: i32);
        pub fn PolygonShape_set_as_box(slf: *mut PolygonShape, hw: f32, hh: f32);
        pub fn PolygonShape_set_as_oriented_box(slf: *mut PolygonShape,
                                                hw: f32,
                                                hh: f32,
                                                center: *const Vec2,
                                                angle: f32);
        pub fn PolygonShape_get_vertex_count(slf: *const PolygonShape) -> i32;
        pub fn PolygonShape_get_vertex(slf: *const PolygonShape, index: i32) -> *const Vec2;
        pub fn PolygonShape_validate(slf: *const PolygonShape) -> bool;
    }
}