diff options
author | N.N. <matju@users.sourceforge.net> | 2005-10-04 02:02:15 +0000 |
---|---|---|
committer | N.N. <matju@users.sourceforge.net> | 2005-10-04 02:02:15 +0000 |
commit | 5e2a1bc9e56003349e533f7e5841041ba5c04e28 (patch) | |
tree | ad040f6894d9383b732423a74420e732f62a66a5 /externals/gridflow/base/main.rb | |
parent | 520a243c297175386ab31c78c84693a664934a69 (diff) |
starting to commit gridflow 0.8.0 ...
if you know how to use "cvs import" please mail me and i'll use it for 0.8.1
svn path=/trunk/; revision=3646
Diffstat (limited to 'externals/gridflow/base/main.rb')
-rw-r--r-- | externals/gridflow/base/main.rb | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/externals/gridflow/base/main.rb b/externals/gridflow/base/main.rb new file mode 100644 index 00000000..82976fb6 --- /dev/null +++ b/externals/gridflow/base/main.rb @@ -0,0 +1,369 @@ +=begin + $Id: main.rb,v 1.1 2005-10-04 02:02:13 matju Exp $ + + GridFlow + Copyright (c) 2001,2002 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 + +# ENV["RUBY_VERBOSE_GC"]="yes" + +# this file gets loaded by main.c upon startup +# module GridFlow is supposed to be created by main.c +# this includes GridFlow.post_string(s) + +# because Ruby1.6 has no #object_id and Ruby1.8 warns on #id +unless Object.instance_methods(true).include? "object_id" + class Object; alias object_id id end +end + +# in case of bug in Ruby ("Error: Success") +module Errno; class E000 < StandardError; end; end + +#$post_log = File.open "/tmp/gridflow.log", "w" +$post_log = nil + +class Array + def split(elem) + r=[] + j=0 + for i in 0...length + (r<<self[j,i-j]; j=i+1) if self[i]==elem + end + r<<self[j,length-j] + end +end + +module GridFlow #------------------ + +def self.post(s,*a) + post_string(sprintf("%s"+s,post_header,*a)) + ($post_log << sprintf(s,*a); $post_log.flush) if $post_log +end + +class<<self + attr_accessor :data_path + attr_accessor :post_header + attr_accessor :verbose + attr_reader :fobjects + attr_reader :fclasses + attr_reader :cpu_hertz + attr_reader :subprocesses + attr_reader :bridge_name + alias gfpost post +end + +@subprocesses={} +@verbose=false +@data_path=[] +if GridFlow.respond_to? :config then + @data_path << GridFlow.config["PUREDATA_PATH"]+"/extra/gridflow/images" +end + +def self.hunt_zombies + #STDERR.puts "GridFlow.hunt_zombies" + # the $$ value is bogus + begin + died = [] + subprocesses.each {|x,v| + Process.waitpid2(x,Process::WNOHANG) and died<<x + } + rescue Errno::ECHILD + end + #STDERR.puts died.inspect + died.each {|x| subprocesses.delete x } +end + +def self.packstring_for_nt(nt) + case nt + when :u, :u8, :uint8; "C*" + when :s, :i16, :int16; "s*" + when :i, :i32, :int32; "l*" + when :f, :f32, :float32; "f*" + when :d, :f64, :float64; "d*" + else raise "no decoder for #{nt.inspect}" + end +end + +self.post_header = "[gf] " + +def self.gfpost2(fmt,s); post("%s",s) end + +if GridFlow.bridge_name then + post "This is GridFlow #{GridFlow::GF_VERSION} within Ruby version #{RUBY_VERSION}" + post "base/main.c was compiled on #{GridFlow::GF_COMPILE_TIME}" + post "Please use at least 1.6.6 if you plan to use sockets" if RUBY_VERSION<"1.6.6" +end + +if not GridFlow.bridge_name then + require "gridflow/bridge/placebo" +end + +Brace1 = "{".intern +Brace2 = "}".intern +Paren1 = "(".intern +Paren2 = ")".intern + +def self.parse(m) + m = m.gsub(/(\{|\})/," \\1 ").split(/\s+/) + m.map! {|x| case x + when Integer, Symbol; x + when /^[+\-]?[0-9]+$/; x.to_i + when String; x.intern + end + } + m +end + +def self.stringify_list(argv) + argv.map {|x| stringify x }.join(" ") +end + +def self.stringify(arg) + case arg + when Integer, Float, Symbol; arg.to_s + when Array; "{#{stringify_list arg}}" + end +end + +::Object.module_eval do def FloatOrSymbol(x) Float(x) rescue x.intern end end + +# adding some functionality to that: +class FObject + @broken_ok = false + @do_loadbangs = true + class<<self + # global + attr_accessor :broken_ok + # per-class + attr_reader :ninlets + attr_reader :noutlets + attr_accessor :do_loadbangs + attr_accessor :comment + def foreign_name; @foreign_name if defined? @foreign_name end + end + def post(*a) GridFlow.post(*a) end + def self.subclass(*args,&b) + qlass = Class.new self + qlass.install(*args) + qlass.module_eval(&b) + end + alias :total_time :total_time_get + alias :total_time= :total_time_set + attr_writer :args # String + attr_accessor :argv # Array + attr_reader :outlets + attr_accessor :parent_patcher + attr_accessor :properties + attr_accessor :classname + def initialize2; end + def args + if defined? @args + @args + else + "[#{self.class} ...]" + end + end + alias info args + def connect outlet, object, inlet + @outlets ||= [] + @outlets[outlet] ||= [] + @outlets[outlet].push [object, inlet] + end + def self.name_lookup sym + qlasses = GridFlow.fclasses + qlass = qlasses[sym.to_s] + if not qlass + return qlasses['broken'] if @broken_ok + raise "object class '#{sym}' not found" + end + qlass + end + def self.[](*m) + o=nil + if m.length==1 and m[0] =~ / / + o="[#{m[0]}]" + m=GridFlow.parse(m[0]) + else + o=m.inspect + end + GridFlow.handle_braces!(m) + ms = m.split ','.intern + m = ms.shift + qlass = m.shift + qlassname = qlass.to_s + qlass = name_lookup qlass.to_s unless Class===qlass + r = qlass.new(*m) + r.classname = qlassname + GridFlow.post "%s",r.args if GridFlow.verbose + for x in ms do r.send_in(-2, *x) end if FObject.do_loadbangs + r + end + def inspect + if args then "#<#{self.class} #{args}>" else super end + end + def initialize(*argv) + s = GridFlow.stringify_list argv + @argv = argv + @args = "[" + @args << (self.class.foreign_name || self.to_s) + @args << " " if s.length>0 + @args << s << "]" + @parent_patcher = nil + @properties = {} + @init_messages = [] + end +end + +class FPatcher < FObject + class << self + attr_reader :fobjects + attr_reader :wires + end + def initialize(*) + super + fobjects = self.class.fobjects + wires = self.class.wires + @fobjects = fobjects.map {|x| if String===x then FObject[x] else x.call end } + @inlets = [] + @ninlets = self.class.ninlets or raise "oops" + i=0 + @fobjects << self + while i<wires.length do + a,b,c,d = wires[i,4] + if a==-1 then + a=self + @inlets[b]||=[] + @inlets[b] << [@fobjects[c],d] + else + if c==-1 then + @fobjects[a].connect b,self,d+@ninlets + else + @fobjects[a].connect b,@fobjects[c],d + end + end + i+=4 + end + end + def method_missing(sym,*args) + sym=sym.to_s + if sym =~ /^_(\d)_(.*)/ then + inl = Integer $1 + sym = $2.intern + if inl<@ninlets then + raise "#{inspect} has not @inlets[#{inl}]" if not @inlets[inl] + for x in @inlets[inl] do + x[0].send_in x[1],sym,*args end + else + send_out(inl-@ninlets,sym,*args) + end + else super end + end +end + +def GridFlow.estimate_cpu_clock + u0,t0=GridFlow.rdtsc,Time.new.to_f; sleep 0.01 + u1,t1=GridFlow.rdtsc,Time.new.to_f; (u1-u0)/(t1-t0) +end + +begin + @cpu_hertz = (0...3).map { + GridFlow.estimate_cpu_clock + }.sort[1] # median of three tries +rescue + GridFlow.post $! +end + +def GridFlow.find_file s + s=s.to_s + if s==File.basename(s) then + dir = GridFlow.data_path.find {|x| File.exist? "#{x}/#{s}" } + if dir then "#{dir}/#{s}" else s end + elsif GridFlow.respond_to? :find_file_2 + GridFlow.find_file_2 s + else + s + end +end + +def GridFlow.macerr(i) + begin + f=File.open("/System/Library/Frameworks/CoreServices.framework/"+ + "Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/"+ + "MacErrors.h") + while f.gets + m = /^\s*(\w+)\s*=\s*(-\d+),\s*\/\*\s*(.*)\s*\*\/$/.match $_ + next if not m + if m[2].to_i == i then return "#{m[2]}: \"#{m[3]}\"" end + end + return "no error message available for this error number" + rescue FileError + return "Can't find Apple's precious copyrighted list of error messages on this system." + ensure + f.close if f + end +end + +end # module GridFlow + +class IO + def nonblock= flag + bit = Fcntl::O_NONBLOCK + state = fcntl(Fcntl::F_GETFL, 0) + fcntl(Fcntl::F_SETFL, (state & ~bit) | + (if flag; bit else 0 end)) + end +end + +def protect + yield +rescue Exception => e + STDERR.puts "#{e.class}: #{e}" + STDERR.puts e.backtrace +end + +def GridFlow.load_user_config + require "gridflow/bridge/puredata.rb" if GridFlow.bridge_name == "puredata" + user_config_file = ENV["HOME"] + "/.gridflow_startup" + begin + load user_config_file if File.exist? user_config_file + rescue Exception => e + GridFlow.post "#{e.class}: #{e}:\n" + e.backtrace.join("\n") + GridFlow.post "while loading ~/.gridflow_startup" + end +end + +require "gridflow/base/flow_objects.rb" +require "gridflow/format/main.rb" + +%w( + # #for #finished #type #dim #transpose #perspective #store #outer + #grade #redim #import #export #export_list #cast + #scale_by #downscale_by #draw_polygon #draw_image #layer + #print #pack #export_symbol #rotate + #in #out +).each {|k| + GridFlow::FObject.name_lookup(k).add_creator k.gsub(/#/,"@") +} + +END { + GridFlow.fobjects.each {|k,v| k.delete if k.respond_to? :delete } + GridFlow.fobjects.clear + GC.start +} + |