tracksperanto 1.7.4 → 1.7.5

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.
@@ -1,3 +1,7 @@
1
+ === 1.7.5 / 2010-02-17
2
+
3
+ * Use a special IO so that we can display progress when parsing/reading a file (based on the IO offset)
4
+
1
5
  === 1.7.4 / 2010-02-02
2
6
 
3
7
  * Introduce an intentional gap in the reference exports to test trackers with gaps
@@ -46,6 +46,7 @@ lib/tracksperanto/const_name.rb
46
46
  lib/tracksperanto/ext_io.rb
47
47
  lib/tracksperanto/format_detector.rb
48
48
  lib/tracksperanto/keyframe.rb
49
+ lib/tracksperanto/progressive_io.rb
49
50
  lib/tracksperanto/safety.rb
50
51
  lib/tracksperanto/simple_export.rb
51
52
  lib/tracksperanto/tracker.rb
@@ -129,6 +130,7 @@ test/test_const_name.rb
129
130
  test/test_extio.rb
130
131
  test/test_format_detector.rb
131
132
  test/test_keyframe.rb
133
+ test/test_progressive_io.rb
132
134
  test/test_simple_export.rb
133
135
  test/test_tracker.rb
134
136
  test/test_tracksperanto.rb
@@ -92,7 +92,6 @@ end
92
92
  input_file = ARGV.pop
93
93
  if !input_file
94
94
  STDERR.puts "No input file provided - should be the last argument"
95
- puts parser
96
95
  exit(-1)
97
96
  end
98
97
 
@@ -100,20 +99,26 @@ class Spinner
100
99
  RING = ['|', '/', '-', '\\', '|', '/', '-', '\\']
101
100
 
102
101
  def initialize
103
- @counter = 0
104
- @last_message_length = 0
102
+ @counter, @last_len = 0, 0
105
103
  end
106
104
 
107
105
  def spin(percent, msg)
108
106
  current = RING[(@counter += 1) % RING.length]
109
107
  output = " [%s %d%%]" % [current, percent]
110
- STDOUT.write(output + "\r" * output.length)
108
+ STDOUT.write(output + ("\r" * output.length))
111
109
  STDOUT.flush
110
+ @last_len = output.length
111
+ end
112
+
113
+ def finish(with_message = '')
114
+ STDOUT.write("\r" * @last_len.to_i)
115
+ STDOUT.flush
116
+ STDOUT.puts(with_message)
112
117
  end
113
118
  end
114
119
 
115
- pipe = Tracksperanto::Pipeline::Base.new
116
- pipe.progress_block = Spinner.new.method(:spin).to_proc
120
+ spinner = Spinner.new
121
+ pipe = Tracksperanto::Pipeline::Base.new(:progress_block => spinner.method(:spin).to_proc)
117
122
 
118
123
  if sole_format
119
124
  begin
@@ -137,4 +142,5 @@ pipe.run(input_file, :pix_w => width, :pix_h => height, :parser => reader_klass)
137
142
  lerpm.enabled = lerp
138
143
  len.min_length = length_gate
139
144
  end
140
- STDOUT.puts("\rConverted #{pipe.converted_points} trackers with #{pipe.converted_keyframes} keys")
145
+
146
+ spinner.finish("Converted #{pipe.converted_points} trackers with #{pipe.converted_keyframes} keys")
@@ -25,7 +25,7 @@ class Tracksperanto::Export::SynthEyes < Tracksperanto::Export::Base
25
25
  end
26
26
 
27
27
  def start_tracker_segment(tracker_name)
28
- @last_f, @tracker_name = nil, tracker_name
28
+ @last_registered_frame, @tracker_name = nil, tracker_name
29
29
  end
30
30
 
31
31
  def export_point(frame, abs_float_x, abs_float_y, float_residual)
@@ -38,14 +38,14 @@ class Tracksperanto::Export::SynthEyes < Tracksperanto::Export::Base
38
38
  # It's very important that we provide an outcome code for Syntheyes. Regular keyframes get
39
39
  # STATUS_STD, and after a gap we have to signal STATUS_REENABLE, otherwise this might bust solves
40
40
  def get_outcome_code(frame)
41
- outcome = if @last_f.nil?
41
+ outcome = if @last_registered_frame.nil?
42
42
  STATUS_KF
43
- elsif @last_f && (@last_f != frame -1)
43
+ elsif @last_registered_frame != (frame - 1)
44
44
  STATUS_REENABLE
