@@ -55,25 +55,21 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1) {
55
55
void ClassDB::add_property_group (const char *p_class, const char *p_name, const char *p_prefix) {
56
56
ERR_FAIL_COND_MSG (classes.find (p_class) == classes.end (), " Trying to add property to non-existing class." );
57
57
58
- ClassInfo &info = classes[p_class];
59
-
60
- info.property_list .push_back (PropertyInfo (Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_GROUP));
58
+ internal::interface->classdb_register_extension_class_property_group (internal::library, p_class, p_name, p_prefix);
61
59
}
62
60
63
61
void ClassDB::add_property_subgroup (const char *p_class, const char *p_name, const char *p_prefix) {
64
62
ERR_FAIL_COND_MSG (classes.find (p_class) == classes.end (), " Trying to add property to non-existing class." );
65
63
66
- ClassInfo &info = classes[p_class];
67
-
68
- info.property_list .push_back (PropertyInfo (Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_SUBGROUP));
64
+ internal::interface->classdb_register_extension_class_property_subgroup (internal::library, p_class, p_name, p_prefix);
69
65
}
70
66
71
67
void ClassDB::add_property (const char *p_class, const PropertyInfo &p_pinfo, const char *p_setter, const char *p_getter, int p_index) {
72
68
ERR_FAIL_COND_MSG (classes.find (p_class) == classes.end (), " Trying to add property to non-existing class." );
73
69
74
70
ClassInfo &info = classes[p_class];
75
71
76
- ERR_FAIL_COND_MSG (info.property_setget .find (p_pinfo.name ) != info.property_setget .end (), " Property already exists in class." );
72
+ ERR_FAIL_COND_MSG (info.property_names .find (p_pinfo.name ) != info.property_names .end (), " Property already exists in class." );
77
73
78
74
MethodBind *setter = nullptr ;
79
75
if (p_setter) {
@@ -94,7 +90,18 @@ void ClassDB::add_property(const char *p_class, const PropertyInfo &p_pinfo, con
94
90
ERR_FAIL_COND_MSG (exp_args != getter->get_argument_count (), " Getter method must not take any argument." );
95
91
}
96
92
97
- info.property_list .push_back (p_pinfo);
93
+ // register property with plugin
94
+ info.property_names .insert (p_pinfo.name );
95
+
96
+ // register with Godot
97
+ GDNativePropertyInfo prop_info = {
98
+ (uint32_t )p_pinfo.type , // uint32_t type;
99
+ p_pinfo.name , // const char *name;
100
+ p_pinfo.class_name , // const char *class_name;
101
+ p_pinfo.hint , // NONE //uint32_t hint;
102
+ p_pinfo.hint_string , // const char *hint_string;
103
+ p_pinfo.usage , // DEFAULT //uint32_t usage;
104
+ };
98
105
99
106
PropertySetGet setget;
100
107
setget.setter = p_setter;
@@ -104,7 +111,7 @@ void ClassDB::add_property(const char *p_class, const PropertyInfo &p_pinfo, con
104
111
setget.index = p_index;
105
112
setget.type = p_pinfo.type ;
106
113
107
- info.property_setget [p_pinfo. name ] = setget;
114
+ internal::interface-> classdb_register_extension_class_property (internal::library, info.name , &prop_info, setget. setter , setget. getter ) ;
108
115
}
109
116
110
117
MethodBind *ClassDB::get_method (const char *p_class, const char *p_method) {
@@ -162,38 +169,83 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const M
162
169
163
170
p_bind->set_argument_names (args);
164
171
165
- type. method_order . push_back (p_bind);
172
+ // register our method bind within our plugin
166
173
type.method_map [method_name.name ] = p_bind;
167
174
175
+ // and register with godot
176
+ bind_method_godot (type.name , p_bind);
177
+
168
178
return p_bind;
169
179
}
170
180
181
+ void ClassDB::bind_method_godot (const char *p_class_name, MethodBind *p_method) {
182
+ GDNativeExtensionClassMethodInfo method_info = {
183
+ p_method->get_name (), // const char *name;
184
+ p_method, // void *method_userdata;
185
+ MethodBind::bind_call, // GDNativeExtensionClassMethodCall call_func;
186
+ MethodBind::bind_ptrcall, // GDNativeExtensionClassMethodPtrCall ptrcall_func;
187
+ GDNATIVE_EXTENSION_METHOD_FLAGS_DEFAULT, // uint32_t method_flags; /* GDNativeExtensionClassMethodFlags */
188
+ (uint32_t )p_method->get_argument_count (), // uint32_t argument_count;
189
+ (GDNativeBool)p_method->has_return (), // GDNativeBool has_return_value;
190
+ MethodBind::bind_get_argument_type, // (GDNativeExtensionClassMethodGetArgumentType) get_argument_type_func;
191
+ MethodBind::bind_get_argument_info, // GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func; /* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */
192
+ MethodBind::bind_get_argument_metadata, // GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func;
193
+ p_method->get_hint_flags (), // uint32_t default_argument_count;
194
+ nullptr , // GDNativeVariantPtr *default_arguments;
195
+ };
196
+ internal::interface->classdb_register_extension_class_method (internal::library, p_class_name, &method_info);
197
+ }
198
+
171
199
void ClassDB::add_signal (const char *p_class, const MethodInfo &p_signal) {
172
200
std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find (p_class);
173
201
174
202
ERR_FAIL_COND_MSG (type_it == classes.end (), " Class doesn't exist." );
175
203
176
- ClassInfo &base = type_it->second ;
177
- ClassInfo *check = &base;
204
+ ClassInfo &cl = type_it->second ;
205
+
206
+ // Check if this signal is already register
207
+ ClassInfo *check = &cl;
178
208
while (check) {
179
- ERR_FAIL_COND_MSG (check->signal_map .find (p_signal.name ) != check->signal_map .end (), String (" Class '" + String (p_class) + " ' already has signal '" + String (p_signal.name ) + " '." ).utf8 ().get_data ());
209
+ ERR_FAIL_COND_MSG (check->signal_names .find (p_signal.name ) != check->signal_names .end (), String (" Class '" + String (p_class) + " ' already has signal '" + String (p_signal.name ) + " '." ).utf8 ().get_data ());
180
210
check = check->parent_ptr ;
181
211
}
182
212
183
- base.signal_map [p_signal.name ] = p_signal;
213
+ // register our signal in our plugin
214
+ cl.signal_names .insert (p_signal.name );
215
+
216
+ // register our signal in godot
217
+ std::vector<GDNativePropertyInfo> parameters;
218
+ parameters.reserve (p_signal.arguments .size ());
219
+
220
+ for (const PropertyInfo &par : p_signal.arguments ) {
221
+ parameters.push_back (GDNativePropertyInfo{
222
+ static_cast <uint32_t >(par.type ), // uint32_t type;
223
+ par.name , // const char *name;
224
+ par.class_name , // const char *class_name;
225
+ par.hint , // uint32_t hint;
226
+ par.hint_string , // const char *hint_string;
227
+ par.usage , // uint32_t usage;
228
+ });
229
+ }
230
+
231
+ internal::interface->classdb_register_extension_class_signal (internal::library, cl.name , p_signal.name , parameters.data (), parameters.size ());
184
232
}
185
233
186
- void ClassDB::bind_integer_constant (const char *p_class , const char *p_enum , const char *p_name , GDNativeInt p_constant ) {
187
- std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find (p_class );
234
+ void ClassDB::bind_integer_constant (const char *p_class_name , const char *p_enum_name , const char *p_constant_name , GDNativeInt p_constant_value ) {
235
+ std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find (p_class_name );
188
236
189
237
ERR_FAIL_COND_MSG (type_it == classes.end (), " Class doesn't exist." );
190
238
191
239
ClassInfo &type = type_it->second ;
192
240
193
- ERR_FAIL_COND_MSG (type.constant_map .find (p_name) != type.constant_map .end (), " Constant already registered." );
241
+ // check if it already exists
242
+ ERR_FAIL_COND_MSG (type.constant_names .find (p_constant_name) != type.constant_names .end (), " Constant already registered." );
243
+
244
+ // register it with our plugin (purely to check for duplicates)
245
+ type.constant_names .insert (p_constant_name);
194
246
195
- type. constant_map [p_name] = std::pair<std::string, GDNativeInt>{ p_enum, p_constant };
196
- type. constant_order . push_back (p_name );
247
+ // Register it with Godot
248
+ internal::interface-> classdb_register_extension_class_integer_constant (internal::library, p_class_name, p_enum_name, p_constant_name, p_constant_value );
197
249
}
198
250
199
251
GDNativeExtensionClassCallVirtual ClassDB::get_virtual_func (void *p_userdata, const char *p_name) {
@@ -225,95 +277,17 @@ void ClassDB::bind_virtual_method(const char *p_class, const char *p_method, GDN
225
277
type.virtual_methods [p_method] = p_call;
226
278
}
227
279
280
+ void ClassDB::initialize_class (const ClassInfo &p_cl) {
281
+ }
282
+
228
283
void ClassDB::initialize (GDNativeInitializationLevel p_level) {
229
284
for (const std::pair<std::string, ClassInfo> pair : classes) {
230
285
const ClassInfo &cl = pair.second ;
231
286
if (cl.level != p_level) {
232
287
continue ;
233
288
}
234
289
235
- GDNativeExtensionClassCreationInfo class_info = {
236
- nullptr , // GDNativeExtensionClassSet set_func;
237
- nullptr , // GDNativeExtensionClassGet get_func;
238
- nullptr , // GDNativeExtensionClassGetPropertyList get_property_list_func;
239
- nullptr , // GDNativeExtensionClassFreePropertyList free_property_list_func;
240
- nullptr , // GDNativeExtensionClassNotification notification_func;
241
- nullptr , // GDNativeExtensionClassToString to_string_func;
242
- nullptr , // GDNativeExtensionClassReference reference_func;
243
- nullptr , // GDNativeExtensionClassUnreference
244
- cl.constructor , // GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
245
- cl.destructor , // GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
246
- cl.object_instance , // GDNativeExtensionClassObjectInstance object_instance_func; /* this one is mandatory */
247
- &ClassDB::get_virtual_func, // GDNativeExtensionClassGetVirtual get_virtual_func;
248
- (void *)cl.name , // void *class_userdata;
249
- };
250
-
251
- internal::interface->classdb_register_extension_class (internal::library, cl.name , cl.parent_name , &class_info);
252
-
253
- for (MethodBind *method : cl.method_order ) {
254
- GDNativeExtensionClassMethodInfo method_info = {
255
- method->get_name (), // const char *name;
256
- method, // void *method_userdata;
257
- MethodBind::bind_call, // GDNativeExtensionClassMethodCall call_func;
258
- MethodBind::bind_ptrcall, // GDNativeExtensionClassMethodPtrCall ptrcall_func;
259
- GDNATIVE_EXTENSION_METHOD_FLAGS_DEFAULT, // uint32_t method_flags; /* GDNativeExtensionClassMethodFlags */
260
- (uint32_t )method->get_argument_count (), // uint32_t argument_count;
261
- (GDNativeBool)method->has_return (), // GDNativeBool has_return_value;
262
- MethodBind::bind_get_argument_type, // (GDNativeExtensionClassMethodGetArgumentType) get_argument_type_func;
263
- MethodBind::bind_get_argument_info, // GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func; /* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */
264
- MethodBind::bind_get_argument_metadata, // GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func;
265
- method->get_hint_flags (), // uint32_t default_argument_count;
266
- nullptr , // GDNativeVariantPtr *default_arguments;
267
- };
268
- internal::interface->classdb_register_extension_class_method (internal::library, cl.name , &method_info);
269
- }
270
-
271
- for (const PropertyInfo &property : cl.property_list ) {
272
- GDNativePropertyInfo info = {
273
- (uint32_t )property.type , // uint32_t type;
274
- property.name , // const char *name;
275
- property.class_name , // const char *class_name;
276
- property.hint , // NONE //uint32_t hint;
277
- property.hint_string , // const char *hint_string;
278
- property.usage , // DEFAULT //uint32_t usage;
279
- };
280
-
281
- if (info.usage == PROPERTY_USAGE_GROUP) {
282
- internal::interface->classdb_register_extension_class_property_group (internal::library, cl.name , info.name , info.hint_string );
283
- } else if (info.usage == PROPERTY_USAGE_SUBGROUP) {
284
- internal::interface->classdb_register_extension_class_property_subgroup (internal::library, cl.name , info.name , info.hint_string );
285
- } else {
286
- const PropertySetGet &setget = cl.property_setget .find (property.name )->second ;
287
-
288
- internal::interface->classdb_register_extension_class_property (internal::library, cl.name , &info, setget.setter , setget.getter );
289
- }
290
- }
291
-
292
- for (const std::pair<std::string, MethodInfo> pair : cl.signal_map ) {
293
- const MethodInfo &signal = pair.second ;
294
-
295
- std::vector<GDNativePropertyInfo> parameters;
296
- parameters.reserve (signal.arguments .size ());
297
-
298
- for (const PropertyInfo &par : signal.arguments ) {
299
- parameters.push_back (GDNativePropertyInfo{
300
- static_cast <uint32_t >(par.type ), // uint32_t type;
301
- par.name , // const char *name;
302
- par.class_name , // const char *class_name;
303
- par.hint , // uint32_t hint;
304
- par.hint_string , // const char *hint_string;
305
- par.usage , // uint32_t usage;
306
- });
307
- }
308
-
309
- internal::interface->classdb_register_extension_class_signal (internal::library, cl.name , pair.first .c_str (), parameters.data (), parameters.size ());
310
- }
311
-
312
- for (std::string constant : cl.constant_order ) {
313
- const std::pair<std::string, GDNativeInt> &def = cl.constant_map .find (constant)->second ;
314
-
315
- internal::interface->classdb_register_extension_class_integer_constant (internal::library, cl.name , def.first .c_str (), constant.c_str (), def.second );
316
- }
290
+ // Nothing to do here for now...
317
291
}
318
292
}
319
293
@@ -326,8 +300,8 @@ void ClassDB::deinitialize(GDNativeInitializationLevel p_level) {
326
300
327
301
internal::interface->classdb_unregister_extension_class (internal::library, cl.name );
328
302
329
- for (MethodBind * method : cl.method_order ) {
330
- memdelete (method);
303
+ for (auto method : cl.method_map ) {
304
+ memdelete (method. second );
331
305
}
332
306
}
333
307
}
0 commit comments