Skip to content

Commit

Permalink
Merge pull request #492 from TitanNano/jovan/impl_script_instance
Browse files Browse the repository at this point in the history
Implementation of godots `GDExtensionScriptInstance`
  • Loading branch information
Bromeon authored Dec 5, 2023
2 parents ef8b2b4 + 91b6cc3 commit 6cb6895
Show file tree
Hide file tree
Showing 9 changed files with 1,221 additions and 2 deletions.
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,
}

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() };

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

0 comments on commit 6cb6895

Please sign in to comment.