more work: allocator, input, shift responsibilities
This commit is contained in:
parent
79d38da497
commit
4f1b352b2a
68
docs/api.md
68
docs/api.md
|
@ -176,46 +176,46 @@ for consistency.
|
|||
|
||||
The code-entry Helper object has the following API:
|
||||
|
||||
* `update_nameplates()`: requests an updated list of nameplates from the
|
||||
* `refresh_nameplates()`: requests an updated list of nameplates from the
|
||||
Rendezvous Server. These form the first portion of the wormhole code (e.g.
|
||||
"4" in "4-purple-sausages"). Note that they are unicode strings (so "4",
|
||||
not 4). The Helper will get the response in the background, and calls to
|
||||
`complete_nameplate()` after the response will use the new list.
|
||||
* `completions = h.complete_nameplate(prefix)`: returns (synchronously) a
|
||||
list of suffixes for the given nameplate prefix. For example, if the server
|
||||
reports nameplates 1, 12, 13, 24, and 170 are in use,
|
||||
`complete_nameplate("1")` will return `["", "2", "3", "70"]`. Raises
|
||||
`AlreadyClaimedNameplateError` if called after `h.claim_nameplate`.
|
||||
* `d = h.claim_nameplate(nameplate)`: accepts a string with the chosen
|
||||
nameplate. May only be called once, after which `OnlyOneNameplateError` is
|
||||
raised. Returns a Deferred that fires (with None) when the nameplate's
|
||||
wordlist is known (which happens after the nameplate is claimed, requiring
|
||||
a roundtrip to the server).
|
||||
* `completions = h.complete_words(prefix)`: return (synchronously) a list of
|
||||
suffixes for the given words prefix. The possible completions depend upon
|
||||
the wordlist in use for the previously-claimed nameplate, so calling this
|
||||
before `claim_nameplate` will raise `MustClaimNameplateFirstError`. Given a
|
||||
prefix like "su", this returns a list of strings which are appropriate to
|
||||
append to the prefix (e.g. `["pportive", "rrender", "spicious"]`, for
|
||||
expansion into "supportive", "surrender", and "suspicious". The prefix
|
||||
should not include the nameplate, but *should* include whatever words and
|
||||
hyphens have been typed so far (the default wordlist uses alternate lists,
|
||||
where even numbered words have three syllables, and odd numbered words have
|
||||
two, so the completions depend upon how many words are present, not just
|
||||
the partial last word). E.g. `complete_words("pr")` will return
|
||||
`["ocessor", "ovincial", "oximate"]`, while `complete_words("opulent-pr")`
|
||||
will return `["eclude", "efer", "eshrunk", "inter", "owler"]`.
|
||||
If the wordlist is not yet known (i.e. the Deferred from `claim_nameplate`
|
||||
has not yet fired), this returns an empty list. It will also return an
|
||||
empty list if the prefix is complete (the last word matches something in
|
||||
the completion list, and there are no longer extension words), although the
|
||||
code may not yet be complete if there are additional words. The completions
|
||||
will never include a hyphen: the UI frontend must supply these if desired.
|
||||
* `h.submit_words(words)`: call this when the user is finished typing in the
|
||||
`get_nameplate_completions()` after the response will use the new list.
|
||||
* `completions = h.get_nameplate_completions(prefix)`: returns
|
||||
(synchronously) a list of suffixes for the given nameplate prefix. For
|
||||
example, if the server reports nameplates 1, 12, 13, 24, and 170 are in
|
||||
use, `get_nameplate_completions("1")` will return `["", "2", "3", "70"]`.
|
||||
Raises `AlreadyClaimedNameplateError` if called after `h.choose_nameplate`.
|
||||
* `h.choose_nameplate(nameplate)`: accepts a string with the chosen nameplate.
|
||||
May only be called once, after which `OnlyOneNameplateError` is raised. (in
|
||||
this future, this might return a Deferred that fires (with None) when the
|
||||
nameplate's wordlist is known (which happens after the nameplate is
|
||||
claimed, requiring a roundtrip to the server)).
|
||||
* `completions = h.get_word_completions(prefix)`: return (synchronously) a
|
||||
list of suffixes for the given words prefix. The possible completions
|
||||
depend upon the wordlist in use for the previously-claimed nameplate, so
|
||||
calling this before `choose_nameplate` will raise
|
||||
`MustClaimNameplateFirstError`. Given a prefix like "su", this returns a
|
||||
list of strings which are appropriate to append to the prefix (e.g.
|
||||
`["pportive", "rrender", "spicious"]`, for expansion into "supportive",
|
||||
"surrender", and "suspicious". The prefix should not include the nameplate,
|
||||
but *should* include whatever words and hyphens have been typed so far (the
|
||||
default wordlist uses alternate lists, where even numbered words have three
|
||||
syllables, and odd numbered words have two, so the completions depend upon
|
||||
how many words are present, not just the partial last word). E.g.
|
||||
`get_word_completions("pr")` will return `["ocessor", "ovincial",
|
||||
"oximate"]`, while `get_word_completions("opulent-pr")` will return
|
||||
`["eclude", "efer", "eshrunk", "inter", "owler"]`. If the wordlist is not
|
||||
yet known, this returns an empty list. It will also return an empty list if
|
||||
the prefix is complete (the last word matches something in the completion
|
||||
list, and there are no longer extension words), although the code may not
|
||||
yet be complete if there are additional words. The completions will never
|
||||
include a hyphen: the UI frontend must supply these if desired.
|
||||
* `h.choose_words(words)`: call this when the user is finished typing in the
|
||||
code. It does not return anything, but will cause the Wormhole's
|
||||
`w.when_code()` (or corresponding delegate) to fire, and triggers the
|
||||
wormhole connection process. This accepts a string like "purple-sausages",
|
||||
without the nameplate. It must be called after `h.claim_nameplate()` or
|
||||
without the nameplate. It must be called after `h.choose_nameplate()` or
|
||||
`MustClaimNameplateFirstError` will be raised.
|
||||
|
||||
The `rlcompleter` wrapper is a function that knows how to use the code-entry
|
||||
|
|
|
@ -11,8 +11,12 @@ digraph {
|
|||
S0B -> P_allocate [label="allocate"]
|
||||
P_allocate [shape="box" label="RC.tx_allocate" color="orange"]
|
||||
P_allocate -> S1B [color="orange"]
|
||||
S1B [label="S1B:\nallocating" color="orange"]
|
||||
S1B -> S1A [label="lost"]
|
||||
{rank=same; S1A P_allocate S1B}
|
||||
S0B -> S1B [style="invis"]
|
||||
S1B [label="S1B:\nallocating\nconnected" color="orange"]
|
||||
S1B -> foo [label="lost"]
|
||||
foo [style="dotted" label=""]
|
||||
foo -> S1A
|
||||
S1A [label="S1A:\nallocating\ndisconnected" color="orange"]
|
||||
S1A -> P_allocate [label="connected" color="orange"]
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ digraph {
|
|||
|
||||
{rank=same; P0_code S0}
|
||||
P0_code [shape="box" style="dashed"
|
||||
label="input -> Code.input\n or allocate -> Code.allocate\n or set_code -> Code.set_code"]
|
||||
label="C.input_code\n or C.allocate_code\n or C.set_code"]
|
||||
P0_code -> S0
|
||||
S0 [label="S0: empty"]
|
||||
S0 -> P0_build [label="set_code"]
|
||||
|
@ -22,7 +22,7 @@ digraph {
|
|||
P_close_error -> S_closing
|
||||
S0 -> P_close_lonely [label="close"]
|
||||
|
||||
P0_build [shape="box" label="W.got_code\nN.set_nameplate\nK.got_code"]
|
||||
P0_build [shape="box" label="W.got_code"]
|
||||
P0_build -> S1
|
||||
S1 [label="S1: lonely" color="orange"]
|
||||
|
||||
|
@ -67,7 +67,7 @@ digraph {
|
|||
|
||||
{rank=same; Other S_closed}
|
||||
Other [shape="box" style="dashed"
|
||||
label="rx_welcome -> process\nsend -> S.send\ngot_message -> got_version or got_phase\ngot_key -> W.got_key\ngot_verifier -> W.got_verifier\nallocate -> C.allocate\ninput -> C.input\nset_code -> C.set_code"
|
||||
label="rx_welcome -> process\nsend -> S.send\ngot_message -> got_version or got_phase\ngot_key -> W.got_key\ngot_verifier -> W.got_verifier\nallocate_Code -> C.allocate_code\ninput_code -> C.input_code\nset_code -> C.set_code"
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,27 +1,39 @@
|
|||
digraph {
|
||||
|
||||
start [label="C:\nCode\nManagement" style="dotted"]
|
||||
start [label="C:\nCode\n(management)" style="dotted"]
|
||||
{rank=same; start S0}
|
||||
start -> S0 [style="invis"]
|
||||
S0 [label="S0:\nidle"]
|
||||
S0 -> P0_got_code [label="set_code"]
|
||||
P0_got_code [shape="box" label="B.got_code"]
|
||||
P0_got_code -> S3
|
||||
S3 [label="S3: known" color="green"]
|
||||
P0_got_code [shape="box" label="N.set_nameplate"]
|
||||
P0_got_code -> P_done
|
||||
P_done [shape="box" label="K.got_code\nB.got_code"]
|
||||
P_done -> S5
|
||||
S5 [label="S5: known" color="green"]
|
||||
|
||||
{rank=same; S1_inputting S2_allocating}
|
||||
{rank=same; S1_inputting_nameplate S3_allocating}
|
||||
{rank=same; P0_got_code P1_set_nameplate P3_got_nameplate}
|
||||
S0 -> P_input [label="input_code"]
|
||||
P_input [shape="box" label="I.start"]
|
||||
P_input -> S1_inputting
|
||||
S1_inputting [label="S1:\ninputting"]
|
||||
S1_inputting -> P0_got_code [label="finished_input"]
|
||||
P_input -> S1_inputting_nameplate
|
||||
S1_inputting_nameplate [label="S1:\ninputting\nnameplate"]
|
||||
S1_inputting_nameplate -> P1_set_nameplate [label="got_nameplate"]
|
||||
P1_set_nameplate [shape="box" label="N.set_nameplate"]
|
||||
P1_set_nameplate -> S2_inputting_words
|
||||
S2_inputting_words [label="S2:\ninputting\nwords"]
|
||||
S2_inputting_words -> P1_got_words [label="finished_input"]
|
||||
P1_got_words [shape="box" label="assemble\ncode"]
|
||||
P1_got_words -> P_done
|
||||
P_done
|
||||
|
||||
S0 -> P_allocate [label="allocate_code"]
|
||||
P_allocate [shape="box" label="A.allocate"]
|
||||
P_allocate -> S2_allocating
|
||||
S2_allocating [label="S2:\nallocating"]
|
||||
S2_allocating -> P1_generate [label="allocated_nameplate"]
|
||||
P1_generate [shape="box" label="generate\nrandom words"]
|
||||
P1_generate -> P0_got_code
|
||||
P_allocate -> S3_allocating
|
||||
S3_allocating [label="S3:\nallocating"]
|
||||
S3_allocating -> P3_got_nameplate [label="allocated_nameplate"]
|
||||
P3_got_nameplate [shape="box" label="N.set_nameplate"]
|
||||
P3_got_nameplate -> P3_generate
|
||||
P3_generate [shape="box" label="append\nrandom words"]
|
||||
P3_generate -> P_done
|
||||
|
||||
}
|
||||
|
|
|
@ -5,28 +5,39 @@ digraph {
|
|||
start -> S0 [style="invis"]
|
||||
S0 [label="S0:\nidle"]
|
||||
|
||||
S0 -> P0_list_nameplates [label="start" color="orange"]
|
||||
P0_list_nameplates [shape="box" label="L.refresh_nameplates" color="orange"]
|
||||
P0_list_nameplates -> S1 [color="orange"]
|
||||
S0 -> P0_list_nameplates [label="start"]
|
||||
P0_list_nameplates [shape="box" label="L.refresh"]
|
||||
P0_list_nameplates -> S1
|
||||
S1 [label="S1: typing\nnameplate" color="orange"]
|
||||
|
||||
{rank=same; foo P0_list_nameplates}
|
||||
S1 -> foo [label="update_nameplates"]
|
||||
S1 -> foo [label="refresh_nameplates" color="orange" fontcolor="orange"]
|
||||
foo [style="dashed" label=""]
|
||||
foo -> P0_list_nameplates
|
||||
|
||||
S1 -> P1_claim [label="claim_nameplate" color="orange" fontcolor="orange"]
|
||||
P1_claim [shape="box" label="N.set_nameplate" color="orange"]
|
||||
P1_claim -> S2 [color="orange"]
|
||||
S2 [label="S2: typing\ncode\n(no wordlist)" color="orange"]
|
||||
S2 -> P2_stash_wordlist [label="got_nameplates" color="orange"]
|
||||
P2_stash_wordlist [shape="box" label="stash\nwordlist" color="orange"]
|
||||
P2_stash_wordlist -> S3 [color="orange"]
|
||||
S2 -> P_done [label="submit_words"]
|
||||
S3 [label="S3: typing\ncode\n(yes wordlist)" color="orange"]
|
||||
S3 -> P_done [label="submit_words" color="orange" fontcolor="orange"]
|
||||
P_done [shape="box" label="C.finished_input" color="orange"]
|
||||
P_done -> S4 [color="orange"]
|
||||
S4 [label="S4: known" color="green"]
|
||||
S1 -> P1_record [label="got_nameplates"]
|
||||
P1_record [shape="box" label="record\nnameplates"]
|
||||
P1_record -> S1
|
||||
|
||||
S1 -> P1_claim [label="choose_nameplate" color="orange" fontcolor="orange"]
|
||||
P1_claim [shape="box" label="stash nameplate\nC.got_nameplate"]
|
||||
P1_claim -> S2
|
||||
S2 [label="S2: typing\ncode\n(no wordlist)"]
|
||||
S2 -> S2 [label="got_nameplates"]
|
||||
S2 -> P2_stash_wordlist [label="got_wordlist"]
|
||||
P2_stash_wordlist [shape="box" label="stash wordlist"]
|
||||
P2_stash_wordlist -> S3
|
||||
S2 -> P_done [label="choose_words" color="orange" fontcolor="orange"]
|
||||
S3 [label="S3: typing\ncode\n(yes wordlist)"]
|
||||
S3 -> S3 [label="got_nameplates"]
|
||||
S3 -> P_done [label="choose_words" color="orange" fontcolor="orange"]
|
||||
P_done [shape="box" label="build code\nC.finished_input"]
|
||||
P_done -> S4
|
||||
S4 [label="S4: done" color="green"]
|
||||
S4 -> S4 [label="got_nameplates\ngot_wordlist"]
|
||||
|
||||
other [shape="box" style="dotted"
|
||||
label="h.refresh_nameplates()\nh.get_nameplate_completions(prefix)\nh.choose_nameplate(nameplate)\nh.get_word_completions(prefix)\nh.choose_words(words)"
|
||||
]
|
||||
{rank=same; S4 other}
|
||||
}
|
||||
|
|
|
@ -31,12 +31,9 @@ digraph {
|
|||
foo2 [label="" style="dashed"]
|
||||
foo2 -> P_tx
|
||||
|
||||
S0B -> P_notify [label="rx"]
|
||||
S1B -> P_notify [label="rx" color="orange" fontcolor="orange"]
|
||||
P_notify [shape="box" label="C.got_nameplates()"]
|
||||
S0B -> P_notify [label="rx_nameplates"]
|
||||
S1B -> P_notify [label="rx_nameplates" color="orange" fontcolor="orange"]
|
||||
P_notify [shape="box" label="I.got_nameplates()"]
|
||||
P_notify -> S0B
|
||||
|
||||
{rank=same; foo foo2 legend}
|
||||
legend [shape="box" style="dotted"
|
||||
label="refresh: L.refresh_nameplates()\nrx: L.rx_nameplates()"]
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@ digraph {
|
|||
Wormhole [shape="oval" color="blue" fontcolor="blue"]
|
||||
Boss [shape="box" label="Boss\n(manager)"
|
||||
color="blue" fontcolor="blue"]
|
||||
Nameplate [shape="box" color="blue" fontcolor="blue"]
|
||||
Mailbox [shape="box" color="blue" fontcolor="blue"]
|
||||
Nameplate [label="Nameplate\n(claimer)"
|
||||
shape="box" color="blue" fontcolor="blue"]
|
||||
Mailbox [label="Mailbox\n(opener)"
|
||||
shape="box" color="blue" fontcolor="blue"]
|
||||
Connection [label="Rendezvous\nConnector"
|
||||
shape="oval" color="blue" fontcolor="blue"]
|
||||
#websocket [color="blue" fontcolor="blue"]
|
||||
|
@ -16,9 +18,11 @@ digraph {
|
|||
color="blue" fontcolor="blue"]
|
||||
Allocator [shape="box" label="(nameplate)\nAllocator"
|
||||
color="blue" fontcolor="blue"]
|
||||
Input [shape="box" label="(code)\nInput helper"
|
||||
Input [shape="box" label="(interactive\ncode)\nInput"
|
||||
color="blue" fontcolor="blue"]
|
||||
Terminator [shape="box" color="blue" fontcolor="blue"]
|
||||
InputHelperAPI [shape="oval" label="input\nhelper\nAPI"
|
||||
color="blue" fontcolor="blue"]
|
||||
|
||||
#Connection -> websocket [color="blue"]
|
||||
#Connection -> Order [color="blue"]
|
||||
|
@ -36,11 +40,8 @@ digraph {
|
|||
|
||||
Boss -> Send [style="dashed" color="red" fontcolor="red" label="send"]
|
||||
|
||||
Boss -> Nameplate [style="dashed" color="red" fontcolor="red"
|
||||
label="set_nameplate"]
|
||||
#Boss -> Mailbox [color="blue"]
|
||||
Mailbox -> Order [style="dashed" label="got_message (once)"]
|
||||
Boss -> Key [style="dashed" label="got_code"]
|
||||
Key -> Boss [style="dashed" label="got_key\ngot_verifier\nscared"]
|
||||
Order -> Key [style="dashed" label="got_pake"]
|
||||
Order -> Receive [style="dashed" label="got_message"]
|
||||
|
@ -85,15 +86,18 @@ digraph {
|
|||
]
|
||||
#Code -> Lister [color="blue"]
|
||||
Input -> Lister [style="dashed" color="red" fontcolor="red"
|
||||
label="refresh_nameplates"
|
||||
label="refresh"
|
||||
]
|
||||
Boss -> Code [style="dashed" color="red" fontcolor="red"
|
||||
label="allocate_code\ninput_code\nset_code"]
|
||||
Code -> Boss [style="dashed"
|
||||
label="got_code"]
|
||||
Code -> Boss [style="dashed" label="got_code"]
|
||||
Code -> Key [style="dashed" label="got_code"]
|
||||
Code -> Nameplate [style="dashed" label="set_nameplate"]
|
||||
|
||||
Code -> Input [style="dashed" color="red" fontcolor="red" label="start"]
|
||||
Input -> Code [style="dashed" label="finished_input"]
|
||||
Input -> Code [style="dashed" label="got_nameplate\nfinished_input"]
|
||||
InputHelperAPI -> Input [label="refresh_nameplates\nget_nameplate_completions\nchoose_nameplate\nget_word_completions\nchoose_words" color="orange" fontcolor="orange"]
|
||||
|
||||
Code -> Allocator [style="dashed" color="red" fontcolor="red"
|
||||
label="allocate"]
|
||||
Allocator -> Code [style="dashed" label="allocated"]
|
||||
|
|
65
src/wormhole/_allocator.py
Normal file
65
src/wormhole/_allocator.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
from __future__ import print_function, absolute_import, unicode_literals
|
||||
from zope.interface import implementer
|
||||
from attr import attrs, attrib
|
||||
from attr.validators import provides
|
||||
from automat import MethodicalMachine
|
||||
from . import _interfaces
|
||||
|
||||
@attrs
|
||||
@implementer(_interfaces.IAllocator)
|
||||
class Allocator(object):
|
||||
_timing = attrib(validator=provides(_interfaces.ITiming))
|
||||
m = MethodicalMachine()
|
||||
@m.setTrace()
|
||||
def set_trace(): pass # pragma: no cover
|
||||
|
||||
def wire(self, rendezvous_connector, code):
|
||||
self._RC = _interfaces.IRendezvousConnector(rendezvous_connector)
|
||||
self._C = _interfaces.ICode(code)
|
||||
|
||||
@m.state(initial=True)
|
||||
def S0A_idle(self): pass # pragma: no cover
|
||||
@m.state()
|
||||
def S0B_idle_connected(self): pass # pragma: no cover
|
||||
@m.state()
|
||||
def S1A_allocating(self): pass # pragma: no cover
|
||||
@m.state()
|
||||
def S1B_allocating_connected(self): pass # pragma: no cover
|
||||
@m.state()
|
||||
def S2_done(self): pass # pragma: no cover
|
||||
|
||||
# from Code
|
||||
@m.input()
|
||||
def allocate(self): pass
|
||||
|
||||
# from RendezvousConnector
|
||||
@m.input()
|
||||
def connected(self): pass
|
||||
@m.input()
|
||||
def lost(self): pass
|
||||
@m.input()
|
||||
def rx_allocated(self, nameplate): pass
|
||||
|
||||
@m.output()
|
||||
def RC_tx_allocate(self):
|
||||
self._RC.tx_allocate()
|
||||
@m.output()
|
||||
def C_allocated(self, nameplate):
|
||||
self._C.allocated(nameplate)
|
||||
|
||||
S0A_idle.upon(connected, enter=S0B_idle_connected, outputs=[])
|
||||
S0B_idle_connected.upon(lost, enter=S0A_idle, outputs=[])
|
||||
|
||||
S0A_idle.upon(allocate, enter=S1A_allocating, outputs=[])
|
||||
S0B_idle_connected.upon(allocate, enter=S1B_allocating_connected,
|
||||
outputs=[RC_tx_allocate])
|
||||
|
||||
S1A_allocating.upon(connected, enter=S1B_allocating_connected,
|
||||
outputs=[RC_tx_allocate])
|
||||
S1B_allocating_connected.upon(lost, enter=S1A_allocating, outputs=[])
|
||||
|
||||
S1B_allocating_connected.upon(rx_allocated, enter=S2_done,
|
||||
outputs=[C_allocated])
|
||||
|
||||
S2_done.upon(connected, enter=S2_done, outputs=[])
|
||||
S2_done.upon(lost, enter=S2_done, outputs=[])
|
|
@ -15,6 +15,8 @@ from ._key import Key
|
|||
from ._receive import Receive
|
||||
from ._rendezvous import RendezvousConnector
|
||||
from ._lister import Lister
|
||||
from ._allocator import Allocator
|
||||
from ._input import Input
|
||||
from ._code import Code
|
||||
from ._terminator import Terminator
|
||||
from .errors import (ServerError, LonelyError, WrongPasswordError,
|
||||
|
@ -49,6 +51,8 @@ class Boss(object):
|
|||
self._reactor, self._journal,
|
||||
self._tor_manager, self._timing)
|
||||
self._L = Lister()
|
||||
self._A = Allocator(self._timing)
|
||||
self._I = Input(self._timing)
|
||||
self._C = Code(self._timing)
|
||||
self._T = Terminator()
|
||||
|
||||
|
@ -59,7 +63,9 @@ class Boss(object):
|
|||
self._K.wire(self, self._M, self._R)
|
||||
self._R.wire(self, self._S)
|
||||
self._RC.wire(self, self._N, self._M, self._C, self._L, self._T)
|
||||
self._L.wire(self._RC, self._C)
|
||||
self._L.wire(self._RC, self._I)
|
||||
self._A.wire(self._RC, self._C)
|
||||
self._I.wire(self._C, self._L)
|
||||
self._C.wire(self, self._RC, self._L)
|
||||
self._T.wire(self, self._RC, self._N, self._M)
|
||||
|
||||
|
@ -189,8 +195,6 @@ class Boss(object):
|
|||
|
||||
@m.output()
|
||||
def do_got_code(self, code):
|
||||
nameplate = code.split("-")[0]
|
||||
self._N.set_nameplate(nameplate)
|
||||
self._K.got_code(code)
|
||||
self._W.got_code(code)
|
||||
@m.output()
|
||||
|
|
|
@ -74,13 +74,11 @@ class Code(object):
|
|||
@m.input()
|
||||
def got_wordlist(self, wordlist): pass
|
||||
|
||||
# from CodeInputHelper
|
||||
# from Input
|
||||
@m.input()
|
||||
def update_nameplates(self): pass
|
||||
def got_nameplate(self, nameplate): pass
|
||||
@m.input()
|
||||
def claim_nameplate(self, nameplate): pass
|
||||
@m.input()
|
||||
def submit_words(self, words): pass
|
||||
def finished_input(self, code): pass
|
||||
|
||||
@m.output()
|
||||
def L_refresh_nameplates(self):
|
||||
|
@ -137,6 +135,7 @@ class Code(object):
|
|||
self._B_got_code()
|
||||
|
||||
def _B_got_code(self):
|
||||
self._N.set_nameplate(nameplate) XXX
|
||||
self._B.got_code(self._code)
|
||||
|
||||
S0A_unknown.upon(connected, enter=S0B_unknown_connected, outputs=[])
|
||||
|
|
106
src/wormhole/_input.py
Normal file
106
src/wormhole/_input.py
Normal file
|
@ -0,0 +1,106 @@
|
|||
from __future__ import print_function, absolute_import, unicode_literals
|
||||
from zope.interface import implementer
|
||||
from attr import attrs, attrib
|
||||
from attr.validators import provides
|
||||
from automat import MethodicalMachine
|
||||
from . import _interfaces
|
||||
|
||||
@attrs
|
||||
@implementer(_interfaces.IInput)
|
||||
class Input(object):
|
||||
_timing = attrib(validator=provides(_interfaces.ITiming))
|
||||
m = MethodicalMachine()
|
||||
@m.setTrace()
|
||||
def set_trace(): pass # pragma: no cover
|
||||
|
||||
def __attrs_post_init__(self):
|
||||
self._nameplate = None
|
||||
self._wordlist = None
|
||||
self._claimed_waiter = None
|
||||
|
||||
def wire(self, code, lister):
|
||||
self._C = _interfaces.ICode(code)
|
||||
self._L = _interfaces.ILister(lister)
|
||||
|
||||
@m.state(initial=True)
|
||||
def S0_idle(self): pass # pragma: no cover
|
||||
@m.state()
|
||||
def S1_nameplate(self): pass # pragma: no cover
|
||||
@m.state()
|
||||
def S2_code_no_wordlist(self): pass # pragma: no cover
|
||||
@m.state()
|
||||
def S3_code_yes_wordlist(self): pass # pragma: no cover
|
||||
@m.state(terminal=True)
|
||||
def S4_done(self): pass # pragma: no cover
|
||||
|
||||
# from Code
|
||||
@m.input()
|
||||
def start(self): pass
|
||||
|
||||
# from Lister
|
||||
@m.input()
|
||||
def got_nameplates(self, nameplates): pass
|
||||
|
||||
# from Nameplate??
|
||||
@m.input()
|
||||
def got_wordlist(self, wordlist): pass
|
||||
|
||||
# from CodeInputHelper
|
||||
@m.input()
|
||||
def refresh_nameplates(self): pass
|
||||
@m.input()
|
||||
def _choose_nameplate(self, nameplate): pass
|
||||
@m.input()
|
||||
def choose_words(self, words): pass
|
||||
|
||||
@m.output()
|
||||
def L_refresh_nameplates(self):
|
||||
self._L.refresh_nameplates()
|
||||
@m.output()
|
||||
def start_and_L_refresh_nameplates(self, input_helper):
|
||||
self._input_helper = input_helper
|
||||
self._L.refresh_nameplates()
|
||||
@m.output()
|
||||
def stash_wordlist_and_notify(self, wordlist):
|
||||
self._wordlist = wordlist
|
||||
if self._claimed_waiter:
|
||||
self._claimed_waiter.callback(None)
|
||||
del self._claimed_waiter
|
||||
@m.output()
|
||||
def stash_nameplate(self, nameplate):
|
||||
self._nameplate = nameplate
|
||||
@m.output()
|
||||
def C_got_nameplate(self, nameplate):
|
||||
self._C.got_nameplate(nameplate)
|
||||
|
||||
@m.output()
|
||||
def finished(self, words):
|
||||
code = self._nameplate + "-" + words
|
||||
self._C.finished_input(code)
|
||||
|
||||
S0_idle.upon(start, enter=S1_nameplate, outputs=[L_refresh_nameplates])
|
||||
S1_nameplate.upon(refresh_nameplates, enter=S1_nameplate,
|
||||
outputs=[L_refresh_nameplates])
|
||||
S1_nameplate.upon(_choose_nameplate, enter=S2_code_no_wordlist,
|
||||
outputs=[stash_nameplate, C_got_nameplate])
|
||||
S2_code_no_wordlist.upon(got_wordlist, enter=S3_code_yes_wordlist,
|
||||
outputs=[stash_wordlist_and_notify])
|
||||
S2_code_no_wordlist.upon(choose_words, enter=S4_done, outputs=[finished])
|
||||
S3_code_yes_wordlist.upon(choose_words, enter=S4_done, outputs=[finished])
|
||||
|
||||
# methods for the CodeInputHelper to use
|
||||
#refresh_nameplates/_choose_nameplate/choose_words: @m.input methods
|
||||
|
||||
def get_nameplate_completions(self, prefix):
|
||||
completions = []
|
||||
for nameplate in self._nameplates
|
||||
pass
|
||||
def choose_nameplate(self, nameplate):
|
||||
if self._claimed_waiter is not None:
|
||||
raise X
|
||||
d = self._claimed_waiter = defer.Deferred()
|
||||
self._choose_nameplate(nameplate)
|
||||
|
||||
def get_word_completions(self, prefix):
|
||||
pass
|
||||
|
|
@ -22,6 +22,10 @@ class ILister(Interface):
|
|||
pass
|
||||
class ICode(Interface):
|
||||
pass
|
||||
class IInput(Interface):
|
||||
pass
|
||||
class IAllocator(Interface):
|
||||
pass
|
||||
class ITerminator(Interface):
|
||||
pass
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ class Lister(object):
|
|||
@m.setTrace()
|
||||
def set_trace(): pass # pragma: no cover
|
||||
|
||||
def wire(self, rendezvous_connector, code):
|
||||
def wire(self, rendezvous_connector, input):
|
||||
self._RC = _interfaces.IRendezvousConnector(rendezvous_connector)
|
||||
self._C = _interfaces.ICode(code)
|
||||
self._I = _interfaces.IInput(input)
|
||||
|
||||
# Ideally, each API request would spawn a new "list_nameplates" message
|
||||
# to the server, so the response would be maximally fresh, but that would
|
||||
|
@ -44,8 +44,8 @@ class Lister(object):
|
|||
def RC_tx_list(self):
|
||||
self._RC.tx_list()
|
||||
@m.output()
|
||||
def C_got_nameplates(self, message):
|
||||
self._C.got_nameplates(message["nameplates"])
|
||||
def I_got_nameplates(self, message):
|
||||
self._I.got_nameplates(message["nameplates"])
|
||||
|
||||
S0A_idle_disconnected.upon(connected, enter=S0B_idle_connected, outputs=[])
|
||||
S0B_idle_connected.upon(lost, enter=S0A_idle_disconnected, outputs=[])
|
||||
|
@ -59,9 +59,9 @@ class Lister(object):
|
|||
S0B_idle_connected.upon(refresh_nameplates, enter=S1B_wanting_connected,
|
||||
outputs=[RC_tx_list])
|
||||
S0B_idle_connected.upon(rx_nameplates, enter=S0B_idle_connected,
|
||||
outputs=[C_got_nameplates])
|
||||
outputs=[I_got_nameplates])
|
||||
S1B_wanting_connected.upon(lost, enter=S1A_wanting_disconnected, outputs=[])
|
||||
S1B_wanting_connected.upon(refresh_nameplates, enter=S1B_wanting_connected,
|
||||
outputs=[RC_tx_list])
|
||||
S1B_wanting_connected.upon(rx_nameplates, enter=S0B_idle_connected,
|
||||
outputs=[C_got_nameplates])
|
||||
outputs=[I_got_nameplates])
|
||||
|
|
Loading…
Reference in New Issue
Block a user