Skip to content

Commit 4d396e7

Browse files
committed
Vector conversion functions from/to tuples and arrays
1 parent aa7107a commit 4d396e7

File tree

7 files changed

+76
-5
lines changed

7 files changed

+76
-5
lines changed

godot-core/src/builtin/vectors/vector2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ use std::fmt;
2424
/// is always 64-bit. The engine can be compiled with the option `precision=double` to use 64-bit
2525
/// vectors; use the gdext library with the `double-precision` feature in that case.
2626
///
27+
#[doc = shared_vector_docs!()]
28+
///
2729
/// ### Navigation to `impl` blocks within this page
2830
///
2931
/// - [Constants](#constants)

godot-core/src/builtin/vectors/vector2i.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ use std::fmt;
1919
/// 2-element structure that can be used to represent discrete positions or directions in 2D space,
2020
/// as well as any other pair of numeric values.
2121
///
22-
/// It uses integer coordinates and is therefore preferable to [`Vector2`] when exact precision is
22+
/// `Vector2i` uses integer coordinates and is therefore preferable to [`Vector2`] when exact precision is
2323
/// required. Note that the values are limited to 32 bits, and unlike `Vector2` this cannot be
2424
/// configured with an engine build option. Use `i64` or [`PackedInt64Array`][crate::builtin::PackedInt64Array]
2525
/// if 64-bit values are needed.
2626
///
27+
#[doc = shared_vector_docs!()]
28+
///
2729
/// ### Navigation to `impl` blocks within this page
2830
///
2931
/// - [Constants](#constants)

godot-core/src/builtin/vectors/vector3.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ use std::fmt;
2424
/// is always 64-bit. The engine can be compiled with the option `precision=double` to use 64-bit
2525
/// vectors instead; use the gdext library with the `double-precision` feature in that case.
2626
///
27+
#[doc = shared_vector_docs!()]
28+
///
2729
/// ### Navigation to `impl` blocks within this page
2830
///
2931
/// - [Constants](#constants)

godot-core/src/builtin/vectors/vector3i.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ use crate::builtin::{inner, real, RVec3, Vector3, Vector3Axis};
1919
/// 3-element structure that can be used to represent discrete positions or directions in 3D space,
2020
/// as well as any other triple of numeric values.
2121
///
22-
/// It uses integer coordinates and is therefore preferable to [`Vector3`] when exact precision is
22+
/// `Vector3i` uses integer coordinates and is therefore preferable to [`Vector3`] when exact precision is
2323
/// required. Note that the values are limited to 32 bits, and unlike `Vector3` this cannot be
2424
/// configured with an engine build option. Use `i64` or [`PackedInt64Array`][crate::builtin::PackedInt64Array]
2525
/// if 64-bit values are needed.
2626
///
27+
#[doc = shared_vector_docs!()]
28+
///
2729
/// ### Navigation to `impl` blocks within this page
2830
///
2931
/// - [Constants](#constants)

godot-core/src/builtin/vectors/vector4.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use std::fmt;
2222
/// is always 64-bit. The engine can be compiled with the option `precision=double` to use 64-bit
2323
/// vectors; use the gdext library with the `double-precision` feature in that case.
2424
///
25+
#[doc = shared_vector_docs!()]
26+
///
2527
/// ### Navigation to `impl` blocks within this page
2628
///
2729
/// - [Constants](#constants)

godot-core/src/builtin/vectors/vector4i.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ use std::fmt;
1818
///
1919
/// 4-element structure that can be used to represent 4D grid coordinates or sets of integers.
2020
///
21-
/// It uses integer coordinates and is therefore preferable to [`Vector4`] when exact precision is
21+
/// `Vector4i` uses integer coordinates and is therefore preferable to [`Vector4`] when exact precision is
2222
/// required. Note that the values are limited to 32 bits, and unlike `Vector4` this cannot be
2323
/// configured with an engine build option. Use `i64` or [`PackedInt64Array`][crate::builtin::PackedInt64Array]
2424
/// if 64-bit values are needed.
2525
///
26+
#[doc = shared_vector_docs!()]
27+
///
2628
/// ### Navigation to `impl` blocks within this page
2729
///
2830
/// - [Constants](#constants)

