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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dbb5362886495f17bf74055bf1ad4cbc96bb7f0e4518e8db0b18f9572559adf2
4
- data.tar.gz: 19040d301c6cb135a3e5ef1270f211f48f007f02ec3e5fe7edcbc3be03f275da
3
+ metadata.gz: f5856ad97384408635e170c1ea252dc3dbdfa1ba3955bfc8b8c1ac2c29585ac1
4
+ data.tar.gz: 67a9b78e39b61805afca932fc80365b59e068493f2da937c57b03e1500a2adf5
5
5
  SHA512:
6
- metadata.gz: 27a0c320d8592b2e6a6531b66ed0de3a83a3f606058d16469af530d0633a02d2d13e848e5ca4dd8d6c184015449a2ba56b4eb6c7e63ede1ccb7bfa6d447b5f1b
7
- data.tar.gz: '033190ef229e3f567db9c7a7d338da4107072a6120e79c928a5e03dffcca922ffe75ac76f631fda810133cd6316d6af55ea234eb3fce214540fe1e92fd7d6eaf'
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LibUI
4
- VERSION = '0.0.9'
4
+ VERSION = '0.0.10'
5
5
  end
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["SOEXT"]}"
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
- class << self
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
- FFI.public_send(original_method_name, *args)
59
- end
60
- end
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
- warn 'error'
68
- warn UI.free_init_error(init)
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.9
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-08-25 00:00:00.000000000 Z
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