mirror of
https://github.com/godotengine/gdnative-demos.git
synced 2026-01-03 14:09:44 +03:00
246 lines
6.4 KiB
C
246 lines
6.4 KiB
C
#include <gdnative_api_struct.gen.h>
|
|
#include <stdio.h>
|
|
|
|
#include <GLFW/glfw3.h>
|
|
|
|
struct glfw {
|
|
GLFWwindow *window;
|
|
};
|
|
|
|
const godot_gdnative_core_api_struct *api = NULL;
|
|
const godot_gdnative_ext_nativescript_api_struct *nativescript_api = NULL;
|
|
|
|
void window_close_callback(GLFWwindow *window) {
|
|
godot_object *instance = glfwGetWindowUserPointer(window);
|
|
// emit a signal
|
|
|
|
printf("user says: \"please close.\"\n");
|
|
|
|
{
|
|
// Object.callv("emit_signal", ["closed"])
|
|
static godot_method_bind *mb = NULL;
|
|
if (!mb) {
|
|
mb = api->godot_method_bind_get_method("Object", "callv");
|
|
}
|
|
|
|
godot_variant v;
|
|
godot_array args;
|
|
api->godot_array_new(&args);
|
|
|
|
godot_string name;
|
|
api->godot_string_new(&name);
|
|
api->godot_string_parse_utf8(&name, "emit_signal");
|
|
|
|
{
|
|
godot_string signal_name;
|
|
api->godot_string_new(&signal_name);
|
|
api->godot_string_parse_utf8(&signal_name, "closed");
|
|
|
|
godot_variant signal_name_var;
|
|
api->godot_variant_new_string(&signal_name_var, &signal_name);
|
|
|
|
api->godot_array_append(&args, &signal_name_var);
|
|
|
|
api->godot_variant_destroy(&signal_name_var);
|
|
api->godot_string_destroy(&signal_name);
|
|
}
|
|
|
|
const void *c_args[] = {
|
|
&name,
|
|
&args
|
|
};
|
|
api->godot_method_bind_ptrcall(mb, instance, c_args, &v);
|
|
|
|
api->godot_string_destroy(&name);
|
|
api->godot_array_destroy(&args);
|
|
}
|
|
}
|
|
|
|
void *glfw_constructor(godot_object *instance, void *method_data);
|
|
void glfw_destructor(godot_object *instance, void *method_data, struct glfw *user_data);
|
|
|
|
godot_variant glfw_create_window(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args);
|
|
|
|
godot_variant glfw_close(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args);
|
|
|
|
godot_variant glfw_poll_events(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args);
|
|
|
|
godot_variant glfw_is_closed(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args);
|
|
|
|
void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *p_options) {
|
|
api = p_options->api_struct;
|
|
|
|
// now find our extensions
|
|
for (int i = 0; i < api->num_extensions; i++) {
|
|
switch (api->extensions[i]->type) {
|
|
case GDNATIVE_EXT_NATIVESCRIPT: {
|
|
nativescript_api = (godot_gdnative_ext_nativescript_api_struct *)api->extensions[i];
|
|
}; break;
|
|
default:
|
|
break;
|
|
};
|
|
};
|
|
}
|
|
|
|
void GDN_EXPORT godot_nativescript_init(void *p_handle) {
|
|
if (!glfwInit()) {
|
|
fprintf(stderr, "can't initialize GLFW\n");
|
|
return;
|
|
}
|
|
|
|
godot_instance_create_func create = {};
|
|
create.create_func = &glfw_constructor;
|
|
|
|
godot_instance_destroy_func destroy = {};
|
|
destroy.destroy_func = &glfw_destructor;
|
|
|
|
nativescript_api->godot_nativescript_register_class(p_handle, "GLFW", "Reference", create, destroy);
|
|
|
|
{
|
|
godot_instance_method create_window = {};
|
|
create_window.method = &glfw_create_window;
|
|
|
|
godot_method_attributes attributes = {};
|
|
attributes.rpc_type = GODOT_METHOD_RPC_MODE_DISABLED;
|
|
|
|
nativescript_api->godot_nativescript_register_method(p_handle, "GLFW", "create", attributes, create_window);
|
|
}
|
|
|
|
{
|
|
godot_instance_method close_window = {};
|
|
close_window.method = &glfw_close;
|
|
|
|
godot_method_attributes attributes = {};
|
|
attributes.rpc_type = GODOT_METHOD_RPC_MODE_DISABLED;
|
|
|
|
nativescript_api->godot_nativescript_register_method(p_handle, "GLFW", "close", attributes, close_window);
|
|
}
|
|
|
|
{
|
|
godot_instance_method poll_events = {};
|
|
poll_events.method = &glfw_poll_events;
|
|
|
|
godot_method_attributes attributes = {};
|
|
attributes.rpc_type = GODOT_METHOD_RPC_MODE_DISABLED;
|
|
|
|
nativescript_api->godot_nativescript_register_method(p_handle, "GLFW", "poll_events", attributes, poll_events);
|
|
}
|
|
|
|
{
|
|
godot_instance_method is_closed = {};
|
|
is_closed.method = &glfw_is_closed;
|
|
|
|
godot_method_attributes attributes = {};
|
|
attributes.rpc_type = GODOT_METHOD_RPC_MODE_DISABLED;
|
|
|
|
nativescript_api->godot_nativescript_register_method(p_handle, "GLFW", "is_closed", attributes, is_closed);
|
|
}
|
|
|
|
{
|
|
godot_signal signal = {};
|
|
signal.num_args = 0;
|
|
signal.num_default_args = 0;
|
|
api->godot_string_new(&signal.name);
|
|
api->godot_string_parse_utf8(&signal.name, "closed");
|
|
|
|
nativescript_api->godot_nativescript_register_signal(p_handle, "GLFW", &signal);
|
|
|
|
api->godot_string_destroy(&signal.name);
|
|
}
|
|
}
|
|
|
|
void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *options) {
|
|
glfwTerminate();
|
|
}
|
|
|
|
godot_variant glfw_create_window(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args) {
|
|
godot_variant ret;
|
|
api->godot_variant_new_nil(&ret);
|
|
|
|
int width = api->godot_variant_as_int(args[0]);
|
|
int height = api->godot_variant_as_int(args[1]);
|
|
godot_string title = api->godot_variant_as_string(args[2]);
|
|
|
|
printf("create window: %dx%d\n", width, height);
|
|
|
|
{
|
|
godot_char_string title_char_string = api->godot_string_utf8(&title);
|
|
const char *c_title = api->godot_char_string_get_data(&title_char_string);
|
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
|
|
user_data->window = glfwCreateWindow(width, height, c_title, NULL, NULL);
|
|
|
|
api->godot_char_string_destroy(&title_char_string);
|
|
|
|
glfwSetWindowUserPointer(user_data->window, instance);
|
|
|
|
glfwSetWindowCloseCallback(user_data->window, window_close_callback);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
godot_variant glfw_close(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args) {
|
|
godot_variant ret;
|
|
api->godot_variant_new_nil(&ret);
|
|
|
|
if (user_data->window) {
|
|
glfwDestroyWindow(user_data->window);
|
|
user_data->window = NULL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
godot_variant glfw_is_closed(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args) {
|
|
godot_variant ret;
|
|
api->godot_variant_new_bool(&ret, user_data->window == NULL);
|
|
|
|
return ret;
|
|
}
|
|
|
|
godot_variant glfw_poll_events(godot_object *instance, void *method_data,
|
|
struct glfw *user_data,
|
|
int num_args, godot_variant **args) {
|
|
godot_variant ret;
|
|
api->godot_variant_new_nil(&ret);
|
|
|
|
glfwPollEvents();
|
|
|
|
return ret;
|
|
}
|
|
|
|
void *glfw_constructor(godot_object *instance, void *method_data) {
|
|
printf("GLFW._init()\n");
|
|
|
|
struct glfw *user_data = api->godot_alloc(sizeof(struct glfw));
|
|
user_data->window = NULL;
|
|
|
|
return user_data;
|
|
}
|
|
|
|
void glfw_destructor(godot_object *instance, void *method_data, struct glfw *user_data) {
|
|
// destroy window
|
|
|
|
if (user_data->window) {
|
|
glfwDestroyWindow(user_data->window);
|
|
user_data->window = NULL;
|
|
}
|
|
|
|
api->godot_free(user_data);
|
|
}
|