Hi,

> > I'm sorry but 'fileevent' command is not implemented on Ruby/Tk.
> > Because, Ruby has better way to treat streams than Tcl/Tk.
> > I recommend you to use threads for treatment of streams.
> > But attention!
> > Sometimes Ruby/Tk is running too slow,
> > if the event loop, Tk.mainloop, is running in the sub thread.

Too slow? Is that because of the if-statements in the
Tk-bindings, behaving differently when in the main thread or not?

Matz, aren't all Ruby-threads equal?

> > Please use sub threads for stream access,
> > and use the main thread for Tk.mainloop.
> 
> Thx very much I will try that
> (but I'm no sure it's a better way, because receiving file events would
> allow me to treat all the events (user and IO) in a unified way.)

So am I.

See attachment, where I can deal with stdin, network and an
X-connection easily, but know of no way to hook Tk.

Bye,
Kero.

+--- Kero ------------------------------ kero / chello.nl ---+
|  Don't split your mentality without thinking twice       |
|                          Proud like a God -- Guano Apes  |
+--- M38c ------- http://members.chello.nl/~k.vangelder ---+
# Author: Kero van Gelder
# Copyright: Kero van Gelder (the GNU Lesser General Public License applies)
# Since: 24 Sep 2001

module Serialize
  @inputs = []
  @outputs = []
  @errors = []
  @bindings = {}

=begin
== Serialize::(un)set_input/output/error
(De)Associated a block with an input/output/error file descriptor, to be
serialized with other input/output/error fd's, i.e. the blocks associated with
those fd's are never executed simultaneously.

The block must be given and you must ensure the block will let the associated
stream be saturated, that is, input must be consumed, output buffers must be
filled. (Otherwise the loop in Serialize::serialize will never block anymore,
though it will not prevent other blocks from being called.)
=end
  def Serialize::set_input(input, &block)
    raise "Must provide a block"  unless block
    @inputs << input  unless @bindings.fetch(input, nil)
    @bindings.store(input, block)
  end

  def Serialize::set_output(output, &block)
    raise "Must provide a block"  unless block
    @outputs << output  unless @bindings.fetch(output, nil)
    @bindings.store(output, block)
  end

  def Serialize::set_error(error, &block)
    raise "Must provide a block"  unless block
    @errors << error  unless @bindings.fetch(error, nil)
    @bindings.store(error, block)
  end

  def Serialize::unset_input(input)
    @inputs.delete(input)
    @bindings.delete(input)
  end

  def Serialize::unset_output(output)
    @outputs.delete(output)
    @bindings.delete(output)
  end

  def Serialize::unset_error(error)
    @errors.delete(error)
    @bindings.delete(error)
  end

=begin
== Serialize::serialize
Start serializing events.

It is suggested that once this loop is started, you only set and unset file
descriptors in the blocks invoked by this thread, not other threads.
=end
  def Serialize::serialize()
    loop {
      break  if @inputs.empty? and @outputs.empty? and @errors.empty?
      available = select(@inputs, @outputs, @errors, nil).flatten
      available.each { |fd|
	@bindings.fetch(fd, nil).call
      }
    }
    puts "Serialize::serialize() ended (no fd's left)"  if $DEBUG
  end
end