Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Array typehints #639

Merged
merged 1 commit into from Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -15,6 +15,7 @@ members = [
"examples/resource",
"examples/native_plugin",
"examples/rpc",
"examples/array_export",
"impl/proc_macros"
]

Expand Down
12 changes: 12 additions & 0 deletions examples/array_export/Cargo.toml
@@ -0,0 +1,12 @@
[package]
name = "array_export"
version = "0.1.0"
authors = ["The godot-rust developers"]
publish = false
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
gdnative = { path = "../../gdnative" }
9 changes: 9 additions & 0 deletions examples/array_export/ExportsArrays.gdns
@@ -0,0 +1,9 @@
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://array_export_library.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "ExportsArrays"
class_name = "ExportsArrays"
library = ExtResource( 1 )
script_class_name = "ExportsArrays"
10 changes: 10 additions & 0 deletions examples/array_export/ExportsArrays.tscn
@@ -0,0 +1,10 @@
[gd_scene load_steps=2 format=2]

[ext_resource path="res://ExportsArrays.gdns" type="Script" id=1]

[node name="ExportsArrays" type="Node"]
script = ExtResource( 1 )
single_array = [ 133.7, 1337, "Third Element" ]
single_array_range = [ -5, 1, 3, -3, 0 ]
double_array = [ [ 6, "(0, 1)" ], [ "Element 1, 0", 1375.5 ] ]
double_array_range = [ [ -2, 3 ], [ 4, -5 ] ]
17 changes: 17 additions & 0 deletions examples/array_export/array_export_library.gdnlib
@@ -0,0 +1,17 @@
[entry]

X11.64="res://../../target/debug/libarray_export.so"
OSX.64="res://../../target/debug/libarray_export.dylib"
Windows.64="res://../../target/debug/array_export.dll"

[dependencies]

X11.64=[ ]
OSX.64=[ ]

[general]

singleton=false
load_once=true
symbol_prefix="godot_"
reloadable=true
7 changes: 7 additions & 0 deletions examples/array_export/default_env.tres
@@ -0,0 +1,7 @@
[gd_resource type="Environment" load_steps=2 format=2]

[sub_resource type="ProceduralSky" id=1]

[resource]
background_mode = 2
background_sky = SubResource( 1 )
Binary file added examples/array_export/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions examples/array_export/icon.png.import
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]

[params]

compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
32 changes: 32 additions & 0 deletions examples/array_export/project.godot
@@ -0,0 +1,32 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters

config_version=4

_global_script_classes=[ {
"base": "",
"class": "ExportsArrays",
"language": "NativeScript",
"path": "res://ExportsArrays.gdns"
} ]
_global_script_class_icons={
"ExportsArrays": ""
}

[application]

config/name="array_export"
run/main_scene="res://ExportsArrays.tscn"
config/icon="res://icon.png"

[rendering]

quality/driver/driver_name="GLES2"
vram_compression/import_etc=true
vram_compression/import_etc2=false
environment/default_environment="res://default_env.tres"
61 changes: 61 additions & 0 deletions examples/array_export/src/lib.rs
@@ -0,0 +1,61 @@
use gdnative::nativescript::init::property::hint::{ArrayHint, IntHint, RangeHint};
use gdnative::prelude::*;

#[derive(NativeClass)]
#[inherit(Node)]
#[register_with(Self::register)]
struct ExportsArrays;

#[gdnative::methods]
impl ExportsArrays {
fn new(_owner: &Node) -> Self {
ExportsArrays
}

fn register(builder: &ClassBuilder<Self>) {
builder
.add_property::<VariantArray>("single_array")
.with_setter(ExportsArrays::set_single_array)
.done();
builder
.add_property::<VariantArray>("single_array_range")
.with_setter(ExportsArrays::set_single_array_range)
.with_hint(ArrayHint::with_element_hint::<i64>(IntHint::Range(
RangeHint::new(-5, 5),
)))
.done();
builder
.add_property::<VariantArray>("double_array")
.with_setter(ExportsArrays::set_double_array)
.with_hint(ArrayHint::with_element_hint::<VariantArray>(
ArrayHint::new(),
))
.done();
builder
.add_property::<VariantArray>("double_array_range")
.with_setter(ExportsArrays::set_double_array_range)
.with_hint(ArrayHint::with_element_hint::<VariantArray>(
ArrayHint::with_element_hint::<i64>(IntHint::Range(RangeHint::new(-5, 5))),
))
.done();
}

fn set_single_array(&mut self, _owner: TRef<Node>, value: VariantArray) {
godot_print!("Single: {:?}", value);
}
fn set_single_array_range(&mut self, _owner: TRef<Node>, value: VariantArray) {
godot_print!("Single Range: {:?}", value);
}
fn set_double_array(&mut self, _owner: TRef<Node>, value: VariantArray) {
godot_print!("Double: {:?}", value);
}
fn set_double_array_range(&mut self, _owner: TRef<Node>, value: VariantArray) {
godot_print!("Double Range: {:?}", value);
}
}

