Class: TkarDriver

Inherits:
Object show all
Defined in:
lib/redshift/util/tkar-driver.rb

Overview

Manages interface to external animation process. Depends on:

gem install tkar

See also:

https://github.com/vjoel/tkar

Constant Summary collapse

MAX_LAG =

never let the simulation get more than this many steps ahead

10
MIN_LAG =

let the visualization lag by this many steps, or more

5

Instance Method Summary collapse

Constructor Details

#initialize(dragger = nil) {|@pipe| ... } ⇒ TkarDriver

dragger is a callable object that takes (id, x, y) and should move object id to (x,y)

Yields:

  • (@pipe)


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/redshift/util/tkar-driver.rb', line 9

def initialize dragger = nil
  @dragger = dragger
  cmd =
    case RUBY_PLATFORM
    when /mswin/
      "tkar --radians 2>nul"
    else
      # Use setsid so that ^C doesn't kill it
      "setsid tkar --radians 2>/dev/null"
    end

  @pipe = IO.popen(cmd, "w+")
  yield @pipe if block_given?

  @buf = 0
  update
end

Instance Method Details

#catch_up_within(steps) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/redshift/util/tkar-driver.rb', line 69

def catch_up_within steps
  return unless @pipe

  while @buf > steps || (steps==0 && select([@pipe],[],[],0))
      ## alternately: if steps==0, send "echo ..." and wait for ...
    case line=@pipe.gets
    when nil
      close
      return
    when /^update$/
      @buf -= 1
    when /^drag (\S+) (\S+) (\S+)/
      drag_parms = $1.to_i, $2.to_f, $3.to_f
    when /^drop/
      @dragger[*drag_parms] if @dragger
    ## TODO: handle dropping on another object
    else
      puts "tkar: #{line}"
    end
  end
rescue Errno::EPIPE
  close
end

#closeObject



33
34
35
36
37
38
# File 'lib/redshift/util/tkar-driver.rb', line 33

def close
  if @pipe
    @pipe.close
    @pipe = nil
  end
end

#closed?Boolean

Returns:

  • (Boolean)


40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/redshift/util/tkar-driver.rb', line 40

def closed?
  return true if not @pipe or @pipe.closed?
  
  begin
    @pipe.puts " " # no-op
    @pipe.flush
  rescue Errno::EPIPE
    close
    true
  else
    @pipe.closed?
  end
end

#updateObject

:yields: pipe



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/redshift/util/tkar-driver.rb', line 54

def update # :yields: pipe
  return unless @pipe

  yield @pipe if block_given?

  @pipe.puts "update"
  @pipe.flush
  @buf += 1
  if @buf > MAX_LAG
    catch_up_within MIN_LAG
  end
rescue Errno::EPIPE
  close
end