Skip to content

Commit

Permalink
Merge pull request #10 from Waridley/feature/builtin_types
Browse files Browse the repository at this point in the history
Implement more builtin types
  • Loading branch information
Bromeon authored Oct 16, 2022
2 parents 8972a40 + a36e41a commit 152b9ff
Show file tree
Hide file tree
Showing 9 changed files with 404 additions and 83 deletions.
95 changes: 95 additions & 0 deletions gdext-builtin/src/arrays.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use crate::{FromVariant, Variant};
use gdext_sys as sys;
use std::marker::PhantomData;
use sys::{ffi_methods, interface_fn, types::*, GodotFfi};

impl_builtin_stub!(Array, OpaqueArray);
impl_builtin_stub!(ByteArray, OpaquePackedByteArray);
impl_builtin_stub!(ColorArray, OpaquePackedColorArray);
impl_builtin_stub!(Float32Array, OpaquePackedFloat32Array);
impl_builtin_stub!(Float64Array, OpaquePackedFloat64Array);
impl_builtin_stub!(Int32Array, OpaquePackedInt32Array);
impl_builtin_stub!(Int64Array, OpaquePackedInt64Array);
impl_builtin_stub!(StringArray, OpaquePackedStringArray);
impl_builtin_stub!(Vector2Array, OpaquePackedVector2Array);
impl_builtin_stub!(Vector3Array, OpaquePackedVector3Array);

impl_builtin_froms!(Array;
ByteArray => array_from_packed_byte_array,
ColorArray => array_from_packed_color_array,
Float32Array => array_from_packed_float32_array,
Float64Array => array_from_packed_float64_array,
Int32Array => array_from_packed_int32_array,
Int64Array => array_from_packed_int64_array,
StringArray => array_from_packed_string_array,
Vector2Array => array_from_packed_vector2_array,
Vector3Array => array_from_packed_vector3_array,
);

impl_builtin_froms!(ByteArray; Array => packed_byte_array_from_array);
impl_builtin_froms!(ColorArray; Array => packed_color_array_from_array);
impl_builtin_froms!(Float32Array; Array => packed_float32_array_from_array);
impl_builtin_froms!(Float64Array; Array => packed_float64_array_from_array);
impl_builtin_froms!(Int32Array; Array => packed_int32_array_from_array);
impl_builtin_froms!(Int64Array; Array => packed_int64_array_from_array);
impl_builtin_froms!(StringArray; Array => packed_string_array_from_array);
impl_builtin_froms!(Vector2Array; Array => packed_vector2_array_from_array);
impl_builtin_froms!(Vector3Array; Array => packed_vector3_array_from_array);

impl Array {
pub fn get(&self, index: i64) -> Option<Variant> {
unsafe {
let ptr = (interface_fn!(array_operator_index))(self.sys(), index) as *mut Variant;
if ptr.is_null() {
return None;
}
Some((*ptr).clone())
}
}
}

#[repr(C)]
pub struct TypedArray<T> {
opaque: OpaqueArray,
_phantom: PhantomData<T>,
}
impl<T> TypedArray<T> {
fn from_opaque(opaque: OpaqueArray) -> Self {
Self {
opaque,
_phantom: PhantomData,
}
}
}

impl<T> Clone for TypedArray<T> {
fn clone(&self) -> Self {
unsafe {
Self::from_sys_init(|opaque_ptr| {
let ctor = sys::method_table().array_construct_copy;
ctor(opaque_ptr, &self.sys() as *const sys::GDNativeTypePtr);
})
}
}
}
impl<T> GodotFfi for TypedArray<T> {
ffi_methods! { type sys::GDNativeTypePtr = *mut Opaque; .. }
}
impl<T> Drop for TypedArray<T> {
fn drop(&mut self) {
unsafe {
let destructor = sys::method_table().array_destroy;
destructor(self.sys_mut());
}
}
}

impl<T: FromVariant> TypedArray<T> {
pub fn get(&self, index: i64) -> Option<T> {
unsafe {
let ptr = (interface_fn!(array_operator_index))(self.sys(), index);
let v = Variant::from_var_sys(ptr);
T::try_from_variant(&v).ok()
}
}
}
4 changes: 4 additions & 0 deletions gdext-builtin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@

pub mod macros;

mod arrays;
mod color;
mod others;
mod string;
mod variant;
mod vector2;
mod vector3;
mod vector4;

pub use arrays::*;
pub use color::*;
pub use others::*;
pub use string::*;
pub use variant::*;
pub use vector2::*;
pub use vector3::*;
pub use vector4::*;

pub use glam;

Expand Down
34 changes: 34 additions & 0 deletions gdext-builtin/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,37 @@ macro_rules! impl_traits_as_sys {
)*
)
}

macro_rules! impl_builtin_stub {
($Class:ident, $OpaqueTy:ident) => {
#[repr(C)]
pub struct $Class {
opaque: sys::types::$OpaqueTy,
}

impl $Class {
fn from_opaque(opaque: sys::types::$OpaqueTy) -> Self {
Self { opaque }
}
}

impl GodotFfi for $Class {
ffi_methods! { type sys::GDNativeTypePtr = *mut Opaque; .. }
}
};
}