45
45
  else
46
46
  STATUS_STD
47
47
  end
48
- @last_f = frame
48
+ @last_registered_frame = frame
49
49
  outcome
50
50
  end
51
51
  end
@@ -12,6 +12,8 @@ module Tracksperanto::ShakeGrammar
12
12
  attr_reader :sentinel
13
13
 
14
14
  STOP_TOKEN = :__stop #:nodoc:
15
+ MAX_BUFFER_SIZE = 32000
16
+ MAX_STACK_DEPTH = 127
15
17
 
16
18
  # The first argument is the IO handle to the data of the Shake script.
17
19
  # The second argument is a "sentinel" that is going to be passed
@@ -42,11 +44,11 @@ module Tracksperanto::ShakeGrammar
42
44
 
43
45
  c = @io.read(1)
44
46
 
45
- if @buf.length > 32000 # Wrong format and the buffer is filled up, bail
47
+ if @buf.length > MAX_BUFFER_SIZE # Wrong format and the buffer is filled up, bail
46
48
  raise WrongInput, "Buffer overflow at 32K, this is definitely not a Shake script"
47
49
  end
48
50
 
49
- if @stack_depth > 127 # Wrong format - parentheses overload
51
+ if @stack_depth > MAX_STACK_DEPTH # Wrong format - parentheses overload
50
52
  raise WrongInput, "Stack overflow at level 128, this is probably a LISP program uploaded by accident"
51
53
  end
52
54
 
@@ -13,6 +13,8 @@
13
13
  # and setup outputs for all supported export formats.
14
14
  class Tracksperanto::Pipeline::Base
15
15
 
16
+ include Tracksperanto::BlockInit
17
+
16
18
  # How many points have been converted. In general, the pipeline does not preserve the parsed tracker objects
17
19
  # after they have been exported
18
20
  attr_reader :converted_points
@@ -83,16 +85,27 @@ class Tracksperanto::Pipeline::Base
83
85
  # If a block is passed, the block will receive the percent complete and the last
84
86
  # status message that you can pass back to the UI
85
87
  def run_export(tracker_data_io, parser, processor)
86
- @ios << tracker_data_io
87
-
88
88
  points, keyframes, percent_complete = 0, 0, 0.0
89
89
 
90
90
  yield(percent_complete, "Starting the parser") if block_given?
91
+
92
+ # Report progress from the parser
91
93
  parser.progress_block = lambda do | message |
92
94
  yield(percent_complete, message) if block_given?
93
95
  end
94
96
 
95
- trackers = parser.parse(tracker_data_io)
97
+ # Wrap the input in a progressive IO
98
+ io_with_progress = Tracksperanto::ProgressiveIO.new(tracker_data_io)
99
+ @ios << io_with_progress
100
+
101
+ # Setup a lambda that will spy on the reader and update the percentage.
102
+ # We will only broadcast messages that come from the parser though (complementing it
103
+ # with a percentage)
104
+ io_with_progress.progress_block = lambda do | offset, of_total |
105
+ percent_complete = (50.0 / of_total) * offset
106
+ end
107
+
108
+ trackers = parser.parse(io_with_progress)
96
109
 
97
110
  validate_trackers!(trackers)
98
111
 
@@ -4,7 +4,7 @@ require 'tempfile'
4
4
 
5
5
  module Tracksperanto
6
6
  PATH = File.expand_path(File.dirname(__FILE__))
7
- VERSION = '1.7.4'
7
+ VERSION = '1.7.5'
8
8
 
9
9
  module Import; end
10
10
  module Export; end
@@ -42,8 +42,7 @@ module Tracksperanto
42
42
  # Case-insensitive search for an export module by name
43
43
  def self.get_exporter(name)
44
44
  exporters.each do | x |
45
- normalized_name = x.to_s.split("::")[-1].downcase
46
- return x if normalized_name == name.downcase
45
+ return x if x.const_name.downcase == name.downcase
47
46
  end
48
47
 
49
48
  raise NameError, "Unknown exporter #{name}"
@@ -52,8 +51,7 @@ module Tracksperanto
52
51
  # Case-insensitive search for an export module by name
53
52
  def self.get_importer(name)
54
53
  importers.each do | x |
55
- normalized_name = x.to_s.split("::")[-1].downcase
56
- return x if normalized_name == name.downcase
54
+ return x if x.const_name.downcase == name.downcase
57
55
  end
