CTCLLiveEventLoop

Name

CTCLLiveEventLoop -- Run Tcl with event loop.

Synopsis


#include <CTCLLiveEventLoop.h>
         
 class CTCLLiveEventLoop {

  static CTCLLiveEventLoop* getInstance();
  void start();
  void start(CTCLInterpreter* pInterp);
  void stop();
  long setStopLatency(long ms);
  const long getStopLatency();
}

Description

The Tcl/Tk applications programming interfaces provides an event loop. In the case of Tk programs, the event loop is active once the Tk package starts. For pure Tcl (non GUI) programs, the event loop is not active unless the script explicitly enters the event loop via e.g. vwait.

vwait and other pure Tcl commands that enter the event loop block the interpreter from processing commands on stdin while the loop is running. For some Tcl based data acquisition programs this is not acceptable. For example, a readout program may want to accept commands on the command line while doing some periodic processing. This class provides the ability to do this.

The class is a singleton pattern instance, which means that you cannot actually construct an instance, but must use the getInstance method to get a pointer to the single instance of the singleton. The class works by establishing an event handler on stdin, and manually running the event loop at the C++ level. The C++ event loop and stdin input handler do prompting analagous to that of tclsh. When the stdin event handler has accumulated a syntactically complete command it passes that on to the interpreter for evaluation, reporting the result to stdout.

Public member functions

static CTCLLiveEventLoop* getInstance();

Returns a pointer to the singleton instance of the live event loop object. The object is a singleton because while each application may have more than one interpreter, there is only at most one event loop.

void start();

Starts the event loop. This will not return to the caller until some external force has stopped the event loop. External forces include the user closing stdin, or the event loop being asked to stop.

In this invocation, the commands accumulated on stdin are dispatched to the interpreter that was bound to the CTCLApplication object.

void start(CTCLInterpreter* pInterp);

Starts the event loop. Commands accumulated by the stdin event handler are submited to pInterp for execution.

void stop();

Requests the event loop to stop processing. See below for the latency between this request and the actual stop time. Note that a different thread can call this than the one running the target interpreter.

long setStopLatency(long ms);

The event loop waits for events with a timeout. When a wait has completed, if there are events in the queue, they are all processed. After processing any pending events, the event loop determines if a stop has been requested, and if so, returns to its caller.

The wait timeout is set by this member function to ms milliseconds. This effectively sets an estimated latency between the stop member being called, and the event loop actually exiting.

The function returns the prior latency setting.

const long getStopLatency();

Returns the current value of the latency setting. See setStopLatency above for more information.

EXAMPLES

The sample below is a stock tclsh that always runs the event loop in the background. It is installed in the NSCLDAQ bin directory as evttclsh

Example 1. evttclsh


#include <TCLApplication.h>
#include <TCLLiveEventLoop.h>

class evttclsh : public CTCLApplication
{
public:
  virtual int operator()();
};

int
evttclsh::operator()()
{
  CTCLLiveEventLoop* pLoop = CTCLLiveEventLoop::getInstance();
  pLoop->start();
  return TCL_ERROR;
}

CTCLApplication* gpTCLApplication = new evttclsh;