Skip to content

Commit

Permalink
Implementation of godots GDExtensionScriptInstance
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Haller <[email protected]>
Co-authored-by: Lili Zoey <[email protected]>
  • Loading branch information
3 people committed Dec 2, 2023
1 parent 05a1b09 commit 66d8a09
Show file tree
Hide file tree
Showing 9 changed files with 1,215 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 @@ -157,6 +157,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 @@ -272,3 +272,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::EngineEnum 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"),
}
}
}
2 changes: 2 additions & 0 deletions godot-core/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub use real_inner::*;
pub use rect2::*;
pub use rect2i::*;
pub use rid::*;
pub use script::*;
pub use string::*;
pub use transform2d::*;
pub use transform3d::*;
Expand Down Expand Up @@ -91,6 +92,7 @@ mod quaternion;
mod rect2;
mod rect2i;
mod rid;
mod script;
mod string;
mod transform2d;
mod transform3d;
Expand Down
Loading

0 comments on commit 66d8a09

Please sign in to comment.