Skip to content

Commit 91b6cc3

Browse files
TitanNanoBromeon
authored andcommitted
Implementation of Godot's GDExtensionScriptInstance
1 parent ef8b2b4 commit 91b6cc3

File tree

9 files changed

+1221
-2
lines changed

9 files changed

+1221
-2
lines changed

godot-codegen/src/codegen_special_cases.rs

+3
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ const SELECTED_CLASSES: &[&str] = &[
164164
"ResourceLoader",
165165
"RigidBody2D",
166166
"SceneTree",
167+
"Script",
168+
"ScriptExtension",
169+
"ScriptLanguage",
167170
"Sprite2D",
168171
"SpriteFrames",
169172
"TextServer",

godot-core/src/builtin/meta/mod.rs

+60
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,63 @@ impl PropertyInfo {
275275
}
276276
}
277277
}
278+
279+
#[derive(Debug)]
280+
pub struct MethodInfo {
281+
pub id: i32,
282+
pub method_name: StringName,
283+
pub class_name: ClassName,
284+
pub return_type: PropertyInfo,
285+
pub arguments: Vec<PropertyInfo>,
286+
pub default_arguments: Vec<Variant>,
287+
pub flags: global::MethodFlags,
288+
}
289+
290+
impl MethodInfo {
291+
/// Converts to the FFI type. Keep this object allocated while using that!
292+
///
293+
/// The struct returned by this function contains pointers into the fields of `self`. `self` should therefore not be dropped while the
294+
/// [`sys::GDExtensionMethodInfo`] is still in use.
295+
///
296+
/// This function also leaks memory that has to be cleaned up by the caller once it is no longer used. Specifically the `arguments` and
297+
/// `default_arguments` vectors have to be reconstructed from the pointer and length and then dropped/freed.
298+
///
299+
/// Each vector can be reconstructed with `Vec::from_raw_parts` since the pointers were created with `Vec::into_boxed_slice`, which
300+
/// guarantees that the vector capacity and length are equal.
301+
pub fn method_sys(&self) -> sys::GDExtensionMethodInfo {
302+
use crate::obj::EngineBitfield as _;
303+
304+
let argument_count = self.arguments.len() as u32;
305+
let argument_vec = self
306+
.arguments
307+
.iter()
308+
.map(|arg| arg.property_sys())
309+
.collect::<Vec<_>>()
310+
.into_boxed_slice();
311+
312+
// SAFETY: dereferencing the new box pointer is fine as it is guaranteed to not be null
313+
let arguments = unsafe { (*Box::into_raw(argument_vec)).as_mut_ptr() };
314+
315+
let default_argument_count = self.default_arguments.len() as u32;
316+
let default_argument_vec = self
317+
.default_arguments
318+
.iter()
319+
.map(|arg| arg.var_sys())
320+
.collect::<Vec<_>>()
321+
.into_boxed_slice();
322+
323+
// SAFETY: dereferencing the new box pointer is fine as it is guaranteed to not be null
324+
let default_arguments = unsafe { (*Box::into_raw(default_argument_vec)).as_mut_ptr() };
325+
326+
sys::GDExtensionMethodInfo {
327+
id: self.id,
328+
name: self.method_name.string_sys(),
329+
return_value: self.return_type.property_sys(),
330+
argument_count,
331+
arguments,
332+
default_argument_count,
333+
default_arguments,
334+
flags: u32::try_from(self.flags.ord()).expect("flags should be valid"),
335+
}
336+
}
337+
}

godot-core/src/builtin/variant/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ impl Variant {
236236
/// # Safety
237237
/// `variant_ptr_array` must be a valid pointer to an array of `length` variant pointers.
238238
/// The caller is responsible of keeping the backing storage alive while the unbounded references exist.
239-
#[cfg(since_api = "4.2")] // unused before
240239
pub(crate) unsafe fn unbounded_refs_from_sys<'a>(
241240
variant_ptr_array: *const sys::GDExtensionConstVariantPtr,
242241
length: usize,
@@ -253,6 +252,14 @@ impl Variant {
253252
pub(crate) fn ptr_from_sys_mut(variant_ptr: sys::GDExtensionVariantPtr) -> *mut Variant {
254253
variant_ptr as *mut Variant
255254
}
255+
256+
/// Move `self` into a system pointer. This transfers ownership and thus does not call the destructor.
257+
///
258+
/// # Safety
259+
/// `dst` must be a pointer to a [`Variant`] which is suitable for ffi with Godot.
260+
pub(crate) unsafe fn move_var_ptr(self, dst: sys::GDExtensionVariantPtr) {
261+
self.move_return_ptr(dst as *mut _, sys::PtrcallType::Standard);
262+
}
256263
}
257264

258265
// SAFETY:

godot-core/src/engine/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ pub use crate::gen::utilities;
1919
use crate::sys;
2020

2121
mod gfile;
22+
mod script_instance;
2223

2324
pub use gfile::{GFile, NotUniqueError};
25+
pub use script_instance::{create_script_instance, ScriptInstance};
2426

2527
/// Support for Godot _native structures_.
2628
///

0 commit comments

Comments
 (0)