aboutsummaryrefslogtreecommitdiff
path: root/externals/gridflow/base/flow_objects.rb
diff options
context:
space:
mode:
Diffstat (limited to 'externals/gridflow/base/flow_objects.rb')
-rw-r--r--externals/gridflow/base/flow_objects.rb1457
1 files changed, 0 insertions, 1457 deletions
diff --git a/externals/gridflow/base/flow_objects.rb b/externals/gridflow/base/flow_objects.rb
deleted file mode 100644
index 8782ae21..00000000
--- a/externals/gridflow/base/flow_objects.rb
+++ /dev/null
@@ -1,1457 +0,0 @@
-=begin
- $Id: flow_objects.rb,v 1.2 2006-03-15 04:37:28 matju Exp $
-
- GridFlow
- Copyright (c) 2001,2002,2003,2004,2005 by Mathieu Bouchard
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- See file ../COPYING for further informations on licensing terms.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-=end
-
-module GridFlow
-
-#-------- fClasses for: control + misc
-
-# a dummy class that gives access to any stuff global to GridFlow.
-FObject.subclass("gridflow",1,1) {
- def _0_profiler_reset
- GridFlow.fobjects.each {|o,*| o.total_time = 0 }
- GridFlow.profiler_reset2 if GridFlow.respond_to? :profiler_reset2
- end
- def _0_profiler_dump
- ol = []
- total=0
- post "-"*32
- post "microseconds percent pointer constructor"
- GridFlow.fobjects.each {|o,*| ol.push o }
-
- # HACK: BitPacking is not a real fobject
- # !@#$ is this still necessary?
- ol.delete_if {|o| not o.respond_to? :total_time }
-
- ol.sort! {|a,b| a.total_time <=> b.total_time }
- ol.each {|o| total += o.total_time }
- total=1 if total<1
- total_us = 0
- ol.each {|o|
- ppm = o.total_time * 1000000 / total
- us = (o.total_time*1E6/GridFlow.cpu_hertz).to_i
- total_us += us
- post "%12d %2d.%04d %08x %s", us,
- ppm/10000, ppm%10000, o.object_id, o.args
- }
- post "-"*32
- post "sum of accounted microseconds: #{total_us}"
- if GridFlow.respond_to? :memcpy_calls then
- post "memcpy calls: #{GridFlow.memcpy_calls} "+
- "; bytes: #{GridFlow.memcpy_bytes}"+
- "; time: #{GridFlow.memcpy_time}"
- end
- if GridFlow.respond_to? :malloc_calls then
- post "malloc calls: #{GridFlow.malloc_calls} "+
- "; bytes: #{GridFlow.malloc_bytes}"+
- "; time: #{GridFlow.malloc_time}"
- end
- post "-"*32
- end
- def _0_formats
- post "-"*32
- GridFlow.fclasses.each {|k,v|
- next if not /#io:/ =~ k
- modes = case v.flags
- when 2; "#out"
- when 4; "#in"
- when 6; "#in/#out"
- end
- post "%s %s: %s", modes, k, v.description
- if v.respond_to? :info then
- post "-> %s", v.info
- end
- }
- post "-"*32
- end
- # security issue if patches shouldn't be allowed to do anything they want
- def _0_eval(*l)
- s = l.map{|x|x.to_i.chr}.join""
- post "ruby: %s", s
- post "returns: %s", eval(s).inspect
- end
- add_creator "@global"
- GridFlow.bind "gridflow", "gridflow" rescue Exception
-}
-FObject.subclass("fps",1,1) {
- def initialize(*options)
- super
- @history = [] # list of delays between incoming messages
- @last = 0.0 # when was last time
- @duration = 0.0 # how much delay since last summary
- @period = 1 # minimum delay between summaries
- @detailed = false
- @mode = :real
- options.each {|o|
- case o
- when :detailed; @detailed=true
- when :real,:user,:system,:cpu; @mode=o
- end
- }
- def @history.moment(n=1)
- sum = 0
- each {|x| sum += x**n }
- sum/length
- end
- end
- def method_missing(*a) end # ignore non-bangs
- def _0_period x; @period=x end
- def publish
- @history.sort!
- n=@history.length
- fps = @history.length/@duration
- if not @detailed then send_out 0, fps; return end
- send_out 0, fps,
- 1000*@history.min,
- 500*(@history[n/2]+@history[(n-1)/2]),
- 1000*@history.max,
- 1000/fps,
- 1000*(@history.moment(2) - @history.moment(1)**2)**0.5
- end
- def _0_bang
- t = case @mode
- when :real; Time.new.to_f
- when :user; Process.times.utime
- when :system; Process.times.stime
- when :cpu; GridFlow.rdtsc/GridFlow.cpu_hertz
- end
- @history.push t-@last
- @duration += t-@last
- @last = t
- return if @duration<@period
- fps = @history.length/@duration
- publish if fps>0.001
- @history.clear
- @duration = 0
- end
-}
-
-# to see what the messages look like when they get on the Ruby side.
-FObject.subclass("rubyprint",1,0) {
- def initialize(*a)
- super
- @time = !!(a.length and a[0]==:time)
- end
-
- def method_missing(s,*a)
- s=s.to_s
- pre = if @time then sprintf "%10.6f ", Time.new.to_f else "" end
- case s
- when /^_0_/; post "%s","#{pre}#{s[3..-1]}: #{a.inspect}"
- else super
- end
- end
-}
-FObject.subclass("printargs",0,0) {
- def initialize(*a) super; post a.inspect end
-}
-GridObject.subclass("#print",1,0) {
- install_rgrid 0, true
- attr_accessor :name
- def initialize(name=nil)
- super # don't forget super!!!
- if name then @name = name.to_s+": " else @name="" end
- @base=10; @format="d"; @trunc=70; @maxrows=50
- end
- def end_hook; end # other hijackability
- def format
- case @nt
- when :float32; '%6.6f'
- when :float64; '%14.14f'
- else "%#{@columns}#{@format}" end
- end
- def _0_base(x)
- @format = (case x
- when 2; "b"
- when 8; "o"
- when 10; "d"
- when 16; "x"
- else raise "base #{x} not supported" end)
- @base = x
- end
- def _0_trunc(x)
- x=x.to_f
- (0..240)===x or raise "out of range (not in 0..240 range)"
- @trunc = x
- end
- def _0_maxrows(x) @maxrows = x.to_i end
- def make_columns udata
- min = udata.min
- max = udata.max
- @columns = "" # huh?
- @columns = [
- sprintf(format,min).length,
- sprintf(format,max).length].max
- end
- def unpack data
- ps = GridFlow.packstring_for_nt @nt
- data.unpack ps
- end
- def _0_rgrid_begin
- @dim = inlet_dim 0
- @nt = inlet_nt 0
- @data = ""
- end
- def _0_rgrid_flow(data) @data << data end
- def _0_rgrid_end
- head = "#{name}Dim[#{@dim.join','}]"
- head << "(#{@nt})" if @nt!=:int32
- head << ": "
- if @dim.length > 3 then
- post head+" (not printed)"
- elsif @dim.length < 2 then
- udata = unpack @data
- make_columns udata
- post trunc(head + dump(udata))
- elsif @dim.length == 2 then
- post head
- udata = unpack @data
- make_columns udata
- sz = udata.length/@dim[0]
- rown = 1
- for row in 0...@dim[0] do
- post trunc(dump(udata[sz*row,sz]))
- rown += 1
- (post "..."; break) if rown>@maxrows
- end
- elsif @dim.length == 3 then
- post head
- make_columns unpack(@data)
- sz = @data.length/@dim[0]
- sz2 = sz/@dim[1]
- rown = 1
- for row in 0...@dim[0]
- column=0; str=""
- for col in 0...@dim[1]
- str << "(" << dump(unpack(@data[sz*row+sz2*col,sz2])) << ")"
- break if str.length>@trunc
- end
- post trunc(str)
- rown += 1
- (post "..."; break) if rown>@maxrows
- end
- end
- @data,@dim,@nt = nil
- end_hook
- end
- def dump(udata,sep=" ")
- f = format
- udata.map{|x| sprintf f,x }.join sep
- end
- def trunc s
- if s.length>@trunc then s[0...@trunc]+" [...]" else s end
- end
-}
-GridPack =
-GridObject.subclass("#pack",1,1) {
- install_rgrid 0
- class<<self;attr_reader :ninlets;end
- def initialize(n=2,cast=:int32)
- n||=self.class.ninlets
- n>=16 and raise "too many inlets"
- super
- @data=[0]*n
- @cast=cast
- @ps =GridFlow.packstring_for_nt cast
- end
- def initialize2
- return if self.class.ninlets>1
- add_inlets @data.length-1
- end
- def _0_cast(cast)
- @ps = GridFlow.packstring_for_nt cast
- @cast = cast
- end
- def self.define_inlet i
- module_eval "
- def _#{i}_int x; @data[#{i}]=x; _0_bang; end
- def _#{i}_float x; @data[#{i}]=x; _0_bang; end
- "
- end
- (0...15).each {|x| define_inlet x }
- def _0_bang
- send_out_grid_begin 0, [@data.length], @cast
- send_out_grid_flow 0, @data.pack(@ps), @cast
- end
- self
-}
-
-# the install_rgrids in the following are hacks so that
-# outlets can work. (install_rgrid is supposed to be for receiving)
-# maybe GF-0.8 doesn't need that.
-GridPack.subclass("@two", 2,1) { install_rgrid 0; def initialize() super 2 end }
-GridPack.subclass("@three",3,1) { install_rgrid 0; def initialize() super 2 end }
-GridPack.subclass("@four", 4,1) { install_rgrid 0; def initialize() super 2 end }
-GridPack.subclass("@eight",8,1) { install_rgrid 0; def initialize() super 2 end }
-GridObject.subclass("#unpack",1,0) {
- install_rgrid 0, true
- def initialize(n=2)
- @n=n
- n>=10 and raise "too many outlets"
- super
- end
- def initialize2; add_outlets @n end
- def _0_rgrid_begin
- inlet_dim(0)==[@n] or raise "expecting Dim[#{@n}], got Dim#{@dim}"
- inlet_set_factor 0,@n
- end
- def _0_rgrid_flow data
- @ps = GridFlow.packstring_for_nt inlet_nt(0)
- duh = data.unpack(@ps)
- i=duh.size-1
- until i<0 do send_out i,duh[i]; i-=1 end
- end
- def _0_rgrid_end; end
-}
-
-GridObject.subclass("#export_symbol",1,1) {
- install_rgrid 0
- def _0_rgrid_begin; @data="" end
- def _0_rgrid_flow data; @data << data; end
- def _0_rgrid_end
- send_out 0, :symbol, @data.unpack("I*").pack("c*").intern
- end
-}
-GridObject.subclass("unix_time",1,3) {
- install_rgrid 0
- def _0_bang
- t = Time.new
- tt = t.to_s
- send_out_grid_begin 0, [tt.length], :uint8
- send_out_grid_flow 0, tt, :uint8
- send_out 1, t.to_i/86400, t.to_i%86400,
- ((t.to_f-t.to_f.floor)*1000000).to_i
- send_out 2, t.year, t.month, t.day, t.hour, t.min, t.day
- end
-}
-### test with "shell xlogo &" -> [exec]
-FObject.subclass("exec",1,0) {
- def _0_shell(*a) system(a.map!{|x| x.to_s }.join(" ")) end
-}
-FObject.subclass("renamefile",1,0) {
- def initialize; end
- def _0_list(a,b) File.rename(a.to_s,b.to_s) end
-}
-FObject.subclass("ls",1,1) {
- def _0_symbol(s) send_out 0, :list, *Dir.new(s.to_s).map {|x| x.intern } end
- def _0_glob (s) send_out 0, :list, *Dir[ s.to_s].map {|x| x.intern } end
-}
-
-#-------- fClasses for: math
-
-FPatcher.subclass("gfmessagebox",1,1) {
- def initialize(*a) @a=a end
- def _0_float(x) send_out 0, *@a.map {|y| if y=="$1".intern then x else y end } end
- def _0_symbol(x) send_out 0, *@a.map {|y| if y=="$1".intern then x else y end } end
-}
-
-FPatcher.subclass("@!",1,1) {
- @fobjects = ["# +","#type","gfmessagebox list $1 #"]
- @wires = [-1,0,1,0, 1,0,2,0, 2,0,0,1, -1,0,0,0, 0,0,-1,0]
- def initialize(sym)
- super
- @fobjects[0].send_in 0, case sym
- when :rand; "op rand"; when :sqrt; "op sqrt"
- when :abs; "op abs-"; when :sq; "op sq-"
- else raise "bork BORK bork" end
- end
-}
-FPatcher.subclass("@fold",2,1) {
- @fobjects = ["#fold +","gfmessagebox seed $1"]
- @wires = [-1,0,0,0, -1,1,1,0, 1,0,0,1, 0,0,-1,0]
- def initialize(op,seed=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :seed, seed end
-}
-FPatcher.subclass("@scan",2,1) {
- @fobjects = ["#scan +","gfmessagebox seed $1"]
- @wires = [-1,0,0,0, -1,1,1,0, 1,0,0,1, 0,0,-1,0]
- def initialize(op,seed=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :seed, seed end
-}
-FPatcher.subclass("@inner",3,1) {
- @fobjects = ["#inner","gfmessagebox seed $1"]
- @wires = [-1,0,0,0, -1,1,1,0, 1,0,0,0, 0,0,-1,0, -1,2,0,1]
- def initialize(op=:*,fold=:+,seed=0,r=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :fold, fold
- o.send_in 0, :seed, seed; o.send_in 1, r end
-}
-FPatcher.subclass("@convolve",2,1) {
- @fobjects = ["#convolve"]
- @wires = [-1,0,0,0, -1,2,0,1, 0,0,-1,0]
- def initialize(op=:*,fold=:+,seed=0,r=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :fold, fold
- o.send_in 0, :seed, seed; o.send_in 1, r end
-}
-
-#-------- fClasses for: video
-
-FPatcher.subclass("@scale_to",2,1) {
- @fobjects = [
- "@for {0 0} {42 42} {1 1}","@ *","@ /",
- "@store","#dim","@redim {2}","#finished",
- ]
- @wires = []
- for i in 1..3 do @wires.concat [i-1,0,i,0] end
- @wires.concat [3,0,-1,0, 4,0,5,0, 5,0,1,1, 6,0,0,0,
- -1,0,4,0, -1,0,3,1, -1,0,6,0, -1,1,0,1, -1,1,2,1]
- def initialize(size)
- (size.length==2 and Numeric===size[0] and Numeric===size[1]) or
- raise "expecting {height width}"
- super
- send_in 1, size
- end
-}
-
-#<vektor> told me to:
-# RGBtoYUV : @fobjects = ["#inner (3 3 # 66 -38 112 128 -74 -94 25 112 -18)",
-# "@ >> 8","@ + {16 128 128}"]
-# YUVtoRGB : @fobjects = ["@ - (16 128 128)",
-# "#inner (3 3 # 298 298 298 0 -100 516 409 -208 0)","@ >> 8"]
-
-FPatcher.subclass("#rotate",2,1) {
- @fobjects = ["#inner","# >> 8"]
- @wires = [-1,0,0,0, 0,0,1,0, 1,0,-1,0]
- def update_rotator
- n = @axis[2]
- rotator = (0...n).map {|i| (0...n).map {|j| if i==j then 256 else 0 end }}
- th = @angle * Math::PI / 18000
- scale = 1<<8
- (0...2).each {|i| (0...2).each {|j|
- a = @axis[i].to_i
- b = @axis[j].to_i
- #GridFlow.post "(#{a},#{b}) #{rotator[a].inspect}"
- rotator[a][b] = (scale*Math.cos(th+(j-i)*Math::PI/2)).to_i
- }}
- @fobjects[0].send_in 1,n,n,"#".intern,*rotator.flatten
- end
- def _0_axis(from,to,total)
- total>=0 or raise "total-axis number incorrect"
- from>=0 and from<total or raise "from-axis number incorrect"
- to >=0 and to <total or raise "to-axis number incorrect"
- @axis = [from.to_i,to.to_i,total.to_i]
- update_rotator
- end
- def initialize(rot=0,axis=[0,1,2])
- super
- @angle=0
- _0_axis(*axis)
- send_in 1, rot
- end
- def _1_int(angle) @angle = angle; update_rotator end
- alias _1_float _1_int
-}
-
-FObject.subclass("foreach",1,1) {
- def initialize() super end
- def _0_list(*a)
- a.each {|e|
- if Symbol===e then
- send_out 0,:symbol,e
- else
- send_out 0,e
- end
- }
- end
-}
-FObject.subclass("listflatten",1,1) {
- def initialize() super end
- def _0_list(*a) send_out 0,:list,*a.flatten end
-}
-FObject.subclass("rubysprintf",2,1) {
- def initialize(*format) _1_list(format) end
- def _0_list(*a) send_out 0, :symbol, (sprintf @format, *a).intern end
- alias _0_float _0_list
- alias _0_symbol _0_list
- def _1_list(*format) @format = format.join(" ") end
- alias _1_symbol _1_list
-}
-
-#-------- fClasses for: jMax compatibility
-
-class JMaxUDPSend < FObject
- def initialize(host,port)
- super
- @socket = UDPSocket.new
- @host,@port = host.to_s,port.to_i
- end
- def encode(x)
- case x
- when Integer; "\x03" + [x].pack("N")
- when Float; "\x04" + [x].pack("g")
- when Symbol, String; "\x01" + x.to_s + "\x02"
- end
- end
- def method_missing(sel,*args)
- sel=sel.to_s.sub(/^_\d_/, "")
- @socket.send encode(sel) +
- args.map{|arg| encode(arg) }.join("") + "\x0b",
- 0, @host, @port
- end
- def delete; @socket.close end
- install "jmax_udpsend", 1, 0
-end
-
-class JMaxUDPReceive < FObject
- def initialize(port)
- super
- @socket = UDPSocket.new
- @port = port.to_i
- @socket.bind nil, @port
- @clock = Clock.new self
- @clock.delay 0
- end
- def decode s
- n = s.length
- i=0
- m = []
- case s[i]
- when 3; i+=5; m << s[i-4,4].unpack("N")[0]
- when 4; i+=5; m << s[i-4,4].unpack("g")[0]
- when 1; i2=s.index("\x02",i); m << s[i+1..i2-1].intern; i=i2+1
- when 11; break
- else raise "unknown code in udp packet"
- end while i<n
- m
- end
- def call
- ready_to_read = IO.select [@socket],[],[],0
- return if not ready_to_read
- data,sender = @socket.recvfrom 1024
- return if not data
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode data)
- @clock.delay 50
- end
- def delete; @clock.unset; @socket.close end
- install "jmax_udpreceive", 0, 2
-end
-
-class JMax4UDPSend < FObject
- def initialize(host,port)
- super
- @socket = UDPSocket.new
- @host,@port = host.to_s,port.to_i
- @symbols = {}
- end
- def encode(x)
- case x
- when Integer; "\x01" + [x].pack("N")
- when Float; "\x02" + [x].pack("G")
- when Symbol, String
- x = x.to_s
- y = x.intern
- if not @symbols[y]
- @symbols[y]=true
- "\x04" + [y].pack("N") + x + "\0"
- else
- "\x03" + [y].pack("N")
- end
- end
- end
- def method_missing(sel,*args)
- sel=sel.to_s.sub(/^_\d_/, "")
- sel=(case sel; when "int","float"; ""; else encode(sel) end)
- args=args.map{|arg| encode(arg) }.join("")
- @socket.send(sel+args+"\x0f", 0, @host, @port)
- end
- def delete; @socket.close end
- install "jmax4_udpsend", 1, 0
-end
-
-class JMax4UDPReceive < FObject
- def initialize(port)
- super
- @socket = UDPSocket.new
- @port = port.to_i
- @socket.bind nil, @port
- @clock = Clock.new self
- @clock.delay 0
- @symbols = {}
- end
- def decode s
- n = s.length
- i=0
- m = []
- case s[i]
- when 1; i+=5; m << s[i-4,4].unpack("N")[0]
- when 2; i+=9; m << s[i-8,8].unpack("G")[0]
- when 3
- i+=5; sid = s[i-4,4].unpack("N")[0]
- m << @symbols[sid]
- when 4
- i+=5; sid = s[i-4,4].unpack("N")[0]
- i2=s.index("\x00",i)
- @symbols[sid] = s[i..i2-1].intern
- m << @symbols[sid]
- i=i2+1
- when 15; break
- else post "unknown code %d in udp packet %s", s[i], s.inspect; return m
- end while i<n
- m
- end
- def call
- ready_to_read = IO.select [@socket],[],[],0
- return if not ready_to_read
- data,sender = @socket.recvfrom 1024
- return if not data
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode data)
- @clock.delay 50
- end
- def delete; @clock.unset; @socket.close end
- install "jmax4_udpreceive", 0, 2
-end
-
-class PDNetSocket < FObject
- def initialize(host,port,protocol=:udp,*options)
- super
- _1_connect(host,port,protocol)
- @options = {}
- options.each {|k|
- k=k.intern if String===k
- @options[k]=true
- }
- end
- def _1_connect(host,port,protocol=:udp)
- host = host.to_s
- port = port.to_i
- @host,@port,@protocol = host.to_s,port.to_i,protocol
- case protocol
- when :udp
- @socket = UDPSocket.new
- if host=="-" then
- @socket.bind nil, port
- end
- when :tcp
- if host=="-" then
- @server = TCPServer.new("localhost",port)
- else
- @socket = TCPSocket.new(host,port)
- end
-
- end
- @clock = Clock.new self
- @clock.delay 0
- @data = ""
- end
- def encode(x)
- x=x.to_i if @options[:nofloat] and Float===x
- x.to_s
- end
- def method_missing(sel,*args)
- sel=sel.to_s
- sel.sub!(/^_\d_/, "") or return super
- sel=(case sel; when "int","float"; ""; else encode(sel) end)
- msg = [sel,*args.map{|arg| encode(arg) }].join(" ")
- if @options[:nosemicolon] then msg << "\n" else msg << ";\n" end
- post "encoding as: %s", msg.inspect if @options[:debug]
- case @protocol
- when :udp; @socket.send msg, 0, @host, @port
- when :tcp; @socket.send msg, 0
- end
- end
- def delete; @clock.unset; @socket.close end
- def decode s
- post "decoding from: %s", s.inspect if @options[:debug]
- s.chomp!("\n")
- s.chomp!("\r")
- s.chomp!(";")
- a=s.split(/[\s\0]+/)
- a.shift if a[0]==""
- a.map {|x|
- case x
- when /-?\d+$/; x.to_i
- when /-?\d/; x.to_f
- else x.intern
- end
- }
- end
- def call
- ready_to_accept = IO.select [@server],[],[],0 if @server
- if ready_to_accept
- @socket.close if @socket
- @socket = @server.accept
- end
- ready_to_read = IO.select [@socket],[],[],0 if @socket
- return if not ready_to_read
- case @protocol
- when :udp
- data,sender = @socket.recvfrom 1024
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode data)
- when :tcp
- @data << @socket.sysread(1024)
- sender = @socket.peeraddr
- loop do
- n = /\n/ =~ @data
- break if not n
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode @data.slice!(0..n))
- end
- end
- @clock.delay 50
- end
- install "pd_netsocket", 2, 2
-end
-
-PDNetSocket.subclass("pd_netsend",1,0) {}
-PDNetSocket.subclass("pd_netreceive",0,2) {
- def initialize(port) super("-",port) end
-}
-
-# bogus class for representing objects that have no recognized class.
-FObject.subclass("broken",0,0) {
- def args; a=@args.dup; a[7,0] = " "+classname; a end
-}
-
-FObject.subclass("fork",1,2) {
- def method_missing(sel,*args)
- sel.to_s =~ /^_(\d)_(.*)$/ or super
- send_out 1,$2.intern,*args
- send_out 0,$2.intern,*args
- end
-}
-FObject.subclass("shunt",2,0) {
- def initialize(n=2,i=0) super; @n=n; @i=i end
- def initialize2; add_outlets @n end
- def method_missing(sel,*args)
- sel.to_s =~ /^_(\d)_(.*)$/ or super
- send_out @i,$2.intern,*args
- end
- def _1_int i; @i=i.to_i % @n end
- alias :_1_float :_1_int
- # hack: this is an alias.
- class Demux < self; install "demux", 2, 0; end
-}
-
-#-------- fClasses for: jmax2pd
-
- FObject.subclass("button",1,1) {
- def method_missing(*) send_out 0 end
- }
- FObject.subclass("toggle",1,1) {
- def _0_bang; @state ^= true; trigger end
- def _0_int x; @state = x!=0; trigger end
- def trigger; send_out 0, (if @state then 1 else 0 end) end
- }
- FObject.subclass("jpatcher",0,0) {
- def initialize(*a) super; @subobjects={} end
- attr_accessor :subobjects
- }
- FObject.subclass("jcomment",0,0) {}
- FObject.subclass("loadbang",0,1) { def trigger; send_out 0 end }
- FObject.subclass("messbox",1,1) {
- def _0_bang; send_out 0, *@argv end
- def clear; @argv=[]; end
- def append(*argv) @argv<<argv; end
- }
-
-#-------- fClasses for: list manipulation (jMax-compatible)
-
- FObject.subclass("listmake",2,1) {
- def initialize(*a) @a=a end
- def _0_list(*a) @a=a; _0_bang end
- def _1_list(*a) @a=a end
- def _0_bang; send_out 0, :list, *@a end
- }
- FObject.subclass("listlength",1,1) {
- def initialize() super end
- def _0_list(*a) send_out 0, a.length end
- }
- FObject.subclass("listelement",2,1) {
- def initialize(i=0) super; @i=i.to_i end
- def _1_int(i) @i=i.to_i end; alias _1_float _1_int
- def _0_list(*a)
- e=a[@i]
- if Symbol===e then
- send_out 0, :symbol, e
- else
- send_out 0, e
- end
- end
- }
- FObject.subclass("listsublist",3,1) {
- def initialize(i=0,n=1) super; @i,@n=i.to_i,n.to_i end
- def _1_int(i) @i=i.to_i end; alias _1_float _1_int
- def _2_int(n) @n=n.to_i end; alias _2_float _2_int
- def _0_list(*a) send_out 0, :list, *a[@i,@n] end
- }
- FObject.subclass("listprepend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_list(*a) a[0,0]=@b; send_out 0, :list, *a end
- def _1_list(*b) @b=b end
- }
- FObject.subclass("listappend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_list(*a) a[a.length,0]=@b; send_out 0, :list, *a end
- def _1_list(*b) @b=b end
- }
- FObject.subclass("listreverse",1,1) {
- def initialize() super end
- def _0_list(*a) send_out 0,:list,*a.reverse end
- }
- FObject.subclass("messageprepend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_(*a) a[0,0]=@b; send_out 0, *a end
- def _1_list(*b) @b=b end
- def method_missing(sym,*a)
- (m = /(_\d_)(.*)/.match sym.to_s) or return super
- _0_ m[2].intern, *a
- end
- }
- FObject.subclass("messageappend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_(*a) a[a.length,0]=@b; send_out 0, *a end
- def _1_list(*b) @b=b end
- def method_missing(sym,*a)
- (m = /(_\d_)(.*)/.match sym.to_s) or return super
- _0_ m[2].intern, *a
- end
- }
-
-# this was the original demo for the Ruby/jMax/PureData bridges
-# FObjects are Ruby Objects that are exported to the PureData system.
-# _0_bang means bang message on inlet 0
-# FObject#send_out sends a message through an outlet
-FObject.subclass("for",3,1) {
- attr_accessor :start, :stop, :step
- def cast(key,val)
- val = Integer(val) if Float===val
- raise ArgumentError, "#{key} isn't a number" unless Integer===val
- end
- def initialize(start,stop,step)
- super
- cast("start",start)
- cast("stop",stop)
- cast("step",step)
- @start,@stop,@step = start,stop,step
- end
- def _0_bang
- x = start
- if step > 0
- (send_out 0, x; x += step) while x < stop
- elsif step < 0
- (send_out 0, x; x += step) while x > stop
- end
- end
- def _0_float(x) self.start=x; _0_bang end
- alias _1_float stop=
- alias _2_float stop=
-}
-FObject.subclass("oneshot",2,1) {
- def initialize(state=true) @state=state!=0 end
- def method_missing(sel,*a)
- m = /^_0_(.*)$/.match(sel.to_s) or return super
- send_out 0, m[1].intern, *a if @state
- @state=false
- end
- def _1_int(state) @state=state!=0 end
- alias _1_float _1_int
- def _1_bang; @state=true end
-}
-FObject.subclass("inv+",2,1) {
- def initialize(b=0) @b=b end; def _1_float(b) @b=b end
- def _0_float(a) send_out 0, :float, @b-a end
-}
-FObject.subclass("inv*",2,1) {
- def initialize(b=0) @b=b end; def _1_float(b) @b=b end
- def _0_float(a) send_out 0, :float, @b/a end
-}
-FObject.subclass("range",1,1) {
- def initialize(*a) @a=a end
- def initialize2
- add_inlets @a.length
- add_outlets @a.length
- end
- def _0_float(x) i=0; i+=1 until @a[i]==nil or x<@a[i]; send_out i,x end
- def method_missing(sel,*a)
- m = /^(_\d+_)(.*)/.match(sel.to_s) or return super
- m[2]=="float" or return super
- @a[m[1].to_i-1] = a[0]
- post "setting a[#{m[1].to_i-1}] = #{a[0]}"
- end
-}
-FObject.subclass("listfind",2,1) {
- def initialize(*a) _1_list(*a) end
- def _1_list(*a) @a = a end
- def _0_float(x)
- i=0
- while i<@a.length
- (send_out 0,i; return) if @a[i]==x
- i+=1
- end
- send_out 0,-1
- end
- doc:_1_list,"list to search into"
- doc:_0_float,"float to find in that list"
- doc_out:_0_float,"position of the incoming float in the stored list"
-}
-
-#-------- fClasses for: GUI
-
-module Gooey # to be included in any FObject class
- def initialize(*)
- super
- @selected=false
- @bg = "#ffffff" # white background
- @bgb = "#000000" # black border
- @bgs = "#0000ff" # blue border when selected
- @fg = "#000000" # black foreground
- @rsym = "#{self.class}#{self.object_id}".intern # unique id for use in Tcl
- @can = nil # the canvas number
- @canvas = nil # the canvas string
- @y,@x = 0,0 # position on canvas
- @sy,@sx = 16,16 # size on canvas
- @font = "Courier -12"
- @vis = nil
- end
- attr_reader :canvas
- attr_reader :selected
- def canvas=(can)
- @can = can if Integer===can
- @canvas = case can
- when String; can
- when Integer; ".x%x.c"%(4*can)
- else raise "huh?"
- end
- end
- def initialize2(*) GridFlow.bind self, @rsym.to_s end
- def pd_displace(can,x,y) self.canvas||=can; @x+=x; @y+=y; pd_show(can) end
- def pd_activate(can,*) self.canvas||=can end
- def quote(text) # for tcl (isn't completely right ?)
- text=text.gsub(/[\{\}]/) {|x| "\\"+x }
- "{#{text}}"
- end
- def pd_vis(can,vis)
- self.canvas||=can; @vis=vis!=0; update end
- def update; pd_show @can if @vis end
- def pd_getrect(can)
- self.canvas||=can
- @x,@y = get_position(can)
- # the extra one-pixel on each side was for #peephole only
- # not sure what to do with this
- [@x-1,@y-1,@x+@sx+1,@y+@sy+1]
- end
- def pd_click(can,x,y,shift,alt,dbl,doit) return 0 end
- def outline; if selected then @bgs else "#000000" end end
- def pd_select(can,sel)
- self.canvas||=can
- @selected=sel!=0
- GridFlow.gui %{ #{canvas} itemconfigure #{@rsym} -outline #{outline} \n }
- end
- def pd_delete(can) end
- def pd_show(can)
- self.canvas||=can
- @x,@y = get_position can if can
- end
- def highlight(color,ratio) # doesn't use self
- c = /^#(..)(..)(..)/.match(color)[1..3].map {|x| x.hex }
- c.map! {|x| [255,(x*ratio).to_i].min }
- "#%02x%02x%02x" % c
- end
-end
-
-class Display < FObject; include Gooey
- attr_accessor :text
- def initialize()
- super
- @sel = nil; @args = [] # contents of last received message
- @text = "..."
- @sy,@sx = 16,80 # default size of the widget
- @bg,@bgs,@fg = "#6774A0","#00ff80","#ffff80"
- end
- def _0_set_size(sy,sx) @sy,@sx=sy,sx end
- def atom_to_s a
- case a
- when Float; sprintf("%.5f",a).gsub(/\.?0+$/, "")
- else a.to_s
- end
- end
- def method_missing(sel,*args)
- m = /^(_\d+_)(.*)/.match(sel.to_s) or return super
- @sel,@args = m[2].intern,args
- @text = case @sel
- when nil; "..."
- when :float; atom_to_s @args[0]
- else @sel.to_s + ": " + @args.map{|a| atom_to_s a }.join(' ')
- end
- update
- end
- def pd_show(can)
- super
- return if not canvas or not @vis # can't show for now...
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas delete #{@rsym}TEXT
- set y #{@y+2}
- foreach line [split #{quote @text} \\n] {
- $canvas create text #{@x+2} $y -fill #{@fg} -font #{quote @font}\
- -text $line -anchor nw -tag #{@rsym}TEXT
- set y [expr $y+14]
- }
- foreach {x1 y1 x2 y2} [$canvas bbox #{@rsym}TEXT] {}
- set sx [expr $x2-$x1+1]
- set sy [expr $y2-$y1+3]
- $canvas delete #{@rsym}
- $canvas create rectangle #{@x} #{@y} \
- [expr #{@x}+$sx] [expr #{@y}+$sy] -fill #{@bg} \
- -tags #{@rsym} -outline #{outline}
- $canvas lower #{@rsym} #{@rsym}TEXT
- pd \"#{@rsym} set_size $sy $sx;\n\";
- }
- end
- def pd_delete(can)
- if @vis
- GridFlow.gui %{ #{canvas} delete #{@rsym} #{@rsym}TEXT \n}
- end
- super
- end
- def delete; super end
- def _0_grid(*foo) # big hack!
- # hijacking a [#print]
- gp = FObject["#print"]
- @text = ""
- overlord = self
- gp.instance_eval { @overlord = overlord }
- def gp.post(fmt,*args) @overlord.text << sprintf(fmt,*args) << "\n" end
- def gp.end_hook
- @overlord.instance_eval{@text.chomp!}
- @overlord.update
- end
- #gp.send_in 0, :trunc, 70
- gp.send_in 0, :maxrows, 20
- gp.send_in 0, :grid, *foo
- end
-
- install "display", 1, 1
- gui_enable if GridFlow.bridge_name =~ /puredata/
-end
-
-class GridEdit < GridObject; include Gooey
- def initialize(grid)
- super
- @store = GridStore.new
- @store.connect 0,self,2
- @fin = GridFinished.new
- @fin.connect 0,self,3
- @bg,@bgs,@fg = "#609068","#0080ff","#ff80ff"
- @bghi = highlight(@bg,1.25) # "#80C891" # highlighted @bg
- #@bghihi = highlight(@bghi,1.5) # very highlighted @bg
- @cellsy,@cellsx = 16,48
- @i,@j = nil,nil # highlighted cell dex
- send_in 0, grid
- end
- def _0_cell_size(sy,sx) @cellsy,@cellsx=sy,sx; update end
- def _0_float(*a) @store.send_in 1,:float,*a; @store.send_in 0; update end
- def _0_list (*a) @store.send_in 1, :list,*a; @store.send_in 0; update end
- def _0_grid (*a) @store.send_in 1, :grid,*a; @fin.send_in 0, :grid,*a end
- def _3_bang; @store.send_in 0; update end
- def edit_start(i,j)
- edit_end if @i
- @i,@j=i,j
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas itemconfigure #{@rsym}CELL_#{@i}_#{@j} -fill #{@bghi}
- }
- end
- def edit_end
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas itemconfigure #{@rsym}CELL_#{@i}_#{@j} -fill #{@bg}
- }
- unfocus @can
- end
- def _2_rgrid_begin
- @data = []
- @dim = inlet_dim 2
- @nt = inlet_nt 2
- post "_2_rgrid_begin: dim=#{@dim.inspect} nt=#{@nt.inspect}"
- send_out_grid_begin 0, @dim, @nt
- end
- def _2_rgrid_flow data
- ps = GridFlow.packstring_for_nt @nt
- @data[@data.length,0] = data.unpack(ps)
- post "_2_rgrid_flow: data=#{@data.inspect}"
- send_out_grid_flow 0, data
- end
- def _2_rgrid_end
- post "_2_rgrid_end"
- end
- def pd_click(can,x,y,shift,alt,dbl,doit)
- post "pd_click: %s", [can,x,y,shift,alt,dbl,doit].inspect
- return 0 if not doit!=0
- i = (y-@y-1)/@cellsy
- j = (x-@x-1)/@cellsx
- post "%d,%d", i,j
- ny = @dim[0] || 1
- nx = @dim[1] || 1
- if (0...ny)===i and (0...nx)===j then
- focus @can,x,y
- edit_start i,j
- end
- return 0
- end
- def pd_key(key)
- post "pd_key: %s", [key].inspect
- if key==0 then unfocus @can; return end
- end
- def pd_motion(dx,dy)
- post "pd_motion: %s", [dx,dy].inspect
- ny = @dim[0] || 1
- nx = @dim[1] || 1
- k = @i*nx+@j
- post "@data[#{k}]=#{@data[k]} before"
- @data[k]-=dy
- @store.send_in 1, :put_at, [@i,@j]
- @store.send_in 1, @data[k]
- @store.send_in 0
- post "@data[#{k}]=#{@data[k]} after"
- update
- end
- def pd_show(can)
- super
- return if not can
- ny = @dim[0] || 1
- nx = @dim[1] || 1
- @sy = 2+@cellsy*ny
- @sx = 2+@cellsx*nx
- g = %{
- set canvas #{canvas}
- $canvas delete #{@rsym} #{@rsym}CELL
- $canvas create rectangle #{@x} #{@y} #{@x+@sx} #{@y+@sy} \
- -fill #{@bg} -tags #{@rsym} -outline #{outline}
- }
- ny.times {|i|
- nx.times {|j|
- y1 = @y+1+i*@cellsy; y2 = y1+@cellsy
- x1 = @x+1+j*@cellsx; x2 = x1+@cellsx
- v = @data[i*nx+j]
- g << %{
- $canvas create rectangle #{x1} #{y1} #{x2} #{y2} -fill #{@bg} \
- -tags {#{@rsym}CELL #{@rsym}CELL_#{i}_#{j}} -outline #{outline}
- $canvas create text #{x2-4} #{y1+2} -text "#{v}" -anchor ne -fill #ffffff \
- -tags {#{@rsym}CELL_#{i}_#{j}_T}
- }
- }
- }
- GridFlow.gui g
- end
- install "#edit", 2, 1
- install_rgrid 2, true
- gui_enable if GridFlow.bridge_name =~ /puredata/
-end
-
-class Peephole < FPatcher; include Gooey
- @fobjects = ["#dim","#export_list","#downscale_by 1 smoothly","#out","#scale_by 1",
- proc{Demux.new(2)}]
- @wires = [-1,0,0,0, 0,0,1,0, -1,0,5,0, 2,0,3,0, 4,0,3,0, 5,0,2,0, 5,1,4,0, 3,0,-1,0]
- def initialize(sy=32,sx=32,*args)
- super
- @fobjects[1].connect 0,self,2
- post "Peephole#initialize: #{sx} #{sy} #{args.inspect}"
- @scale = 1
- @down = false
- @sy,@sx = sy,sx # size of the widget
- @fy,@fx = 0,0 # size of last frame after downscale
- @bg,@bgs = "#A07467","#00ff80"
- end
- def pd_show(can)
- super
- return if not can
- if not @open
- GridFlow.gui %{
- pd \"#{@rsym} open [eval list [winfo id #{@canvas}]] 1;\n\";
- }
- @open=true
- end
- # round-trip to ensure this is done after the open
- GridFlow.gui %{
- pd \"#{@rsym} set_geometry #{@y} #{@x} #{@sy} #{@sx};\n\";
- }
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas delete #{@rsym}
- $canvas create rectangle #{@x} #{@y} #{@x+@sx} #{@y+@sy} \
- -fill #{@bg} -tags #{@rsym} -outline #{outline}
- }
- set_geometry_for_real_now
- end
- def set_geometry_for_real_now
- @fy,@fx=@sy,@sx if @fy<1 or @fx<1
- @down = (@fx>@sx or @fy>@sx)
- if @down then
- @scale = [(@fy+@sy-1)/@sy,(@fx+@sx-1)/@sx].max
- @scale=1 if @scale<1 # what???
- @fobjects[2].send_in 1, @scale
- sy2 = @fy/@scale
- sx2 = @fx/@scale
- else
- @scale = [@sy/@fy,@sx/@fx].min
- @fobjects[4].send_in 1, @scale
- sy2 = @fy*@scale
- sx2 = @fx*@scale
- end
- begin
- @fobjects[5].send_in 1, (if @down then 0 else 1 end)
- x2=@y+(@sy-sy2)/2
- y2=@x+(@sx-sx2)/2
- @fobjects[3].send_in 0, :set_geometry,
- x2, y2, sy2, sx2
- rescue StandardError => e
- post "peeperr: %s", e.inspect
- end
- post "set_geometry_for_real_now (%d,%d) (%d,%d) (%d,%d) (%d,%d) (%d,%d)",
- @x+1,@y+1,@sx,@sy,@fx,@fy,sx2,sy2,x2,y2
- end
- def _0_open(wid,use_subwindow)
- post "%s", [wid,use_subwindow].inspect
- @use_subwindow = use_subwindow==0 ? false : true
- if @use_subwindow then
- @fobjects[3].send_in 0, :open,:x11,:here,:embed_by_id,wid
- end
- end
- def _0_set_geometry(y,x,sy,sx)
- @sy,@sx = sy,sx
- @y,@x = y,x
- set_geometry_for_real_now
- end
- def _0_fall_thru(flag) # never worked ?
- post "fall_thru: #{flag}"
- @fobjects[3].send_in 0, :fall_thru, flag
- end
- # note: the numbering here is a FPatcher gimmick... -1,0 goes to _1_.
- def _1_position(y,x,b)
- s=@scale
- if @down then y*=s;x*=s else y*=s;x*=s end
- send_out 0,:position,y,x,b
- end
- def _2_list(sy,sx,chans)
- @fy,@fx = sy,sx
- set_geometry_for_real_now
- end
- def _0_paint()
- post "paint()"
- @fobjects[3].send_in 0, "draw"
- end
- def delete
- post "deleting peephole"
- GridFlow.gui %{ #{canvas} delete #{@rsym} \n}
- @fobjects[3].send_in 0, :close
- super
- end
- def method_missing(s,*a)
- #post "%s: %s", s.to_s, a.inspect
- super rescue NameError
- end
-
- install "#peephole", 1, 1
- gui_enable if GridFlow.bridge_name =~ /puredata/
- #GridFlow.addtomenu "#peephole" # was this IMPD-specific ?
-end
-
-#-------- fClasses for: Hardware
-
-# requires Ruby 1.8.0 because of bug in Ruby 1.6.x
-FObject.subclass("joystick_port",0,1) {
- def initialize(port)
- raise "sorry, requires Ruby 1.8" if RUBY_VERSION<"1.8"
- @f = File.open(port.to_s,"r+")
- @status = nil
- @clock = Clock.new self
- @clock.delay 0
- @f.nonblock=true
- end
- def delete; @clock.unset; @f.close end
- def call
- loop{
- begin
- event = @f.read(8)
- rescue Errno::EAGAIN
- @clock.delay 0
- return
- end
- return if not event
- return if event.length<8
- send_out 0, *event.unpack("IsCC")
- }
- end
-}
-
-# plotter control (HPGL)
-FObject.subclass("plotter_control",1,1) {
- def puts(x)
- x<<"\n"
- x.each_byte {|b| send_out 0, b }
- send_out 0
- end
- def _0_pu; puts "PU;" end
- def _0_pd; puts "PD;" end
- def _0_pa x,y; puts "PA#{x},#{y};" end
- def _0_sp c; puts "SP#{c};"; end
- def _0_ip(*v) puts "IP#{v.join','};" end
- def _0_other(command,*v) puts "#{command.to_s.upcase}#{v.join','};" end
- def _0_print(*text) puts "LB#{text.join(' ')}\003;" end
- def _0_print_from_ascii(*codes)
- _0_print codes.map{|code| code.chr }.join("")
- end
-}
-
-# ASCII, useful for controlling pics
-FObject.subclass("ascii",1,1) {
- def puts(x)
- x.each_byte {|b| send_out 0, b }
- end
- def _0_float x; puts "#{x.to_i}" end
-}
-
-# System, similar to shell
-FObject.subclass("system",1,1) {
- def _0_system(*a)
- system(a.join(" "))
- end
-}
-
-(begin require "linux/ParallelPort"; true; rescue LoadError; false end) and
-FObject.subclass("parallel_port",1,3) {
- def initialize(port,manually=0)
- @f = File.open(port.to_s,"r+")
- @f.extend Linux::ParallelPort
- @status = nil
- @flags = nil
- @manually = manually!=0
- @clock = (if @manually then nil else Clock.new self end)
- @clock.delay 0 if @clock
- end
- def delete; @clock.unset unless @manually; @f.close end
- def _0_int(x) @f.write x.to_i.chr; @f.flush end
- alias _0_float _0_int
- def call
- flags = @f.port_flags
- send_out 2, flags if @flags != flags
- @flags = flags
- status = @f.port_status
- send_out 1, status if @status != status
- @status = status
- @clock.delay 20 if @clock
- end
- def _0_bang
- @status = @flags = nil
- call
- end
- # outlet 0 reserved (future use)
-}
-
-(begin require "linux/SoundMixer"; true; rescue LoadError; false end) and
-#FObject.subclass("SoundMixer",1,1) {
-class GFSoundMixer < FObject; install "SoundMixer",1,1
- # BUG? i may have the channels (left,right) backwards
- def initialize(filename)
- super
- @file = File.open filename.to_s, 0
- @file.extend Linux::SoundMixer
- $sm = self
- end
- @@vars = Linux::SoundMixer.instance_methods.grep(/=/)
- @@vars_h = {}
- @@vars.each {|attr|
- attr.chop!
- eval %{ def _0_#{attr}(x) @file.#{attr} = x[0]*256+x[1] end }
- @@vars_h[attr]=true
- }
- def _0_get(sel=nil)
- if sel then
- sels=sel.to_s
- sel=sels.intern
- raise if not @@vars_h.include? sel.to_s
- begin
- x = @file.send sel
- send_out 0, sel, "(".intern, (x>>8)&255, x&255, ")".intern
- rescue
- send_out 0, sel, "(".intern, -1, -1, ")".intern
- end
- else
- @@vars.each {|var| _0_get var }
- end
- end
-end#}
-
-# experimental
-FObject.subclass("rubyarray",2,1) {
- def initialize() @a=[]; @i=0; end
- def _0_float i; @i=i; send_out 0, *@a[@i]; end
- def _1_list(*l) @a[@i]=l; end
- def _0_save(filename,format=nil)
- f=File.open(filename.to_s,"w")
- if format then
- @a.each {|x| f.puts(format.to_s%x) }
- else
- @a.each {|x| f.puts(x.join(",")) }
- end
- f.close
- end
- def _0_load(filename)
- f=File.open(filename.to_s,"r")
- @a.clear
- f.each {|x| @a.push x.split(",").map {|y| Float(y) rescue y.intern }}
- f.close
- end
-}
-
-FObject.subclass("regsub",3,1) {
- def initialize(from,to) _1_symbol(from); _2_symbol(to) end
- def _0_symbol(s) send_out 0, :symbol, s.to_s.gsub(@from, @to).intern end
- def _1_symbol(from) @from = Regexp.new(from.to_s.gsub(/`/,"\\")) end
- def _2_symbol(to) @to = to.to_s.gsub(/`/,"\\") end
- doc:_0_symbol,"a string to transform"
- doc:_1_symbol,"a regexp pattern to be found inside of the string"
- doc:_2_symbol,"a replacement for the found pattern"
- doc_out:_0_symbol,"the transformed string"
-}
-
-FObject.subclass("memstat",1,1) {
- def _0_bang
- f = File.open("/proc/#{$$}/stat")
- send_out 0, Float(f.gets.split(" ")[22]) / 1024.0
- f.close
- end
- doc:_0_bang,"lookup process stats for the currently running pd+ruby "+
- "and figure out how much RAM it uses."
- doc_out:_0_float,"virtual size of RAM in kilobytes (includes swapped out and shared memory)"
-}
-
-FObject.subclass("sendgui",1,0) {
- def _0_list(*x)
- GridFlow.gui x.join(" ").gsub(/`/,";")+"\n"
- end
- install "sys_vgui", 1, 0
- doc:_0_list,"a Tcl/Tk command to send to the pd client."
-}
-
-end # module GridFlow
-
-begin
- require "gridflow/rblti"
- GridFlow.post "Ruby-LTI support loaded."
-rescue Exception => e
- #GridFlow.post "%s", e.inspect
- #GridFlow.post "(rblti not found)"
-end