DIRECTORY Buttons USING [Button, ButtonProc, Create], Imager USING [Font], ActionQueue USING [Action, Queue, QueueObj ], ActionQueuePrivate USING [Event, MyClickInfoObj, UserClick, Enqueue], Menus USING [ClickProc, CreateEntry, MenuEntry], Process USING [DisableTimeout, EnableAborts], Rope USING [ROPE], ViewerClasses USING [Viewer, ViewerRec]; ActionQueueImpl: CEDAR MONITOR LOCKS q.std USING q: ActionQueue.Queue IMPORTS Buttons, Menus, Process, ActionQueuePrivate EXPORTS ActionQueue ~ BEGIN QueueObj: TYPE ~ ActionQueue.QueueObj; -- export concrete type to ActionQueue Queue: TYPE ~ ActionQueue.Queue; Action: TYPE ~ ActionQueue.Action; Viewer: TYPE = ViewerClasses.Viewer; ROPE: TYPE = Rope.ROPE; ClientProgrammingError: ERROR = CODE; InternalProgrammingError: ERROR = CODE; Create: PUBLIC PROC [pushModel: BOOL] RETURNS [queue: Queue] = TRUSTED { queue.std _ NEW[QueueObj_ [pushModel: pushModel]]; queue.panic _ NEW[QueueObj_ [pushModel: pushModel]]; Process.DisableTimeout[@queue.std.newEvent]; Process.EnableAborts[@queue.std.newEvent]; Process.DisableTimeout[@queue.panic.newEvent]; Process.EnableAborts[@queue.panic.newEvent]; RETURN[queue]; }; CreateMenuEntry: PUBLIC PROC [q: Queue, name: Rope.ROPE, proc: Menus.ClickProc, clientData: REF ANY _ NIL, documentation: REF ANY _ NIL, fork: BOOL _ TRUE, guarded: BOOL _ FALSE, panic: BOOL _ FALSE] RETURNS [Menus.MenuEntry] = { RETURN[Menus.CreateEntry[ name, ActionQueuePrivate.UserClick, NEW[ActionQueuePrivate.MyClickInfoObj_ [proc, clientData, panic, q]], documentation, FALSE, guarded ]] }; CreateButton: PUBLIC PROC [q: Queue, info: ViewerClasses.ViewerRec, proc: Buttons.ButtonProc, clientData: REF ANY, fork: BOOL, font: Imager.Font, documentation: REF ANY, guarded: BOOL, paint: BOOL, panic: BOOL _ FALSE ] RETURNS [Buttons.Button] = { RETURN[Buttons.Create[ info, ActionQueuePrivate.UserClick, NEW[ActionQueuePrivate.MyClickInfoObj_ [proc, clientData, panic, q]], FALSE, font, documentation, guarded, paint ]] }; QueueClientAction: PUBLIC PROC [q: Queue, proc: PROC [REF ANY], data: REF ANY] = { newEvent: ActionQueuePrivate.Event _ CONS[first: [client[proc, data]], rest: NIL]; ActionQueuePrivate.Enqueue[q.std, newEvent]; }; DequeueAction: PUBLIC ENTRY PROC [q: Queue] RETURNS [Action] = { ENABLE UNWIND => NULL; event: ActionQueuePrivate.Event; IF q.std.pushModel THEN RETURN WITH ERROR ClientProgrammingError; WHILE q.std.firstEvent=NIL DO WAIT q.std.newEvent ENDLOOP; event _ q.std.firstEvent; q.std.firstEvent_ q.std.firstEvent.rest; RETURN [event.first]; }; FlushWithCallback: PUBLIC ENTRY PROC [q: Queue, proc: PROC[Action]_ NIL] = { ENABLE UNWIND => NULL; event: ActionQueuePrivate.Event; IF proc = NIL THEN q.std.firstEvent_ NIL ELSE UNTIL q.std.firstEvent = NIL DO event_ q.std.firstEvent; q.std.firstEvent_ q.std.firstEvent.rest; proc[event.first]; ENDLOOP; }; Flush: PUBLIC ENTRY PROC [q: Queue] = { q.std.firstEvent_ NIL }; END. ²ActionQueueImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Created by Cattell and Haugeland October 20, 1982 4:20 pm Cattell on October 25, 1982 1:54 pm Willie-Sue on October 25, 1982 4:04 pm Doug Wyatt, May 9, 1985 10:26:55 am PDT Russ Atkinson (RRA) June 18, 1985 6:07:16 pm PDT Crow, September 18, 1986 5:46:56 pm PDT Public procedures Like UserClick defined later, but queues a client-defined .action Κ ˜codešœ™Kšœ Οmœ1™