1
1
#[ macro_use]
2
- extern crate gdnative as godot ;
2
+ extern crate gdnative;
3
3
extern crate euclid;
4
4
5
- use godot:: init:: { Property , PropertyHint , PropertyUsage } ;
6
- use godot:: { GodotString , Variant , ResourceLoader , PackedScene , Spatial , Int32Array } ;
5
+ use gdnative:: { GodotString , Variant , ResourceLoader , PackedScene , Spatial } ;
7
6
use euclid:: vec3;
8
7
9
8
#[ derive( Debug , Clone , PartialEq ) ]
@@ -15,36 +14,32 @@ pub enum ManageErrs {
15
14
#[ derive( gdnative:: NativeClass ) ]
16
15
#[ inherit( gdnative:: Spatial ) ]
17
16
struct SceneCreate {
18
- /// Store the loaded scene for a very slight performance boost but mostly to show you how.
17
+ // Store the loaded scene for a very slight performance boost but mostly to show you how.
19
18
template : Option < PackedScene > ,
20
- children_spawned : i32 ,
19
+ children_spawned : u32 ,
21
20
}
22
21
23
22
24
- /// Demonstrates Scene creation, calling to/from gdscript
25
- ///
26
- /// 1. Child scene is created when spawn_1 is called
27
- /// 2. Child scenes are deleted when remove_1 is called
28
- /// 3. Find and call functions in a node (Panel)
29
- /// 4. Call functions in GDNative (from panel into spawn/remove)
30
- ///
31
- /// Note, the same mechanism which is used to call from panel into spawn_1 and remove_1 can be
32
- /// used to call other GDNative classes here in rust.
23
+ // Demonstrates Scene creation, calling to/from gdscript
24
+ //
25
+ // 1. Child scene is created when spawn_one is called
26
+ // 2. Child scenes are deleted when remove_one is called
27
+ // 3. Find and call functions in a node (Panel)
28
+ // 4. Call functions in GDNative (from panel into spawn/remove)
29
+ //
30
+ // Note, the same mechanism which is used to call from panel into spawn_one and remove_one can be
31
+ // used to call other GDNative classes here in rust.
33
32
34
33
#[ gdnative:: methods]
35
34
impl SceneCreate {
36
35
37
36
fn _init ( _owner : gdnative:: Spatial ) -> Self {
38
37
SceneCreate {
39
38
template : None , // Have not loaded this template yet.
40
- children_spawned : - 1 ,
39
+ children_spawned : 0 ,
41
40
}
42
41
}
43
42
44
- fn class_name ( ) -> & ' static str {
45
- "SceneCreate"
46
- }
47
-
48
43
#[ export]
49
44
fn _ready ( & mut self , _owner : gdnative:: Spatial ) {
50
45
self . template = load_scene ( "res://Child_scene.tscn" ) ;
@@ -55,9 +50,9 @@ impl SceneCreate {
55
50
}
56
51
57
52
#[ export]
58
- fn spawn_1 ( & mut self , mut owner : gdnative:: Spatial , str : GodotString ) {
53
+ unsafe fn spawn_one ( & mut self , mut owner : gdnative:: Spatial , message : GodotString ) {
59
54
60
- godot_print ! ( "Called spawn_1 ({})" , str . to_string( ) ) ;
55
+ godot_print ! ( "Called spawn_one ({})" , message . to_string( ) ) ;
61
56
62
57
let template = if let Some ( template) = & self . template {
63
58
template
@@ -71,90 +66,91 @@ impl SceneCreate {
71
66
match instance_scene :: < Spatial > ( template) {
72
67
Ok ( mut spatial) => {
73
68
// Here is how you rename the child...
74
- self . children_spawned += 1 ;
75
69
let key_str = format ! ( "child_{}" , self . children_spawned) ;
76
- unsafe {
77
- spatial. set_name ( GodotString :: from_str ( & key_str) ) ;
70
+ spatial. set_name ( GodotString :: from_str ( & key_str) ) ;
78
71
79
- let x = ( self . children_spawned % 10 ) as f32 ;
80
- let z = ( self . children_spawned / 10 ) as f32 ;
81
- spatial. translate ( vec3 ( -10.0 + x * 2.0 , 0.0 , -10.0 + z * 2.0 ) ) ;
82
72
73
+ let x = ( self . children_spawned % 10 ) as f32 ;
74
+ let z = ( self . children_spawned / 10 ) as f32 ;
75
+ spatial. translate ( vec3 ( -10.0 + x * 2.0 , 0.0 , -10.0 + z * 2.0 ) ) ;
83
76
84
- // You need to parent the new scene under some node if you want it in the scene.
85
- // We parent it under ourselves.
86
- owner. add_child ( Some ( spatial. to_object ( ) ) , false ) ;
87
- } ;
88
77
78
+ // You need to parent the new scene under some node if you want it in the scene.
79
+ // We parent it under ourselves.
80
+ owner. add_child ( Some ( spatial. to_object ( ) ) , false ) ;
81
+ self . children_spawned += 1 ;
89
82
90
83
} ,
91
84
Err ( err) => godot_print ! ( "Could not instance Child : {:?}" , err) ,
92
85
}
93
86
94
- let num_children = unsafe { owner. get_child_count ( ) } ;
87
+ let num_children = owner. get_child_count ( ) ;
95
88
update_panel ( & mut owner, num_children) ;
96
89
}
97
90
98
91
#[ export]
99
- fn remove_1 ( & mut self , mut owner : gdnative:: Spatial , str : GodotString ) {
100
- godot_print ! ( "Called remove_1 ({})" , str . to_string( ) ) ;
101
- let num_children = unsafe { owner. get_child_count ( ) } ;
92
+ unsafe fn remove_one ( & mut self , mut owner : gdnative:: Spatial , str : GodotString ) {
93
+ godot_print ! ( "Called remove_one ({})" , str . to_string( ) ) ;
94
+ let num_children = owner. get_child_count ( ) ;
102
95
if num_children <= 0 {
103
96
godot_print ! ( "No children to delete" ) ;
104
97
return ;
105
98
}
106
99
107
- let mut last_child = unsafe { owner. get_child ( num_children - 1 ) } ;
100
+ assert_eq ! ( self . children_spawned as i64 , num_children) ;
101
+
102
+ let last_child = owner. get_child ( num_children - 1 ) ;
108
103
if let Some ( mut node) = last_child {
109
- unsafe { node. queue_free ( ) }
104
+ node. queue_free ( ) ;
105
+ self . children_spawned -= 1 ;
106
+
110
107
}
111
108
112
109
update_panel ( & mut owner, num_children - 1 ) ;
113
110
}
114
111
115
112
}
116
113
117
- fn init ( handle : godot :: init:: InitHandle ) {
114
+ fn init ( handle : gdnative :: init:: InitHandle ) {
118
115
handle. add_class :: < SceneCreate > ( ) ;
119
116
}
120
117
121
- pub fn load_scene ( name : & str ) -> Option < PackedScene > {
118
+ pub fn load_scene ( path : & str ) -> Option < PackedScene > {
122
119
let scene = ResourceLoader :: godot_singleton ( ) . load (
123
- GodotString :: from_str ( name) ,
124
- GodotString :: from_str ( "PackedScene" ) , false ) ;
125
-
120
+ GodotString :: from_str ( path) , // could also use path.into() here
121
+ GodotString :: from_str ( "PackedScene" ) ,
122
+ false ,
123
+ ) ;
126
124
127
125
scene. and_then ( |s| s. cast :: < PackedScene > ( ) )
128
126
}
129
127
130
- // Root here is needs to be the same type (or a parent type) of the node that you put in the child
131
- // scene as the root. For instance Spatial is used for this example.
132
- pub fn instance_scene < Root > ( scene : & PackedScene ) -> Result < Root , ManageErrs >
133
- where Root : godot :: GodotObject {
134
- let mut inst_option = scene. instance ( 0 ) ; // 0 - GEN_EDIT_STATE_DISABLED
128
+ /// Root here is needs to be the same type (or a parent type) of the node that you put in the child
129
+ /// scene as the root. For instance Spatial is used for this example.
130
+ unsafe fn instance_scene < Root > ( scene : & PackedScene ) -> Result < Root , ManageErrs >
131
+ where Root : gdnative :: GodotObject {
132
+ let inst_option = scene. instance ( 0 ) ; // 0 - GEN_EDIT_STATE_DISABLED
135
133
136
- if let Some ( mut instance) = inst_option {
137
- if let Some ( mut instance_root) = unsafe { instance. cast :: < Root > ( ) } {
134
+ if let Some ( instance) = inst_option {
135
+ if let Some ( instance_root) = instance. cast :: < Root > ( ) {
138
136
Ok ( instance_root)
139
137
}
140
138
else {
141
- Err ( ManageErrs :: RootClassNotSpatial ( unsafe { instance. get_name ( ) } . to_string ( ) ) )
139
+ Err ( ManageErrs :: RootClassNotSpatial ( instance. get_name ( ) . to_string ( ) ) )
142
140
143
141
}
144
142
} else {
145
143
Err ( ManageErrs :: CouldNotMakeInstance )
146
144
}
147
145
}
148
146
149
- fn update_panel ( owner : & mut gdnative:: Spatial , num_children : i64 ) {
147
+ unsafe fn update_panel ( owner : & mut gdnative:: Spatial , num_children : i64 ) {
150
148
// Here is how we call into the panel. First we get its node (we might have saved it
151
149
// from earlier)
152
- let panel_node_opt = unsafe {
153
- owner. get_parent ( ) . and_then ( |parent|
150
+ let panel_node_opt = owner. get_parent ( ) . and_then ( |parent|
154
151
parent. find_node ( GodotString :: from_str ( "Panel" ) , true , false )
155
- ) } ;
156
- if let Some ( panel_node) = panel_node_opt
157
- {
152
+ ) ;
153
+ if let Some ( panel_node) = panel_node_opt {
158
154
// Put the Node
159
155
let mut as_variant = Variant :: from_object ( & panel_node) ;
160
156
match as_variant. call ( & GodotString :: from_str ( "set_num_children" ) ,
0 commit comments