class GirFFI::Builders::UserDefinedBuilder

Implements the creation of GObject subclasses from Ruby.

Public Class Methods

new(info) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 10
def initialize(info)
  @info = info
end

Public Instance Methods

setup_class() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 14
def setup_class
  setup_layout
  register_type
  setup_constants
  setup_property_accessors
  setup_initializer
  TypeBuilder::CACHE[@gtype] = klass
end
target_gtype() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 23
def target_gtype
  @gtype ||= klass.gtype
end

Private Instance Methods

class_init_proc() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 73
def class_init_proc
  proc do |type_class_or_ptr, _data|
    object_class_ptr = type_class_or_ptr.to_ptr
    setup_properties object_class_ptr
    setup_vfuncs object_class_ptr
  end
end
class_size() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 100
def class_size
  parent_gtype.class_size + interface_gtypes.map(&:class_size).inject(0, :+)
end
field_alignment() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 174
def field_alignment
  @field_alignment ||= superclass::Struct.alignment
end
gobject_interface_info(interface) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 67
def gobject_interface_info(interface)
  GObject::InterfaceInfo.new.tap do |interface_info|
    interface_info.interface_init = interface_init_proc(interface)
  end
end
gobject_type_info() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 59
def gobject_type_info
  GObject::TypeInfo.new.tap do |type_info|
    type_info.class_size = class_size
    type_info.instance_size = instance_size
    type_info.class_init = class_init_proc
  end
end
included_interfaces() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 51
def included_interfaces
  klass.included_interfaces
end
install_vfunc(container_struct, vfunc_name, vfunc_info, implementation) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 155
def install_vfunc(container_struct, vfunc_name, vfunc_info, implementation)
  vfunc = VFuncBuilder.new(vfunc_info).build_class
  container_struct[vfunc_name] = vfunc.from implementation
end
instance_size() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 88
def instance_size
  if property_fields.any?
    last_property = property_fields.last
    size = last_property.offset
    type_size = FFI.type_size(last_property.ffi_type)
    size += [type_size, field_alignment].max
  else
    size = parent_gtype.instance_size
  end
  size
end
interface_gtypes() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 47
def interface_gtypes
  included_interfaces.map { |interface| GType.new(interface.gtype) }
end
interface_init_proc(interface) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 81
def interface_init_proc(interface)
  proc do |interface_or_ptr, _data|
    interface_ptr = interface_or_ptr.to_ptr
    setup_interface_vfuncs interface, interface_ptr
  end
end
klass() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 55
def klass
  @klass ||= @info.described_class
end
layout_specification() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 164
def layout_specification
  parent_spec = [:parent, superclass::Struct]

  fields_spec = property_fields.flat_map do |property_info|
    [property_info.field_symbol, property_info.ffi_type, property_info.offset]
  end

  parent_spec + fields_spec
end
method_introspection_data(_method) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 197
def method_introspection_data(_method)
  nil
end
parent_gtype() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 43
def parent_gtype
  @info.parent_gtype
end
parent_info() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 39
def parent_info
  @info.parent
end
properties() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 160
def properties
  @properties ||= info.properties
end
property_fields() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 184
def property_fields
  @property_fields ||=
    begin
      offset = parent_gtype.instance_size
      properties.map do |param_spec|
        field_info = UserDefinedPropertyInfo.new(param_spec, info, offset)
        type_size = FFI.type_size(field_info.ffi_type)
        offset += [type_size, field_alignment].max
        field_info
      end
    end
end
property_getter() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 115
def property_getter
  proc do |object, _property_id, value, pspec|
    value.set_value object.send(pspec.accessor_name)
  end
end
property_setter() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 121
def property_setter
  proc do |object, _property_id, value, pspec|
    object.send("#{pspec.accessor_name}=", value.get_value)
  end
end
register_type() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 29
def register_type
  @gtype = GObject.type_register_static(parent_gtype.to_i,
                                        info.g_name,
                                        gobject_type_info, 0)
  included_interfaces.each do |interface|
    ifinfo = gobject_interface_info interface
    GObject.type_add_interface_static @gtype, interface.gtype, ifinfo
  end
end
setup_interface_vfuncs(interface, interface_ptr) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 136
def setup_interface_vfuncs(interface, interface_ptr)
  interface_builder = interface.gir_ffi_builder

  interface_struct = interface_builder.interface_struct::Struct.new(interface_ptr)
  interface_info = interface_builder.info

  info.vfunc_implementations.each do |impl|
    setup_vfunc interface_info, interface_struct, impl
  end
end
setup_properties(object_class_ptr) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 104
def setup_properties(object_class_ptr)
  object_class = GObject::ObjectClass.wrap object_class_ptr

  object_class.get_property = property_getter
  object_class.set_property = property_setter

  property_fields.each_with_index do |property, index|
    object_class.install_property index + 1, property.param_spec
  end
end
setup_property_accessors() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 178
def setup_property_accessors
  property_fields.each do |field_info|
    FieldBuilder.new(field_info, klass).build
  end
end
setup_vfunc(ancestor_info, ancestor_struct, impl) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 147
def setup_vfunc(ancestor_info, ancestor_struct, impl)
  vfunc_name = impl.name
  vfunc_info = ancestor_info.find_vfunc vfunc_name.to_s
  return unless vfunc_info

  install_vfunc ancestor_struct, vfunc_name, vfunc_info, impl.implementation
end
setup_vfuncs(object_class_ptr) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 127
def setup_vfuncs(object_class_ptr)
  super_class_struct =
    superclass.gir_ffi_builder.object_class_struct::Struct.new(object_class_ptr)

  info.vfunc_implementations.each do |impl|
    setup_vfunc parent_info, super_class_struct, impl
  end
end