Module: Qt::Native

Defined in:
lib/qt/native.rb

Overview

Thin FFI access layer for generated bridge entry points.

Constant Summary collapse

ROOT =
File.expand_path('../..', __dir__)
GENERATED_API =
File.join(ROOT, 'build', 'generated', 'bridge_api.rb')
COERCERS =
{
  string: :to_s.to_proc,
  int: ->(value) { Integer(value) },
  bool: ->(value) { !value.nil? && value != false },
  pointer: lambda { |value|
    return nil if value.nil?

    value.respond_to?(:handle) ? value.handle : value
  }
}.freeze

Class Method Summary collapse

Class Method Details

.available?Boolean

Returns:

  • (Boolean)


26
27
28
29
30
# File 'lib/qt/native.rb', line 26

def available?
  return @available unless @available.nil?

  @available = Bridge.load! && Bridge.loaded?
end

.coerce_bridge_args(args, signature) ⇒ Object



84
85
86
87
88
89
# File 'lib/qt/native.rb', line 84

def coerce_bridge_args(args, signature)
  args.zip(signature).map do |value, type|
    coercer = COERCERS[type]
    coercer ? coercer.call(value) : value
  end
end

.define_bridge_wrapper(function_spec) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/qt/native.rb', line 51

def define_bridge_wrapper(function_spec)
  native_name = function_spec[:name].to_s.sub(/\Aqt_ruby_/, '')
  signature = function_spec[:args]
  bridge_name = function_spec[:name]

  define_singleton_method(native_name) do |*args|
    ensure_loaded!
    normalized = normalize_bridge_args(args, signature)
    converted = coerce_bridge_args(normalized, signature)
    Bridge.public_send(bridge_name, *converted)
  end
end

.define_bridge_wrappers!Object



40
41
42
43
44
45
46
47
48
49
# File 'lib/qt/native.rb', line 40

def define_bridge_wrappers!
  return if @bridge_wrappers_defined
  return unless defined?(Qt::BridgeAPI::FUNCTIONS)

  Qt::BridgeAPI::FUNCTIONS.each do |fn|
    define_bridge_wrapper(fn)
  end

  @bridge_wrappers_defined = true
end

.ensure_loaded!Object



32
33
34
35
36
37
38
# File 'lib/qt/native.rb', line 32

def ensure_loaded!
  return if available?

  detail = Bridge.load_error ? " (#{Bridge.load_error.message})" : ''
  raise NativeExtensionError,
        "Qt bridge is not available. Build it with: bundle exec rake compile#{detail}"
end

.ensure_missing_args_optional!(args, signature) ⇒ Object



75
76
77
78
# File 'lib/qt/native.rb', line 75

def ensure_missing_args_optional!(args, signature)
  missing = signature[args.length..]
  raise_wrong_arity(args.length, signature.length) unless missing.all? { |type| type == :pointer }
end

.normalize_bridge_args(args, signature) ⇒ Object



64
65
66
67
68
69
70
71
72
73
# File 'lib/qt/native.rb', line 64

def normalize_bridge_args(args, signature)
  if args.length < signature.length
    ensure_missing_args_optional!(args, signature)

    return args + ([nil] * (signature.length - args.length))
  end
  raise_wrong_arity(args.length, signature.length) if args.length > signature.length

  args
end

.raise_wrong_arity(given, expected) ⇒ Object

Raises:

  • (ArgumentError)


80
81
82
# File 'lib/qt/native.rb', line 80

def raise_wrong_arity(given, expected)
  raise ArgumentError, "wrong number of arguments (given #{given}, expected #{expected})"
end