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 8
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 12
def setup_class
  register_type
  setup_layout
  setup_constants
  setup_property_accessors
  setup_constructor
  TypeBuilder::CACHE[@gtype] = klass
end
target_gtype() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 21
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 71
def class_init_proc
  proc do |object_class_ptr, _data|
    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 92
def class_size
  parent_gtype.class_size + interface_gtypes.map(&:class_size).inject(0, :+)
end
gobject_interface_info(interface) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 65
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 57
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 49
def included_interfaces
  klass.included_modules - Object.included_modules
end
install_vfunc(container_struct, vfunc_name, vfunc_info, implementation) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 157
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 84
def instance_size
  size = parent_gtype.instance_size
  properties.each do
    size += FFI.type_size(:int32)
  end
  size
end
interface_gtypes() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 45
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 78
def interface_init_proc(interface)
  proc do |interface_ptr, _data|
    setup_interface_vfuncs interface, interface_ptr
  end
end
klass() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 53
def klass
  @klass ||= @info.described_class
end
layout_specification() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 166
def layout_specification
  parent_spec = [:parent, superclass::Struct, 0]
  offset = superclass::Struct.size
  fields_spec = properties.flat_map do |pinfo|
    spec = [pinfo.name.to_sym, :int32, offset]
    offset += FFI.type_size(:int32)
    spec
  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 41
def parent_gtype
  @parent_gtype ||= GType.new(klass.superclass.gtype)
end
parent_info() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 37
def parent_info
  @parent_info ||= gir.find_by_gtype(parent_gtype.to_i)
end
properties() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 162
def properties
  info.properties
end
property_getter() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 107
def property_getter
  proc do |object, _property_id, value, pspec|
    value.set_value object.send(pspec.get_name)
  end
end
property_setter() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 113
def property_setter
  proc do |object, _property_id, value, pspec|
    object.send("#{pspec.get_name}=", value.get_value)
  end
end
register_type() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 27
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_accessors_for_param_info(pinfo) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 183
def setup_accessors_for_param_info(pinfo)
  field_name = pinfo.name
  code = <<-CODE
  def #{field_name}
    @struct[:#{field_name}]
  end
  def #{field_name}= val
    @struct[:#{field_name}] = val
  end
  CODE

  klass.class_eval code
end
setup_constructor() click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 201
def setup_constructor
  code = <<-CODE
  def initialize
    ptr = GObject::Lib.g_object_newv #{@gtype}, 0, nil
    store_pointer(ptr)
  end
  CODE
  klass.class_eval code
end
setup_interface_vfunc(interface_info, interface_struct, impl) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 148
def setup_interface_vfunc(interface_info, interface_struct, impl)
  vfunc_name = impl.name
  vfunc_info = interface_info.find_vfunc vfunc_name.to_s

  if vfunc_info
    install_vfunc interface_struct, vfunc_name, vfunc_info, impl.implementation
  end
end
setup_interface_vfuncs(interface, interface_ptr) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 128
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_interface_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 96
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

  properties.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 177
def setup_property_accessors
  properties.each do |pinfo|
    setup_accessors_for_param_info pinfo
  end
end
setup_vfunc(super_class_struct, impl) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 139
def setup_vfunc(super_class_struct, impl)
  vfunc_name = impl.name
  vfunc_info = parent_info.find_vfunc vfunc_name.to_s

  if vfunc_info
    install_vfunc super_class_struct, vfunc_name, vfunc_info, impl.implementation
  end
end
setup_vfuncs(object_class_ptr) click to toggle source
# File lib/gir_ffi/builders/user_defined_builder.rb, line 119
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 super_class_struct, impl
  end
end