diff --git a/python_payload/apps/demo_worms.py b/python_payload/apps/demo_worms.py index 2231c077b73cf30614b8a0c7db2371a933464964..e4009551592d76f6d41d31b4ad23325fb38acc3f 100644 --- a/python_payload/apps/demo_worms.py +++ b/python_payload/apps/demo_worms.py @@ -72,7 +72,7 @@ class AppWorms(application.Application): self.last_render = now def handle_input(self,data): - worms = app.worms + worms = self.worms worms.append(Worm(data.get("index",0)*2*math.pi/10+math.pi )) if len(worms)>10: worms.pop(0) diff --git a/python_payload/apps/flow3r/__init__.py b/python_payload/apps/flow3r/__init__.py index 3f6aa3969f3404cdd25b08de5f59458a96043663..f96eb2b44d0ed3e493f25b717ea9ee7419b1b1df 100644 --- a/python_payload/apps/flow3r/__init__.py +++ b/python_payload/apps/flow3r/__init__.py @@ -1,10 +1,16 @@ -from st3m.application import Application,menu +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info(f"running {__name__}") +from st3m.application import Application +log.info(f"import app") from . import menu_main +log.info(f"import menu") + class myApp(Application): def on_init(self): self.menu = menu_main.get_menu() def on_foreground(self): - menu.set_active_menu(self.menu) + self.menu.start() -app=myApp("flow3r") +app=myApp("flow3r", exit_on_menu_enter=False) diff --git a/python_payload/apps/flow3r/menu_main.py b/python_payload/apps/flow3r/menu_main.py index 5fb3177c42c1b14313b1969adb72d738719e24a0..9aa7e1c0f2af8170aa05bde084213025963dd0ae 100644 --- a/python_payload/apps/flow3r/menu_main.py +++ b/python_payload/apps/flow3r/menu_main.py @@ -13,7 +13,7 @@ def get_menu(): menu_apps = menu.Menu("apps") menu_music = menu.Menu("music") - + #Skipping for mem constraints #for app_module in [demo_sparabo,melodic_demo,harmonic_demo]: # menu_music.add(menu.MenuItemApp(app_module.app)) diff --git a/python_payload/main.py b/python_payload/main.py index 49f8af1acb866900bd10fb1d996340c4a1adca24..17ff616650da93a90c2e7c5817be62d2f2739f5f 100644 --- a/python_payload/main.py +++ b/python_payload/main.py @@ -1,9 +1,27 @@ -from st3m.system import hardware,audio +import gc,time +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info(f"starting main") +from st3m import control,application,ui,menu +gc.collect() +time.sleep_ms(100) +log.info(f"free memory: {gc.mem_free()}") from apps import flow3r +log.info(f"free memory: {gc.mem_free()}") +log.info("import apps done") + +gc.collect() + + #TODO persistent settings +from st3m.system import hardware,audio +log.info("calibrating captouch, reset volume") hardware.captouch_autocalib() audio.set_volume_dB(0) #Start default app -flow3r.app.run() \ No newline at end of file +default_app = flow3r.app + +#log.info(f"running default app '{default_app.title}'") +default_app.run() \ No newline at end of file diff --git a/python_payload/st3m/application.py b/python_payload/st3m/application.py index 45c8aef0b0ea70c90c270d55a091fa91f3d5de53..97ec2cf7d3030abb4e0b8567a8dad71b3c35be44 100644 --- a/python_payload/st3m/application.py +++ b/python_payload/st3m/application.py @@ -1,3 +1,6 @@ +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info("import") from . import ui,event,menu STATE_OFF = 0 @@ -6,9 +9,10 @@ STATE_BACKGROUND = 200 STATE_FOREGROUND = 300 STATE_ERROR = 500 - +log.info("setting up application") class Application(): - def __init__(self,title="badge23 app", author="someone@earth"): + def __init__(self,title="badge23 app", author="someone@earth", exit_on_menu_enter=True): + log.info(f"__init__ app '{title}'") self.title = title self.author = author self.state = STATE_OFF @@ -20,21 +24,19 @@ class Application(): self.icon = ui.Icon(label=self.title, size=100) self.engine = event.the_engine self.menu = None - - self.add_event(event.Event( - name="exit", - action=self.exit, - condition=lambda e: e["type"]=="button" and e.get("from")==2 and e["change"] - )) + if exit_on_menu_enter: + self.add_event(event.Event( + name="exit", + action=self.exit, + condition=lambda e: e["type"]=="button" and e.get("from")==2 and e["change"] + )) def __repr__(self): return "App "+self.title def init(self): - print("INIT") + log.info(f"init app '{self.title}'") self.state = STATE_INIT - print("before on_init") self.on_init() - print("after on_init") if self.has_background: if self._events_background: self._set_events(self._events_background,True) @@ -42,25 +44,25 @@ class Application(): def run(self): - print ("RUN from",self.state) + log.info(f"run app '{self.title}' from state {self.state}") if self.state == STATE_OFF: - print("go init") + log.info("from STATE_OFF, doing init()") self.init() - if self.has_foreground: self._to_foreground() elif self.has_background: self._to_background() - print ("App {} has no foreground, running in background".format(self.title)) else: - print("App has neither foreground nor background, not doing anything") + log.warning(f"App {self.title} has neither foreground nor background, not doing anything") #start the eventloop if it is not already running - event.the_engine.eventloop() + if not event.the_engine.is_running: + log.info("eventloop not yet running, starting") + event.the_engine.eventloop() def exit(self,data={}): - print("EXIT") + log.info(f"exit app '{self.title}' from state {self.state}") self.on_exit() if self.state == STATE_FOREGROUND: self._to_background() @@ -68,6 +70,7 @@ class Application(): def kill(self): #disable all events + log.info(f"kill app '{self.title}' from state {self.state}") engine.register_service_loop(self.main_always,False) engine.foreground_app = None @@ -92,9 +95,9 @@ class Application(): return self.state == STATE_FOREGROUND def _to_foreground(self): - print ("to foreground", self) + log.info(f"to_foreground app '{self.title}' from state {self.state}") if not self.has_foreground: - #TODO log + log.error(f"app has no foreground!") return if self._events_background: @@ -105,10 +108,10 @@ class Application(): self._set_events(self._events_foreground,True) self.on_foreground() - #self.engine.register_main_loop(self.main_foreground,True) self.engine.foreground_app = self def _to_background(self): + log.info(f"to_background app '{self.title}' from state {self.state}") self.state = STATE_BACKGROUND if self._events_foreground: self._set_events(self._events_foreground,False) @@ -123,25 +126,24 @@ class Application(): e.set_enabled(enabled) def on_init(self): - print("nothing to init") - pass + log.info(f"app {self.title}: on_init()") def on_foreground(self): - pass + log.info(f"app {self.title}: on_foreground()") def on_background(self): - pass + log.info(f"app {self.title}: on_background()") def on_exit(self): - pass + log.info(f"app {self.title}: on_exit()") def on_kill(self): - pass + log.info(f"app {self.title}: on_kill()") def on_draw(self): #self.ui.ctx.rgb(*ui.RED).rectangle(-120,-120,120,120).fill() #self.icon.draw() - pass + log.debug(f"app {self.title}: on_draw()") def main_foreground(self): pass diff --git a/python_payload/st3m/control.py b/python_payload/st3m/control.py index fe3febc9a68a8ae410256f2d6e86226dcd5d7376..59663340e78c19f5956cb2e8abcae101c880beaa 100644 --- a/python_payload/st3m/control.py +++ b/python_payload/st3m/control.py @@ -1,3 +1,7 @@ +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info("import") + from . import ui class Control(): @@ -15,7 +19,6 @@ class Control(): def draw(self): self.ui.value = self.get_value() - print("draw: value", self.get_value()) self.ui.draw() def get_normal_value(self): @@ -70,10 +73,14 @@ class ControlFloat(Control): def get_normal_value(self): v = self.get_value() n = (v-self.min)/(self.max-self.min) - #print("normal:",v,n) return n class ControlKnob(ControlFloat): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._x_init = 0 + self._touch_started_here = False + def enter(self): #repeat action with current value self.set_value(self.get_value()) @@ -93,13 +100,16 @@ class ControlKnob(ControlFloat): def touch_1d(self,x,z): if z>0: #Inital Contact self._x_init = x + self._touch_started_here=True if z==0: #Continous contact + if not self._touch_started_here: + return diff = self._x_init-x self.scroll(5*diff) if z<0: #Release - pass + self._touch_started_here = False class ControlSlide(ControlFloat): @@ -114,7 +124,7 @@ class ControlSlide(ControlFloat): if z==0: #Continous contact v = (self.max-self.min)*x+self.min self.set_value(v) - print("c",x,v,self.max,self.min) + #print("c",x,v,self.max,self.min) if z<0: #Release if self.do_reset: diff --git a/python_payload/st3m/event.py b/python_payload/st3m/event.py index 6aa5f8be947261b9d28beda0e50f62d6a20089f4..a7fd51e40708c08f218a0c832760033c251e7073 100644 --- a/python_payload/st3m/event.py +++ b/python_payload/st3m/event.py @@ -1,4 +1,9 @@ -import hardware +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info("import") + +from st3m.system import hardware + import time import math import random @@ -47,15 +52,6 @@ class Engine(): def remove_input(self,group_id): self.events_input = [event for event in self.events_input if event.group_id!=group_id] - def register_main_loop(self,loop,enable=True): - if enable: - #print ("new userloop",loop) - #loop() - self.userloop = loop - elif self.userloop == loop: - #print ("removed userloop") - self.userloop = None - def _sort_timed(self): self.events_timed = sorted(self.events_timed, key = lambda event: event.deadline) @@ -149,11 +145,10 @@ class Engine(): def eventloop(self): + log.info("starting eventloop") if self.is_running: - print ("eventloop already running") + log.warning("eventloop already running, doing nothing") return - else: - print("eventloop started") self.is_running=True last_draw = 0 while self.is_running: @@ -190,7 +185,7 @@ class Event(): def trigger(self,triggerdata={}): - print ("triggered {} (with {})".format(self.name,triggerdata)) + log.debug("triggered {} (with {})".format(self.name,triggerdata)) if not self.action is None: triggerdata.update(self.data) self.action(triggerdata) @@ -203,12 +198,12 @@ class Event(): self.remove() def remove(self): - print ("remove",self) + log.info(f"remove {self}") while self in the_engine.events_input: - print ("from input") + #print ("from input") the_engine.events_input.remove(self) while self in the_engine.events_timed: - print("from timed") + #print("from timed") the_engine.events_timed.remove(self) the_engine._sort_timed() @@ -245,7 +240,7 @@ class Sequence(): self.is_running = False if not action: - self.action = lambda data: print("step {}".format(data.get("step"))) + self.action = lambda data: log.info("step {}".format(data.get("step"))) else: self.action = action @@ -253,7 +248,7 @@ class Sequence(): if self.is_running: self.stop() stepsize_ms = int(60*1000/self.bpm) for i in range(self.steps): - print("adding sequence event ", i) + log.debug("adding sequence event ", i) self.events.append(EventTimed(stepsize_ms*i,name="seq{}".format(i),action=self.action, data={'step':i}, group_id=self.group_id,enabled=True)) if self.loop: self.repeat_event=EventTimed(stepsize_ms*self.steps,name="loop", group_id=self.group_id, enabled=True, action=on_restart, data={"object":self}) @@ -261,7 +256,7 @@ class Sequence(): def stop(self): #for e in self.events: e.remove() - print("sequence stop") + log.info("sequence stop") the_engine.remove_timed(group_id=self.group_id) self.events = [] if self.repeat_event: self.repeat_event.remove() diff --git a/python_payload/st3m/menu.py b/python_payload/st3m/menu.py index f3c2c57395d23a9b2ce37f471a3a989579346ae7..0749abbe4ea05c0bf66dee819617cef1c5f1adef 100644 --- a/python_payload/st3m/menu.py +++ b/python_payload/st3m/menu.py @@ -1,5 +1,8 @@ +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info("import") + from . import ui,event -import hardware import time @@ -41,7 +44,7 @@ class Menu(): self.ui.children.pop() def start(self): - print(self) + log.info(f"starting menu {self.name}") set_active_menu(self) def scroll(self, n=0): @@ -119,7 +122,7 @@ class MenuItem(): return "item: {} (action: {})".format(self.name,"?") def enter(self,data={}): - print("Enter MenuItem {}".format(self.name)) + log.info("enter MenuItem {}".format(self.name)) if self.action: self.action(data) @@ -142,8 +145,9 @@ class MenuItemSubmenu(MenuItem): self.target = submenu def enter(self,data={}): - print("Enter Submenu {}".format(self.target.name)) menu_stack.append(get_active_menu()) + log.info(f"enter submenu {self.target.name} (Stack: {len(menu_stack)})") + set_active_menu(self.target) class MenuItemBack(MenuItem): @@ -161,7 +165,7 @@ class MenuItemControl(MenuItem): self.ui=control.ui def enter(self): - print("menu enter") + log.info(f"item {self.name} (MenuItemControl): enter") self.control.enter() def scroll(self,delta): @@ -178,7 +182,6 @@ def on_scroll(d): if d["index"]==0:#right button hovered=active_menu.get_hovered_item() if hasattr(hovered, "scroll"): - print("has_scroll") hovered.scroll(d["value"]) else: #index=1, #left button @@ -199,7 +202,6 @@ def on_scroll_captouch(d): return if abs(d["radius"]) < 10000: return - print(d["angle"]) active_menu.rotate_to(d["angle"]+math.pi) def on_release(d): @@ -217,14 +219,14 @@ def on_touch_1d(d): if active_menu is None: return - #print(d["radius"]) + v = min(1.0,max(0.0,((d["radius"]+25000.0)/50000.0))) z = 0 if d["change"]: if d["value"] == 1: z=1 else: z=-1 - print("menu: touch_1d",v,z) + log.debug(f"menu: touch_1d ({v},{z})") hovered=active_menu.get_hovered_item() @@ -235,7 +237,6 @@ def on_touch_1d(d): if hasattr(hovered, "touch_1d"): - print("hastouch") hovered.touch_1d(v,z) @@ -243,13 +244,12 @@ def on_enter(d): active_menu = get_active_menu() if active_menu is None: - - #TODO this should not bee needed... - event.the_engine.userloop=None + log.info("menu enter without active menu, opening last menu") menu_back() return if active_menu: + log.info("menu enter, opening item") active_menu.get_hovered_item().enter() @@ -279,16 +279,6 @@ event.Event(name="menu button enter",group_id="menu", action=on_enter, enabled=True ) -def old_render(): - - print (active_menu) - return - if active_menu is None: - return - - ui.the_ctx.rectangle(-120,-120,240,240).rgb(*ui.BLACK).fill() - active_menu.draw() - #hardware.display_update() def set_active_menu(menu): event.the_engine.active_menu = menu @@ -296,16 +286,9 @@ def set_active_menu(menu): def get_active_menu(): return event.the_engine.active_menu -#def menu_disable(): -# global active_menu -# if active_menu: -# menu_stack.append(active_menu) -# active_menu=None - def menu_back(): - if not menu_stack: - return - previous = menu_stack.pop() + log.info(f"back to previous menu {previous.name} (Stack: {len(menu_stack)})") + set_active_menu(previous) \ No newline at end of file diff --git a/python_payload/st3m/system/__init__.py b/python_payload/st3m/system/__init__.py index 93c01cec089e843cc4dd252e3d521b6feadd0345..2960c66a23714654ef01cabbbbcdb8d490e9ba20 100644 --- a/python_payload/st3m/system/__init__.py +++ b/python_payload/st3m/system/__init__.py @@ -26,5 +26,15 @@ except ModuleNotFoundError: print("no real audio, using mock module") _audio = MockObject("audio") + +try: + import audio as _audio +except ModuleNotFoundError: + print("no real audio, using mock module") + _audio = MockObject("audio") + + hardware = _hardware -audio = _audio \ No newline at end of file +audio = _audio + +ctx =hardware.get_ctx() \ No newline at end of file diff --git a/python_payload/st3m/ui.py b/python_payload/st3m/ui.py index ea187b94ef694f18144eb334f439eda997042c85..063a9f4453d0dab5cfaec791032f05d5a41aa7c6 100644 --- a/python_payload/st3m/ui.py +++ b/python_payload/st3m/ui.py @@ -1,4 +1,8 @@ -import hardware +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info("import") + +from st3m.system import ctx import random import math import time @@ -19,7 +23,7 @@ GREY = (0.5,0.5,0.5) GO_GREEN = (63/255,255/255,33/53) PUSH_RED = (251/255,72/255,196/255) -the_ctx = hardware.get_ctx() +the_ctx = ctx # Utility functions def xy_from_polar(r,phi): diff --git a/python_payload/st3m/utils.py b/python_payload/st3m/utils.py index 0be418b9e617a8150934c75705afee918b3d2aff..687835af5ba10217833798c636ad3a9fc2e6d6a4 100644 --- a/python_payload/st3m/utils.py +++ b/python_payload/st3m/utils.py @@ -1,3 +1,7 @@ +from st3m import logging +log = logging.Log(__name__,level=logging.INFO) +log.info("import") + import time from hardware import * from st3m.system import audio