Skip to content

Commit 94ca2a5

Browse files
TitanNanoBromeonlilizoey
committed
Implementation of Godot's GDExtensionScriptInstance
Co-authored-by: Jan Haller <[email protected]> Co-authored-by: Lili Zoey <[email protected]>
1 parent 9816e48 commit 94ca2a5

File tree

9 files changed

+1219
-2
lines changed

9 files changed

+1219
-2
lines changed

godot-codegen/src/codegen_special_cases.rs

+3
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ const SELECTED_CLASSES: &[&str] = &[
158158
"ResourceLoader",
159159
"RigidBody2D",
160160
"SceneTree",
161+
"Script",
162+
"ScriptExtension",
163+
"ScriptLanguage",
161164
"Sprite2D",
162165
"SpriteFrames",
163166
"TextServer",

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

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

godot-core/src/builtin/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub use real_inner::*;
5151
pub use rect2::*;
5252
pub use rect2i::*;
5353
pub use rid::*;
54+
pub use script::*;
5455
pub use string::*;
5556
pub use transform2d::*;
5657
pub use transform3d::*;
@@ -92,6 +93,7 @@ mod quaternion;
9293
mod rect2;
9394
mod rect2i;
9495
mod rid;
96+
mod script;
9597
mod string;
9698
mod transform2d;
9799
mod transform3d;

0 commit comments

Comments
 (0)