libui 0.0.4.alpha → 0.0.5.alpha

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: a74f99e290fdd8cddcd933eea2a41dd3ca6949c385feb496f3991df6cdbc730f
4
- data.tar.gz: d329a9c983c42281a4897f91c84c562a200d231b75dd8f7bee44763b3c719ad8
3
+ metadata.gz: 9942c95097af2b3c542472fa3e144e040cf3f9c0ef253e891d87b79b93070e77
4
+ data.tar.gz: a69a733f1cd1dd2274c601422a2cb3a5b91d762055d73fc3e9e9f59e6f11c919
5
5
  SHA512:
6
- metadata.gz: 715cd016369cce7a28b4f4789f3b42fbe383b13d97c7bd8debda929cabefba2672487c5ecbdef8f9b621fae22228e17c39914de3c99b67da659b6a6fd0b976bf
7
- data.tar.gz: 7271aad7f11b22d39f82ef693d3e0be914cf6c33e851872b6b0eef6e080890f7854192dcb104550de6f0e626b5793c916caf3d415618084b86dd4a987bc9754d
6
+ metadata.gz: 47d42cfbc47996ad411f0ba9e6634378fa2bd088d84bc4179698c4ad3c049a7ce8e75218c8fd93538362d01961c9ca4d278aa2c60a5074a1fea532d4b22841b8
7
+ data.tar.gz: 25c390450f42ff51ee05a9f5c7c9409c16860ac1ae3351e0d85aa30ad1d753f7cad2e1091ff9193bdf85cb21d77c344fbe1acdb5e429746e9d69574b59388379
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # libui
2
+
3
+ ![build](https://github.com/kojix2/libui/workflows/build/badge.svg)
2
4
  [![Gem Version](https://badge.fury.io/rb/libui.svg)](https://badge.fury.io/rb/libui)
3
5
 
4
- [libui](https://github.com/andlabs/libui) - a portable GUI library -for Ruby
6
+ :radio_button: [libui](https://github.com/andlabs/libui) - a portable GUI library -for Ruby
5
7
 
6
8
  ## Installation
7
9
 
@@ -9,6 +11,8 @@
9
11
  gem install libui --pre
10
12
  ```
11
13
 
14
+ The libui gem package contains the official release of the libui shared library version 4.1 for Windows, Mac, and Linux.
15
+
12
16
  ## Usage
13
17
 
14
18
  See [examples](https://github.com/kojix2/libui/tree/main/examples) directory.
@@ -9,31 +9,68 @@ module LibUI
9
9
  attr_accessor :ffi_lib
10
10
  end
11
11
 
12
- self.ffi_lib = case RbConfig::CONFIG['host_os']
13
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
14
- # File.expand_path("libui.dll", ENV['LIBUIDIR'])
15
- File.expand_path('../vendor/libui.dll', __dir__)
16
- when /darwin|mac os/
17
- # File.expand_path("libui.dylib", ENV['LIBUIDIR'])
18
- File.expand_path('../vendor/libui.dylib', __dir__)
19
- else # TODO: Mac
20
- # File.expand_path("libui.so", ENV['LIBUIDIR'])
21
- File.expand_path('../vendor/libui.so', __dir__)
12
+ lib_name = case RbConfig::CONFIG['host_os']
13
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
14
+ 'libui.dll'
15
+ when /darwin|mac os/
16
+ 'libui.dylib'
17
+ else
18
+ 'libui.so'
19
+ end
20
+
21
+ self.ffi_lib = if ENV['LIBUIDIR'] && !ENV['LIBUIDIR'].empty?
22
+ File.expand_path(lib_name, ENV['LIBUIDIR'])
23
+ else
24
+ File.expand_path("../vendor/#{lib_name}", __dir__)
22
25
  end
23
26
 
24
27
  require_relative 'libui/ffi'
25
28
 
26
29
  class << self
27
- FFI.ffi_methods.each do |original_method_name|
30
+ FFI.func_map.each_key do |original_method_name|
31
+ # Convert snake_case to CamelCase.
28
32
  name = original_method_name.delete_prefix('ui')
29
33
  .gsub(/::/, '/')
30
34
  .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
31
35
  .gsub(/([a-z\d])([A-Z])/, '\1_\2')
32
36
  .tr('-', '_')
33
37
  .downcase
34
- define_method(name) do |*args|
38
+
39
+ func = FFI.func_map[original_method_name]
40
+
41
+ define_method(name) do |*args, &blk|
42
+ # Assume that block is the last argument.
43
+ args << blk if blk
44
+
45
+ # The proc object is converted to a Closure::BlockCaller object.
46
+ args.map!.with_index do |arg, idx|
47
+ if arg.is_a?(Proc)
48
+ # The types of the function arguments are recorded beforehand.
49
+ # See the monkey patch in ffi.rb.
50
+ Fiddle::Closure::BlockCaller.new(*func.inner_functions[idx][1..2], &arg)
51
+ else
52
+ arg
53
+ end
54
+ end
55
+
56
+ # Make it possible to omit the last nil. This may be an over-optimization.
57
+ siz = func.argtype.size - 1
58
+ args[siz] = nil if args.size == siz
59
+
35
60
  FFI.public_send(original_method_name, *args)
36
61
  end
37
62
  end
63
+
64
+ module CustomMethods
65
+ def init(opt = FFI::InitOptions.malloc)
66
+ i = super(opt)
67
+ unless i.size.zero?
68
+ warn 'error'
69
+ warn UI.free_init_error(init)
70
+ end
71
+ end
72
+ end
73
+
74
+ prepend CustomMethods
38
75
  end
39
76
  end
@@ -2,6 +2,81 @@
2
2
 
3
3
  require 'fiddle/import'
4
4
 
5
+ module Fiddle
6
+ # Change the Function to hold a little more information.
7
+ # FIXME: Give inner_function a better name.
8
+ class Function
9
+ attr_accessor :inner_functions, :argtype
10
+ end
11
+
12
+ module Importer
13
+ def parse_signature(signature, tymap = nil)
14
+ tymap ||= {}
15
+ ret, func, args = split_signature(signature)
16
+ symname = func
17
+ ctype = parse_ctype(ret, tymap)
18
+ inner_funcs = [] # Added
19
+ argtype = split_arguments(args).collect.with_index do |arg, idx| # Added with_index
20
+ # Check if it is a function pointer or not
21
+ if arg =~ /\(\*.*\)\(.*\)/ # Added
22
+ # From the arguments, create a notation that looks like a function declaration
23
+ # int(*f)(int *, void *) -> int f(int *, void *)
24
+ func_arg = arg.sub('(*', ' ').sub(')', '') # Added
25
+ # Use Fiddle's parse_signature method again.
26
+ inner_funcs[idx] = parse_signature(func_arg) # Added
27
+ end # Added
28
+ parse_ctype(arg, tymap)
29
+ end
30
+ # Added inner_funcs. Original method return only 3 values.
31
+ [symname, ctype, argtype, inner_funcs]
32
+ end
33
+
34
+ # refactored
35
+ def split_signature(signature)
36
+ case compact(signature)
37
+ when /^(?:[\w*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/
38
+ func = Regexp.last_match(1)
39
+ args = Regexp.last_match(2)
40
+ [TYPE_VOIDP, func, args]
41
+ when /^([\w*\s]+[*\s])(\w+)\((.*?)\);?$/
42
+ ret = Regexp.last_match(1).strip
43
+ func = Regexp.last_match(2)
44
+ args = Regexp.last_match(3)
45
+ [ret, func, args]
46
+ else
47
+ raise("can't parse the function prototype: #{signature}")
48
+ end
49
+ end
50
+
51
+ def extern(signature, *opts)
52
+ symname, ctype, argtype, inner_funcs = parse_signature(signature, type_alias)
53
+ opt = parse_bind_options(opts)
54
+ f = import_function(symname, ctype, argtype, opt[:call_type])
55
+
56
+ f.inner_functions = inner_funcs # Added
57
+ f.argtype = argtype # Added
58
+
59
+ name = symname.gsub(/@.+/, '')
60
+ @func_map[name] = f
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
+ f
76
+ end
77
+ end
78
+ end
79
+
5
80
  module LibUI
6
81
  module FFI
7
82
  extend Fiddle::Importer
@@ -13,20 +88,12 @@ module LibUI
13
88
  end
14
89
 
15
90
  class << self
16
- attr_reader :ffi_methods
91
+ attr_reader :func_map
17
92
 
18
- # Improved extern method.
19
- # 1. Ignore functions that cannot be attached.
20
- # 2. Available function (names) are stored in @ffi_methods.
21
93
  def try_extern(signature, *opts)
22
- @ffi_methods ||= []
23
- begin
24
- func = extern(signature, *opts)
25
- @ffi_methods << func.name
26
- func
27
- rescue StandardError => e
28
- warn "#{e.class.name}: #{e.message}"
29
- end
94
+ extern(signature, *opts)
95
+ rescue StandardError => e
96
+ warn "#{e.class.name}: #{e.message}"
30
97
  end
31
98
  end
32
99
 
@@ -401,6 +468,11 @@ module LibUI
401
468
 
402
469
  try_extern 'uiAttribute *uiNewUnderlineColorAttribute(uiUnderlineColor u, double r, double g, double b, double a)'
403
470
  try_extern 'void uiAttributeUnderlineColor(const uiAttribute *a, uiUnderlineColor *u, double *r, double *g, double *b, double *alpha)'
471
+
472
+ # uiOpenTypeFeatures
473
+
474
+ typealias 'uiOpenTypeFeaturesForEachFunc', 'void*'
475
+
404
476
  try_extern 'uiOpenTypeFeatures *uiNewOpenTypeFeatures(void)'
405
477
  try_extern 'void uiFreeOpenTypeFeatures(uiOpenTypeFeatures *otf)'
406
478
  try_extern 'uiOpenTypeFeatures *uiOpenTypeFeaturesClone(const uiOpenTypeFeatures *otf)'
@@ -410,6 +482,11 @@ module LibUI
410
482
  try_extern 'void uiOpenTypeFeaturesForEach(const uiOpenTypeFeatures *otf, uiOpenTypeFeaturesForEachFunc f, void *data)'
411
483
  try_extern 'uiAttribute *uiNewFeaturesAttribute(const uiOpenTypeFeatures *otf)'
412
484
  try_extern 'const uiOpenTypeFeatures *uiAttributeFeatures(const uiAttribute *a)'
485
+
486
+ # uiAttributedString
487
+
488
+ typealias 'uiAttributedStringForEachAttributeFunc', 'void*'
489
+
413
490
  try_extern 'uiAttributedString *uiNewAttributedString(const char *initialString)'
414
491
  try_extern 'void uiFreeAttributedString(uiAttributedString *s)'
415
492
  try_extern 'const char *uiAttributedStringString(const uiAttributedString *s)'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LibUI
4
- VERSION = '0.0.4.alpha'
4
+ VERSION = '0.0.5.alpha'
5
5
  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.alpha
4
+ version: 0.0.5.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-09 00:00:00.000000000 Z
11
+ date: 2020-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler