Files
HeurAMS/src/heurams/interface/screens/preparation.py
2026-04-23 00:13:57 +08:00

198 lines
6.5 KiB
Python

"""记忆准备界面"""
from textual.app import ComposeResult
from textual.containers import ScrollableContainer, Horizontal
from textual.screen import Screen
from textual.widgets import (
Button,
Footer,
Header,
Label,
Markdown,
Static,
Sparkline,
)
from textual.lazy import Reveal
from textual import events, on
import heurams.kernel.particles as pt
from heurams.context import *
from heurams.context import config_var
from heurams.kernel.repolib import *
from heurams.kernel.algorithms import algorithms
from heurams.services.logger import get_logger
logger = get_logger(__name__)
class PreparationScreen(Screen):
SUB_TITLE = "准备记忆集"
BINDINGS = [
("q", "go_back", "返回"),
("p", "precache", "缓存"),
("d", "toggle_dark", ""),
("0,1,2,3", "app.push_screen('about')", ""),
]
CSS_PATH = rootdir / "interface" / "css" / "screens" / "preparation.tcss"
def __init__(self, repo: Repo) -> None:
super().__init__(name=None, id=None, classes=None)
self.repo = repo
self.load_data()
@on(events.ScreenResume)
def post_active(self, event):
from heurams.interface import shim
shim.set_term_title(f"{self.app.TITLE} - {self.SUB_TITLE}")
def compose(self) -> ComposeResult:
from heurams.services.attic import Attic
a = Attic("ana", {"openpre": 0})
a.data["openpre"] += 1
if config_var.get()["interface"]["global"]["show_header"]:
yield Header(
show_clock=config_var.get()["interface"]["global"]["clock_on_header"]
)
with ScrollableContainer(id="main_container"):
yield Markdown(
f"**准备就绪**: `{self.repo.manifest['title']}`\n", id="title"
)
yield Label(f"单元集路径: {self.repo.source}")
yield Label(
f"学习完成度: {self.repo.progress['touched']}/{len(self.repo)} [d]\\[{round(self.repo.progress['touched']/self.repo.progress['total']*100, 1)}%][/d]"
)
yield Label(
f"调度算法: {self.repo.config["algorithm"]} {algorithms[self.repo.config["algorithm"]].desc}"
)
yield Label(
f"学习数量: {self.repo.preview['review'] + self.scheduled_num} = {self.repo.preview['review']} [d][复习][/d] + {self.scheduled_num} [d][新识记][/d]\n",
id="schnum_label",
)
yield Horizontal(
Button(
"开始记忆",
id="start_memorizing_button",
variant="primary",
classes="btn",
),
Button(
"管理缓存",
id="precache_button",
variant="success",
classes="btn",
),
id="operations",
)
yield Static()
yield Sparkline(self.spark_line_arr, summary_function=max)
# yield Static(str(self.spark_line_arr))
with Reveal(ScrollableContainer(id="previewer_container")):
for i in self.content.splitlines():
yield Static(i, classes="unit-statline")
yield Footer()
# def watch_scheduled_num(self, old_scheduled_num, new_scheduled_num):
# logger.debug("响应", old_scheduled_num, "->", new_scheduled_num)
# try:
# one = self.query_one("#schnum_label")
# one.update(f"单次记忆数量: {new_scheduled_num}") # type: ignore
# except:
# pass
def load_data(self):
self.scheduled_num = self.repo.config["scheduled_num"]
content = ""
spark_line_arr = []
for i in self.repo.ident_index:
n = pt.Nucleon.from_data(
nucleonic_data=self.repo.nucleonic_data_lict.get_itemic_unit(i)
)
e = pt.Electron.from_data(
electronic_data=self.repo.electronic_data_lict.get_itemic_unit(i),
algo_name=self.repo.config["algorithm"],
)
statstr = ""
if e.is_activated():
statstr = "[#00ff00]A[/]"
if e.is_due():
statstr = "[#ffff00]R[/]"
# statstr += ('[dim]' + str(e.rept(real_rept=True)).zfill(2)+'[/]')
else:
statstr = "[#ff0000]U[/]"
spark_line_arr.append(e.rept(real_rept=True))
content += f" {statstr} {n['content'].replace('/', '')} \n"
self.content = content
self.spark_line_arr = spark_line_arr
def action_go_back(self):
self.app.pop_screen()
def action_precache(self):
from ..screens.precache import PrecachingScreen
lst = list()
for i in self.repo.ident_index:
lst.append(
pt.Nucleon.from_data(self.repo.nucleonic_data_lict.get_itemic_unit(i))
)
precache_screen = PrecachingScreen(
nucleons=lst, desc=self.repo.manifest["title"]
)
self.app.push_screen(precache_screen)
def action_quit_app(self):
self.app.exit()
def on_button_pressed(self, event: Button.Pressed) -> None:
event.stop()
logger.debug("按下按钮")
if event.button.id == "start_memorizing_button":
launch(repo=self.repo, app=self.app, scheduled_num=self.scheduled_num)
elif event.button.id == "precache_button":
self.action_precache()
def launch(repo, app, scheduled_num):
if scheduled_num == -1:
scheduled_num = config_var.get()["interface"]["global"]["scheduled_num"]
atoms = list()
for i in repo.ident_index:
n = pt.Nucleon.from_data(
nucleonic_data=repo.nucleonic_data_lict.get_itemic_unit(i)
)
e = pt.Electron.from_data(
electronic_data=repo.electronic_data_lict.get_itemic_unit(i),
algo_name=repo.config["algorithm"],
)
a = pt.Atom(n, e, repo.orbitic_data)
atoms.append(a)
atoms_to_provide = list()
left_new = scheduled_num
for i in atoms:
i: pt.Atom
if i.registry["electron"].is_activated():
if i.registry["electron"].is_due():
atoms_to_provide.append(i)
else:
left_new -= 1
if left_new >= 0:
atoms_to_provide.append(i)
import heurams.kernel.reactor as rt
from .memoqueue import MemScreen
router = rt.Router(atoms_to_provide)
memscreen = MemScreen(router=router, repo=repo)
app.push_screen(memscreen)