DIRECTORY FeedbackTypes, IO, Rope, SimpleFeedback; Feedback: CEDAR DEFINITIONS = BEGIN MsgClass: TYPE = SimpleFeedback.MsgClass; MsgType: TYPE = SimpleFeedback.MsgType; ROPE: TYPE ~ Rope.ROPE; MsgRouter: TYPE = REF MsgRouterObj; MsgRouterObj: TYPE = FeedbackTypes.MsgRouterObj; typeBreaksAt: READONLY ARRAY MsgType OF Breaks; Breaks: TYPE ~ RECORD [begin, end: BOOL]; breaksToType: READONLY ARRAY --begin:--BOOL OF ARRAY --end:--BOOL OF MsgType; CreateRouter: PROC RETURNS [router: MsgRouter]; RegisterRouter: PROC [router: MsgRouter, routerName: ATOM] RETURNS [oldRouter: MsgRouter ฌ NIL]; RouterFromName: PROC [routerName: ATOM] RETURNS [router: MsgRouter]; EnsureRouter: PROC [routerName: ATOM] RETURNS [router: MsgRouter]; ScanRouters: PROC [foreach: PROC [ATOM, MsgRouter] RETURNS [stop: BOOL ฌ FALSE]] RETURNS [RouterScanResult]; RouterScanResult: TYPE ~ RECORD [stopped: BOOL ฌ FALSE, atName: ATOM ฌ NIL, atRouter: MsgRouter ฌ NIL]; Append: PROC [router: MsgRouter, msgType: MsgType, msgClass: MsgClass, msg: ROPE]; PutFL: PROC [router: MsgRouter, msgType: MsgType, msgClass: MsgClass, format: ROPE ฌ NIL, list: LIST OF IO.Value ฌ NIL ]; PutF: PROC [router: MsgRouter, msgType: MsgType, msgClass: MsgClass, format: Rope.ROPE ฌ NIL, v1: IO.Value ]; Blink: PROC [router: MsgRouter, msgClass: MsgClass]; ClearHerald: PROC [router: MsgRouter, msgClass: MsgClass]; SetRouterOn: PROC [router: MsgRouter, on: BOOL]; GetRouterOn: PROC [router: MsgRouter] RETURNS [on: BOOL]; MsgHandler: TYPE ~ REF MsgHandlerObj; MsgHandlerObj: TYPE; SetHandler: PROC [router: MsgRouter, msgClass: MsgClass, mh: MsgHandler] RETURNS [previous: MsgHandler]; SetMultiHandler: PROC [router: MsgRouter, msgClasses: LIST OF MsgClass, mh: MsgHandler]; GetHandler: PROC [router: MsgRouter, msgClass: MsgClass] RETURNS [MsgHandler]; GetEffectiveHandler: PROC [router: MsgRouter, msgClass: MsgClass] RETURNS [MsgHandler]; ScanHandlers: PROC [router: MsgRouter, foreach: PROC [MsgClass, MsgHandler] RETURNS [stop: BOOL ฌ FALSE]] RETURNS [HandlerScanResult]; HandlerScanResult: TYPE ~ RECORD [stopped: BOOL ฌ FALSE, atClass: MsgClass ฌ NIL, atHandler: MsgHandler ฌ NIL]; GetHandledClasses: PROC [MsgRouter] RETURNS [LIST OF MsgClass]; defaultHandler: READONLY Feedback.MsgHandler; SetGlobalDefaultHandlersBehavior: PROC [MsgHandler] RETURNS [previous: MsgHandler]; Problem: READONLY SIGNAL [msg: ROPE]; END. ( Feedback.mesa Copyright ำ 1986, 1990, 1991, 1992 by Xerox Corporation. All rights reserved. Bier, May 1, 1990 10:44 pm PDT Pier, October 23, 1987 3:20:56 pm PDT Last tweaked by Mike Spreitzer on May 3, 1990 7:10:58 am PDT Michael Plass, September 27, 1991 10:55 am PDT Contents: This interface contains advanced routines for sending text messages to the user, in the form of ROPEs. See SimpleFeedback.mesa for a simple interface to this functionality. This interface includes (1) Routines for creating routers, e.g. for applications that require a router per window. (2) Routines for sending text to routers created by this interface (i.e., routers that don't have names). (3) Duplicate (but renamed) copies of the Append, PutF, Blink, and ClearHerald kept here for backwards compatibility with existing Feedback clients. (4) Routines for directing routers to specific output areas. Other interfaces contain routines for directing routers to specific classes of output. For instance, at the time of this writing, FeedbackOps.mesa contains routines to direct routers to use various kinds of Cedar Viewers output. (5) The SIGNAL Problem, which can be used by any application that needs a signal that passes a ROPE but doesn't want to clutter up the world with yet another SIGNAL name. Types & Friends The following two arrays are for conversions between MsgType and the more perspicuous representation as a pair of Booleans: typeBreaksAt[mt]=[b,e] <=> breaksToType[b][e]=mt. Creating and Registering Routers Creates an unnamed router. This router can be used immediately. Until redirected (e.g., using SetHandler below) it will send all of its output to the global default handler. Registers router under the given name. If a router already exists under that name, the new router is given the name, and the old router is returned. Returns the currently registered router of name routerName. If no such router exists, returns NIL. Returns the currently registered router of name routerName. If no such router exists, we create one, register it, and return it. For each router registered since Feedback was last loaded, ScanRouters calls foreach. If foreach returns TRUE, ScanRouters returns immediately; if foreach never returns TRUE, ScanRouters visits all the routers and returns FALSE. Reports whether the scan was stopped by the consumer, and if so, the name and router for which the consumer returned TRUE. Sending Messages Send "msg" to router. "msgType" helps Append to format the message on a variety of devices by telling it when a message begins and ends (see MsgType in SimpleFeedback.mesa). "msgClass" and "routerName" together determine where and how this message will be displayed (see MsgClass in SimpleFeedback.mesa). Like Append, but uses IO.PutFLR to format the message. Some routers may support the %l conversion specification and other ways of sneaking Tioga formatting through. Common case of PutFL Call attention to router, hopefully in an emphatic, non-textual way. For output devices (such as Labels.Label in Cedar Viewers) that display only one "line" of text, clear that line. This makes the most sense between the end of one message and the beginning of the next; no guarantees about what happens if called under other circumstances. Allows all output to be temporarily disabled or enabled without forgetting which handlers the router is currently attached to. Output operations on disabled routers are no-ops. Returns the current value of the "on" parameter. Sending Messages (Backward Compatibility) These four routines were removed from this interface; clients should be modified to refer to Append, PutF, Blink, and ClearHerald in SimpleFeedback.mesa. AppendByName: ... PutFByName: ... BlinkByName: ... ClearHeraldByName: ... Directing Routers mh#NIL => direct output for the pair (router, msgClass) to the handler mh. mh=NIL => remove explicit directions for the pair (router, msgClass). msgClass=$Default => manipulate the default for that router. msgClass=$Every => remove explicit directions for all MsgClasses and manipulate the default for that router. Like SetHandler, but sets the handler for several specific message classes at once. Reports what was last Set for the given class. If no handler was explicitly set, GetHandler returns NIL. Returns the message handler to which output for this (router, msgClass) pair will be sent. If a handler was explicitly set for this pair, return that handler. Otherwise, return the current default handler for this router, if one has been explicitly set. Otherwise, return the global default handler. For each MsgClass that has been explicitly set to a MsgHandler, call foreach. $Default will be enumerated iff explicit directions for $Default have been given (and not rescinded); $Every is never enumerated. Reports whether the scan was stopped by the consumer, and if so, the class and handler for which the consumer returned TRUE. A convenience procedure that constructs a list of the classes enumerated by ScanHandlers. The global default handler. The handler that will be used for all undirected MsgClasses of all routers for whom a $Default handler has not explicitly been set. The identity of the defaultHandler never changes, but its behavior is to indirect through a variable that can be set by the following procedure. The Feedback package takes responsibility for ensuring that the behavior of the global default handler is always reasonable. Sets the handler that the defaultHandler calls through, returning the previous value (may be NIL the first time this is called). All routers are immediately affected, even those created before SetGlobalDefaultHandlersBehavior is called (because of the indirection). CLIENTS DON'T NEED TO CALL THIS PROCEDURE; IT EXISTS ONLY TO ALLOW THE VARIOUS MODULES OF THE FEEDBACK IMPLEMENTATION TO COMMUNICATE WITH ONE ANOTHER. A General-Purpose SIGNAL That Passes a ROPE ส๋•NewlineDelimiter –(cedarcode) style™code™ Kšœ ฯeœC™NK™K™%K™