#@package: EventLoop EventLoop

package require Itcl

#
# Copyright (C) 1992-1997 NeoSoft.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided
# that the above copyright notice appear in all copies.  NeoSoft makes no 
# representations about the suitability of this software for any purpose.
# It is provided "as is" without express or implied warranty.

### 
#
#
# $Id: eventloop.tcl,v 1.1.1.1 1999/03/31 20:34:39 damon Exp $
#
# Incr Tcl Event Loop class.
#
# For use with Extended Tcl, but not Wishx, which has its
# own mechanism (addinput).  A functionally identical EventLoop 
# class for Wishx would be really nice.
#

itcl_class EventLoop {

    constructor {config} {
    }

    destructor {
    }

    # make a list containing the file handles of all the sockets,
    # pipes, fifos, etc, we are waiting for data from.
    method make_select_list {} {
	set readSelectList [array names readSelectorCallouts]
    }

    #
    # run an event loop, waiting for input from any of the file handles
    # we've been told to look at, and calling the timeoutCallout,
    # if it exists, every selectTimeout floating point seconds.
    #
    method run {} {
	set running 1
	make_select_list

	while {$running} {

	    set selectResult \
		[select $readSelectList "" "" $selectTimeout]
	    set readReadyList [lindex $selectResult 0]

            if {$readReadyList == ""} {
		eval $timeoutCallout
	    }
	    foreach readReady $readReadyList {
		set command $readSelectorCallouts($readReady)
		if {[gets $readReady line] < 0} {
		    close $readReady
		    continue
		}
		[lindex $command 0] [lindex $command 1] $line
	    }
	}
    }

    # stop the event loop after the event that invoked this method
    # finishes
    method stop {} {
	set running 0
    }

    # add a trigger whereby data on the specified filehandle causes
    # command to execute
    method add_trigger {file command} {
	set readSelectorCallouts($file) $command
    }

    # remove the trigger on the specified filehandle
    method remove_trigger {file} {
	unset readSelectorCallouts($file)
    }

    # true while the event loop is running
    protected running 0

    # array where keys are file handles and data are commands to execute
    protected readSelectorCallouts

    # list of file handles to select on as a list
    protected readSelectList

    # timeout interval, default 10 seconds
    public selectTimeout 10

    # timeout callout code, default is to do nothing
    public timeoutCallout ""
}

