Implement working example
Implement a working example using the GDExtension C API.
This commit is contained in:
parent
2c4cdb41a1
commit
f8025b805a
4 changed files with 25 additions and 33 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -16,10 +16,6 @@
|
||||||
!README
|
!README
|
||||||
!TODO
|
!TODO
|
||||||
|
|
||||||
# /bin
|
|
||||||
!/bin/
|
|
||||||
/bin/*
|
|
||||||
|
|
||||||
!/bin/main.gdextension
|
!/bin/main.gdextension
|
||||||
|
|
||||||
# /docs
|
# /docs
|
||||||
|
|
@ -35,6 +31,12 @@
|
||||||
!/engine/project.godot
|
!/engine/project.godot
|
||||||
!/engine/icon.svg
|
!/engine/icon.svg
|
||||||
|
|
||||||
|
# /engine/bin
|
||||||
|
!/engine/bin
|
||||||
|
/engine/bin/*
|
||||||
|
|
||||||
|
!/engine/bin/librtr.gdextension
|
||||||
|
|
||||||
# /src
|
# /src
|
||||||
!/src/
|
!/src/
|
||||||
/src/*
|
/src/*
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
[configuration]
|
|
||||||
entry_symbol = "rtr_extension_init"
|
|
||||||
compatibility_minimum = "4.2"
|
|
||||||
|
|
||||||
[libraries]
|
|
||||||
windows.x86_64 = "../src/.libs/librtr.dll"
|
|
||||||
macos = "../src/.libs/librtr.dylib"
|
|
||||||
linux.debug.x86_64 = "res://../src/.libs/librtr.so"
|
|
||||||
8
engine/bin/librtr.gdextension
Normal file
8
engine/bin/librtr.gdextension
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
[configuration]
|
||||||
|
entry_symbol = "librtr_extension_init"
|
||||||
|
compatibility_minimum = "4.2"
|
||||||
|
|
||||||
|
[libraries]
|
||||||
|
windows.x86_64 = "res://../src/.libs/librtr.dll"
|
||||||
|
macos = "res://../src/.libs/librtr.dylib"
|
||||||
|
linux.debug.x86_64 = "res://../src/.libs/librtr.so"
|
||||||
32
src/main.c
32
src/main.c
|
|
@ -19,6 +19,9 @@ int main()
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Boilerplate provided by examples. */
|
||||||
|
/* Some lines are over 80 characters. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t godot_data_dont_touch_this[sizeof(void *)];
|
uint8_t godot_data_dont_touch_this[sizeof(void *)];
|
||||||
} String;
|
} String;
|
||||||
|
|
@ -31,55 +34,46 @@ typedef struct {
|
||||||
uint8_t godot_data_dont_touch_this[24];
|
uint8_t godot_data_dont_touch_this[24];
|
||||||
} Variant;
|
} Variant;
|
||||||
|
|
||||||
// GDExtension interface function pointers
|
|
||||||
static GDExtensionInterfaceStringNewWithUtf8Chars string_new_with_utf8_chars;
|
static GDExtensionInterfaceStringNewWithUtf8Chars string_new_with_utf8_chars;
|
||||||
static GDExtensionInterfaceVariantGetPtrConstructor variant_get_ptr_constructor;
|
static GDExtensionInterfaceVariantGetPtrConstructor variant_get_ptr_constructor;
|
||||||
static GDExtensionInterfaceVariantGetPtrDestructor variant_get_ptr_destructor;
|
static GDExtensionInterfaceVariantGetPtrDestructor variant_get_ptr_destructor;
|
||||||
static GDExtensionInterfaceGetVariantFromTypeConstructor get_variant_from_type_constructor;
|
static GDExtensionInterfaceGetVariantFromTypeConstructor get_variant_from_type_constructor;
|
||||||
static GDExtensionInterfaceVariantGetPtrUtilityFunction variant_get_ptr_utility_function;
|
static GDExtensionInterfaceVariantGetPtrUtilityFunction variant_get_ptr_utility_function;
|
||||||
static GDExtensionInterfaceVariantDestroy variant_destroy;
|
static GDExtensionInterfaceVariantDestroy variant_destroy;
|
||||||
// Godot API function pointers
|
|
||||||
|
/* GDExtension API Pointers */
|
||||||
static GDExtensionPtrConstructor construct_StringName_from_String;
|
static GDExtensionPtrConstructor construct_StringName_from_String;
|
||||||
static GDExtensionVariantFromTypeConstructorFunc construct_Variant_from_String;
|
static GDExtensionVariantFromTypeConstructorFunc construct_Variant_from_String;
|
||||||
static GDExtensionPtrDestructor destroy_String;
|
static GDExtensionPtrDestructor destroy_String;
|
||||||
static GDExtensionPtrDestructor destroy_StringName;
|
static GDExtensionPtrDestructor destroy_StringName;
|
||||||
|
|
||||||
// here is our global "print" StringName
|
|
||||||
static StringName print_StringName;
|
static StringName print_StringName;
|
||||||
// and here is our global "print" function
|
|
||||||
static GDExtensionPtrUtilityFunction print_function;
|
static GDExtensionPtrUtilityFunction print_function;
|
||||||
|
|
||||||
StringName construct_StringName_from_cstring(const char *text) {
|
StringName construct_StringName_from_cstring(const char *text) {
|
||||||
// 1. Construct a String from the C string
|
|
||||||
String string;
|
String string;
|
||||||
string_new_with_utf8_chars(&string, text);
|
string_new_with_utf8_chars(&string, text);
|
||||||
|
|
||||||
// 2. Construct a StringName from the String
|
|
||||||
StringName string_name;
|
StringName string_name;
|
||||||
GDExtensionConstTypePtr constructor_arguments[1] = { &string };
|
GDExtensionConstTypePtr constructor_arguments[1] = { &string };
|
||||||
construct_StringName_from_String(&string_name, constructor_arguments);
|
construct_StringName_from_String(&string_name, constructor_arguments);
|
||||||
|
|
||||||
// 3. Destroy the String, since it's not needed anymore
|
|
||||||
destroy_String(&string);
|
destroy_String(&string);
|
||||||
|
|
||||||
return string_name;
|
return string_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(const char *text) {
|
void print(const char *text) {
|
||||||
// 1. Construct a String from the C string
|
|
||||||
String string;
|
String string;
|
||||||
string_new_with_utf8_chars(&string, text);
|
string_new_with_utf8_chars(&string, text);
|
||||||
|
|
||||||
// 2. Construct a Variant from the String
|
|
||||||
Variant arg1;
|
Variant arg1;
|
||||||
construct_Variant_from_String(&arg1, &string);
|
construct_Variant_from_String(&arg1, &string);
|
||||||
|
|
||||||
// 3. Call the utility function
|
|
||||||
// Since it's a void function, use "NULL" for the return pointer
|
|
||||||
GDExtensionConstVariantPtr args[1] = { &arg1 };
|
GDExtensionConstVariantPtr args[1] = { &arg1 };
|
||||||
print_function(NULL, args, 1);
|
print_function(NULL, args, 1);
|
||||||
|
|
||||||
// 4. Clean up resources that are no longer needed
|
|
||||||
variant_destroy(&arg1);
|
variant_destroy(&arg1);
|
||||||
destroy_String(&string);
|
destroy_String(&string);
|
||||||
}
|
}
|
||||||
|
|
@ -89,19 +83,15 @@ void initialize(void *userdata, GDExtensionInitializationLevel p_level) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringName constructor at index 2 is the one that receives String
|
|
||||||
// You can find this information in `extension_api.json` file
|
|
||||||
construct_StringName_from_String = variant_get_ptr_constructor(GDEXTENSION_VARIANT_TYPE_STRING_NAME, 2);
|
construct_StringName_from_String = variant_get_ptr_constructor(GDEXTENSION_VARIANT_TYPE_STRING_NAME, 2);
|
||||||
construct_Variant_from_String = get_variant_from_type_constructor(GDEXTENSION_VARIANT_TYPE_STRING);
|
construct_Variant_from_String = get_variant_from_type_constructor(GDEXTENSION_VARIANT_TYPE_STRING);
|
||||||
destroy_String = variant_get_ptr_destructor(GDEXTENSION_VARIANT_TYPE_STRING);
|
destroy_String = variant_get_ptr_destructor(GDEXTENSION_VARIANT_TYPE_STRING);
|
||||||
destroy_StringName = variant_get_ptr_destructor(GDEXTENSION_VARIANT_TYPE_STRING_NAME);
|
destroy_StringName = variant_get_ptr_destructor(GDEXTENSION_VARIANT_TYPE_STRING_NAME);
|
||||||
|
|
||||||
// Initialize "print" StringName
|
|
||||||
print_StringName = construct_StringName_from_cstring("print");
|
print_StringName = construct_StringName_from_cstring("print");
|
||||||
// then fetch the "print" function pointer
|
|
||||||
print_function = variant_get_ptr_utility_function(&print_StringName, 2648703342);
|
print_function = variant_get_ptr_utility_function(&print_StringName, 2648703342);
|
||||||
|
|
||||||
print("Hello GDExtension from C!");
|
print("Starting...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinitialize(void *userdata, GDExtensionInitializationLevel p_level) {
|
void deinitialize(void *userdata, GDExtensionInitializationLevel p_level) {
|
||||||
|
|
@ -109,20 +99,20 @@ void deinitialize(void *userdata, GDExtensionInitializationLevel p_level) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("Goodbye GDExtension from C!");
|
print("Exited.");
|
||||||
|
|
||||||
// Destroy "print" StringName
|
|
||||||
destroy_StringName(&print_StringName);
|
destroy_StringName(&print_StringName);
|
||||||
}
|
}
|
||||||
|
|
||||||
GDExtensionBool hello_extension_entry(
|
/* librtr object; called by Godot when it reads the librtr.gdextension file that
|
||||||
|
* provides a configuration using this name. */
|
||||||
|
GDExtensionBool librtr_extension_init(
|
||||||
GDExtensionInterfaceGetProcAddress p_get_proc_address,
|
GDExtensionInterfaceGetProcAddress p_get_proc_address,
|
||||||
GDExtensionClassLibraryPtr p_library,
|
GDExtensionClassLibraryPtr p_library,
|
||||||
GDExtensionInitialization *r_initialization
|
GDExtensionInitialization *r_initialization
|
||||||
) {
|
) {
|
||||||
r_initialization->initialize = &initialize;
|
r_initialization->initialize = &initialize;
|
||||||
r_initialization->deinitialize = &deinitialize;
|
r_initialization->deinitialize = &deinitialize;
|
||||||
// save the GDExtension API function pointers globally
|
|
||||||
string_new_with_utf8_chars = (GDExtensionInterfaceStringNewWithUtf8Chars) p_get_proc_address("string_new_with_utf8_chars");
|
string_new_with_utf8_chars = (GDExtensionInterfaceStringNewWithUtf8Chars) p_get_proc_address("string_new_with_utf8_chars");
|
||||||
variant_get_ptr_constructor = (GDExtensionInterfaceVariantGetPtrConstructor) p_get_proc_address("variant_get_ptr_constructor");
|
variant_get_ptr_constructor = (GDExtensionInterfaceVariantGetPtrConstructor) p_get_proc_address("variant_get_ptr_constructor");
|
||||||
variant_get_ptr_destructor = (GDExtensionInterfaceVariantGetPtrDestructor) p_get_proc_address("variant_get_ptr_destructor");
|
variant_get_ptr_destructor = (GDExtensionInterfaceVariantGetPtrDestructor) p_get_proc_address("variant_get_ptr_destructor");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue