ruby-gr 0.0.20 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
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'