58
56
 
59
57
  raise NameError, "Unknown importer #{name}"
@@ -70,6 +68,7 @@ end
70
68
  tracker
71
69
  format_detector
72
70
  ext_io
71
+ progressive_io
73
72
  simple_export
74
73
  uv_coordinates
75
74
  ).each do | submodule |
@@ -1,17 +1,17 @@
1
1
  # Many importers use this as a standard. This works like a wrapper for any
2
- # IO object with a couple extra methods added
2
+ # IO object with a couple extra methods added.
3
3
  class Tracksperanto::ExtIO < DelegateClass(IO)
4
4
  def initialize(with)
5
5
  __setobj__ with
6
6
  end
7
7
 
8
8
  def gets_and_strip
9
- s = __getobj__.gets
9
+ s = gets
10
10
  s ? s.strip : nil
11
11
  end
12
12
 
13
13
  def gets_non_empty
14
- line = __getobj__.gets
14
+ line = gets
15
15
  return nil if line.nil?
16
16
  s = line.strip
17
17
  return gets_non_empty if s.empty?
@@ -0,0 +1,79 @@
1
+ # Used for IO objects that need to report the current offset at each operation that changes the said offset
2
+ # (useful for building progress bars that report on a file read operation)
3
+ class Tracksperanto::ProgressiveIO < DelegateClass(IO)
4
+
5
+ # Should contain a block that accepts the current offset in bytes and the total size
6
+ attr_accessor :progress_block
7
+
8
+ # Get or set the total size of the contained IO. If the passed IO is a File object
9
+ # the size will be preset automatically
10
+ attr_accessor :total_size
11
+
12
+ def initialize(with_file)
13
+ __setobj__(with_file)
14
+ @total_size = with_file.stat.size if with_file.respond_to?(:stat)
15
+ end
16
+
17
+ def each(sep_string = $/, &blk)
18
+ # Report offset at each call of the iterator
19
+ result = super(sep_string) do | line |
20
+ yield(line)
21
+ notify_read
22
+ end
23
+ end
24
+ alias_method :each_line, :each
25
+
26
+ def each_byte(&blk)
27
+ # Report offset at each call of the iterator
28
+ super { |b| yield(b); notify_read }
29
+ end
30
+
31
+ def getc
32
+ returning(super) { notify_read }
33
+ end
34
+
35
+ def gets
36
+ returning(super) { notify_read }
37
+ end
38
+
39
+ def read(*a)
40
+ returning(super) { notify_read }
41
+ end
42
+
43
+ def readbytes(*a)
44
+ returning(super) { notify_read }
45
+ end
46
+
47
+ def readchar
48
+ returning(super) { notify_read }
49
+ end
50
+
51
+ def readline(*a)
52
+ returning(super) { notify_read }
53
+ end
54
+
55
+ def readlines(*a)
56
+ returning(super) { notify_read }
57
+ end
58
+
59
+ def seek(*a)
60
+ returning(super) { notify_read }
61
+ end
62
+
63
+ def ungetc(*a)
64
+ returning(super) { notify_read }
65
+ end
66
+
67
+ def pos=(p)
68
+ returning(super) { notify_read }
69
+ end
70
+
71
+ private
72
+ def returning(r)
73
+ yield; r
74
+ end
75
+
76
+ def notify_read
77
+ @progress_block.call(pos, @total_size) if @progress_block
78
+ end
79
+ end
@@ -0,0 +1,119 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestProgressiveIO < Test::Unit::TestCase
4
+
5
+ def e(s)
6
+
7
+ # Make a mock File object from a string
8
+ io = StringIO.new(s)
9
+ mock_stat = flexmock(:size => s.length)
10
+ flexmock(io).should_receive(:stat).and_return(mock_stat)
11
+
12
+ Tracksperanto::ProgressiveIO.new(io)
13
+ end
14
+
15
+ def test_each
16
+ io, messages = e("Mary\nHad\nA little\nLamb"), []
17
+
18
+ io.progress_block = lambda do | offset, total |
19
+ messages.push([offset, total])
20
+ end
21
+
22
+ lines = []
23
+ io.each {|line| lines.push(line) }
24
+ assert_equal ["Mary\n", "Had\n", "A little\n", "Lamb"], lines
25
+ assert_equal [[5, 22], [9, 22], [18, 22], [22, 22]], messages
26
+ end
27
+
28
+ def test_each_byte
29
+ io, messages = e("123"), []
30
+
31
+ io.progress_block = lambda do | offset, total |
32
+ messages.push([offset, total])
33
+ end
34
+
35
+ bytes = []
36
+ io.each_byte{|s| bytes << s }
37
+ assert_equal [49, 50, 51], bytes
38
+ assert_equal [[1, 3], [2, 3], [3, 3]], messages
39
+ end
40
+
41
+ def test_getc
42
+ io = e("123")
43
+ io.progress_block = lambda do | offset, total |
44
+ assert_equal [1, 3], [offset, total]
45
+ end
46
+ assert_equal 49, io.getc
47
+ end
48
+
49
+ def test_gets
50
+ io = e("Mary\nHad\nA little\nLamb")
51
+ io.progress_block = lambda do | offset, total |
52
+ assert_equal [5, 22], [offset, total]
53
+ end
54
+ assert_equal "Mary\n", io.gets
55
+ end
56
+
57
+ def test_read
58
+ io = e("Mary\nHad\nA little\nLamb")
59
+ io.progress_block = lambda do | offset, total |
60
+ assert_equal [15, 22], [offset, total]
61
+ end
62
+ assert_equal "Mary\nHad\nA litt", io.read(15)
63
+ end
64
+
65
+ def test_readchar
66
+ io = e("123")
67
+ io.progress_block = lambda do | offset, total |
68
+ assert_equal [1, 3], [offset, total]
69
+ end
70
+ assert_equal 49, io.readchar
71
+ end
72
+
73
+ def test_readline
74
+ io = e("Mary\nHad\nA little\nLamb")
75
+ io.progress_block = lambda do | offset, total |
76
+ assert_equal [5, 22], [offset, total]
77
+ end
78
+ assert_equal "Mary\n", io.readline
79
+ end
80
+
81
+ def test_readlines
82
+ io = e("Mary\nHad\nA little\nLamb")
83
+ m = []
84
+ io.progress_block = lambda do | offset, total |
85
+ m.push([offset, total])
86
+ end
87
+
88
+ assert_equal ["Mary\n", "Had\n", "A little\n", "Lamb"], io.readlines
89
+ assert_equal [[22, 22]], m
90
+ end
91
+
92
+ def test_seek
93
+ io = e("Mary\nHad\nA little\nLamb")
94
+ io.progress_block = lambda do | offset, total |
95
+ assert_equal [6, 22], [offset, total]
96
+ end
97
+ io.seek(6)
98
+ end
99
+
100
+ def test_ungetc
101
+ io = e("Mary\nHad\nA little\nLamb")
102
+ m = []
103
+ io.progress_block = lambda do | offset, total |
104
+ m.push([offset, total])
105
+ end
106
+
107
+ io.getc
108
+ io.ungetc(2)
109
+ assert_equal [[1, 22], [0, 22]], m
110
+ end
111
+
112
+ def test_poseq
113
+ io = e("Mary\nHad\nA little\nLamb")
114
+ io.progress_block = lambda do | offset, total |
115
+ assert_equal [2, 22], [offset, total]
116
+ end
117
+ io.pos = 2
118
+ end
119
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracksperanto
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.4
4
+ version: 1.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-09 00:00:00 +01:00
12
+ date: 2010-02-17 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -93,6 +93,7 @@ files:
93
93
  - lib/tracksperanto/ext_io.rb
94
94
  - lib/tracksperanto/format_detector.rb
95
95
  - lib/tracksperanto/keyframe.rb
96
+ - lib/tracksperanto/progressive_io.rb
96
97
  - lib/tracksperanto/safety.rb
97
98
  - lib/tracksperanto/simple_export.rb
98
99
  - lib/tracksperanto/tracker.rb
@@ -176,6 +177,7 @@ files:
176
177
  - test/test_extio.rb
177
178
  - test/test_format_detector.rb
178
179
  - test/test_keyframe.rb
180
+ - test/test_progressive_io.rb
179
181
  - test/test_simple_export.rb
180
182
  - test/test_tracker.rb
181
183
  - test/test_tracksperanto.rb
@@ -244,6 +246,7 @@ test_files:
244
246
  - test/test_extio.rb
245
247
  - test/test_format_detector.rb
246
248
  - test/test_keyframe.rb
249
+ - test/test_progressive_io.rb
247
250
  - test/test_simple_export.rb
248
251
  - test/test_tracker.rb
249
252
  - test/test_tracksperanto.rb