shrub/app/aqua.hoon

549 lines
13 KiB
Plaintext
Raw Normal View History

2019-02-06 05:21:41 +03:00
:: An aquarium of virtual ships. Put in some fish and watch them!
::
2019-02-02 00:49:14 +03:00
:: usage:
2019-02-02 04:00:15 +03:00
:: |start %aqua
2019-02-06 05:21:41 +03:00
:: /- aquarium
:: :aqua &pill .^(pill:aquarium %cx %/urbit/pill)
:: OR
:: :aqua &pill +solid
::
:: Then try stuff:
2019-02-02 04:14:11 +03:00
:: :aqua [%init ~[~bud ~dev]]
:: :aqua [%dojo ~[~bud ~dev] "[our eny (add 3 5)]"]
:: :aqua [%dojo ~[~bud] "|hi ~dev"]
2019-02-05 01:31:55 +03:00
:: :aqua [%wish ~[~bud ~dev] '(add 2 3)']
:: :aqua [%peek ~[~bud] /cx/~bud/home/(scot %da now)/app/curl/hoon]
:: :aqua [%dojo ~[~bud ~dev] '|mount %']
:: :aqua [%file ~[~bud ~dev] %/sys/vane]
:: :aqua [%pause-events ~[~bud ~dev]]
2019-02-02 00:49:14 +03:00
::
2019-02-02 04:00:15 +03:00
::
2019-02-06 05:21:41 +03:00
:: We get ++unix-event and ++pill from /-aquarium
2019-02-02 04:00:15 +03:00
::
2019-02-06 05:21:41 +03:00
/- aquarium
=, aquarium
2019-02-02 00:49:14 +03:00
=> $~ |%
2019-03-06 23:22:37 +03:00
+$ move (pair bone card)
+$ card
2019-03-07 10:31:14 +03:00
$% [%diff diff-type]
2019-02-02 00:49:14 +03:00
==
2019-03-06 23:22:37 +03:00
::
:: Outgoing subscription updates
::
+$ diff-type
$% [%aqua-effects aqua-effects]
[%aqua-events aqua-events]
[%aqua-boths aqua-boths]
==
::
+$ state
2019-02-02 04:00:15 +03:00
$: %0
pil=pill
2019-02-02 00:49:14 +03:00
assembled=*
2019-02-09 06:18:38 +03:00
tym=@da
2019-02-02 00:49:14 +03:00
fleet-snaps=(map term (map ship pier))
piers=(map ship pier)
==
2019-03-06 23:22:37 +03:00
::
+$ pier
2019-02-09 06:18:38 +03:00
$: snap=*
2019-03-06 23:22:37 +03:00
event-log=(list unix-timed-event)
2019-02-02 00:49:14 +03:00
next-events=(qeu unix-event)
processing-events=?
==
--
=, gall
2019-02-08 04:12:57 +03:00
::
2019-03-07 00:14:32 +03:00
:: unix-{effects,events,boths}: collect jar of effects and events to
:: brodcast all at once to avoid gall backpressure
2019-02-08 05:03:46 +03:00
:: moves: Hoist moves into state for cleaner state management
2019-02-08 04:12:57 +03:00
::
2019-02-08 05:03:46 +03:00
=| unix-effects=(jar ship unix-effect)
2019-03-06 23:22:37 +03:00
=| unix-events=(jar ship unix-timed-event)
=| unix-boths=(jar ship unix-both)
2019-02-08 04:12:57 +03:00
=| moves=(list move)
2019-02-06 05:21:41 +03:00
|_ $: hid=bowl
2019-02-02 00:49:14 +03:00
state
==
2019-02-02 04:00:15 +03:00
::
:: Represents a single ship's state.
::
2019-02-02 00:49:14 +03:00
++ pe
|= who=ship
=+ (fall (~(get by piers) who) *pier)
=* pier-data -
|%
2019-03-07 00:14:32 +03:00
::
:: Done; install data
::
2019-02-08 04:12:57 +03:00
++ abet-pe
^+ this
2019-02-02 00:49:14 +03:00
=. piers (~(put by piers) who pier-data)
2019-02-08 04:12:57 +03:00
this
2019-02-02 00:49:14 +03:00
::
2019-03-07 00:14:32 +03:00
:: Initialize new ship
::
2019-02-02 00:49:14 +03:00
++ apex
2019-02-02 04:00:15 +03:00
=. pier-data *pier
2019-02-02 00:49:14 +03:00
=. snap assembled
2019-03-07 00:14:32 +03:00
~& pill-size=(met 3 (jam snap))
2019-02-08 04:12:57 +03:00
..abet-pe
2019-02-02 00:49:14 +03:00
::
2019-03-07 00:14:32 +03:00
:: Enqueue events to child arvo
::
2019-02-02 00:49:14 +03:00
++ push-events
2019-03-08 08:15:42 +03:00
|= ues=(list unix-event)
2019-02-08 04:12:57 +03:00
^+ ..abet-pe
2019-03-08 08:15:42 +03:00
=. next-events (~(gas to next-events) ues)
2019-02-08 04:12:57 +03:00
..abet-pe
2019-02-02 00:49:14 +03:00
::
2019-03-07 00:14:32 +03:00
:: Send moves to host arvo
::
2019-02-02 00:49:14 +03:00
++ emit-moves
|= ms=(list move)
2019-02-08 05:03:46 +03:00
=. this (^emit-moves ms)
2019-02-08 04:12:57 +03:00
..abet-pe
2019-02-02 00:49:14 +03:00
::
2019-02-02 04:00:15 +03:00
:: Process the events in our queue.
::
2019-02-02 00:49:14 +03:00
++ plow
2019-02-08 04:12:57 +03:00
|- ^+ ..abet-pe
2019-02-02 00:49:14 +03:00
?: =(~ next-events)
2019-02-08 04:12:57 +03:00
..abet-pe
2019-02-02 00:49:14 +03:00
?. processing-events
2019-02-08 04:12:57 +03:00
..abet-pe
2019-03-07 10:31:14 +03:00
=^ ue next-events ~(get to next-events)
2019-03-07 00:14:32 +03:00
=/ poke-arm (mox +47.snap)
?> ?=(%0 -.poke-arm)
=/ poke p.poke-arm
2019-02-09 02:21:40 +03:00
=. tym (max +(tym) now.hid)
2019-03-07 10:31:14 +03:00
=/ poke-result (slum poke tym ue)
2019-03-07 00:14:32 +03:00
=. snap +.poke-result
2019-03-07 10:31:14 +03:00
=. ..abet-pe (publish-event tym ue)
2019-03-07 00:14:32 +03:00
=. ..abet-pe (handle-effects ((list ovum) -.poke-result))
2019-02-02 00:49:14 +03:00
$
::
2019-02-05 01:31:55 +03:00
:: Peek
::
++ peek
|= p=*
=/ res (mox +46.snap)
?> ?=(%0 -.res)
=/ peek p.res
2019-02-15 04:18:04 +03:00
=/ pax (path p)
?> ?=([@ @ @ @ *] pax)
=. i.t.t.t.pax (scot %da tym)
=/ pek (slum peek [tym pax])
pek
2019-02-05 01:31:55 +03:00
::
:: Wish
::
++ wish
|= txt=@t
=/ res (mox +22.snap)
?> ?=(%0 -.res)
=/ wish p.res
~& [who=who %wished (slum wish txt)]
2019-02-08 04:12:57 +03:00
..abet-pe
2019-02-05 01:31:55 +03:00
::
2019-02-02 04:00:15 +03:00
++ mox |=(* (mock [snap +<] scry))
::
:: Start/stop processing events. When stopped, events are added to
:: our queue but not processed.
::
2019-02-02 00:49:14 +03:00
++ start-processing-events .(processing-events &)
++ stop-processing-events .(processing-events |)
2019-02-02 04:00:15 +03:00
::
:: Handle all the effects produced by a single event.
2019-02-02 00:49:14 +03:00
::
++ handle-effects
|= effects=(list ovum)
2019-02-08 04:12:57 +03:00
^+ ..abet-pe
2019-02-02 00:49:14 +03:00
?~ effects
2019-02-08 04:12:57 +03:00
..abet-pe
=. ..abet-pe
2019-02-02 00:49:14 +03:00
=/ sof ((soft unix-effect) i.effects)
?~ sof
2019-03-21 03:37:05 +03:00
~? aqua-debug=| [who=who %unknown-effect i.effects]
2019-02-08 04:12:57 +03:00
..abet-pe
2019-02-06 05:21:41 +03:00
(publish-effect u.sof)
2019-02-02 00:49:14 +03:00
$(effects t.effects)
::
2019-02-06 05:21:41 +03:00
:: Give effect to our subscribers
::
++ publish-effect
2019-03-07 10:31:14 +03:00
|= uf=unix-effect
2019-02-08 04:12:57 +03:00
^+ ..abet-pe
2019-03-07 10:31:14 +03:00
=. unix-effects (~(add ja unix-effects) who uf)
=. unix-boths (~(add ja unix-boths) who [%effect uf])
2019-03-06 23:22:37 +03:00
..abet-pe
::
:: Give event to our subscribers
::
++ publish-event
2019-03-07 10:31:14 +03:00
|= ute=unix-timed-event
2019-03-06 23:22:37 +03:00
^+ ..abet-pe
2019-03-07 10:31:14 +03:00
=. event-log [ute event-log]
=. unix-events (~(add ja unix-events) who ute)
=. unix-boths (~(add ja unix-boths) who [%event ute])
2019-02-08 05:03:46 +03:00
..abet-pe
--
::
++ this .
::
:: ++apex-aqua and ++abet-aqua must bookend calls from gall
::
++ apex-aqua
^+ this
2019-03-06 23:22:37 +03:00
=: moves ~
2019-02-08 05:03:46 +03:00
unix-effects ~
2019-03-06 23:22:37 +03:00
unix-events ~
unix-boths ~
2019-02-08 05:03:46 +03:00
==
this
::
++ abet-aqua
^- (quip move _this)
=. this
2019-02-06 05:21:41 +03:00
%- emit-moves
2019-03-07 10:31:14 +03:00
%- zing ^- (list (list move))
%+ turn ~(tap by sup.hid)
2019-02-06 05:21:41 +03:00
|= [b=bone her=ship pax=path]
2019-03-07 10:31:14 +03:00
^- (list move)
2019-03-06 23:22:37 +03:00
?+ pax ~
[%effects @ ~]
=/ who (slav %p i.t.pax)
2019-03-07 10:31:14 +03:00
=/ ufs (~(get ja unix-effects) who)
?~ ufs
2019-03-06 23:22:37 +03:00
~
2019-03-08 09:28:10 +03:00
[b %diff %aqua-effects who (flop ufs)]~
2019-03-07 10:31:14 +03:00
::
[%effects ~]
%+ turn
~(tap by unix-effects)
|= [who=ship ufs=(list unix-effect)]
2019-03-08 09:28:10 +03:00
[b %diff %aqua-effects who (flop ufs)]
2019-03-06 23:22:37 +03:00
::
[%events @ ~]
=/ who (slav %p i.t.pax)
=/ ve (~(get ja unix-events) who)
?~ ve
~
2019-03-08 09:28:10 +03:00
[b %diff %aqua-events who (flop ve)]~
2019-03-06 23:22:37 +03:00
::
[%boths @ ~]
=/ who (slav %p i.t.pax)
=/ bo (~(get ja unix-boths) who)
?~ bo
~
2019-03-08 09:28:10 +03:00
[b %diff %aqua-boths who (flop bo)]~
2019-03-06 23:22:37 +03:00
==
2019-02-08 05:03:46 +03:00
[(flop moves) this]
::
++ emit-moves
|= ms=(list move)
=. moves (weld ms moves)
this
2019-02-02 04:00:15 +03:00
::
::
:: Run all events on all ships until all queues are empty
::
2019-02-02 00:49:14 +03:00
++ plow-all
2019-02-08 04:12:57 +03:00
|- ^+ this
2019-02-02 00:49:14 +03:00
=/ who
=/ pers ~(tap by piers)
|- ^- (unit ship)
?~ pers
~
?: &(?=(^ next-events.q.i.pers) processing-events.q.i.pers)
`p.i.pers
$(pers t.pers)
2019-03-20 23:57:24 +03:00
~? aqua-debug=| plowing=who
2019-02-02 00:49:14 +03:00
?~ who
2019-02-08 04:12:57 +03:00
this
=. this abet-pe:plow:(pe u.who)
$
2019-02-02 00:49:14 +03:00
::
2019-02-06 05:21:41 +03:00
:: Subscribe to effects from a ship
::
++ peer-effects
|= pax=path
^- (quip move _this)
2019-03-08 08:15:42 +03:00
?. ?=([@ *] pax)
2019-02-06 05:21:41 +03:00
~& [%aqua-bad-peer-effects pax]
`this
?~ (slaw %p i.pax)
~& [%aqua-bad-peer-effects-ship pax]
2019-02-08 05:03:46 +03:00
!!
2019-02-06 05:21:41 +03:00
`this
::
2019-03-06 23:22:37 +03:00
:: Subscribe to events to a ship
::
++ peer-events
|= pax=path
^- (quip move _this)
?. ?=([@ ~] pax)
~& [%aqua-bad-peer-events pax]
`this
?~ (slaw %p i.pax)
~& [%aqua-bad-peer-events-ship pax]
!!
`this
::
:: Subscribe to both events and effects of a ship
::
++ peer-boths
|= pax=path
^- (quip move _this)
?. ?=([@ ~] pax)
~& [%aqua-bad-peer-boths pax]
`this
?~ (slaw %p i.pax)
~& [%aqua-bad-peer-boths-ship pax]
!!
`this
::
2019-02-02 04:00:15 +03:00
:: Load a pill and assemble arvo. Doesn't send any of the initial
:: events.
::
2019-02-02 00:49:14 +03:00
++ poke-pill
|= p=pill
^- (quip move _this)
2019-02-08 05:03:46 +03:00
=. this apex-aqua =< abet-aqua
2019-02-02 00:49:14 +03:00
=. pil p
~& lent=(met 3 (jam boot-ova.pil))
=/ res=toon :: (each * (list tank))
(mock [boot-ova.pil [2 [0 3] [0 2]]] scry)
2019-02-22 02:13:40 +03:00
=. fleet-snaps ~
2019-02-02 00:49:14 +03:00
?- -.res
%0
~& %suc
=. assembled +7.p.res
2019-02-08 04:12:57 +03:00
this
2019-02-02 00:49:14 +03:00
::
%1
~& [%vere-blocked p.res]
2019-02-08 04:12:57 +03:00
this
2019-02-02 00:49:14 +03:00
::
%2
~& %vere-fail
%- (slog p.res)
2019-02-08 04:12:57 +03:00
this
2019-02-02 00:49:14 +03:00
==
::
2019-02-06 05:21:41 +03:00
:: Handle commands from CLI
2019-02-02 04:00:15 +03:00
::
:: Should put some thought into arg structure, maybe make a mark.
::
2019-02-06 05:21:41 +03:00
:: Should convert some of these to just rewrite into ++poke-events.
::
2019-02-02 00:49:14 +03:00
++ poke-noun
|= val=*
^- (quip move _this)
2019-02-08 05:03:46 +03:00
=. this apex-aqua =< abet-aqua
2019-02-08 04:12:57 +03:00
^+ this
2019-02-02 04:00:15 +03:00
:: Could potentially factor out the three lines of turn-ships
:: boilerplate
::
2019-02-02 00:49:14 +03:00
?+ val ~|(%bad-noun-arg !!)
2019-02-22 02:13:40 +03:00
[%swap-vanes vs=*]
?> ?=([[%7 * %1 installed=*] ~] boot-ova.pil)
=. installed.boot-ova.pil
%+ roll (,(list term) vs.val)
|= [v=term _installed.boot-ova.pil]
%^ slum installed.boot-ova.pil now.hid
=/ vane
?+ v ~|([%unknown-vane v] !!)
%a %ames
%b %behn
%c %clay
%d %dill
%e %eyre
%f %ford
%g %gall
%j %ford
==
=/ pax
/(scot %p our.hid)/home/(scot %da now.hid)/sys/vane/[vane]
=/ txt .^(@ %cx (weld pax /hoon))
[/vane/[vane] [%veer v pax txt]]
=> .(this ^+(this this))
=^ ms this (poke-pill pil)
(emit-moves ms)
2019-02-05 01:31:55 +03:00
::
[%wish hers=* p=@t]
%+ turn-ships ((list ship) hers.val)
|= [who=ship thus=_this]
=. this thus
(wish:(pe who) p.val)
::
[%unpause-events hers=*]
%+ turn-ships ((list ship) hers.val)
|= [who=ship thus=_this]
=. this thus
start-processing-events:(pe who)
::
[%pause-events hers=*]
%+ turn-ships ((list ship) hers.val)
|= [who=ship thus=_this]
=. this thus
stop-processing-events:(pe who)
::
[%clear-snap lab=@tas]
=. fleet-snaps ~ :: (~(del by fleet-snaps) lab.val)
this
2019-02-02 00:49:14 +03:00
==
::
2019-02-08 04:12:57 +03:00
:: Apply a list of events tagged by ship
2019-02-06 05:21:41 +03:00
::
++ poke-aqua-events
|= events=(list aqua-event)
^- (quip move _this)
2019-02-08 05:03:46 +03:00
=. this apex-aqua =< abet-aqua
2019-02-06 05:21:41 +03:00
%+ turn-events events
2019-03-07 10:31:14 +03:00
|= [ae=aqua-event thus=_this]
2019-02-06 05:21:41 +03:00
=. this thus
2019-03-07 10:31:14 +03:00
?- -.ae
2019-02-06 05:21:41 +03:00
%init-ship
2019-03-07 10:31:14 +03:00
=. this abet-pe:(publish-effect:(pe who.ae) [/ %sleep ~])
=/ initted
=< plow
2019-03-07 10:31:14 +03:00
%- push-events:apex:(pe who.ae)
^- (list unix-event)
:~ [/ %wack 0] :: eny
2019-03-07 10:31:14 +03:00
[/ %whom who.ae] :: eny
[//newt/0v1n.2m9vh %barn ~]
[//behn/0v1n.2m9vh %born ~]
2019-03-06 23:22:37 +03:00
:+ //term/1 %boot
2019-03-07 10:31:14 +03:00
?~ keys.ae
[%fake who.ae]
[%dawn u.keys.ae]
-.userspace-ova.pil
[//http/0v1n.2m9vh %born ~]
[//http/0v1n.2m9vh %live 8.080 `8.445]
==
=. this abet-pe:initted
2019-03-07 10:31:14 +03:00
(pe who.ae)
2019-02-09 00:34:24 +03:00
::
%pause-events
2019-03-07 10:31:14 +03:00
stop-processing-events:(pe who.ae)
2019-02-12 05:46:36 +03:00
::
%snap-ships
=. fleet-snaps
2019-03-07 10:31:14 +03:00
%+ ~(put by fleet-snaps) lab.ae
2019-02-12 05:46:36 +03:00
%- malt
2019-03-07 10:31:14 +03:00
%+ murn hers.ae
2019-02-12 05:46:36 +03:00
|= her=ship
^- (unit (pair ship pier))
=+ per=(~(get by piers) her)
?~ per
~
`[her u.per]
2019-03-07 10:31:14 +03:00
(pe -.hers.ae)
2019-02-12 05:46:36 +03:00
::
%restore-snap
=. this
%+ turn-ships (turn ~(tap by piers) head)
|= [who=ship thus=_this]
=. this thus
2019-03-07 10:31:14 +03:00
(publish-effect:(pe who) [/ %sleep ~])
=. piers (~(uni by piers) (~(got by fleet-snaps) lab.ae))
2019-02-12 05:46:36 +03:00
=. this
%+ turn-ships (turn ~(tap by piers) head)
|= [who=ship thus=_this]
=. this thus
2019-03-07 10:31:14 +03:00
(publish-effect:(pe who) [/ %restore ~])
2019-02-12 05:46:36 +03:00
(pe ~bud) :: XX why ~bud? need an example
2019-02-06 05:21:41 +03:00
::
%event
2019-03-21 00:38:42 +03:00
~? &(aqua-debug=| !?=(?(%belt %hear) -.q.ue.ae))
2019-03-13 14:50:56 +03:00
raw-event=[who.ae -.q.ue.ae]
2019-03-27 04:07:42 +03:00
~? &(debug=& ?=(%they -.q.ue.ae))
raw-event=[who.ae ue.ae]
2019-03-07 10:31:14 +03:00
(push-events:(pe who.ae) [ue.ae]~)
2019-02-06 05:21:41 +03:00
==
::
2019-02-02 04:00:15 +03:00
:: Run a callback function against a list of ships, aggregating state
:: and plowing all ships at the end.
::
:: I think we should use patterns like this more often. Because we
:: don't, here's some points to be aware.
::
:: `fun` must take `this` as a parameter, since it needs to be
:: downstream of previous state changes. You could use `state` as
:: the state variable, but it muddles the code and it's not clear
:: whether it's better. You could use the `_(pe)` core if you're
:: sure you'll never need to refer to anything outside of your pier,
:: but I don't think we can guarantee that.
::
:: The callback function must start with `=. this thus`, or else
:: you don't get the new state. Would be great if you could hot-swap
:: that context in here, but we don't know where to put it unless we
:: restrict the callbacks to always have `this` at a particular axis,
:: and that doesn't feel right
::
2019-02-06 05:21:41 +03:00
++ turn-plow
|* arg=mold
|= [hers=(list arg) fun=$-([arg _this] _(pe))]
2019-02-08 04:12:57 +03:00
|- ^+ this
2019-02-02 00:49:14 +03:00
?~ hers
2019-02-08 04:12:57 +03:00
plow-all
=. this
abet-pe:plow:(fun i.hers this)
$(hers t.hers, this this)
2019-02-02 04:00:15 +03:00
::
2019-02-06 05:21:41 +03:00
++ turn-ships (turn-plow ship)
++ turn-events (turn-plow aqua-event)
::
2019-03-07 10:31:14 +03:00
:: Check whether we have a snapshot
2019-02-12 05:46:36 +03:00
::
++ peek-x-fleet-snap
|= pax=path
^- (unit (unit [%noun noun]))
?. ?=([@ ~] pax)
~
:^ ~ ~ %noun
(~(has by fleet-snaps) i.pax)
::
2019-03-07 10:31:14 +03:00
:: Pass scry into child ship
2019-02-15 04:18:04 +03:00
::
++ peek-x-i
|= pax=path
^- (unit (unit [%noun noun]))
?. ?=([@ @ @ *] pax)
~
=/ who (slav %p i.pax)
=/ pier (~(get by piers) who)
?~ pier
~
:^ ~ ~ %noun
(peek:(pe who) [%cx pax])
::
2019-03-07 10:31:14 +03:00
:: Get all created ships
::
++ peek-x-ships
|= pax=path
2019-03-08 08:15:42 +03:00
^- (unit (unit [%noun (list ship)]))
2019-03-07 10:31:14 +03:00
?. ?=(~ pax)
~
:^ ~ ~ %noun
2019-03-08 08:15:42 +03:00
`(list ship)`(turn ~(tap by piers) head)
2019-03-07 10:31:14 +03:00
::
2019-02-02 04:00:15 +03:00
:: Trivial scry for mock
::
2019-02-02 00:49:14 +03:00
++ scry |=([* *] ~)
::
2019-02-02 04:00:15 +03:00
:: Throw away old state if it doesn't soft to new state.
::
2019-02-02 00:49:14 +03:00
++ prep
|= old/(unit noun)
^- [(list move) _+>.$]
2019-02-12 05:46:36 +03:00
~& prep=%aqua
2019-02-02 00:49:14 +03:00
?~ old
`+>.$
=+ new=((soft state) u.old)
?~ new
`+>.$
`+>.$(+<+ u.new)
--