# Copyright 2003-2004 Kevin Reid. # This source code and related files are distributed under the MIT License, as described in the document named "License.txt" which should be provided with this source distribution. pragma.enable("explicit-result-guard") pragma.disable("no-dot-call") pragma.disable("easy-return") pragma.enable("importer") pragma.enable("exporter") pragma.enable("pattern-default") pragma.enable("map-tail") pragma.enable("accumulator") def := def := def := def lazy := def InteriorDelegate := # def JPanel__quasiParser := lazy(fn{ }) def Name := lazy(fn{ }) def action := lazy(fn{ }) def buildIncrementalList := lazy(fn{ }) def description__quasiParser := lazy(fn{ }) def makeInterior := lazy(fn{ }) def makeLamportSlot := def makeThing := lazy(fn{ }) def name__quasiParser := def setupComponentReactor := def whenever := def makeBox { to __optUncall() :any { return [, "get", [meta.context().getFQNPrefix().split("$")[0]]] } to run([ => self := (def box; box), "super" => optSuper := null, => contentsInterior := (def superArgs; def contentsDelegate; lazy(fn{ makeInterior(contentsDelegate, superArgs["owner"], superArgs["identityHolder"]) })), => topInterior := (def topDelegate; lazy(fn{ makeInterior(topDelegate, superArgs["owner"], superArgs["identityHolder"]) })), "open" => initOpen := false ] | bind superArgs) :any { def &open := makeLamportSlot(boolean, initOpen) def outerSuper := if (optSuper != null) { optSuper } else { makeThing([=> self] | superArgs | ["name" => name`a box`]) } bind contentsDelegate implements InteriorDelegate { to __optSealedDispatch(brand) :any { switch (brand) { match ==((def sealer := self.getOwner().getUncallSealer()).getBrand()) { sealer.seal([E, "send", [box, "getContentsInteriorDelegate", []]]) } match _ { null } } } to getName() :any { self.getName() } to lookFrom(contentInfo) :any { self.exterior_look() } } bind topDelegate implements InteriorDelegate { to __optSealedDispatch(brand) :any { switch (brand) { match ==((def sealer := self.getOwner().getUncallSealer()).getBrand()) { sealer.seal([E, "send", [box, "getTopInteriorDelegate", []]]) } match _ { null } } } to getName() :any { self.getName() } to lookFrom(contentInfo) :any { self.exterior_look() } } def visibleInteriorsReporter := whenever([&open], fn{ [topInterior] + if (open) {[contentsInterior]} else {[]} }) bind box extends outerSuper { to __optUncall() :any { [makeBox, "run", [[=> self, => super, => contentsInterior, => topInterior, => open]]] } to __conformTo(guard) :any { if (guard.__respondsTo("isDenDetailGuard", 0) && guard.isDenDetailGuard()) { def outerPanel def superDetail := guard.sprout().coerce(super).getComponent() def contentsDetail := guard.sprout().coerce(contentsInterior).getComponent() def topDetail := guard.sprout().coerce(topInterior).getComponent() def openBox := ("Open") setupComponentReactor(openBox, self.getOpenReporter(), def detailUpdateIsOpen(newValue) :void { openBox.setSelected(newValue) }, null) openBox.addActionListener(action(openBox, fn{ self.setOpen(openBox.isSelected()) null })) bind outerPanel := JPanel` ${superDetail}.X.Y > ${JPanel``} $openBox ${("Top: ")} $topDetail.X.Y ${JPanel``}.Y V ${("Contents: ")} $contentsDetail.X.Y ${JPanel``}.Y V ` def detail { to isDenDetail() :any { true } to getComponent() :any { outerPanel } } } else { box } } to getOpen() :any { open } to setOpen(new :boolean) :any { open := new } to getOpenReporter() :any { (&open).readOnly() } to getContentsInterior() :any { contentsInterior } to getTopInterior() :any { topInterior } to getContentsInteriorDelegate() :any { contentsDelegate } to getTopInteriorDelegate() :any { topDelegate } to exterior_getVisibleInteriorsReporter() :any { visibleInteriorsReporter } to exterior_look() :any { def [_, append, finish] := buildIncrementalList() append.splice(super.exterior_look()) if (open) { if ((def items := contentsInterior.getContentsList()) !~ []) { append(description`%?(en:Contents:%|jbo:.i ti vasru ge%)`) for info in items { append(description`%?(en: ${info.getIdentity()}:i;%|jbo: gi ${info.getIdentity()}:i;%)`) } } else { append(description`%?(en:It is open.%|jbo:.i ti kalri%)`) } } else { append(description`%?(en:It is closed.%|jbo:.i ti ganlo%)`) } if ((def items := topInterior.getContentsList()) !~ []) { append(description`%?(en:On top:%|.i ti se cpana ge`) for info in items { append(description`%?(en: ${info.getIdentity()}:i;%|jbo: gi ${info.getIdentity()}:i;%)`) } } finish() } to interact_setOpen([[inModes, outModes], optAllegedActor], newValue, optEvent) :void { require(inModes.contains("touch")) if (newValue != open) { def loc := self.getExterior().getLocation() def event := if (optEvent != null) { loc <- getEventGuard() <- coerce(optEvent) } else { loc <- makeEvent() } def selfId := self.getIdentityHolder().getIdentity() when (event, self.getIdentityHolder().makeAssertions(event, [ "org.cubik.den.eventDescription" => if (newValue){ description`%?(en:$optAllegedActor:I; %!:(opens) $selfId:d;.%|jbo:$selfId:i; kalri zu'e $optAllegedActor:i;%)` } else { description`%?(en:$optAllegedActor:I; %!:(closes) $selfId:d;.%|jbo:$selfId:i; ganlo zu'e $optAllegedActor:i;%)` } ])) -> done(_, _) :void { self.setOpen(newValue) event <- send() } catch p { throw(p) } } else { throw("no change") } } to exterior_getOptCommandImplementation(cmd :List) :any { # NOTE: Yes, this is awful. I'll clean it up after some more experience with commands. def selfId := self.getIdentityHolder().getIdentity() if (cmd =~ [[`string`, verb ? ["open", "close"].contains(verb)], [`thing`, ==selfId]]) { def openImpl(contextBox, from, [[`string`, verb ? ["open", "close"].contains(verb)], [`thing`, ==selfId]]) :vow[void] { when (from.getRcvr() <- getCommandContextUnsealer() <- unseal(contextBox)) -> done(context) :void { def toOpen := verb == "open" if (toOpen != open) { self.interact_setOpen([[["touch"], []], from], toOpen, null) } else { def existingState := open.pick(description`%?(en:open%|jbo:kalri%)`, description`%?(en:closed%|jbo:ganlo%)`) context <- getMsgOutputFunc() <- (description`%?(en:$selfId:D; %!:(is/are) already $existingState..$\n%|.i $selfId:n; $existingState.%)`) } } catch p { throw(p) } } } } } } } ? def makeBox := # value: ?# fixme: more updoc