ruby-gr 0.0.20 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/gr3/ffi.rb CHANGED
@@ -15,7 +15,7 @@ module GR3
15
15
  raise LoadError, 'Could not find GR Framework'
16
16
  end
17
17
 
18
- extend GRCommons::Extern
18
+ extend GRCommons::TryExtern
19
19
 
20
20
  # https://github.com/sciapp/gr/blob/master/lib/gr3/gr3.h
21
21
  # keep same order
@@ -5,8 +5,8 @@ module GRCommons
5
5
  module DefineMethods
6
6
  private
7
7
 
8
- def define_ffi_methods(ffi_class, prefix: '', default_type: :double)
9
- ffi_class.ffi_methods.each do |method|
8
+ def define_ffi_methods(ffi_module, prefix: '', default_type: :double)
9
+ ffi_module.ffi_methods.each do |method|
10
10
  # Use delete_prefix (Ruby >= 2.5)
11
11
  method_name = method.to_s.sub(/^#{prefix}/, '')
12
12
 
@@ -16,14 +16,14 @@ module GRCommons
16
16
  args.map! do |arg|
17
17
  case arg
18
18
  when Array
19
- GRCommons::GRCommonUtils.send(default_type, arg)
19
+ GRCommons::GRCommonUtils.public_send(default_type, arg)
20
20
  when ->(x) { defined?(Numo::NArray) && x.is_a?(Numo::NArray) }
21
- GRCommons::GRCommonUtils.send(default_type, arg)
21
+ GRCommons::GRCommonUtils.public_send(default_type, arg)
22
22
  else
23
23
  arg
24
24
  end
25
25
  end
26
- ffi_class.send(method, *args)
26
+ ffi_module.public_send(method, *args)
27
27
  end
28
28
  end
29
29
  end
@@ -13,7 +13,7 @@ module GRCommons
13
13
  # NOTE: This module is only part of the original code.
14
14
  # kojix2 adds, deletes, and modifies several methods.
15
15
  module Fiddley
16
- # NOTE: GR.rb supports 2.4 +. Unpack 1 does not work under 2.3.
16
+ # NOTE: GR.rb supports 2.5 +. Unpack 1 does not work under 2.3.
17
17
 
18
18
  module Utils
19
19
  # assumes short = 16bit, int = 32bit, long long = 64bit
@@ -210,7 +210,7 @@ module GRCommons
210
210
  end
211
211
 
212
212
  define_method("put_array_of_int#{bits}") do |offset, ary|
213
- put_bytes(offset, ary.pack(form + '*'))
213
+ put_bytes(offset, ary.pack("#{form}*"))
214
214
  end
215
215
 
216
216
  define_method("write_array_of_int#{bits}") do |ary|
@@ -226,7 +226,7 @@ module GRCommons
226
226
  end
227
227
 
228
228
  define_method("get_array_of_int#{bits}") do |offset, num|
229
- @ptr[offset, bytes * num].unpack(form + '*')
229
+ @ptr[offset, bytes * num].unpack("#{form}*")
230
230
  end
231
231
 
232
232
  define_method("read_array_of_int#{bits}") do |num|
@@ -244,7 +244,7 @@ module GRCommons
244
244
  end
245
245
 
246
246
  define_method("put_array_of_uint#{bits}") do |offset, ary|
247
- put_bytes(offset, ary.pack(form2 + '*'))
247
+ put_bytes(offset, ary.pack("#{form2}*"))
248
248
  end
249
249
 
250
250
  define_method("write_array_of_uint#{bits}") do |ary|
@@ -260,7 +260,7 @@ module GRCommons
260
260
  end
261
261
 
262
262
  define_method("get_array_of_uint#{bits}") do |offset, num|
263
- @ptr[offset, bytes * num].unpack(form2 + '*')
263
+ @ptr[offset, bytes * num].unpack("#{form2}*")
264
264
  end
265
265
 
266
266
  define_method("read_array_of_uint#{bits}") do |num|
@@ -330,12 +330,12 @@ module GRCommons
330
330
 
331
331
  # added
332
332
  define_method('get_array_of_double') do |offset, num|
333
- @ptr[offset, 8 * num].unpack('d' + '*')
333
+ @ptr[offset, 8 * num].unpack('d*')
334
334
  end
335
335
 
336
336
  # added
337
337
  define_method('get_array_of_float') do |offset, num|
338
- @ptr[offset, 4 * num].unpack('f' + '*')
338
+ @ptr[offset, 4 * num].unpack('f*')
339
339
  end
340
340
 
341
341
  # added
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'gr_commons/fiddley'
3
+ require_relative 'fiddley'
4
4
 
5
5
  module GRCommons
6
6
  # This module provides functionality common to GR and GR3.
@@ -52,7 +52,7 @@ module GRCommons
52
52
  if narray?(data)
53
53
  Numo::UInt32.cast(data).to_binary
54
54
  else
55
- Fiddley::Utils.array2str(:uint, data.to_a.flatten)
55
+ Fiddley::Utils.array2str(:uint32, data.to_a.flatten)
56
56
  end
57
57
  end
58
58
 
@@ -117,9 +117,9 @@ module GRCommons
117
117
  when Hash
118
118
  typ = type.keys[0]
119
119
  len = type.values[0]
120
- pt.send("read_array_of_#{typ}", len)
120
+ pt.public_send("read_array_of_#{typ}", len)
121
121
  else
122
- pt.send("read_#{type}")
122
+ pt.public_send("read_#{type}")
123
123
  end
124
124
  end
125
125
 
@@ -4,7 +4,11 @@
4
4
  module GRCommons
5
5
  end
6
6
 
7
- require_relative 'extern'
7
+ # Change the default encoding to UTF-8.
8
+ ENV['GKS_ENCODING'] ||= 'utf8'
9
+
10
+ require_relative 'gr_lib'
11
+ require_relative 'try_extern'
8
12
  require_relative 'define_methods'
9
13
  require_relative 'gr_common_utils'
10
14
  require_relative 'jupyter_support'
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pkg-config'
4
+
5
+ module GRCommons
6
+ # This module helps GR, GR and GRM to search the shared library.
7
+ #
8
+ # The order of priority:
9
+ # 1. RubyInstaller ( for Windows only )
10
+ # 2. Environment variable GRDIR
11
+ # 3. pkg-config : https://github.com/ruby-gnome/pkg-config
12
+ # The following packages (should) support pkg-config.
13
+ # - Linux
14
+ # - Red Data Tools https://github.com/red-data-tools/packages.red-data-tools.org
15
+ # - libgr-dev
16
+ # - libgr3-dev
17
+ # - libgrm-dev
18
+ # - Mac
19
+ # - Homebrew https://github.com/Homebrew/homebrew-core
20
+ # - libgr
21
+ # - Windows
22
+ # - MinGW https://github.com/msys2/MINGW-packages
23
+ # - mingw-w64-gr
24
+ module GRLib
25
+ class << self
26
+ # Search the shared library.
27
+ # @note This method does not detect the Operating System.
28
+ #
29
+ # @param lib_names [Array] The actual file name of the shared library.
30
+ # @param pkg_name [String] The package name to be used when searching with pkg-configg
31
+ def search(lib_names, pkg_name)
32
+ def lib_names.map_find(&block)
33
+ lazy.map(&block).find { |path| path }
34
+ end
35
+ # Windows + RubyInstaller
36
+ if Object.const_defined?(:RubyInstaller)
37
+ dir = ENV['GRDIR'] || [
38
+ RubyInstaller::Runtime.msys2_installation.msys_path,
39
+ RubyInstaller::Runtime.msys2_installation.mingwarch
40
+ ].join(File::ALT_SEPARATOR)
41
+ lib_names.lazy.map do |lib_name|
42
+ recursive_search(lib_name, dir)
43
+ end.find { |i| i }.tap do |path|
44
+ RubyInstaller::Runtime.add_dll_directory(File.dirname(path)) if path
45
+ end
46
+ # ENV['GRDIR'] (Linux, Mac, Windows)
47
+ elsif ENV['GRDIR']
48
+ # Search for XXX.dylib and then XXX.so on macOS
49
+ lib_names.map_find do |lib_name|
50
+ recursive_search(lib_name, ENV['GRDIR'])
51
+ end || lib_names.map_find do |lib_name|
52
+ pkg_config_search(lib_name, pkg_name)
53
+ end
54
+ else
55
+ lib_names.map_find do |lib_name|
56
+ pkg_config_search(lib_name, pkg_name)
57
+ end
58
+ end
59
+ end
60
+
61
+ # Recursive file search in directories
62
+ # @param name [String] File to search for
63
+ # @param base_dir [String] Directory to search
64
+ # @retrun path [String, NilClass] Returns the first path found.
65
+ # If not found, nil is returned.
66
+ def recursive_search(name, base_dir)
67
+ Dir.chdir(base_dir) do
68
+ paths = Dir["**/#{name}"].sort
69
+ warn "More than one file found: #{paths}" if paths.size > 1
70
+ path = paths.first
71
+ File.expand_path(path) if path
72
+ end
73
+ end
74
+
75
+ # Use pkg-config to search for shared libraries
76
+ def pkg_config_search(lib_name, pkg_name)
77
+ PKGConfig.variable(pkg_name, 'sopath')
78
+ rescue PackageConfig::NotFoundError => e
79
+ warn "#{e.message} Cannot find #{lib_name}. "
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This script was created primarily for debugging purposes.
4
+ # Note: This script should be isolated.
5
+ # It should not be loaded when gr_commons/gr_commons is loaded.
6
+
7
+ require 'logger'
8
+ require 'rainbow'
9
+ require 'awesome_print'
10
+
11
+ module GRCommons
12
+ class << self
13
+ # Create a new GRLogger
14
+ # @param out [String]
15
+ # @return [GRLogger]
16
+ # @example
17
+ # require 'gr_commons/gr_logger'
18
+ # GRCommons.gr_log("log.txt")
19
+ def gr_log(out = $stderr)
20
+ GRCommons::GRLogger.new(out)
21
+ end
22
+
23
+ # Return the last created GRLogger
24
+ # @return [GRLogger]
25
+ def gr_logger
26
+ GRCommons::GRLogger.logger
27
+ end
28
+ end
29
+
30
+ # Outputs function calls to GR Framework to a log file.
31
+ # Mainly used for debugging.
32
+ # @note This module is for those who want to see low-level function calls in GR.
33
+ #
34
+ # = How it works 
35
+ # prepend a module named Inspector to the singular class
36
+ # of the FFI module. It will inspects the GR function call of the FFI module
37
+ #
38
+ # @example
39
+ # require 'gr_commons/gr_logger'
40
+ # GRCommons.gr_log("log.txt")
41
+ class GRLogger < Logger
42
+ # Return the last created GRLogger
43
+ def self.logger
44
+ @@logger ||= GRCommons::GRLogger.new
45
+ end
46
+
47
+ def initialize(out = $stderr)
48
+ super(out, level: :info)
49
+ @@logger ||= self
50
+ end
51
+ end
52
+ end
53
+
54
+ if Object.const_defined?(:GR)
55
+ module GR
56
+ module FFI
57
+ module Inspector
58
+ GR::FFI.ffi_methods.each do |s|
59
+ define_method(s) do |*args|
60
+ GRCommons.gr_logger.info "GR::FFI.#{s}\n" + args.ai + "\n"
61
+ super(*args)
62
+ end
63
+ end
64
+ end
65
+ class << self
66
+ prepend Inspector
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ if Object.const_defined?(:GR3)
73
+ module GR3
74
+ module FFI
75
+ module Inspector
76
+ GR3::FFI.ffi_methods.each do |s|
77
+ define_method(s) do |*args|
78
+ GRCommons.gr_logger.info "GR3::FFI.#{s}\n" + args.ai + "\n"
79
+ super(*args)
80
+ end
81
+ end
82
+ end
83
+ class << self
84
+ prepend Inspector
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ if Object.const_defined?(:GRM)
91
+ module GRM
92
+ module FFI
93
+ module Inspector
94
+ GRM::FFI.ffi_methods.each do |s|
95
+ define_method(s) do |*args|
96
+ GRCommons.gr_logger.info "GRM::FFI.#{s}\n" + args.ai + "\n"
97
+ super(*args)
98
+ end
99
+ end
100
+ end
101
+ class << self
102
+ prepend Inspector
103
+ end
104
+ end
105
+ end
106
+ end
@@ -19,16 +19,16 @@ module GRCommons
19
19
  type = ENV['GKSwstype']
20
20
  case type
21
21
  when 'svg'
22
- data = File.read(ENV['GKS_FILEPATH'] + '.svg')
22
+ data = File.read("#{ENV['GKS_FILEPATH']}.svg")
23
23
  IRuby.display(data, mime: 'image/svg+xml') if display
24
24
  when 'png', '322', '140'
25
- data = File.read(ENV['GKS_FILEPATH'] + '.png')
25
+ data = File.read("#{ENV['GKS_FILEPATH']}.png")
26
26
  IRuby.display(data, mime: 'image/png') if display
27
27
  when 'jpg', '321', '144'
28
- data = File.read(ENV['GKS_FILEPATH'] + '.jpg')
28
+ data = File.read("#{ENV['GKS_FILEPATH']}.jpg")
29
29
  IRuby.display(data, mime: 'image/jpeg') if display
30
30
  when 'gif', '130'
31
- data = File.read(ENV['GKS_FILEPATH'] + '.gif')
31
+ data = File.read("#{ENV['GKS_FILEPATH']}.gif")
32
32
  IRuby.display(data, mime: 'image/gif') if display
33
33
  when 'webm', 'ogg', 'mp4', 'mov'
34
34
  require 'base64'
@@ -37,7 +37,7 @@ module GRCommons
37
37
  else
38
38
  "video/#{type}"
39
39
  end
40
- data = File.binread(ENV['GKS_FILEPATH'] + '.' + type)
40
+ data = File.binread("#{ENV['GKS_FILEPATH']}.#{type}")
41
41
  if display
42
42
  IRuby.display(
43
43
  "<video autoplay controls><source type=\"#{mimespec}\" " \
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GRCommons
4
4
  # This module records the names of the methods defined by Fiddle::Importer.
5
- module Extern
5
+ module TryExtern
6
6
  attr_reader :ffi_methods
7
7
 
8
8
  # Improved extern method.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GRCommons
4
- VERSION = '0.0.20'
4
+ VERSION = '0.0.25'
5
5
  end
data/lib/grm.rb CHANGED
@@ -1,33 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Check Fiddle version.
4
+ require 'fiddle'
5
+
6
+ # Check if fiddle supports variadic arguments.
7
+ # Fiddle is a standard Gem and may not have VERSION constant.
8
+ if !Fiddle.const_defined?(:VERSION) ||
9
+ (Gem::Version.new(Fiddle::VERSION) <= Gem::Version.new('1.0.0'))
10
+ raise LoadError, <<~MSG
11
+ Failed to load GRM module
12
+ Fiddle 1.0.1 or higher is required to run GRM.
13
+ See https://github.com/ruby/fiddle
14
+ MSG
15
+ end
16
+
3
17
  module GRM
4
18
  class Error < StandardError; end
5
19
 
20
+ class NotFoundError < Error; end
21
+
6
22
  class << self
7
23
  attr_accessor :ffi_lib
8
24
  end
9
25
 
26
+ require_relative 'gr_commons/gr_commons'
27
+
10
28
  # Platforms | path
11
29
  # Windows | bin/libGRM.dll
12
- # MacOSX | lib/libGRM.so (NOT .dylib)
30
+ # MacOSX | lib/libGRM.dylib (v0.53.0 .so)
13
31
  # Ubuntu | lib/libGRM.so
14
- if Object.const_defined?(:RubyInstaller)
15
- ENV['GRDIR'] ||= [
16
- RubyInstaller::Runtime.msys2_installation.msys_path,
17
- RubyInstaller::Runtime.msys2_installation.mingwarch
18
- ].join(File::ALT_SEPARATOR)
19
- self.ffi_lib = File.expand_path('bin/libGRM.dll', ENV['GRDIR'])
20
- RubyInstaller::Runtime.add_dll_directory(File.dirname(ffi_lib))
21
- else
22
- raise Error, 'Please set env variable GRDIR' unless ENV['GRDIR']
23
-
24
- self.ffi_lib = File.expand_path('lib/libGRM.so', ENV['GRDIR'])
25
- end
32
+ platform = RbConfig::CONFIG['host_os']
33
+ lib_names, pkg_name = \
34
+ case platform
35
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
36
+ [['libGRM.dll'], 'grm']
37
+ when /darwin|mac os/
38
+ [['libGRM.dylib', 'libGRM.so'], 'grm']
39
+ else
40
+ [['libGRM.so'], 'grm']
41
+ end
42
+ lib_path = GRCommons::GRLib.search(lib_names, pkg_name)
43
+
44
+ raise NotFoundError, "#{lib_names} not found" if lib_path.nil?
45
+
46
+ self.ffi_lib = lib_path
26
47
 
27
- # change the default encoding to UTF-8.
28
- ENV['GKS_ENCODING'] ||= 'utf8'
29
-
30
- require_relative 'gr_commons/gr_commons'
31
48
  require_relative 'grm/version'
32
49
  require_relative 'grm/ffi'
33
50
  require_relative 'grm/grmbase'