Skip to content

Commit

Permalink
Ruby-level fixes
Browse files Browse the repository at this point in the history
* Fix `Variant#method_missing` circular causes
* Correct `Object#__get_class` encoding
  * Create `String#to_sym`
* Stub `#_frame`, might be useful later according to the error spam
  • Loading branch information
ParadoxV5 committed Oct 1, 2023
1 parent 2c95895 commit ac7e8d3
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 11 deletions.
2 changes: 1 addition & 1 deletion lib/godot/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Object < Variant
private def __get_class
script = get_script #: RubyScript[Object]?
# TODO: could also be scripts from other languages…
script&.klass or Godot.const_get get_class, false
script&.klass or Godot.const_get get_class.to_sym, false
end
end
end
3 changes: 3 additions & 0 deletions lib/godot/ruby_language.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ def _add_named_global_constant(name, value) = RubyScript::Autoloads.const_set(na
def _remove_named_global_constant(name) = RubyScript::Autoloads.remove_const(name)

def _create_script = RubyScript.new

# ??
def _frame = nil
# !
# Dictionary _get_global_class_name ( String path ) virtual const
#
Expand Down
23 changes: 13 additions & 10 deletions lib/godot/variant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,23 @@ def method_missing(name, *args)
when '?'
godot_send("is_#{name[..-1]}", *args)
else
no_method_error = NoMethodError #: _Exception # https://github.com/soutaro/steep/issues/919
# First, check methods (if checking `attr_reader`s first, #[] can return a {Callable})
begin
godot_send(name, *args) # `rescue` attaches `KeyError` cause if this raises
return godot_send(name, *args) # `rescue` attaches `KeyError` cause if this raises
rescue NoMethodError => no_method_error
# Second, check `attr_reader`s
attr_reader_error = nil
if args.empty? # necessary condition for `attr_reader`
begin
return self[name]
rescue StandardError => attr_reader_error
# fall-through
end
# fall-through, clear {$!} to prevent circular causes
end
# @ t ype var no_method_error NoMethodError[self]
# Second, check `attr_reader`s
if args.empty? # necessary condition for `attr_reader`
begin
return self[name]
rescue => e # `attr_reader`s doesn’t work either: re-raise
raise no_method_error, cause: e
end
raise no_method_error, cause: attr_reader_error # `attr_reader`s doesn’t work: re-raise
else
raise no_method_error
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions sig/ruby_language.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ module Godot
def self._remove_named_global_constant: (interned name) -> top

def _create_script: () -> RubyScript[Object]
def _frame: () -> void

INSTANCE: RubyLanguage
end

Expand Down
4 changes: 4 additions & 0 deletions src/ruby/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,15 @@ VALUE godot_rb_cString_i_to_str(VALUE self) {
}
//FIXME: possible multiplication and casting overflows (though one should use buffers instead if they need 2GiB strings)

/** Serialize into a UTF-8 Symbol */
VALUE godot_rb_cString_i_to_sym(VALUE self) { return rb_str_intern(godot_rb_cString_i_to_s(self)); }

init(String, STRING)
// Endian test for UTF-32 -> `char[]`
volatile char32_t sample = 1;
godot_rb_encoding_UTF32 = rb_enc_find(RB_LIKELY(*(char*)&sample) ? "UTF-32LE" : "UTF-32BE");
rb_gc_register_mark_object(encoding_UTF32 = rb_enc_from_encoding(godot_rb_encoding_UTF32));
rb_define_method(cString, "to_s" , godot_rb_cString_i_to_s , 0);
rb_define_method(cString, "to_str", godot_rb_cString_i_to_str, 0);
rb_define_method(cString, "to_sym", godot_rb_cString_i_to_sym, 0);
}

0 comments on commit ac7e8d3

Please sign in to comment.