libui 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/libui/ffi.rb +2 -68
- data/lib/libui/fiddle_patch.rb +79 -0
- data/lib/libui/libui_base.rb +45 -0
- data/lib/libui/version.rb +1 -1
- data/lib/libui.rb +9 -48
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5856ad97384408635e170c1ea252dc3dbdfa1ba3955bfc8b8c1ac2c29585ac1
|
4
|
+
data.tar.gz: 67a9b78e39b61805afca932fc80365b59e068493f2da937c57b03e1500a2adf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5204e35c1c0f4b0c5f8acd69a4a1d76b6482a1fb298376c99ce29632a202c1340a39e017b68c563b4539a74e721b1611cd3a732b4a9983ef2a0fb3eef7a80b3c
|
7
|
+
data.tar.gz: 8fb83fe3d145646bacb598dc88413364d534493f275c2e0ef637e9718908fe895796a1cb95cdb56f6c6d24b216f23ed68a7812a0c0978a5c700a014ecd0d1573
|
data/README.md
CHANGED
@@ -69,6 +69,7 @@ Compared to original libui written in C,
|
|
69
69
|
|
70
70
|
* At the moment, it is not object-oriented.
|
71
71
|
* Instead of providing a half-baked object-oriented approach, leave it as is.
|
72
|
+
* [A list of DSLs for LibUI.](https://github.com/kojix2/LibUI/wiki/DSL-for-LibUI)
|
72
73
|
|
73
74
|
### How to use fiddle pointers?
|
74
75
|
|
data/lib/libui/ffi.rb
CHANGED
@@ -1,78 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fiddle/import'
|
4
|
-
|
5
|
-
module Fiddle
|
6
|
-
# Change the Function to hold a little more information.
|
7
|
-
class Function
|
8
|
-
# Note:
|
9
|
-
# Ruby 2.7 Fiddle::Function dose not have @argument_types
|
10
|
-
# Ruby 3.0 Fiddle::Function has @argument_types
|
11
|
-
attr_accessor :callback_argument_types, :argument_types
|
12
|
-
end
|
13
|
-
|
14
|
-
module Importer
|
15
|
-
def parse_signature(signature, tymap = nil)
|
16
|
-
tymap ||= {}
|
17
|
-
ctype, func, args = case compact(signature)
|
18
|
-
when /^(?:[\w\*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/
|
19
|
-
[TYPE_VOIDP, Regexp.last_match(1), Regexp.last_match(2)]
|
20
|
-
when /^([\w\*\s]+[*\s])(\w+)\((.*?)\);?$/
|
21
|
-
[parse_ctype(Regexp.last_match(1).strip, tymap), Regexp.last_match(2), Regexp.last_match(3)]
|
22
|
-
else
|
23
|
-
raise("can't parserake the function prototype: #{signature}")
|
24
|
-
end
|
25
|
-
symname = func
|
26
|
-
callback_argument_types = {} # Added
|
27
|
-
argtype = split_arguments(args).collect.with_index do |arg, idx| # Added with_index
|
28
|
-
# Check if it is a function pointer or not
|
29
|
-
if arg =~ /\(\*.*\)\(.*\)/ # Added
|
30
|
-
# From the arguments, create a notation that looks like a function declaration
|
31
|
-
# int(*f)(int *, void *) -> int f(int *, void *)
|
32
|
-
func_arg = arg.sub('(*', ' ').sub(')', '') # Added
|
33
|
-
# Use Fiddle's parse_signature method again.
|
34
|
-
callback_argument_types[idx] = parse_signature(func_arg) # Added
|
35
|
-
end
|
36
|
-
parse_ctype(arg, tymap)
|
37
|
-
end
|
38
|
-
# Added callback_argument_types. Original method return only 3 values.
|
39
|
-
[symname, ctype, argtype, callback_argument_types]
|
40
|
-
end
|
41
|
-
|
42
|
-
def extern(signature, *opts)
|
43
|
-
symname, ctype, argtype, callback_argument_types = parse_signature(signature, type_alias)
|
44
|
-
opt = parse_bind_options(opts)
|
45
|
-
func = import_function(symname, ctype, argtype, opt[:call_type])
|
46
|
-
|
47
|
-
func.callback_argument_types = callback_argument_types # Added
|
48
|
-
# Ruby 2.7 Fiddle::Function dose not have @argument_types
|
49
|
-
# Ruby 3.0 Fiddle::Function has @argument_types
|
50
|
-
func.argument_types = argtype
|
51
|
-
|
52
|
-
name = symname.gsub(/@.+/, '')
|
53
|
-
@func_map[name] = func
|
54
|
-
# define_method(name){|*args,&block| f.call(*args,&block)}
|
55
|
-
begin
|
56
|
-
/^(.+?):(\d+)/ =~ caller.first
|
57
|
-
file = Regexp.last_match(1)
|
58
|
-
line = Regexp.last_match(2).to_i
|
59
|
-
rescue StandardError
|
60
|
-
file, line = __FILE__, __LINE__ + 3
|
61
|
-
end
|
62
|
-
module_eval(<<-EOS, file, line)
|
63
|
-
def #{name}(*args, &block)
|
64
|
-
@func_map['#{name}'].call(*args,&block)
|
65
|
-
end
|
66
|
-
EOS
|
67
|
-
module_function(name)
|
68
|
-
func
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
4
|
+
require_relative 'fiddle_patch'
|
72
5
|
|
73
6
|
module LibUI
|
74
7
|
module FFI
|
75
8
|
extend Fiddle::Importer
|
9
|
+
extend FiddlePatch
|
76
10
|
|
77
11
|
begin
|
78
12
|
dlload LibUI.ffi_lib
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module LibUI
|
2
|
+
module FiddlePatch
|
3
|
+
def parse_signature(signature, tymap = nil)
|
4
|
+
tymap ||= {}
|
5
|
+
ctype, func, args = case compact(signature)
|
6
|
+
when /^(?:[\w\*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/
|
7
|
+
[TYPE_VOIDP, Regexp.last_match(1), Regexp.last_match(2)]
|
8
|
+
when /^([\w\*\s]+[*\s])(\w+)\((.*?)\);?$/
|
9
|
+
[parse_ctype(Regexp.last_match(1).strip, tymap), Regexp.last_match(2), Regexp.last_match(3)]
|
10
|
+
else
|
11
|
+
raise("can't parserake the function prototype: #{signature}")
|
12
|
+
end
|
13
|
+
symname = func
|
14
|
+
callback_argument_types = {} # Added
|
15
|
+
argtype = split_arguments(args).collect.with_index do |arg, idx| # Added with_index
|
16
|
+
# Check if it is a function pointer or not
|
17
|
+
if arg =~ /\(\*.*\)\(.*\)/ # Added
|
18
|
+
# From the arguments, create a notation that looks like a function declaration
|
19
|
+
# int(*f)(int *, void *) -> int f(int *, void *)
|
20
|
+
func_arg = arg.sub('(*', ' ').sub(')', '') # Added
|
21
|
+
# Use Fiddle's parse_signature method again.
|
22
|
+
callback_argument_types[idx] = parse_signature(func_arg) # Added
|
23
|
+
end
|
24
|
+
parse_ctype(arg, tymap)
|
25
|
+
end
|
26
|
+
# Added callback_argument_types. Original method return only 3 values.
|
27
|
+
[symname, ctype, argtype, callback_argument_types]
|
28
|
+
end
|
29
|
+
|
30
|
+
def extern(signature, *opts)
|
31
|
+
symname, ctype, argtype, callback_argument_types = parse_signature(signature, type_alias)
|
32
|
+
opt = parse_bind_options(opts)
|
33
|
+
func = import_function(symname, ctype, argtype, opt[:call_type])
|
34
|
+
|
35
|
+
# callback_argument_types
|
36
|
+
func.instance_variable_set(:@callback_argument_types,
|
37
|
+
callback_argument_types) # Added
|
38
|
+
# attr_reader
|
39
|
+
def func.callback_argument_types
|
40
|
+
@callback_argument_types
|
41
|
+
end
|
42
|
+
|
43
|
+
# argument_types
|
44
|
+
# Ruby 2.7 Fiddle::Function dose not have @argument_types
|
45
|
+
# Ruby 3.0 Fiddle::Function has @argument_types
|
46
|
+
if func.instance_variable_defined?(:@argument_types)
|
47
|
+
# check if @argument_types are the same
|
48
|
+
if func.instance_variable_get(:@argument_types) != argtype
|
49
|
+
warn "#{symname} func.argument_types:#{func.argument_types} != argtype #{argtype}"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
func.instance_variable_set(:@argument_types, argtype)
|
53
|
+
end
|
54
|
+
# attr_reader
|
55
|
+
def func.argument_types
|
56
|
+
@argument_types
|
57
|
+
end
|
58
|
+
|
59
|
+
name = symname.gsub(/@.+/, '')
|
60
|
+
@func_map[name] = func
|
61
|
+
# define_method(name){|*args,&block| f.call(*args,&block)}
|
62
|
+
begin
|
63
|
+
/^(.+?):(\d+)/ =~ caller.first
|
64
|
+
file = Regexp.last_match(1)
|
65
|
+
line = Regexp.last_match(2).to_i
|
66
|
+
rescue StandardError
|
67
|
+
file, line = __FILE__, __LINE__ + 3
|
68
|
+
end
|
69
|
+
module_eval(<<-EOS, file, line)
|
70
|
+
def #{name}(*args, &block)
|
71
|
+
@func_map['#{name}'].call(*args,&block)
|
72
|
+
end
|
73
|
+
EOS
|
74
|
+
module_function(name)
|
75
|
+
func
|
76
|
+
end
|
77
|
+
end
|
78
|
+
private_constant :FiddlePatch
|
79
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LibUI
|
4
|
+
module LibUIBase
|
5
|
+
FFI.func_map.each_key do |original_method_name|
|
6
|
+
name = Utils.convert_to_ruby_method(original_method_name)
|
7
|
+
func = FFI.func_map[original_method_name]
|
8
|
+
|
9
|
+
define_method(name) do |*args, &blk|
|
10
|
+
# Assume that block is the last argument.
|
11
|
+
args << blk if blk
|
12
|
+
|
13
|
+
# The proc object is converted to a Closure::BlockCaller object.
|
14
|
+
args.map!.with_index do |arg, idx|
|
15
|
+
if arg.is_a?(Proc)
|
16
|
+
# The types of the function arguments are recorded beforehand.
|
17
|
+
# See the monkey patch in ffi.rb.
|
18
|
+
callback = Fiddle::Closure::BlockCaller.new(
|
19
|
+
*func.callback_argument_types[idx][1..2], &arg
|
20
|
+
)
|
21
|
+
# Protect from GC
|
22
|
+
# See https://github.com/kojix2/LibUI/issues/8
|
23
|
+
receiver = args[0]
|
24
|
+
if receiver.instance_variable_defined?(:@callbacks)
|
25
|
+
receiver.instance_variable_get(:@callbacks) << callback
|
26
|
+
else
|
27
|
+
receiver.instance_variable_set(:@callbacks, [callback])
|
28
|
+
end
|
29
|
+
callback
|
30
|
+
else
|
31
|
+
arg
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Make it possible to omit the last nil. This may be an over-optimization.
|
36
|
+
siz = func.argument_types.size - 1
|
37
|
+
args[siz] = nil if args.size == siz
|
38
|
+
|
39
|
+
FFI.public_send(original_method_name, *args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private_constant :LibUIBase
|
45
|
+
end
|
data/lib/libui/version.rb
CHANGED
data/lib/libui.rb
CHANGED
@@ -10,7 +10,7 @@ module LibUI
|
|
10
10
|
attr_accessor :ffi_lib
|
11
11
|
end
|
12
12
|
|
13
|
-
lib_name = "libui.#{RbConfig::CONFIG[
|
13
|
+
lib_name = "libui.#{RbConfig::CONFIG['SOEXT']}"
|
14
14
|
|
15
15
|
self.ffi_lib = if ENV['LIBUIDIR'] && !ENV['LIBUIDIR'].empty?
|
16
16
|
File.expand_path(lib_name, ENV['LIBUIDIR'])
|
@@ -19,56 +19,17 @@ module LibUI
|
|
19
19
|
end
|
20
20
|
|
21
21
|
require_relative 'libui/ffi'
|
22
|
+
require_relative 'libui/libui_base'
|
22
23
|
|
23
|
-
|
24
|
-
FFI.func_map.each_key do |original_method_name|
|
25
|
-
name = Utils.convert_to_ruby_method(original_method_name)
|
26
|
-
func = FFI.func_map[original_method_name]
|
27
|
-
|
28
|
-
define_method(name) do |*args, &blk|
|
29
|
-
# Assume that block is the last argument.
|
30
|
-
args << blk if blk
|
31
|
-
|
32
|
-
# The proc object is converted to a Closure::BlockCaller object.
|
33
|
-
args.map!.with_index do |arg, idx|
|
34
|
-
if arg.is_a?(Proc)
|
35
|
-
# The types of the function arguments are recorded beforehand.
|
36
|
-
# See the monkey patch in ffi.rb.
|
37
|
-
callback = Fiddle::Closure::BlockCaller.new(
|
38
|
-
*func.callback_argument_types[idx][1..2], &arg
|
39
|
-
)
|
40
|
-
# Protect from GC
|
41
|
-
# See https://github.com/kojix2/LibUI/issues/8
|
42
|
-
receiver = args[0]
|
43
|
-
if receiver.instance_variable_defined?(:@callbacks)
|
44
|
-
receiver.instance_variable_get(:@callbacks) << callback
|
45
|
-
else
|
46
|
-
receiver.instance_variable_set(:@callbacks, [callback])
|
47
|
-
end
|
48
|
-
callback
|
49
|
-
else
|
50
|
-
arg
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Make it possible to omit the last nil. This may be an over-optimization.
|
55
|
-
siz = func.argument_types.size - 1
|
56
|
-
args[siz] = nil if args.size == siz
|
24
|
+
extend LibUIBase
|
57
25
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
module CustomMethods
|
63
|
-
def init(opt = FFI::InitOptions.malloc)
|
64
|
-
i = super(opt)
|
65
|
-
return if i.size.zero?
|
26
|
+
class << self
|
27
|
+
def init(opt = FFI::InitOptions.malloc)
|
28
|
+
i = super(opt)
|
29
|
+
return if i.size.zero?
|
66
30
|
|
67
|
-
|
68
|
-
|
69
|
-
end
|
31
|
+
warn 'error'
|
32
|
+
warn UI.free_init_error(init)
|
70
33
|
end
|
71
|
-
|
72
|
-
prepend CustomMethods
|
73
34
|
end
|
74
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kojix2
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -91,6 +91,8 @@ files:
|
|
91
91
|
- README.md
|
92
92
|
- lib/libui.rb
|
93
93
|
- lib/libui/ffi.rb
|
94
|
+
- lib/libui/fiddle_patch.rb
|
95
|
+
- lib/libui/libui_base.rb
|
94
96
|
- lib/libui/utils.rb
|
95
97
|
- lib/libui/version.rb
|
96
98
|
- vendor/LICENSE
|