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

Implementation of godots GDExtensionScriptInstance #492

Merged
merged 1 commit into from
Dec 5, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions godot-codegen/src/codegen_special_cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ const SELECTED_CLASSES: &[&str] = &[
"ResourceLoader",
"RigidBody2D",
"SceneTree",
"Script",
"ScriptExtension",
"ScriptLanguage",
"Sprite2D",
"SpriteFrames",
"TextServer",
Expand Down
60 changes: 60 additions & 0 deletions godot-core/src/builtin/meta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,63 @@ impl PropertyInfo {
}
}
}

#[derive(Debug)]
pub struct MethodInfo {
pub id: i32,
pub method_name: StringName,
pub class_name: ClassName,
pub return_type: PropertyInfo,
pub arguments: Vec<PropertyInfo>,
pub default_arguments: Vec<Variant>,
pub flags: global::MethodFlags,
}
TitanNano marked this conversation as resolved.
Show resolved Hide resolved

impl MethodInfo {
/// Converts to the FFI type. Keep this object allocated while using that!
///
/// The struct returned by this function contains pointers into the fields of `self`. `self` should therefore not be dropped while the
/// [`sys::GDExtensionMethodInfo`] is still in use.
///
/// This function also leaks memory that has to be cleaned up by the caller once it is no longer used. Specifically the `arguments` and
/// `default_arguments` vectors have to be reconstructed from the pointer and length and then dropped/freed.
///
/// Each vector can be reconstructed with `Vec::from_raw_parts` since the pointers were created with `Vec::into_boxed_slice`, which
/// guarantees that the vector capacity and length are equal.
pub fn method_sys(&self) -> sys::GDExtensionMethodInfo {
use crate::obj::EngineBitfield as _;

let argument_count = self.arguments.len() as u32;
let argument_vec = self
.arguments
.iter()
.map(|arg| arg.property_sys())
.collect::<Vec<_>>()
.into_boxed_slice();

// SAFETY: dereferencing the new box pointer is fine as it is guaranteed to not be null
let arguments = unsafe { (*Box::into_raw(argument_vec)).as_mut_ptr() };
TitanNano marked this conversation as resolved.
Show resolved Hide resolved

let default_argument_count = self.default_arguments.len() as u32;
let default_argument_vec = self
.default_arguments
.iter()
.map(|arg| arg.var_sys())
.collect::<Vec<_>>()
.into_boxed_slice();

// SAFETY: dereferencing the new box pointer is fine as it is guaranteed to not be null
let default_arguments = unsafe { (*Box::into_raw(default_argument_vec)).as_mut_ptr() };

sys::GDExtensionMethodInfo {
id: self.id,
name: self.method_name.string_sys(),
return_value: self.return_type.property_sys(),
argument_count,
arguments,
default_argument_count,
default_arguments,
flags: u32::try_from(self.flags.ord()).expect("flags should be valid"),
}
}
}
9 changes: 8 additions & 1 deletion godot-core/src/builtin/variant/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ impl Variant {
/// # Safety
/// `variant_ptr_array` must be a valid pointer to an array of `length` variant pointers.
/// The caller is responsible of keeping the backing storage alive while the unbounded references exist.
#[cfg(since_api = "4.2")] // unused before
pub(crate) unsafe fn unbounded_refs_from_sys<'a>(
variant_ptr_array: *const sys::GDExtensionConstVariantPtr,
length: usize,
Expand All @@ -253,6 +252,14 @@ impl Variant {
pub(crate) fn ptr_from_sys_mut(variant_ptr: sys::GDExtensionVariantPtr) -> *mut Variant {
variant_ptr as *mut Variant
}

/// Move `self` into a system pointer. This transfers ownership and thus does not call the destructor.
///
/// # Safety
/// `dst` must be a pointer to a [`Variant`] which is suitable for ffi with Godot.
pub(crate) unsafe fn move_var_ptr(self, dst: sys::GDExtensionVariantPtr) {
self.move_return_ptr(dst as *mut _, sys::PtrcallType::Standard);
}
}

// SAFETY:
Expand Down
2 changes: 2 additions & 0 deletions godot-core/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ pub use crate::gen::utilities;
use crate::sys;

mod gfile;
mod script_instance;

pub use gfile::{GFile, NotUniqueError};
pub use script_instance::{create_script_instance, ScriptInstance};

/// Support for Godot _native structures_.
///
Expand Down
Loading
Loading