-- HistoryEventImpl.mesa
-- written by Bill Paxton, June 1981
-- last edit by Bill Paxton, 24-Jun-81 16:47:49

DIRECTORY
HistoryEvent,
SafeStorage;

HistoryEventImpl: PROGRAM 
	IMPORTS SafeStorage
	EXPORTS HistoryEvent =
BEGIN OPEN HistoryEvent;

Ref: TYPE = REF EventBody;
EventBody: PUBLIC TYPE = RECORD [
	undone: BOOLEAN ← FALSE,
	subevents: SubEvent,
	];

SubEvent: TYPE = REF SubEventBody;
SubEventBody: TYPE = RECORD [
	next: SubEvent,
	undoProc: PROC,
	undoRef: REF
	];
	
zone: ZONE ← SafeStorage.NewZone[quantized];

Create: PUBLIC PROC RETURNS [Ref] = { RETURN [NEW[EventBody]] };

Note: PUBLIC PROC [event: Ref, undoProc: PROC, undoRef: REF] = {
	IF event = NIL THEN RETURN;
	event.subevents ← zone.NEW[SubEventBody ← [
		event.subevents, undoProc, undoRef]] };

Undo: PUBLIC PROC [event: Ref] RETURNS [ok: BOOLEAN];
	-- returns false if event was previously undone
	-- otherwise, calls undoProc[undoRef] for each subevent 
	-- in reverse order that subevents originally happened
	IF event=NIL OR event.undone THEN RETURN [FALSE];
	event.undone ← TRUE;
	FOR sub:SubEvent ← event.subevents, sub.next UNTIL sub=NIL DO
		sub.undoProc[sub.undoRef];
		ENDLOOP;
	RETURN [TRUE] };

Start: PUBLIC PROC = {
	};
	
END.