Skip to content

Commit

Permalink
refactor: make create_task functional for the main application just…
Browse files Browse the repository at this point in the history
… like its services
  • Loading branch information
sassanh committed Jan 20, 2024
1 parent 7313b14 commit a5f63bf
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 117 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Version 0.7.14

- refactor: make `create_task` functional for the main application just like its
services

## Version 0.7.13

- feat: #16 add volume chime
Expand Down
78 changes: 39 additions & 39 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "ubo-app"
version = "0.7.13"
version = "0.7.14"
description = "Ubo main app, running on device initialization. A platform for running other apps."
authors = ["Sassan Haradji <[email protected]>"]
license = "Apache-2.0"
Expand Down Expand Up @@ -29,7 +29,7 @@ headless-kivy-pi = [
'dev',
] },
]
python-redux = "^0.9.11"
python-redux = "^0.9.12"
pyzbar = "^0.1.9"
sdbus-networkmanager = { version = "^2.0.0", markers = "platform_machine=='aarch64'" }
rpi_ws281x = { version = "^5.0.0", markers = "platform_machine=='aarch64'" }
Expand Down
8 changes: 0 additions & 8 deletions ubo_app/_loop.py

This file was deleted.

70 changes: 36 additions & 34 deletions ubo_app/load_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ def __init__(self: UboServiceLoopLoader, thread: UboServiceThread) -> None:
self.thread = thread

