ruby-gr 0.0.21 → 0.0.26

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
@@ -138,5 +138,7 @@ module GR3
138
138
  # try_extern 'void gr3_drawtrianglesurface(int n, const float *triangles)'
139
139
  try_extern 'void gr_volume(int nx, int ny, int nz, double *data, ' \
140
140
  'int algorithm, double *dmin_ptr, double *dmax_ptr)'
141
+ try_extern 'void gr3_setorthographicprojection' \
142
+ '(float left, float right, float bottom, float top, float znear, float zfar)'
141
143
  end
142
144
  end
@@ -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
+ 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
+ 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
@@ -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
 
@@ -7,8 +7,8 @@ end
7
7
  # Change the default encoding to UTF-8.
8
8
  ENV['GKS_ENCODING'] ||= 'utf8'
9
9
 
10
- require_relative 'search_shared_library'
11
- require_relative 'extern'
10
+ require_relative 'gr_lib'
11
+ require_relative 'try_extern'
12
12
  require_relative 'define_methods'
13
13
  require_relative 'gr_common_utils'
14
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
@@ -8,7 +8,7 @@ module GRCommons
8
8
  # Sets the environment variable when the module is extended.
9
9
  def self.extended(_obj)
10
10
  require 'tmpdir'
11
- ENV['GKSwstype'] = 'svg'
11
+ ENV['GKS_WSTYPE'] = 'svg'
12
12
  ENV['GKS_FILEPATH'] = Dir::Tmpname.create('plot-') {}
13
13
  end
14
14
 
@@ -16,19 +16,19 @@ module GRCommons
16
16
  def show(display = true)
17
17
  emergencyclosegks
18
18
  sleep 0.5
19
- type = ENV['GKSwstype']
19
+ type = ENV['GKS_WSTYPE']
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.21'
4
+ VERSION = '0.0.26'
5
5
  end
data/lib/grm.rb CHANGED
@@ -17,23 +17,33 @@ end
17
17
  module GRM
18
18
  class Error < StandardError; end
19
19
 
20
+ class NotFoundError < Error; end
21
+
20
22
  class << self
21
23
  attr_accessor :ffi_lib
22
24
  end
23
25
 
24
26
  require_relative 'gr_commons/gr_commons'
25
- extend GRCommons::SearchSharedLibrary
26
27
 
27
28
  # Platforms | path
28
29
  # Windows | bin/libGRM.dll
29
- # MacOSX | lib/libGRM.so (NOT .dylib)
30
+ # MacOSX | lib/libGRM.dylib (v0.53.0 .so)
30
31
  # Ubuntu | lib/libGRM.so
31
- self.ffi_lib = case RbConfig::CONFIG['host_os']
32
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
33
- search_shared_library('libGRM.dll')
34
- else
35
- search_shared_library('libGRM.so')
36
- 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
37
47
 
38
48
  require_relative 'grm/version'
39
49
  require_relative 'grm/ffi'
data/lib/grm/ffi.rb CHANGED
@@ -15,7 +15,7 @@ module GRM
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
  # Currently, the declarations of GRM functions are distributed in several
21
21
  # header files.
@@ -28,6 +28,7 @@ module GRM
28
28
  try_extern 'int grm_args_contains(const grm_args_t *args, const char *keyword)'
29
29
  try_extern 'void grm_args_clear(grm_args_t *args)'
30
30
  try_extern 'void grm_args_remove(grm_args_t *args, const char *key)'
31
+ typealias 'grm_args_ptr_t', 'void*'
31
32
  try_extern 'grm_args_ptr_t grm_length(double value, const char *unit)'
32
33
 
33
34
  # https://github.com/sciapp/gr/blob/master/lib/grm/dump.h
@@ -36,14 +37,17 @@ module GRM
36
37
  try_extern 'char *grm_dump_json_str(void)'
37
38
 
38
39
  # https://github.com/sciapp/gr/blob/master/lib/grm/event.h
40
+ typealias 'grm_event_type_t', 'int' # enum
41
+ typealias 'grm_event_callback_t', 'void*'
39
42
  try_extern 'int grm_register(grm_event_type_t type, grm_event_callback_t callback)'
40
43
  try_extern 'int grm_unregister(grm_event_type_t type)'
41
44
 
42
45
  # https://github.com/sciapp/gr/blob/master/lib/grm/interaction.h
46
+ # FIXME: https://github.com/ruby/fiddle/issues/68
47
+ typealias 'const_int', 'int' # FIXME
43
48
  try_extern 'int grm_input(const grm_args_t *input_args)'
44
- try_extern 'int grm_get_box(const int x1, const int y1, const int x2, const int y2, const int keep_aspect_ratio, int *x, int *y, int *w, int *h)'
45
- try_extern 'grm_input(const grm_args_t *input_args)'
46
- try_extern 'grm_tooltip_info_t *grm_get_tooltip(const int, const int)'
49
+ try_extern 'int grm_get_box(const_int x1, const_int y1, const_int x2, const_int y2, const_int keep_aspect_ratio, int *x, int *y, int *w, int *h)' # FIXME
50
+ try_extern 'grm_tooltip_info_t *grm_get_tooltip(const_int, const_int)' # FIXME
47
51
 
48
52
  # https://github.com/sciapp/gr/blob/master/lib/grm/net.h
49
53
  try_extern 'void *grm_open(int is_receiver, const char *name, unsigned int id,