macro_rules! impl_builtin_froms {
($To:ty; $($From:ty => $from_fn:ident),* $(,)?) => {
$(impl From<&$From> for $To {
fn from(other: &$From) -> Self {
unsafe {
Self::from_sys_init(|ptr| {
let converter = sys::method_table().$from_fn;
converter(ptr, [other.sys()].as_ptr());
})
}
}
})*
};
}
38 changes: 18 additions & 20 deletions gdext-builtin/src/others.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,16 @@ use crate::GodotString;
use gdext_sys as sys;
use sys::{ffi_methods, GodotFfi};

macro_rules! impl_builtin_stub {
($Class:ident, $OpaqueTy:ident) => {
#[repr(C)]
pub struct $Class {
opaque: sys::types::$OpaqueTy,
}

impl $Class {
fn from_opaque(opaque: sys::types::$OpaqueTy) -> Self {
Self { opaque }
}
}

impl GodotFfi for $Class {
ffi_methods! { type sys::GDNativeTypePtr = *mut Opaque; .. }
}
};
}

impl_builtin_stub!(Array, OpaqueArray);
// TODO: Swap more inner math types with glam types
impl_builtin_stub!(AABB, OpaqueAABB);
impl_builtin_stub!(Basis, OpaqueBasis);
impl_builtin_stub!(Plane, OpaquePlane);
impl_builtin_stub!(Quaternion, OpaqueQuaternion);
impl_builtin_stub!(Rect2, OpaqueRect2);
impl_builtin_stub!(Rect2i, OpaqueRect2i);

impl_builtin_stub!(RID, OpaqueRID);
impl_builtin_stub!(Callable, OpaqueCallable);
impl_builtin_stub!(Dictionary, OpaqueDictionary);
impl_builtin_stub!(Transform2D, OpaqueTransform2D);
impl_builtin_stub!(Transform3D, OpaqueTransform3D);
Expand Down Expand Up @@ -61,6 +51,14 @@ impl StringName {
}
}

impl Drop for StringName {
fn drop(&mut self) {
unsafe {
(sys::method_table().string_name_destroy)(self.sys());
}
}
}

impl GodotFfi for StringName {
ffi_methods! {
type sys::GDNativeTypePtr = *mut Opaque;
Expand Down
26 changes: 26 additions & 0 deletions gdext-builtin/src/vector2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,29 @@ impl std::fmt::Display for Vector2 {
self.inner.fmt(f)
}
}

type IInner = glam::IVec2;

#[derive(Default, Copy, Clone, Debug)]
#[repr(C)]
pub struct Vector2i {
inner: IInner,
}

impl Vector2i {
pub fn new(x: i32, y: i32) -> Self {
Self {
inner: IInner::new(x, y),
}
}
}

impl GodotFfi for Vector2i {
ffi_methods! { type sys::GDNativeTypePtr = *mut Self; .. }
}

impl std::fmt::Display for Vector2i {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
26 changes: 26 additions & 0 deletions gdext-builtin/src/vector3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,29 @@ impl std::fmt::Display for Vector3 {
self.inner.fmt(f)
}
}

type IInner = glam::IVec3;

#[derive(Default, Copy, Clone, Debug)]
#[repr(C)]
pub struct Vector3i {
inner: IInner,
}

impl Vector3i {
pub fn new(x: i32, y: i32, z: i32) -> Self {
Self {
inner: IInner::new(x, y, z),
}
}
}

impl GodotFfi for Vector3i {
ffi_methods! { type sys::GDNativeTypePtr = *mut Self; .. }
}

impl std::fmt::Display for Vector3i {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
63 changes: 63 additions & 0 deletions gdext-builtin/src/vector4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

use gdext_sys as sys;
use sys::{ffi_methods, real, GodotFfi};

//#[cfg(not(feature = "real_is_double"))]
type Inner = glam::f32::Vec4;
// #[cfg(feature = "real_is_double")]
// type Inner = glam::f64::DVec4;

#[derive(Default, Copy, Clone, Debug, PartialEq)]
#[repr(C)]
pub struct Vector4 {
inner: Inner,
}

impl Vector4 {
pub fn new(x: real, y: real, z: real, w: real) -> Self {
Self {
inner: Inner::new(x, y, z, w),
}
}
}

impl GodotFfi for Vector4 {
ffi_methods! { type sys::GDNativeTypePtr = *mut Self; .. }
}

impl std::fmt::Display for Vector4 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}

type IInner = glam::IVec4;

#[derive(Default, Copy, Clone, Debug)]
#[repr(C)]
pub struct Vector4i {
inner: IInner,
}

impl Vector4i {
pub fn new(x: i32, y: i32, z: i32, w: i32) -> Self {
Self {
inner: IInner::new(x, y, z, w),
}
}
}

impl GodotFfi for Vector4i {
ffi_methods! { type sys::GDNativeTypePtr = *mut Self; .. }
}

impl std::fmt::Display for Vector4i {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
Loading

0 comments on commit 152b9ff

Please sign in to comment.