@@ -86,7 +86,7 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
86
86
let base = ident ( & conv:: to_pascal_case ( base) ) ;
87
87
( quote ! { crate :: engine:: #base } , Some ( base) )
88
88
}
89
- None => ( quote ! { ( ) } , None ) ,
89
+ None => ( quote ! { crate :: obj :: NoBase } , None ) ,
90
90
} ;
91
91
92
92
let ( constructor, godot_default_impl) = make_constructor_and_default ( class, ctx) ;
@@ -100,8 +100,7 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
100
100
101
101
let enums = enums:: make_enums ( & class. enums ) ;
102
102
let constants = constants:: make_constants ( & class. constants ) ;
103
- let inherits_macro = format_ident ! ( "inherits_transitive_{}" , class_name. rust_ty) ;
104
- let ( exportable_impl, exportable_macro_impl) = make_exportable_impl ( class_name, ctx) ;
103
+ let inherits_macro = format_ident ! ( "unsafe_inherits_transitive_{}" , class_name. rust_ty) ;
105
104
let deref_impl = make_deref_impl ( class_name, & base_ty) ;
106
105
107
106
let all_bases = ctx. inheritance_tree ( ) . collect_all_bases ( class_name) ;
@@ -140,8 +139,18 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
140
139
let instance_id = rtti. check_type:: <Self >( ) ;
141
140
Some ( instance_id)
142
141
}
142
+
143
+ #[ doc( hidden) ]
144
+ pub fn __object_ptr( & self ) -> sys:: GDExtensionObjectPtr {
145
+ self . object_ptr
146
+ }
143
147
} ;
144
148
149
+ let inherits_macro_safety_doc = format ! (
150
+ "The provided class must be a subclass of all the superclasses of [`{}`]" ,
151
+ class_name. rust_ty
152
+ ) ;
153
+
145
154
// mod re_export needed, because class should not appear inside the file module, and we can't re-export private struct as pub.
146
155
let imports = util:: make_imports ( ) ;
147
156
let tokens = quote ! {
@@ -187,31 +196,26 @@ fn make_class(class: &Class, ctx: &mut Context, view: &ApiView) -> GeneratedClas
187
196
type DynMemory = crate :: obj:: bounds:: #assoc_dyn_memory;
188
197
type Declarer = crate :: obj:: bounds:: DeclEngine ;
189
198
}
190
- impl crate :: obj:: EngineClass for #class_name {
191
- fn as_object_ptr( & self ) -> sys:: GDExtensionObjectPtr {
192
- self . object_ptr
193
- }
194
- fn as_type_ptr( & self ) -> sys:: GDExtensionTypePtr {
195
- std:: ptr:: addr_of!( self . object_ptr) as sys:: GDExtensionTypePtr
196
- }
197
- }
199
+
198
200
#(
199
- impl crate :: obj:: Inherits <crate :: engine:: #all_bases> for #class_name { }
201
+ // SAFETY: #all_bases is a list of classes provided by Godot such that #class_name is guaranteed a subclass of all of them.
202
+ unsafe impl crate :: obj:: Inherits <crate :: engine:: #all_bases> for #class_name { }
200
203
) *
201
204
202
- #exportable_impl
203
205
#godot_default_impl
204
206
#deref_impl
205
207
208
+ /// # Safety
209
+ ///
210
+ #[ doc = #inherits_macro_safety_doc]
206
211
#[ macro_export]
207
212
#[ allow( non_snake_case) ]
208
213
macro_rules! #inherits_macro {
209
214
( $Class : ident) => {
210
- impl :: godot:: obj:: Inherits <:: godot:: engine:: #class_name> for $Class { }
215
+ unsafe impl :: godot:: obj:: Inherits <:: godot:: engine:: #class_name> for $Class { }
211
216
#(
212
- impl :: godot:: obj:: Inherits <:: godot:: engine:: #all_bases> for $Class { }
217
+ unsafe impl :: godot:: obj:: Inherits <:: godot:: engine:: #all_bases> for $Class { }
213
218
) *
214
- #exportable_macro_impl
215
219
}
216
220
}
217
221
}
@@ -342,26 +346,8 @@ fn make_constructor_and_default(class: &Class, ctx: &Context) -> (TokenStream, T
342
346
( constructor, godot_default_impl)
343
347
}
344
348
345
- fn make_exportable_impl ( class_name : & TyName , ctx : & mut Context ) -> ( TokenStream , TokenStream ) {
346
- let ( exportable_impl, exportable_macro_impl) ;
347
-
348
- if ctx. is_exportable ( class_name) {
349
- exportable_impl = quote ! {
350
- impl crate :: obj:: ExportableObject for #class_name { }
351
- } ;
352
- exportable_macro_impl = quote ! {
353
- impl :: godot:: obj:: ExportableObject for $Class { }
354
- } ;
355
- } else {
356
- exportable_impl = TokenStream :: new ( ) ;
357
- exportable_macro_impl = TokenStream :: new ( ) ;
358
- } ;
359
-
360
- ( exportable_impl, exportable_macro_impl)
361
- }
362
-
363
349
fn make_deref_impl ( class_name : & TyName , base_ty : & TokenStream ) -> TokenStream {
364
- // The base_ty of `Object` is `() `, and we dont want every engine class to deref to `() `.
350
+ // The base_ty of `Object` is `NoBase `, and we dont want every engine class to deref to `NoBase `.
365
351
if class_name. rust_ty == "Object" {
366
352
return TokenStream :: new ( ) ;
367
353
}
@@ -484,5 +470,6 @@ fn make_class_method_definition(
484
470
varcall_invocation,
485
471
ptrcall_invocation,
486
472
} ,
473
+ None ,
487
474
)
488
475
}
0 commit comments