fn init(handle: InitHandle) {
handle.add_class::<ExportsArrays>();
}

godot_init!(init);
10 changes: 9 additions & 1 deletion gdnative-core/src/nativescript/init/property.rs
Expand Up @@ -407,7 +407,6 @@ mod impl_export {
impl_export_for_core_type_without_hint!(NodePath);
impl_export_for_core_type_without_hint!(Rid);
impl_export_for_core_type_without_hint!(Dictionary);
impl_export_for_core_type_without_hint!(VariantArray);
impl_export_for_core_type_without_hint!(ByteArray);
impl_export_for_core_type_without_hint!(Int32Array);
impl_export_for_core_type_without_hint!(Float32Array);
Expand Down Expand Up @@ -460,4 +459,13 @@ mod impl_export {
T::export_info(hint)
}
}

impl Export for VariantArray<Shared> {
type Hint = ArrayHint;

#[inline]
fn export_info(hint: Option<Self::Hint>) -> ExportInfo {
hint.unwrap_or_default().export_info()
}
}
}
77 changes: 76 additions & 1 deletion gdnative-core/src/nativescript/init/property/hint.rs
Expand Up @@ -7,7 +7,7 @@ use crate::core_types::GodotString;
use crate::core_types::VariantType;
use crate::sys;

use super::ExportInfo;
use super::{Export, ExportInfo};

/// Hints that an integer or float property should be within an inclusive range.
///
Expand Down Expand Up @@ -401,3 +401,78 @@ impl ColorHint {
}
}
}

/// Array hints optionally with an element hint.
#[derive(Debug, Default)]
pub struct ArrayHint {
element_hint: Option<ExportInfo>,
}

impl ArrayHint {
/// Returns an `ArrayHint` without a element hint.
#[inline]
pub fn new() -> Self {
Self::default()
}

/// Returns an `ArrayHint` with an element hint for type `T`, but without a hint for
/// that type.
#[inline]
pub fn with_element<T: Export>() -> Self {
Self::with_maybe_element_hint::<T>(None)
}

/// Returns an `ArrayHint` with an element hint for type `T`, and a hint for that type.
#[inline]
pub fn with_element_hint<T: Export>(hint: T::Hint) -> Self {
Self::with_maybe_element_hint::<T>(Some(hint))
}

/// Returns an `ArrayHint` with an element hint for type `T`, and optionally a hint
/// for that type.
#[inline]
pub fn with_maybe_element_hint<T: Export>(hint: Option<T::Hint>) -> Self {
ArrayHint {
element_hint: Some(T::export_info(hint)),
}
}
}

impl ArrayHint {
#[inline]
pub fn export_info(self) -> ExportInfo {
if let Some(element_hint) = self.element_hint {
let hint_string = match (element_hint.variant_type, element_hint.hint_kind) {
// Special-cased because sub-hints seem to leave off the hint only if it's NONE,
// but Array will also do it on HINT_TYPE_STRING.
(
VariantType::VariantArray,
sys::godot_property_hint_GODOT_PROPERTY_HINT_TYPE_STRING,
) => format!(
"{}:{}",
VariantType::VariantArray as u32,
element_hint.hint_string
),
(variant_type, sys::godot_property_hint_GODOT_PROPERTY_HINT_NONE) => {
format!("{}:{}", variant_type as u32, element_hint.hint_string)
}
(variant_type, hint_type) => format!(
"{}/{}:{}",
variant_type as u32, hint_type, element_hint.hint_string
),
}
.into();
ExportInfo {
variant_type: VariantType::VariantArray,
hint_kind: sys::godot_property_hint_GODOT_PROPERTY_HINT_TYPE_STRING,
hint_string,
}
} else {
ExportInfo {
variant_type: VariantType::VariantArray,
hint_kind: sys::godot_property_hint_GODOT_PROPERTY_HINT_NONE,
hint_string: GodotString::new(),
}
}
}
}