<> <> <> DIRECTORY AMBridge USING [GetWorld], AMEvents USING [Event, EventProc, GetEvents, StopEvents], BBAction USING [Action, ActionKind, NewAction, WaitForDataTaken], BBBreak USING [BreakId, ClearBreak, FindBreakId, NextBreak, NullIndex], BBContext USING [GetDefaultGlobalContext, SetDefaultGlobalContext], BBNub USING [], BBObjectLocation USING [CatchBreakpoint, GFandPCFromLocation, Location], Rope USING [Equal, ROPE], RTBasic USING [TV], WorldVM USING [BadWorld, GetWorld, LocalWorld, LookupFailed, World, WorldName]; BBNubImpl: CEDAR MONITOR IMPORTS AMBridge, BBAction, BBBreak, BBContext, BBObjectLocation, AMEvents, Rope, WorldVM EXPORTS BBNub SHARES BBContext = BEGIN OPEN Rope, RTBasic; Event: TYPE = AMEvents.Event; World: TYPE = WorldVM.World; HandleEvents: AMEvents.EventProc = TRUSTED { <<[data: REF ANY, event: Event] RETURNS[outcome: Outcome]>> ENABLE ABORTED => GO TO abort; actionKind: BBAction.ActionKind _ other; myAction: BBAction.Action _ NIL; info: REF _ NIL; rtn: REF _ NIL; -- place holder for returned TV for signals world: WorldVM.World _ event.world; WITH e: event SELECT FROM break => { actionKind _ break; IF BBObjectLocation.CatchBreakpoint[event] THEN RETURN; RETURN; -- we should try to world-swap this }; signal => actionKind _ signal; booted => { <> IF world = BBContext.GetDefaultGlobalContext[].world THEN [] _ BBContext.SetDefaultGlobalContext[NIL]; <> FOR bx: INT _ BBBreak.NextBreak[BBBreak.NullIndex], BBBreak.NextBreak[bx] WHILE bx # BBBreak.NullIndex DO bid: BBBreak.BreakId = BBBreak.FindBreakId[bx]; loc: BBObjectLocation.Location = bid.loc; gf: TV = BBObjectLocation.GFandPCFromLocation[loc].gf; IF gf = NIL OR AMBridge.GetWorld[gf] # world THEN LOOP; [] _ BBBreak.ClearBreak[bx]; ENDLOOP; }; ENDCASE; myAction _ BBAction.NewAction[event, actionKind]; BBAction.WaitForDataTaken[myAction, info]; IF actionKind = signal THEN { <> }; EXITS abort => RETURN [[quit[]]]; }; worldList: LIST OF World _ NIL; localListen: BOOL _ FALSE; FindWorld: PUBLIC PROC [name: ROPE, new: BOOL _ FALSE] RETURNS [World] = TRUSTED { <> <> <> world: World _ Lookup[name]; IF NOT new THEN RETURN [world]; IF world = NIL THEN { newWorld: World _ WorldVM.GetWorld[ name ! ABORTED => GO TO abort; WorldVM.LookupFailed, WorldVM.BadWorld => GO TO cant]; world _ AddWorld[name, newWorld]; IF world = newWorld THEN AMEvents.GetEvents[world, NIL, HandleEvents]; }; IF world = WorldVM.LocalWorld[] AND NOT localListen THEN { AMEvents.GetEvents[world, NIL, HandleEvents]; localListen _ TRUE}; RETURN [world]; EXITS abort => ERROR ABORTED; cant => RETURN [NIL]; }; Lookup: ENTRY PROC [name: ROPE] RETURNS [World] = TRUSTED { <> <> <> IF name = NIL OR name.Equal["Local", FALSE] THEN RETURN [WorldVM.LocalWorld[]]; FOR list: LIST OF World _ worldList, list.rest UNTIL list = NIL DO each: World _ list.first; IF name.Equal[WorldVM.WorldName[each], FALSE] THEN RETURN [each]; ENDLOOP; RETURN [NIL]; }; AddWorld: ENTRY PROC [name: ROPE, newWorld: World] RETURNS [World] = TRUSTED { <> <> <> FOR list: LIST OF World _ worldList, list.rest UNTIL list = NIL DO each: World _ list.first; IF name.Equal[WorldVM.WorldName[each], FALSE] THEN RETURN [each]; ENDLOOP; worldList _ CONS[newWorld, worldList]; RETURN [newWorld]; }; RemWorld: ENTRY PROC [name: ROPE] RETURNS [World] = TRUSTED { <> lag: LIST OF World _ NIL; FOR list: LIST OF World _ worldList, list.rest UNTIL list = NIL DO each: World _ list.first; IF name.Equal[WorldVM.WorldName[each], FALSE] THEN { IF lag = NIL THEN worldList _ list.rest ELSE lag.rest _ list.rest; RETURN [each]}; lag _ list; ENDLOOP; RETURN [NIL]; }; NextWorld: PUBLIC ENTRY PROC [last: World _ NIL] RETURNS [World] = TRUSTED { <> <> <<... body of loop>> <> IF last = NIL AND localListen THEN RETURN [WorldVM.LocalWorld[]]; IF last = NIL OR last = WorldVM.LocalWorld[] THEN RETURN [IF worldList = NIL THEN NIL ELSE worldList.first]; FOR list: LIST OF World _ worldList, list.rest UNTIL list = NIL DO each: World _ list.first; IF each = last THEN RETURN [IF list.rest = NIL THEN NIL ELSE list.rest.first]; ENDLOOP; RETURN [NIL]; }; TurnADeafEar: PUBLIC PROC [world: World] = TRUSTED { <> <> IF world = NIL THEN RETURN; IF world = WorldVM.LocalWorld[] THEN localListen _ FALSE ELSE world _ RemWorld[WorldVM.WorldName[world]]; IF world # NIL THEN AMEvents.StopEvents[world]; }; END.