Skip to content

Commit

Permalink
iterate now fix later, agile software companies be like
Browse files Browse the repository at this point in the history
except fixing takes forever ☠️
also … there is no `Kernel#tap` 🤑
  • Loading branch information
ParadoxV5 committed Sep 18, 2023
1 parent 7192dc4 commit a863764
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 32 deletions.
4 changes: 2 additions & 2 deletions include/godot_rb.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ extern struct godot_rb_gdextension {
GDExtensionVariantFromTypeConstructorFunc variant_from_string_name;
GDExtensionPtrDestructor string_name_destroy;
// Object APIs
GDExtensionTypeFromVariantConstructorFunc object_from_variant;
GDExtensionVariantFromTypeConstructorFunc variant_from_object;
GDExtensionTypeFromVariantConstructorFunc object_ptr_from_variant;
GDExtensionVariantFromTypeConstructorFunc variant_from_object_ptr;
GDExtensionPtrDestructor object_destroy;
} godot_rb_gdextension;

Expand Down
18 changes: 11 additions & 7 deletions lib/godot/variant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,16 @@ def to_godot = self
end

def self.const_missing(name)
if Engine.has_singleton(name) # First, check Singletons
Engine.get_singleton(name) #: Object
elsif ClassDB.class_exists(name) # Second, check classes
Class.new const_get(Godot::ClassDB.get_parent_class(name)) #: singleton(Object)
else
super # raise {NameError}
end.tap { const_set name, _1 }
File.open('out.txt', 'a') { _1.puts name }
const_set(
name,
if Engine.has_singleton(name) # First, check Singletons
Engine.get_singleton(name) #: Object
elsif ClassDB.class_exists(name) # Second, check classes
Class.new const_get(ClassDB.get_parent_class(name)) #: singleton(Object)
else
super # raise {NameError}
end
)
end
end
13 changes: 10 additions & 3 deletions src/godot_rb.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ __attribute__((used)) GDExtensionBool godot_rb_main(
// Load GDExtension API
godot_rb_gdextension.variant_from_string = godot_rb_gdextension.get_variant_from_type_constructor(GDEXTENSION_VARIANT_TYPE_STRING);
godot_rb_gdextension.variant_from_string_name = godot_rb_gdextension.get_variant_from_type_constructor(GDEXTENSION_VARIANT_TYPE_STRING_NAME);
godot_rb_gdextension.variant_from_object = godot_rb_gdextension.get_variant_from_type_constructor(GDEXTENSION_VARIANT_TYPE_OBJECT);
godot_rb_gdextension.variant_from_object_ptr = godot_rb_gdextension.get_variant_from_type_constructor(GDEXTENSION_VARIANT_TYPE_OBJECT);
godot_rb_gdextension.string_from_variant = godot_rb_gdextension.get_variant_to_type_constructor(GDEXTENSION_VARIANT_TYPE_STRING);
godot_rb_gdextension.string_name_from_variant = godot_rb_gdextension.get_variant_to_type_constructor(GDEXTENSION_VARIANT_TYPE_STRING_NAME);
godot_rb_gdextension.object_from_variant = godot_rb_gdextension.get_variant_to_type_constructor(GDEXTENSION_VARIANT_TYPE_OBJECT);
godot_rb_gdextension.object_ptr_from_variant = godot_rb_gdextension.get_variant_to_type_constructor(GDEXTENSION_VARIANT_TYPE_OBJECT);
GDExtensionInterfaceVariantGetPtrConstructor variant_get_ptr_constructor =
(GDExtensionInterfaceVariantGetPtrConstructor)godot_rb_get_proc("variant_get_ptr_constructor");
godot_rb_gdextension.string_from_string_name = variant_get_ptr_constructor(GDEXTENSION_VARIANT_TYPE_STRING, 2);
Expand Down Expand Up @@ -94,7 +94,14 @@ bool godot_rb_protect(VALUE (* function)(VALUE var), VALUE* var_p) {
VALUE func = rb_funcall(backtrace, rb_intern("label"), 0);
VALUE file = rb_funcall(backtrace, rb_intern("path" ), 0);
int32_t line;
rb_integer_pack(rb_funcall(backtrace, rb_intern("lineno"), 0), &line, 1, sizeof(int32_t), 0, INTEGER_PACK_2COMP);
rb_integer_pack(
rb_funcall(backtrace, rb_intern("lineno"), 0),
&line,
1,
sizeof(int32_t),
0,
INTEGER_PACK_2COMP | INTEGER_PACK_NATIVE_BYTE_ORDER
);
print_error(
message, message,
StringValueCStr(func),
Expand Down
28 changes: 18 additions & 10 deletions src/ruby/engine.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
#include "variants.h"

void godot_rb_init_Engine(void) {
GDExtensionStringName engine_string_name = godot_rb_chars_to_string_name("Engine");
GDExtensionObjectPtr engine_object = (
(GDExtensionInterfaceGlobalGetSingleton)godot_rb_get_proc("global_get_singleton")
)(&engine_string_name);
godot_rb_gdextension.string_name_destroy(&engine_string_name);
GDExtensionVariantPtr engine_variant = godot_rb_variant_alloc();
godot_rb_gdextension.object_from_variant(&engine_object, engine_variant);
GDExtensionInterfaceGlobalGetSingleton gdext_global_get_singleton;
/** code around the general method call API so the singleton subclasses from Object rather than the singleton class */
VALUE godot_rb_Engine_impl_get_singleton(GDExtensionStringName name) {
GDExtensionObjectPtr object_ptr = gdext_global_get_singleton(&name);
godot_rb_gdextension.string_name_destroy(&name);
GDExtensionVariantPtr variant = godot_rb_variant_alloc();
godot_rb_gdextension.variant_from_object_ptr(variant, &object_ptr);
// Probably should not free an actually-returned pointer
VALUE m_Engine = godot_rb_wrap_variant(godot_rb_cObject, engine_variant);
rb_const_set(godot_rb_mGodot, rb_intern("Engine"), m_Engine);
return godot_rb_wrap_variant(godot_rb_cObject, variant);
}
VALUE godot_rb_Engine_get_singleton(__attribute__((unused)) VALUE self, VALUE name) {
return godot_rb_Engine_impl_get_singleton(godot_rb_obj_to_string_name(name));
}

void godot_rb_init_Engine(void) {
gdext_global_get_singleton = (GDExtensionInterfaceGlobalGetSingleton)godot_rb_get_proc("global_get_singleton");
VALUE Engine = godot_rb_Engine_impl_get_singleton(godot_rb_chars_to_string_name("Engine"));
rb_const_set(godot_rb_mGodot, rb_intern("Engine"), Engine);
rb_define_singleton_method(Engine, "get_singleton", godot_rb_Engine_get_singleton, 1);
}
8 changes: 4 additions & 4 deletions src/ruby/string_name.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ GDExtensionStringName godot_rb_obj_to_string_name(VALUE self) {

VALUE godot_rb_sym_from_string_name(GDExtensionConstStringNamePtr string_name) {
GDExtensionString string;
godot_rb_gdextension.string_from_string_name(&string, string_name);
godot_rb_gdextension.string_from_string_name(&string, &string_name);
// Because symbols of different encodings are still considered distinct, we must also serialize to UTF-8.
string2str_utf8
return rb_intern3(str, (long)length, rb_utf8_encoding());
return ID2SYM(rb_intern3(str, (long)length, rb_utf8_encoding()));
}
//FIXME: possible multiplication and casting overflows (though one should use buffers instead if they need 2GiB strings)
VALUE godot_rb_cStringName_i_to_sym(VALUE self) {
GDExtensionStringName string_name;
VALUE symbol = godot_rb_sym_from_string_name(string_name);
GDExtensionStringName string_name = godot_rb_obj_to_string_name(self);
VALUE symbol = godot_rb_sym_from_string_name(&string_name);
godot_rb_gdextension.string_name_destroy(&string_name);
return symbol;
}
Expand Down
14 changes: 8 additions & 6 deletions src/ruby/variant.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ VALUE godot_rb_parse_variant(GDExtensionVariantPtr variant) {
case GDEXTENSION_VARIANT_TYPE_OBJECT:
if RB_LIKELY(godot_rb_gdextension.variant_booleanize(variant)) { // Non-null check
// “`godot_rb_parse_object`”
GDExtensionObject object;
godot_rb_gdextension.object_from_variant(&object, variant);
GDExtensionObjectPtr object;
godot_rb_gdextension.object_ptr_from_variant(&object, variant);
GDExtensionStringName class_name_str;
godot_rb_gdextension.object_get_class_name(&object, godot_rb_library, &class_name_str);
godot_rb_gdextension.object_destroy(&object);
VALUE class_name = godot_rb_sym_from_string_name(class_name_str);
godot_rb_gdextension.object_get_class_name(object, godot_rb_library, &class_name_str);
godot_rb_gdextension.object_destroy(object);
VALUE class_name = godot_rb_sym_from_string_name(&class_name_str);
godot_rb_gdextension.string_name_destroy(class_name_str);
// “`godot_rb_wrap_object`”
return TypedData_Wrap_Struct(
Expand Down Expand Up @@ -199,7 +199,9 @@ static void godot_rb_cVariant_impl_godot_send(
GDExtensionVariantPtr r_return,
GDExtensionCallError* r_error
) {
godot_rb_gdextension.variant_call(self_variant, godot_rb_obj_to_string_name(meth), argv, argc, r_return, r_error);
GDExtensionStringName meth_string_name = godot_rb_obj_to_string_name(meth);
godot_rb_gdextension.variant_call(self_variant, &meth_string_name, argv, argc, r_return, r_error);
godot_rb_gdextension.string_name_destroy(&meth_string_name);
}
__attribute__((used)) VALUE godot_rb_cVariant_i_godot_send(int argc, VALUE* argv, VALUE self) {
VALUE meth, args;
Expand Down

0 comments on commit a863764

Please sign in to comment.