Inspecting kind/counter · the kinds · the language · the modules
{name}
- id
- kind/counter
- called
- {name}
- kind chain
- kind/counter → record
- owner
- the town
- made by
- the town
- version
- 4
- pin
- jivuk-zafof
- state
- 5263 bytes
Its spells
To cast them, come in.
Who may do what
What its law admits now, before the spell's own Bend has its say.
| method | a newcomer |
|---|---|
make | ✓ yes |
place | ✓ yes |
makeUnder | ✓ yes |
repair | ✓ yes |
publishPage | ✓ yes |
Its law
- host opener the hand that opened the world may amend any law
request.kind == 2 and request.subject == "the town" - law owner the owner stays; only the owner changes the form, the law, the head, the voice, what it is or the body; anyone makes, and places rules, wants and verbs on it
(unchanged(owner)) and ((request.subject == new.owner) or ((((((((request.kind == 0) or (request.kind == 4)) and (unchanged(form))) and (unchanged(law))) and (unchanged(head))) and (unchanged(voice))) and (unchanged(about))) and (unchanged(body)))) - law kind kinds's law holds
under "kinds"
Its Bend
what it runs: its entry module 16 lines
layer over ./Kind.obend
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Form.obend as Form
import ./Rows.obend as Rows
type State = Super.State
form make:
name: text 1..64
def make(state: State, input: MakeInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "name", value: input.name}, tail: Lists.List.nil()}), "", context)
form place:
name: text 1..64
id: text 1..64
def place(state: State, input: PlaceInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "name", value: input.name}, tail: Lists.List.cons({head: {name: "id", value: input.id}, tail: Lists.List.nil()})}), "", context)
the body this kind lays on what it makes 77 lines
Each thing of this kind runs this layer over what the kind is of.
Amend it in the workshop
Its Bend is checked and amended by the workshop's own spell, with the Bend in its block. To send it, come in; the box is here then.
Its fields
- owner
- the town
- ownerHandle
- the town
- name
- counter
- of
- record
- form
- name: text 1..64
- law
- empty
- head
- {name}
- voice
- a number on a wall that anyone may nudge; it remembers who nudged it last
- about
- a number anyone raises or lowers, one step a turn, drawn live on its page
- body
layer over ./Record.obend (4915 characters)
layer over ./Record.obend edition ObjectiveBend 1 import ./Abi.obend as Abi import ./List.obend as Lists import ./Document.obend as Document import ./Form.obend as Form import ./Plan.obend as Plans import ./World.obend as World import ./Card.obend as Card import ./Scenes.obend as Scenes import ./Relation.obend as Relations import ./Rows.obend as Rows import ./Text.obend as Text import ./View.obend as View # The counter's body, over RECORD (docs/VIEWS.md, the first view): a shared number anyone raises (`plus`) or lowers # (`minus`, never below nought), kept in the record's variable `count` (its lines are kept only so many); each turn is # a line, who and which way. Its view is the number, large, between a − and a + button, and the newest hands to move # it; a click is one turn of `plus` or `minus` by whoever clicked. type State = Super.State form plus: form minus: form lines: from: natural 1..1000000000 form door: label: text 1..32 to: text 1..128 form undoor: label: text 1..32 def lines(state: State, input: LinesInput, context: Abi.Context) -> Activity<Card.Replied>: Super.lines(state, {from: input.from}, context) def door(state: State, input: DoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.door(state, {label: input.label, to: input.to}, context) def undoor(state: State, input: UndoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.undoor(state, {label: input.label}, context) def actions(state: State, context: Abi.Context) -> Lists.List<String>: if context.principal == state.owner then Text.words("plus minus lines door undoor") else Text.words("plus minus lines") def methods() -> Lists.List<String>: Text.words("~made ~act") def views() -> Lists.List<String>: Text.words("view") def count(state: State) -> Nat: match Lists.find(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "count"): case some(v): Text.digits(v.value.value, 0n) case none(_): 0n def plus(state: State, context: Abi.Context) -> Activity<Nat>: moved(state, count(state) + 1n, "plus", context) def minus(state: State, context: Abi.Context) -> Activity<Nat>: if count(state) == 0n then nought(Card.called(context, "counter"), context) else moved(state, count(state) - 1n, "minus", context) def nought(id: String, context: Abi.Context) -> Activity<Nat>: Card.refusing(0n, {clause: "nought", reading: "It is at nought already; raise it: delvetalk {id} plus"}, context) def moved(state: State, to: Nat, verb: String, context: Abi.Context) -> Activity<Nat>: let written(_) = world.write(extend(keep(), {vars: counted(state, to)})) lined(state, to, verb, context) def lined(state: State, to: Nat, verb: String, context: Abi.Context) -> Activity<Nat>: let written(_) = write {lines: insert {author: context.principal, handle: context.handle, verb: verb, text: natText(to), at: context.height, n: state.next}, next: add 1n, tended: set context.clock} Card.tell(to, Document.text("{way(verb)} to {natText(to)}.\n")) def way(verb: String) -> String: if verb == "plus" then "Up" else "Down" def moving(verb: String) -> String: if verb == "plus" then "raised" else "lowered" def counted(state: State, to: Nat) -> Plans.Entries<Scenes.Var, Scenes.Var>: match Lists.find(state.vars, fn(v: Scenes.Var) -> Bool: v.name == "count"): case some(v): Plans.Entries.amendItem({item: v.value, change: {name: "count", value: natText(to)}}) case none(_): Plans.Entries.append({item: {name: "count", value: natText(to)}}) def entry(state: State, context: Abi.Context, line: Rows.Line) -> Document.Document: if line.verb == "plus" || line.verb == "minus" then Document.text("{Card.shown(line.author, line.handle, context)}{Card.mine(line.author, context)} {moving(line.verb)} it to {line.text}\n") else Super.entry(state, context, line) def name(state: State) -> String: if state.head == "" then "A COUNTER" else state.head def headLine(state: State, context: Abi.Context, id: String) -> Document.Document: Document.text("{name(state)}: {natText(count(state))}. Raise it: delvetalk {id} plus. Lower it: delvetalk {id} minus.\n{Super.inactiveLine(state, id)}") # What the page draws: the number between its buttons, and who moved it last. def view(state: State, context: Abi.Context) -> View.View: View.stack(View.three(View.heading(name(state)), View.row(View.three(View.button("−", View.bare("minus")), View.large(natText(count(state))), View.button("+", View.bare("plus")))), View.small(latest(state, context)))) def latest(state: State, context: Abi.Context) -> String: match Lists.at(Lists.reverse(Lists.filter(Relations.order(state.lines, fn(l: Rows.Line) -> Nat: l.n), fn(l: Rows.Line) -> Bool: l.verb == "plus" || l.verb == "minus")), 0n): case some(l): "Last moved by {Card.shown(l.value.author, l.value.handle, context)}{Card.mine(l.value.author, context)}, at entry {natText(l.value.at)}." case none(_): "Nobody has moved it yet."- made
1 rows
- object
- counter
- n
- 1
- about
- empty
- count
- 1