ActionQueueImpl.mesa
Copyright © 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
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;
Public procedures
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 ANYNIL, documentation: REF ANYNIL, fork: BOOLTRUE, guarded: BOOLFALSE, panic: BOOLFALSE] 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: BOOLFALSE ] 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] = {
Like UserClick defined later, but queues a client-defined .action
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.