2021-10-19 10:10:04 +00:00
|
|
|
from enum import Enum, auto
|
2022-01-16 21:10:13 +00:00
|
|
|
from typing import List
|
2021-10-19 10:10:04 +00:00
|
|
|
|
2022-01-16 14:30:30 +00:00
|
|
|
from pizzactrl.hal_serial import SerialCommands
|
|
|
|
|
2021-10-19 10:10:04 +00:00
|
|
|
|
2022-01-14 21:47:19 +00:00
|
|
|
class Option(Enum):
|
|
|
|
"""
|
|
|
|
Options can be chosen by the user in WAIT_FOR_INPUT
|
|
|
|
"""
|
|
|
|
CONTINUE = {} # Continue with chapter
|
|
|
|
REPEAT = {'rewind': True} # Repeat chapter from beginning. `rewind=True`: reset scrolls to starting position
|
|
|
|
GOTO = {'chapter': 0} # Jump to chapter number
|
|
|
|
QUIT = {'shutdown': True} # End playback. `shutdown=True` also powers off box
|
|
|
|
|
|
|
|
|
|
|
|
class Select:
|
|
|
|
"""
|
|
|
|
An option instance. Can override the default settings from `Option`s
|
|
|
|
"""
|
|
|
|
def __init__(self, option: Option, **kwargs):
|
|
|
|
self.option = option
|
|
|
|
self.values = {}
|
|
|
|
if option is not None:
|
|
|
|
for key, value in self.option.value.items():
|
|
|
|
self.values[key] = kwargs.get(key, value)
|
|
|
|
|
|
|
|
|
2021-10-19 10:10:04 +00:00
|
|
|
class Activity(Enum):
|
2022-01-14 21:47:19 +00:00
|
|
|
"""
|
|
|
|
Things the box can do
|
|
|
|
"""
|
|
|
|
WAIT_FOR_INPUT = {'on_blue': Select(Option.CONTINUE),
|
|
|
|
'on_red': Select(Option.REPEAT),
|
|
|
|
'on_yellow': Select(None),
|
|
|
|
'on_green': Select(None),
|
|
|
|
'on_timeout': Select(Option.QUIT),
|
|
|
|
'sound': None,
|
|
|
|
'timeout': 0}
|
|
|
|
PLAY_SOUND = {'sound': None}
|
|
|
|
RECORD_SOUND = {'duration': 10.0,
|
|
|
|
'filename': '',
|
|
|
|
'cache': False}
|
|
|
|
RECORD_VIDEO = {'duration': 60.0,
|
|
|
|
'filename': ''}
|
|
|
|
TAKE_PHOTO = {'filename': ''}
|
|
|
|
ADVANCE_UP = {'steps': 100, # TODO set right number of steps
|
|
|
|
'direction': True,
|
|
|
|
'horizontal': False}
|
|
|
|
ADVANCE_LEFT = {'steps': 200, # TODO set right number of steps
|
|
|
|
'direction': True,
|
|
|
|
'horizontal': True}
|
|
|
|
LIGHT_LAYER = {'r': 0,
|
|
|
|
'g': 0,
|
|
|
|
'b': 0,
|
|
|
|
'w': 1.0,
|
|
|
|
'fade': 1.0,
|
2022-01-16 14:30:30 +00:00
|
|
|
'light': [ SerialCommands.FRONTLIGHT ]}
|
2022-01-14 21:47:19 +00:00
|
|
|
LIGHT_BACK = {'r': 0,
|
|
|
|
'g': 0,
|
|
|
|
'b': 0,
|
|
|
|
'w': 1.0,
|
|
|
|
'fade': 1.0,
|
2022-01-16 14:30:30 +00:00
|
|
|
'light': [ SerialCommands.BACKLIGHT ]}
|
2021-10-19 10:10:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Do:
|
2022-01-14 21:47:19 +00:00
|
|
|
"""
|
|
|
|
An activity instance. Can override the default settings from `Activity`s
|
|
|
|
"""
|
2021-10-19 10:10:04 +00:00
|
|
|
def __init__(self, activity: Activity, **kwargs):
|
|
|
|
self.activity = activity
|
|
|
|
self.values = {}
|
|
|
|
for key, value in self.activity.value.items():
|
|
|
|
self.values[key] = kwargs.get(key, value)
|
|
|
|
|
2022-01-16 21:10:13 +00:00
|
|
|
def execute():
|
|
|
|
# TODO implement
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class Do_Parallel:
|
|
|
|
"""
|
|
|
|
A list of activities which should be done at the same time
|
|
|
|
"""
|
|
|
|
def __init__(self, *activities: List[Do]) -> None:
|
|
|
|
self.act_list = activities
|
|
|
|
|
|
|
|
def execute():
|
|
|
|
for act in self.act_list:
|
|
|
|
act.execute()
|
|
|
|
|
2021-10-19 10:10:04 +00:00
|
|
|
|
|
|
|
class Chapter:
|
|
|
|
"""
|
2022-01-14 21:47:19 +00:00
|
|
|
A logical storyboard entity, which can be replayed (rewind to start)
|
|
|
|
or skipped (do all movements at once).
|
2021-10-19 10:10:04 +00:00
|
|
|
|
|
|
|
Keeps track of advanced steps on the scrolls.
|
|
|
|
"""
|
|
|
|
def __init__(self, *activities):
|
|
|
|
self.activities = activities
|
2022-01-14 21:47:19 +00:00
|
|
|
self.index = 0
|
|
|
|
self.h_pos = 0
|
|
|
|
self.v_pos = 0
|
|
|
|
|
2021-10-19 10:10:04 +00:00
|
|
|
def __iter__(self):
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __next__(self):
|
2022-01-14 21:47:19 +00:00
|
|
|
if self.index >= len(self.activities):
|
2021-10-19 10:10:04 +00:00
|
|
|
raise StopIteration
|
2022-01-14 21:47:19 +00:00
|
|
|
|
|
|
|
act = self.activities[self.index]
|
|
|
|
self._update_pos(act)
|
2021-10-19 10:10:04 +00:00
|
|
|
return act
|
|
|
|
|
2022-01-14 21:47:19 +00:00
|
|
|
def _update_pos(self, act: Activity):
|
|
|
|
"""
|
|
|
|
Update the positions from the activity.
|
|
|
|
Implicitly increments the index.
|
|
|
|
"""
|
|
|
|
self.index += 1
|
|
|
|
if act.activity is Activity.ADVANCE_UP:
|
|
|
|
self.v_pos += act.values.get('steps', 0)
|
|
|
|
elif act.activity is Activity.ADVANCE_LEFT:
|
|
|
|
self.h_pos += act.values.get('steps', 0)
|
|
|
|
|
2021-10-19 10:10:04 +00:00
|
|
|
def hasnext(self):
|
2022-01-14 21:47:19 +00:00
|
|
|
"""
|
|
|
|
Returns True if the chapter has more activities
|
|
|
|
"""
|
|
|
|
return self.index < len(self.activities)
|
2021-10-19 10:10:04 +00:00
|
|
|
|
|
|
|
def rewind(self, **kwargs):
|
2022-01-14 21:47:19 +00:00
|
|
|
"""
|
|
|
|
Reset the position to zero. Return how many steps are needed to rewind the scrolls
|
|
|
|
"""
|
|
|
|
self.index = 0
|
|
|
|
h_pos = self.h_pos
|
|
|
|
v_pos = self.v_pos
|
|
|
|
self.h_pos = 0
|
|
|
|
self.v_pos = 0
|
|
|
|
return {'h_steps': -h_pos, 'v_steps': -v_pos}
|
2021-10-19 10:10:04 +00:00
|
|
|
|
2022-01-14 21:47:19 +00:00
|
|
|
def skip(self, **kwargs):
|
|
|
|
"""
|
|
|
|
Skip chapter. Returns all movements necessary to advance scrolls.
|
|
|
|
"""
|
|
|
|
h_pos = self.h_pos
|
|
|
|
v_pos = self.v_pos
|
|
|
|
for act in self.activities[self.index:]:
|
|
|
|
self._update_pos(act)
|
|
|
|
return {'h_steps': self.h_pos - h_pos, 'v_steps': self.v_pos - v_pos}
|
2021-10-19 10:10:04 +00:00
|
|
|
|