def exec_module(self: UboServiceLoopLoader, module: ModuleType) -> None:
cast(Any, module).create_task = (
lambda *args: self.thread.loop.call_soon_threadsafe(
lambda: self.thread.loop.create_task(*args),
cast(Any, module)._create_task = ( # noqa: SLF001
lambda task: self.thread.loop.call_soon_threadsafe(
self.thread.loop.create_task,
task,
)
)

Expand All @@ -62,39 +63,39 @@ class UboServiceFinder(importlib.abc.MetaPathFinder):
def find_spec(
self: UboServiceFinder,
fullname: str,
path: Sequence[str] | None,
_: Sequence[str] | None,
target: ModuleType | None = None,
) -> ModuleSpec | None:
if path is None:
stack = traceback.extract_stack()
matching_path = next(
(
registered_path
for stack_path in stack[::-1]
for registered_path in REGISTERED_PATHS
if stack_path.filename.startswith(registered_path.as_posix())
),
None,
)
if matching_path:
thread = REGISTERED_PATHS[matching_path]
module_name = f'{thread.service_id}:{fullname}'

if fullname == '_loop':
return importlib.util.spec_from_loader(
module_name,
UboServiceLoopLoader(thread),
)

spec = PathFinder.find_spec(
fullname,
[matching_path.as_posix()],
target,
stack = traceback.extract_stack()
matching_path = next(
(
registered_path
for stack_path in stack[::-1]
for registered_path in REGISTERED_PATHS
if stack_path.filename.startswith(registered_path.as_posix())
),
None,
)

if matching_path:
thread = REGISTERED_PATHS[matching_path]
module_name = f'{thread.service_id}:{fullname}'

if fullname == 'ubo_app.utils.loop':
return importlib.util.spec_from_loader(
module_name,
UboServiceLoopLoader(thread),
)
if spec and spec.origin:
spec.name = module_name
spec.loader = UboServiceModuleLoader(fullname, spec.origin)
return spec

spec = PathFinder.find_spec(
fullname,
[matching_path.as_posix()],
target,
)
if spec and spec.origin:
spec.name = module_name
spec.loader = UboServiceModuleLoader(fullname, spec.origin)
return spec
return None


Expand All @@ -111,6 +112,7 @@ def __init__(
self.service_id = service_id
self.path = path
self.loop = asyncio.new_event_loop()
self.module = None
if DEBUG_MODE:
self.loop.set_debug(enabled=True)
try:
Expand Down Expand Up @@ -188,7 +190,7 @@ def load_services() -> None:
service_id = uuid.uuid4().hex
if not service_path.is_dir():
continue
current_path = os.curdir
current_path = Path().absolute()
os.chdir(service_path.as_posix())

thread = UboServiceThread(
Expand Down
40 changes: 8 additions & 32 deletions ubo_app/menu_central.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
# ruff: noqa: D100, D101, D102, D103, D104, D107
from __future__ import annotations

import asyncio
import pathlib
import threading
from functools import cached_property
from threading import Thread
from typing import TYPE_CHECKING, Self, Sequence
from typing import TYPE_CHECKING, Sequence

from debouncer import DebounceOptions, debounce
from kivy.app import Builder
from kivy.clock import Clock
from redux import EventSubscriptionOptions, FinishEvent
from redux import EventSubscriptionOptions
from ubo_gui.app import UboApp
from ubo_gui.gauge import GaugeWidget
from ubo_gui.menu import MenuWidget
Expand All @@ -38,7 +36,7 @@

class HomePage(PageWidget):
def __init__(
self: Self,
self: HomePage,
items: Sequence[Item] | None = None,
*args: object,
**kwargs: object,
Expand All @@ -56,7 +54,7 @@ def sync_output_volume(selector_result: float) -> None:
volume_widget.value = selector_result * 100

@cached_property
def cpu_gauge(self: Self) -> GaugeWidget:
def cpu_gauge(self: HomePage) -> GaugeWidget:
import psutil

gauge = GaugeWidget(value=0, fill_color='#24D636', label='CPU')
Expand All @@ -79,7 +77,7 @@ def calculate_value() -> None:
return gauge

@cached_property
def ram_gauge(self: Self) -> GaugeWidget:
def ram_gauge(self: HomePage) -> GaugeWidget:
import psutil

gauge = GaugeWidget(
Expand All @@ -97,7 +95,7 @@ def set_value(_: int) -> None:


class MenuWidgetWithHomePage(MenuWidget):
def get_current_screen(self: Self) -> Screen | None:
def get_current_screen(self: MenuWidgetWithHomePage) -> Screen | None:
if self.depth == 0:
return HomePage(
self.current_menu_items,
Expand All @@ -121,23 +119,6 @@ def set_path(_: MenuWidget, stack: list[tuple[Menu, int] | PageWidget]) -> None:
)


class WorkerThread(threading.Thread):
def __init__(self: WorkerThread) -> None:
super().__init__()
self.loop = asyncio.new_event_loop()
if DEBUG_MODE:
self.loop.set_debug(enabled=True)

def run(self: WorkerThread) -> None:
asyncio.set_event_loop(self.loop)

subscribe_event(FinishEvent, lambda _: self.stop())
self.loop.run_forever()

def stop(self: WorkerThread) -> None:
self.loop.call_soon_threadsafe(self.loop.stop)


class MenuAppCentral(UboApp):
@cached_property
def central(self: MenuAppCentral) -> Widget | None:
Expand All @@ -151,13 +132,8 @@ async def sync_current_menu(menu: Menu | None) -> None:
return
Clock.schedule_once(lambda _: self.menu_widget.set_root_menu(menu))

thread = WorkerThread()
thread.start()
sync_current_menu.subscribe(
lambda task: thread.loop.call_soon_threadsafe(
lambda: thread.loop.create_task(task),
),
)
create_task(sync_current_menu.value)
sync_current_menu.subscribe(lambda task: create_task(task))

def handle_title_change(_: MenuWidget, title: str) -> None:
self.root.title = title
Expand Down
4 changes: 2 additions & 2 deletions ubo_app/utils/async_.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ async def wrapper() -> None:
},
)

import _loop
import ubo_app.utils.loop

handle = _loop.create_task(wrapper())
handle = ubo_app.utils.loop._create_task(wrapper()) # noqa: SLF001
background_tasks.add(handle)
return handle
Loading

0 comments on commit a5f63bf

Please sign in to comment.