godot-core/src/builtin/vectors/vector_macros.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,37 @@ macro_rules! impl_vector3x_consts {
330330
};
331331
}
332332

333+
macro_rules! shared_vector_docs {
334+
() => {
335+
"Conversions are provided via various `from_*` and `to_*` functions, not via the `From` trait. This encourages `new()` as the main \
336+
way to construct vectors, is explicit about the conversion taking place, needs no type inference, and works in `const` contexts."
337+
};
338+
}
339+
340+
macro_rules! tuple_type {
341+
($Scalar:ty; $x:ident, $y:ident) => {
342+
($Scalar, $Scalar)
343+
};
344+
($Scalar:ty; $x:ident, $y:ident, $z:ident) => {
345+
($Scalar, $Scalar, $Scalar)
346+
};
347+
($Scalar:ty; $x:ident, $y:ident, $z:ident, $w:ident) => {
348+
($Scalar, $Scalar, $Scalar, $Scalar)
349+
};
350+
}
351+
352+
macro_rules! array_type {
353+
($Scalar:ty; $x:ident, $y:ident) => {
354+
[$Scalar; 2]
355+
};
356+
($Scalar:ty; $x:ident, $y:ident, $z:ident) => {
357+
[$Scalar; 3]
358+
};
359+
($Scalar:ty; $x:ident, $y:ident, $z:ident, $w:ident) => {
360+
[$Scalar; 4]
361+
};
362+
}
363+
333364
/// Implements functions that are present on floating-point and integer vectors.
334365
macro_rules! impl_vector_fns {
335366
(
@@ -345,20 +376,48 @@ macro_rules! impl_vector_fns {
345376
/// # Constructors and general vector functions
346377
/// The following associated functions and methods are available on all vectors (2D, 3D, 4D; float and int).
347378
impl $Vector {
348-
/// Returns a vector with the given components.
379+
/// Creates a vector with the given components.
380+
#[inline]
349381
pub const fn new($($comp: $Scalar),*) -> Self {
350382
Self {
351383
$( $comp ),*
352384
}
353385
}
354386

355-
/// Returns a new vector with all components set to `v`.
387+
/// Creates a vector with all components set to `v`.
388+
#[inline]
356389
pub const fn splat(v: $Scalar) -> Self {
357390
Self {
358391
$( $comp: v ),*
359392
}
360393
}
361394

395+
/// Creates a vector from the given tuple.
396+
#[inline]
397+
pub const fn from_tuple(tuple: tuple_type!($Scalar; $($comp),*)) -> Self {
398+
let ( $($comp,)* ) = tuple;
399+
Self::new( $($comp),* )
400+
}
401+
402+
/// Creates a vector from the given array.
403+
#[inline]
404+
pub const fn from_array(array: array_type!($Scalar; $($comp),*)) -> Self {
405+
let [ $($comp,)* ] = array;
406+
Self::new( $($comp),* )
407+
}
408+
409+
/// Returns a tuple with the components of the vector.
410+
#[inline]
411+
pub const fn to_tuple(&self) -> tuple_type!($Scalar; $($comp),*) {
412+
( $(self.$comp,)* )
413+
}
414+
415+
/// Returns an array with the components of the vector.
416+
#[inline]
417+
pub const fn to_array(&self) -> array_type!($Scalar; $($comp),*) {
418+
[ $(self.$comp,)* ]
419+
}
420+
362421
/// Converts the corresponding `glam` type to `Self`.
363422
fn from_glam(v: $GlamVector) -> Self {
364423
Self::new(

0 commit comments

Comments
 (0)