2017-02-24 02:11:07 +00:00
|
|
|
from __future__ import print_function, absolute_import, unicode_literals
|
2017-02-22 19:26:11 +00:00
|
|
|
from zope.interface import implementer
|
2017-02-23 00:56:39 +00:00
|
|
|
from attr import attrs, attrib
|
|
|
|
from attr.validators import provides
|
2017-02-22 19:26:11 +00:00
|
|
|
from automat import MethodicalMachine
|
|
|
|
from . import _interfaces
|
2017-07-04 17:50:21 +00:00
|
|
|
from ._nameplate import validate_nameplate
|
|
|
|
from .errors import KeyFormatError
|
|
|
|
|
2018-04-21 07:30:08 +00:00
|
|
|
|
2017-07-04 17:50:21 +00:00
|
|
|
def validate_code(code):
|
|
|
|
if ' ' in code:
|
|
|
|
raise KeyFormatError("Code '%s' contains spaces." % code)
|
|
|
|
nameplate = code.split("-", 2)[0]
|
2018-04-21 07:30:08 +00:00
|
|
|
validate_nameplate(nameplate) # can raise KeyFormatError
|
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-03-19 23:40:16 +00:00
|
|
|
def first(outputs):
|
|
|
|
return list(outputs)[0]
|
|
|
|
|
2018-04-21 07:30:08 +00:00
|
|
|
|
2017-02-23 00:56:39 +00:00
|
|
|
@attrs
|
2017-02-22 19:26:11 +00:00
|
|
|
@implementer(_interfaces.ICode)
|
|
|
|
class Code(object):
|
2017-02-23 00:56:39 +00:00
|
|
|
_timing = attrib(validator=provides(_interfaces.ITiming))
|
2017-02-22 19:26:11 +00:00
|
|
|
m = MethodicalMachine()
|
2018-04-21 07:30:08 +00:00
|
|
|
set_trace = getattr(m, "_setTrace",
|
|
|
|
lambda self, f: None) # pragma: no cover
|
2017-02-23 00:56:39 +00:00
|
|
|
|
2017-03-17 23:50:37 +00:00
|
|
|
def wire(self, boss, allocator, nameplate, key, input):
|
2017-02-24 01:11:54 +00:00
|
|
|
self._B = _interfaces.IBoss(boss)
|
2017-03-15 07:43:25 +00:00
|
|
|
self._A = _interfaces.IAllocator(allocator)
|
|
|
|
self._N = _interfaces.INameplate(nameplate)
|
|
|
|
self._K = _interfaces.IKey(key)
|
|
|
|
self._I = _interfaces.IInput(input)
|
2017-02-22 19:26:11 +00:00
|
|
|
|
|
|
|
@m.state(initial=True)
|
2018-04-21 07:30:08 +00:00
|
|
|
def S0_idle(self):
|
|
|
|
pass # pragma: no cover
|
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.state()
|
2018-04-21 07:30:08 +00:00
|
|
|
def S1_inputting_nameplate(self):
|
|
|
|
pass # pragma: no cover
|
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.state()
|
2018-04-21 07:30:08 +00:00
|
|
|
def S2_inputting_words(self):
|
|
|
|
pass # pragma: no cover
|
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.state()
|
2018-04-21 07:30:08 +00:00
|
|
|
def S3_allocating(self):
|
|
|
|
pass # pragma: no cover
|
|
|
|
|
2017-03-11 22:18:58 +00:00
|
|
|
@m.state()
|
2018-04-21 07:30:08 +00:00
|
|
|
def S4_known(self):
|
|
|
|
pass # pragma: no cover
|
2017-02-22 19:26:11 +00:00
|
|
|
|
|
|
|
# from App
|
|
|
|
@m.input()
|
2018-04-21 07:30:08 +00:00
|
|
|
def allocate_code(self, length, wordlist):
|
|
|
|
pass
|
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2018-04-21 07:30:08 +00:00
|
|
|
def input_code(self):
|
|
|
|
pass
|
|
|
|
|
2017-07-04 17:50:21 +00:00
|
|
|
def set_code(self, code):
|
2018-04-21 07:30:08 +00:00
|
|
|
validate_code(code) # can raise KeyFormatError
|
2017-07-04 17:50:21 +00:00
|
|
|
self._set_code(code)
|
2018-04-21 07:30:08 +00:00
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2018-04-21 07:30:08 +00:00
|
|
|
def _set_code(self, code):
|
|
|
|
pass
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-03-17 23:50:37 +00:00
|
|
|
# from Allocator
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2018-04-21 07:30:08 +00:00
|
|
|
def allocated(self, nameplate, code):
|
|
|
|
pass
|
2017-03-11 22:18:58 +00:00
|
|
|
|
2017-03-12 17:38:48 +00:00
|
|
|
# from Input
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2018-04-21 07:30:08 +00:00
|
|
|
def got_nameplate(self, nameplate):
|
|
|
|
pass
|
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.input()
|
2018-04-21 07:30:08 +00:00
|
|
|
def finished_input(self, code):
|
|
|
|
pass
|
2017-02-22 19:26:11 +00:00
|
|
|
|
|
|
|
@m.output()
|
2017-03-17 23:50:37 +00:00
|
|
|
def do_set_code(self, code):
|
|
|
|
nameplate = code.split("-", 2)[0]
|
|
|
|
self._N.set_nameplate(nameplate)
|
|
|
|
self._B.got_code(code)
|
2017-03-22 23:09:30 +00:00
|
|
|
self._K.got_code(code)
|
2017-03-17 23:50:37 +00:00
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.output()
|
2017-03-19 16:35:05 +00:00
|
|
|
def do_start_input(self):
|
|
|
|
return self._I.start()
|
2018-04-21 07:30:08 +00:00
|
|
|
|
2017-03-11 22:18:58 +00:00
|
|
|
@m.output()
|
2017-03-17 23:50:37 +00:00
|
|
|
def do_middle_input(self, nameplate):
|
2017-03-11 22:18:58 +00:00
|
|
|
self._N.set_nameplate(nameplate)
|
2018-04-21 07:30:08 +00:00
|
|
|
|
2017-03-11 22:18:58 +00:00
|
|
|
@m.output()
|
2017-03-17 23:50:37 +00:00
|
|
|
def do_finish_input(self, code):
|
|
|
|
self._B.got_code(code)
|
2017-03-22 23:09:30 +00:00
|
|
|
self._K.got_code(code)
|
2017-02-22 19:26:11 +00:00
|
|
|
|
2017-03-11 22:18:58 +00:00
|
|
|
@m.output()
|
2017-03-17 23:50:37 +00:00
|
|
|
def do_start_allocate(self, length, wordlist):
|
|
|
|
self._A.allocate(length, wordlist)
|
2018-04-21 07:30:08 +00:00
|
|
|
|
2017-02-22 19:26:11 +00:00
|
|
|
@m.output()
|
2017-03-17 23:50:37 +00:00
|
|
|
def do_finish_allocate(self, nameplate, code):
|
2018-04-21 07:30:08 +00:00
|
|
|
assert code.startswith(nameplate + "-"), (nameplate, code)
|
2017-03-17 23:50:37 +00:00
|
|
|
self._N.set_nameplate(nameplate)
|
|
|
|
self._B.got_code(code)
|
2017-03-22 23:09:30 +00:00
|
|
|
self._K.got_code(code)
|
2017-03-17 23:50:37 +00:00
|
|
|
|
2017-07-04 17:50:21 +00:00
|
|
|
S0_idle.upon(_set_code, enter=S4_known, outputs=[do_set_code])
|
2018-04-21 07:30:08 +00:00
|
|
|
S0_idle.upon(
|
|
|
|
input_code,
|
|
|
|
enter=S1_inputting_nameplate,
|
|
|
|
outputs=[do_start_input],
|
|
|
|
collector=first)
|
|
|
|
S1_inputting_nameplate.upon(
|
|
|
|
got_nameplate, enter=S2_inputting_words, outputs=[do_middle_input])
|
|
|
|
S2_inputting_words.upon(
|
|
|
|
finished_input, enter=S4_known, outputs=[do_finish_input])
|
|
|
|
S0_idle.upon(
|
|
|
|
allocate_code, enter=S3_allocating, outputs=[do_start_allocate])
|
2017-03-17 23:50:37 +00:00
|
|
|
S3_allocating.upon(allocated, enter=S4_known, outputs=[do_finish_allocate])
|