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

wrap_shape! {
    ffi::CircleShape => CircleShape
    < ffi::CircleShape_as_shape
    > ffi::Shape_as_circle_shape
}

impl CircleShape {
    pub fn new() -> Self {
        unsafe { CircleShape::from_ffi(ffi::CircleShape_new()) }
    }

    pub fn new_with(position: Vec2, radius: f32) -> Self {
        let mut circle = Self::new();
        circle.set_position(position);
        circle.set_radius(radius);
        circle
    }

    pub fn support(&self, dir: &Vec2) -> i32 {
        unsafe { ffi::CircleShape_get_support(self.ptr(), dir) }
    }

    pub fn support_vertex<'a>(&'a self, dir: &Vec2) -> &'a Vec2 {
        unsafe {
            &*ffi::CircleShape_get_support_vertex(self.ptr(), dir) // Comes from a C++ &
        }
    }

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

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

    pub fn radius(&self) -> f32 {
        unsafe { ffi::Shape_get_radius(self.base_ptr()) }
    }

    pub fn set_radius(&mut self, radius: f32) {
        unsafe { ffi::Shape_set_radius(self.mut_base_ptr(), radius) }
    }

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

    pub fn set_position(&mut self, pos: Vec2) {
        unsafe { ffi::CircleShape_set_pos(self.mut_ptr(), pos) }
    }
}

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

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

    pub enum CircleShape {}

    extern "C" {
        pub fn CircleShape_new() -> *mut CircleShape;
        pub fn CircleShape_drop(slf: *mut CircleShape);
        pub fn CircleShape_as_shape(slf: *mut CircleShape) -> *mut Shape;
        pub fn Shape_as_circle_shape(slf: *mut Shape) -> *mut CircleShape;
        pub fn CircleShape_get_support(slf: *const CircleShape, d: *const Vec2) -> i32;
        pub fn CircleShape_get_support_vertex(slf: *const CircleShape,
                                              d: *const Vec2)
                                              -> *const Vec2;
        pub fn CircleShape_get_vertex_count(slf: *const CircleShape) -> i32;
        pub fn CircleShape_get_vertex(slf: *const CircleShape, index: i32) -> *const Vec2;
        pub fn CircleShape_get_pos(slf: *const CircleShape) -> Vec2;
        pub fn CircleShape_set_pos(slf: *mut CircleShape, pos: Vec2);
    }
}