refactor: 开始翻新状态机

This commit is contained in:
2026-04-21 12:52:30 +08:00
parent e53e905e1b
commit fc70aa07f6
19 changed files with 111 additions and 135 deletions

View File

@@ -1 +0,0 @@
{}

View File

@@ -1,3 +0,0 @@
title = "测试单元: 过秦论"
author = "__heurams__"
desc = "高考古诗文: 过秦论"

View File

@@ -1,11 +0,0 @@
["秦孝公据崤函之固, 拥雍州之地,"]
note = []
content = "秦孝公/据/崤函/之固/, 拥/雍州/之地,/"
translation = "秦孝公占据着崤山和函谷关的险固地势,拥有雍州的土地,"
keyword_note = {"据"="占据", "崤函"="崤山和函谷关", "雍州"="古代九州之一"}
["君臣固守以窥周室,"]
note = []
content = "君臣/固守/以窥/周室,/"
translation = "君臣牢固地守卫着,借以窥视周王室的权力,"
keyword_note = {"窥"="窥视"}

View File

@@ -1,5 +0,0 @@
schedule = ["quick_review", "recognition", "final_review"]
[phases]
quick_review = [["FillBlank", "1.0"], ["SelectMeaning", "0.5"], ["Recognition", "1.0"]]
recognition = [["Recognition", "1.0"]]
final_review = [["FillBlank", "0.7"], ["SelectMeaning", "0.7"], ["Recognition", "1.0"]]

View File

@@ -1,17 +0,0 @@
[annotation]
note = "笔记"
keyword_note = "关键词翻译"
translation = "语句翻译"
delimiter = "分隔符"
content = "内容"
tts_text = "文本转语音文本"
[common]
delimiter = "/"
tts_text = "eval:payload['content'].replace('/', '')"
[common.puzzles] # 谜题定义
# 我们称 "Recognition" 为 recognition 谜题的 alia
"Recognition" = { __origin__ = "recognition", __hint__ = "", primary = "eval:payload['content']", secondary = ["eval:payload['keyword_note']", "eval:payload['note']"], top_dim = ["eval:payload['translation']"] }
"SelectMeaning" = { __origin__ = "mcq", __hint__ = "eval:payload['content']", primary = "eval:payload['content']", mapping = "eval:payload['keyword_note']", jammer = "eval:list(payload['keyword_note'].values())", max_riddles_num = "eval:default['mcq']['max_riddles_num']", prefix = "选择正确项: " }
"FillBlank" = { __origin__ = "cloze", __hint__ = "", text = "eval:payload['content']", delimiter = "eval:nucleon['delimiter']", min_denominator = "eval:default['cloze']['min_denominator']"}

View File

@@ -0,0 +1,4 @@
#puzzle_container > * {
height: auto;
width: auto;
}

View File

@@ -5,14 +5,14 @@ from pathlib import Path
from typing import Callable from typing import Callable
from textual.app import ComposeResult from textual.app import ComposeResult
from textual.containers import Center, ScrollableContainer from textual.containers import Center, ScrollableContainer, Container
from textual.reactive import reactive from textual.reactive import reactive
from textual.screen import Screen from textual.screen import Screen
from textual.widgets import Button, Footer, Header, Label, Static from textual.widgets import Button, Footer, Header, Label, Static
import heurams.kernel.particles as pt import heurams.kernel.particles as pt
import heurams.kernel.puzzles as pz import heurams.kernel.puzzles as pz
from heurams.context import config_var from heurams.context import config_var, rootdir
from heurams.kernel.reactor import * from heurams.kernel.reactor import *
from heurams.services.favorite_service import favorite_manager from heurams.services.favorite_service import favorite_manager
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
@@ -28,8 +28,13 @@ class MemScreen(Screen):
("d", "toggle_dark", ""), ("d", "toggle_dark", ""),
("v", "play_voice", "朗读"), ("v", "play_voice", "朗读"),
("*", "toggle_favorite", "收藏"), ("*", "toggle_favorite", "收藏"),
("n", "block_prompt"),
("s", "block_prompt"),
("z", "block_prompt"),
] ]
CSS_PATH = rootdir / 'interface' / 'css' / 'screens' / 'memoqueue.tcss'
if config_var.get()["interface"]["global"]["quick_pass"]: if config_var.get()["interface"]["global"]["quick_pass"]:
BINDINGS.append(("k", "quick_pass", "正确应答")) BINDINGS.append(("k", "quick_pass", "正确应答"))
BINDINGS.append(("f", "quick_fail", "错误应答")) BINDINGS.append(("f", "quick_fail", "错误应答"))
@@ -38,17 +43,17 @@ class MemScreen(Screen):
def __init__( def __init__(
self, self,
phaser: Phaser, router: Router,
repo=None, repo=None,
name=None, name=None,
id=None, id=None,
classes=None, classes=None,
) -> None: ) -> None:
super().__init__(name, id, classes) super().__init__(name, id, classes)
self.phaser = phaser self.router = router
self.repo = repo self.repo = repo
self.update_state() self.update_state()
self.fission: Fission self.expander: Expander
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
yield Header(show_clock=True) yield Header(show_clock=True)
@@ -59,17 +64,17 @@ class MemScreen(Screen):
def update_state(self): def update_state(self):
"""更新状态机""" """更新状态机"""
self.procession: Procession = self.phaser.current_procession() # type: ignore self.procession: Procession = self.router.current_procession() # type: ignore
self.atom: pt.Atom = self.procession.current_atom # type: ignore self.atom: pt.Atom = self.procession.current_atom # type: ignore
def on_mount(self): def on_mount(self):
self.fission = self.procession.get_fission() self.expander = self.procession.get_expander()
self.mount_puzzle() self.mount_puzzle()
self.update_display() self.update_display()
def puzzle_widget(self): def puzzle_widget(self):
try: try:
puzzle = self.fission.get_current_puzzle_inf() puzzle = self.expander.get_current_puzzle_inf()
return shim.puzzle2widget[puzzle["puzzle"]]( # type: ignore return shim.puzzle2widget[puzzle["puzzle"]]( # type: ignore
atom=self.atom, alia=puzzle["alia"] # type: ignore atom=self.atom, alia=puzzle["alia"] # type: ignore
) )
@@ -93,7 +98,7 @@ class MemScreen(Screen):
def mount_puzzle(self): def mount_puzzle(self):
"""挂载当前谜题组件""" """挂载当前谜题组件"""
if self.procession.phase == PhaserState.FINISHED: if self.procession.phase == RouterState.FINISHED:
self.mount_finished_widget() self.mount_finished_widget()
return return
container = self.query_one("#puzzle_container") container = self.query_one("#puzzle_container")
@@ -139,10 +144,10 @@ class MemScreen(Screen):
if new_rating == -1: # 安全值 if new_rating == -1: # 安全值
return return
self.update_state() self.update_state()
if self.procession.phase == PhaserState.FINISHED: if self.procession.phase == RouterState.FINISHED:
rating = -1 rating = -1
return return
self.fission.report(new_rating) self.expander.report(new_rating)
self.forward(new_rating) self.forward(new_rating)
self.rating = -1 self.rating = -1
@@ -150,9 +155,9 @@ class MemScreen(Screen):
self.update_state() self.update_state()
allow_forward = 1 if rating >= 4 else 0 allow_forward = 1 if rating >= 4 else 0
if allow_forward: if allow_forward:
self.fission.forward() self.expander.forward()
if self.fission.state == "retronly": if self.expander.state == "retronly":
self.forward_atom(self.fission.get_quality()) self.forward_atom(self.expander.get_quality())
self.update_state() self.update_state()
self.mount_puzzle() self.mount_puzzle()
self.update_display() self.update_display()
@@ -177,7 +182,7 @@ class MemScreen(Screen):
self.update_state() # 刷新状态 self.update_state() # 刷新状态
self.procession.forward(1) self.procession.forward(1)
self.update_state() # 刷新状态 self.update_state() # 刷新状态
self.fission = self.procession.get_fission() self.expander = self.procession.get_expander()
def action_go_back(self): def action_go_back(self):
self.app.pop_screen() self.app.pop_screen()
@@ -224,3 +229,6 @@ class MemScreen(Screen):
self.app.notify(f"已收藏:{ident}", severity="information") self.app.notify(f"已收藏:{ident}", severity="information")
# 更新显示(如果需要) # 更新显示(如果需要)
self.update_display() self.update_display()
def action_block_prompt(self):
self.app.notify("功能在记忆界面中不可用, 完成或返回后再试", severity="error")

View File

@@ -181,6 +181,6 @@ def launch(repo, app, scheduled_num):
from .memoqueue import MemScreen from .memoqueue import MemScreen
pheser = rt.Phaser(atoms_to_provide) router = rt.Router(atoms_to_provide)
memscreen = MemScreen(pheser, repo=repo) memscreen = MemScreen(router=router, repo=repo)
app.push_screen(memscreen) app.push_screen(memscreen)

View File

@@ -2,7 +2,7 @@ import copy
import random import random
from typing import TypedDict from typing import TypedDict
from textual.containers import Container from textual.containers import Container, ScrollableContainer
from textual.message import Message from textual.message import Message
from textual.widget import Widget from textual.widget import Widget
from textual.widgets import Button, Label, Markdown from textual.widgets import Button, Label, Markdown
@@ -68,7 +68,7 @@ class ClozePuzzle(BasePuzzleWidget):
yield Label(self.puzzle.wording, id="sentence") yield Label(self.puzzle.wording, id="sentence")
yield Markdown(f"> {self.listprint(self.inputlist)}", id="inputpreview") yield Markdown(f"> {self.listprint(self.inputlist)}", id="inputpreview")
# 渲染当前问题的选项 # 渲染当前问题的选项
with Container(id="btn-container"): with ScrollableContainer(id="btn-container"):
for i in self.ans: for i in self.ans:
h = str(hash(i)) h = str(hash(i))
self.hashmap[h] = i self.hashmap[h] = i

View File

@@ -28,7 +28,7 @@ class Finished(Widget):
def compose(self): def compose(self):
yield Label("本次记忆进程结束", id="finished_msg") yield Label("本次记忆进程结束", id="finished_msg")
yield Label(f"算法数据{'已保存' if self.is_saved else "未能保存"}") yield Label(f"算法数据{'已保存' if self.is_saved else "未能保存"}")
yield Button("返回上一级", id="back-to-menu") yield Button("返回上一级", flat=True, id="back-to-menu")
def on_button_pressed(self, event): def on_button_pressed(self, event):
button_id = event.button.id button_id = event.button.id

View File

@@ -75,7 +75,7 @@ class MCQPuzzle(BasePuzzleWidget):
yield Label(f"当前输入: {self.inputlist}", id="inputpreview") yield Label(f"当前输入: {self.inputlist}", id="inputpreview")
# 渲染当前问题的选项 # 渲染当前问题的选项
with Container(id="btn-container"): with ScrollableContainer(id="btn-container"):
for i in current_options: for i in current_options:
self.hashmap[str(hash(i))] = i self.hashmap[str(hash(i))] = i
btnid = f"sel{str(self.cursor).zfill(3)}-{hash(i)}" btnid = f"sel{str(self.cursor).zfill(3)}-{hash(i)}"

View File

@@ -3,9 +3,9 @@
Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实现是解耦的, 以便后期与其他框架的适配.\ Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实现是解耦的, 以便后期与其他框架的适配.\
得益于 Pickle, 状态机模块支持快照! 得益于 Pickle, 状态机模块支持快照!
## Phaser - 全局阶段控制器 ## Router - 全局阶段控制器
在一次队列记忆流程中, Phaser 代表记忆流程本身. 在一次队列记忆流程中, Router 代表记忆流程本身.
### 属性 ### 属性
@@ -25,7 +25,7 @@ Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实
在初始化 Procession 时, 每个 Procession 被赋予一个不重复的状态属性 作为"阶段状态"属性, 以此标识 Procession 的阶段属性, 因为每个 Procession 管理一个阶段下的复习进程. 在初始化 Procession 时, 每个 Procession 被赋予一个不重复的状态属性 作为"阶段状态"属性, 以此标识 Procession 的阶段属性, 因为每个 Procession 管理一个阶段下的复习进程.
你可以用 state 属性获取 Phaser 的当前状态. 你可以用 state 属性获取 Router 的当前状态.
#### Procession 属性 #### Procession 属性
@@ -34,26 +34,26 @@ Reactor 是 HeurAMS 的记忆流程状态机模块, 和界面 (interface) 的实
### 初始化 ### 初始化
Phaser 接受一个存储 Atom 对象的列表, 作为组织记忆流程的材料\ Router 接受一个存储 Atom 对象的列表, 作为组织记忆流程的材料\
在内部, 根据是否激活将其分为 new_atoms 与 old_atoms.\ 在内部, 根据是否激活将其分为 new_atoms 与 old_atoms.\
因此, 如果你传入的列表中有算法上"无所事事"的 Atom, 流程会对其进行"加强复习" 因此, 如果你传入的列表中有算法上"无所事事"的 Atom, 流程会对其进行"加强复习"
由此创建 Procession. 由此创建 Procession.
### 直接输出呈现形式 ### 直接输出呈现形式
Phaser 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\ Router 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
其以 ascii 表格形式输出, 格式也符合 markdown 表格规范, 你可以直接复制到 markdown.\ 其以 ascii 表格形式输出, 格式也符合 markdown 表格规范, 你可以直接复制到 markdown.\
示例: 示例:
```text ```text
| Type | State | Processions | Current Procession | | Type | State | Processions | Current Procession |
|:-------|:--------|:-----------------------|:---------------------| | :----- | :----- | :--------------------- | :----------------- |
| Phaser | unsure | ['新记忆', '总体复习'] | 新记忆 | | Router | unsure | ['新记忆', '总体复习'] | 新记忆 |
``` ```
| Type | State | Processions | Current Procession | | Type | State | Processions | Current Procession |
|:-------|:--------|:-----------------------|:---------------------| | :----- | :----- | :--------------------- | :----------------- |
| Phaser | unsure | ['新记忆', '总体复习'] | 新记忆 | | Router | unsure | ['新记忆', '总体复习'] | 新记忆 |
### 方法 ### 方法
@@ -85,28 +85,28 @@ Phaser 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
- cursor: 指针, 是当前原子在 atoms 列表中的索引 - cursor: 指针, 是当前原子在 atoms 列表中的索引
- phase: "阶段属性" - phase: "阶段属性"
> 注意区分 "Phaser" 和 "Phase", 其中 "Phase" 表示 "Phaser State". > 注意区分 "Router" 和 "Phase", 其中 "Phase" 表示 "Router State".
- name\_: 阶段的命名 - name\_: 阶段的命名
- state: 当前状态属性 - state: 当前状态属性
### 初始化 ### 初始化
接受一个 atoms 列表与 phase_state (PhaserState Enum 类型)对象 接受一个 atoms 列表与 phase_state (RouterState Enum 类型)对象
### 直接输出呈现形式 ### 直接输出呈现形式
Phaser, 但显示数据有所不同\ Router, 但显示数据有所不同\
Phaser 不同, Procession 显示队列会对过长的 atom.ident 进行缩略(末尾 `>` 符号) Router 不同, Procession 显示队列会对过长的 atom.ident 进行缩略(末尾 `>` 符号)
```text ```text
| Type | Name | State | Progress | Queue | Current Atom | | Type | Name | State | Progress | Queue | Current Atom |
|:-----------|:-------|:--------|:-----------|:-----------------------|:------------------------------| | :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, | | Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
``` ```
| Type | Name | State | Progress | Queue | Current Atom | | Type | Name | State | Progress | Queue | Current Atom |
|:-----------|:-------|:--------|:-----------|:-----------------------|:------------------------------| | :--------- | :----- | :----- | :------- | :--------------------- | :---------------------------- |
| Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, | | Procession | 新记忆 | active | 1 / 2 | ['秦孝公>', '君臣固>'] | 秦孝公据崤函之固, 拥雍州之地, |
### 方法 ### 方法
@@ -142,11 +142,11 @@ Phaser 的 __repr__ 定义了此对象"官方的显示"用作直观的调试.\
判断是否为空队列(传入原子列表对象是空列表的队列) 判断是否为空队列(传入原子列表对象是空列表的队列)
#### get_fission(self) #### get_expander(self)
获取当前原子的 Fission 对象, 用于单原子调度展开 获取当前原子的 Expander 对象, 用于单原子调度展开
## Fission - 单原子调度控制器 ## Expander - 单原子调度控制器
### 属性 ### 属性

View File

@@ -1,8 +1,8 @@
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
from .fission import Fission from .expander import Expander
from .phaser import Phaser from .router import Router
from .procession import Procession from .procession import Procession
from .states import PhaserState, ProcessionState from .states import RouterState, ProcessionState
__all__ = ["PhaserState", "ProcessionState", "Procession", "Fission", "Phaser"] __all__ = ["RouterState", "ProcessionState", "Procession", "Expander", "Router"]

View File

@@ -8,39 +8,39 @@ import heurams.kernel.particles as pt
import heurams.kernel.puzzles as puz import heurams.kernel.puzzles as puz
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
from .states import FissionState, PhaserState from .states import ExpanderState, RouterState
logger = get_logger(__name__) logger = get_logger(__name__)
class Fission(Machine): class Expander(Machine):
"""单原子调度展开器""" """单原子调度展开器"""
def __init__(self, atom: pt.Atom, phase=PhaserState.RECOGNITION): def __init__(self, atom: pt.Atom, phase=RouterState.RECOGNITION):
self.phase = phase self.phase = phase
self.cursor = 0 self.cursor = 0
self.atom = atom self.atom = atom
self.current_puzzle_inf: dict self.current_puzzle_inf: dict
# phase 为 PhaserState 枚举实例, 需要获取其value # phase 为 RouterState 枚举实例, 需要获取其value
phase_value = phase.value phase_value = phase.value
states = [ states = [
{"name": FissionState.EXAMMODE.value}, {"name": ExpanderState.EXAMMODE.value},
{"name": FissionState.RETRONLY.value}, {"name": ExpanderState.RETRONLY.value},
] ]
transitions = [ transitions = [
{ {
"trigger": "finish", "trigger": "finish",
"source": FissionState.EXAMMODE.value, "source": ExpanderState.EXAMMODE.value,
"dest": FissionState.RETRONLY.value, "dest": ExpanderState.RETRONLY.value,
}, },
] ]
if phase == PhaserState.FINISHED: if phase == RouterState.FINISHED:
Machine.__init__( Machine.__init__(
self, self,
states=states, states=states,
transitions=transitions, transitions=transitions,
initial=FissionState.EXAMMODE.value, initial=ExpanderState.EXAMMODE.value,
) )
return return
orbital_schedule = atom.registry["orbital"]["phases"][phase_value] # type: ignore orbital_schedule = atom.registry["orbital"]["phases"][phase_value] # type: ignore
@@ -81,7 +81,7 @@ class Fission(Machine):
self, self,
states=states, states=states,
transitions=transitions, transitions=transitions,
initial=FissionState.EXAMMODE.value, initial=ExpanderState.EXAMMODE.value,
) )
def get_puzzles_inf(self): def get_puzzles_inf(self):
@@ -118,7 +118,7 @@ class Fission(Machine):
dic = [ dic = [
{ {
"Type": "Fission", "Type": "Expander",
"Atom": truncate(self.atom.ident), "Atom": truncate(self.atom.ident),
"State": self.state, "State": self.state,
"Progress": f"{self.cursor + 1} / {len(self.puzzles_inf)}", "Progress": f"{self.cursor + 1} / {len(self.puzzles_inf)}",

View File

@@ -4,8 +4,8 @@ from transitions import Machine
import heurams.kernel.particles as pt import heurams.kernel.particles as pt
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
from .fission import Fission from .expander import Expander
from .states import PhaserState, ProcessionState from .states import RouterState, ProcessionState
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -13,7 +13,7 @@ logger = get_logger(__name__)
class Procession(Machine): class Procession(Machine):
"""队列: 标识单次记忆流程""" """队列: 标识单次记忆流程"""
def __init__(self, atoms: list, phase_state: PhaserState, name_: str = ""): def __init__(self, atoms: list, phase_state: RouterState, name_: str = ""):
logger.debug( logger.debug(
"Procession.__init__: 原子数量=%d, phase=%s, name='%s'", "Procession.__init__: 原子数量=%d, phase=%s, name='%s'",
len(atoms), len(atoms),
@@ -113,8 +113,8 @@ class Procession(Machine):
logger.debug("Procession.is_empty: %s", empty) logger.debug("Procession.is_empty: %s", empty)
return empty return empty
def get_fission(self): def get_expander(self):
return Fission(atom=self.current_atom, phase=self.phase) # type: ignore return Expander(atom=self.current_atom, phase=self.phase) # type: ignore
def __repr__(self, style="pipe", ends="\n"): def __repr__(self, style="pipe", ends="\n"):
from heurams.services.textproc import truncate from heurams.services.textproc import truncate

View File

@@ -5,16 +5,16 @@ from heurams.kernel.particles.placeholders import AtomPlaceholder
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
from .procession import Procession from .procession import Procession
from .states import PhaserState, ProcessionState from .states import RouterState, ProcessionState
logger = get_logger(__name__) logger = get_logger(__name__)
class Phaser(Machine): class Router(Machine):
"""全局调度阶段管理器""" """全局调度阶段管理器"""
def __init__(self, atoms: list[pt.Atom]) -> None: def __init__(self, atoms: list[pt.Atom]) -> None:
logger.debug("Phaser.__init__: 原子数量=%d", len(atoms)) logger.debug("Router.__init__: 原子数量=%d", len(atoms))
self.atoms = atoms self.atoms = atoms
new_atoms = list() new_atoms = list()
@@ -32,50 +32,50 @@ class Phaser(Machine):
# TODO: 改进为基于配置文件的可选复习阶段 # TODO: 改进为基于配置文件的可选复习阶段
if len(old_atoms): if len(old_atoms):
self.processions.append( self.processions.append(
Procession(old_atoms, PhaserState.QUICK_REVIEW, "初始复习") Procession(old_atoms, RouterState.QUICK_REVIEW, "初始复习")
) )
logger.debug("创建初始复习 Procession") logger.debug("创建初始复习 Procession")
if len(new_atoms): if len(new_atoms):
self.processions.append( self.processions.append(
Procession(new_atoms, PhaserState.RECOGNITION, "新记忆") Procession(new_atoms, RouterState.RECOGNITION, "新记忆")
) )
logger.debug("创建新记忆 Procession") logger.debug("创建新记忆 Procession")
self.processions.append(Procession(atoms, PhaserState.FINAL_REVIEW, "总体复习")) self.processions.append(Procession(atoms, RouterState.FINAL_REVIEW, "总体复习"))
logger.debug("创建总体复习 Procession") logger.debug("创建总体复习 Procession")
logger.debug("Phaser 初始化完成, processions 数量=%d", len(self.processions)) logger.debug("Router 初始化完成, processions 数量=%d", len(self.processions))
# 设置transitions状态机 # 设置transitions状态机
states = [ states = [
{"name": PhaserState.UNSURE.value, "on_enter": "on_unsure"}, {"name": RouterState.UNSURE.value, "on_enter": "on_unsure"},
{"name": PhaserState.QUICK_REVIEW.value, "on_enter": "on_quick_review"}, {"name": RouterState.QUICK_REVIEW.value, "on_enter": "on_quick_review"},
{"name": PhaserState.RECOGNITION.value, "on_enter": "on_recognition"}, {"name": RouterState.RECOGNITION.value, "on_enter": "on_recognition"},
{"name": PhaserState.FINAL_REVIEW.value, "on_enter": "on_final_review"}, {"name": RouterState.FINAL_REVIEW.value, "on_enter": "on_final_review"},
{"name": PhaserState.FINISHED.value, "on_enter": "on_finished"}, {"name": RouterState.FINISHED.value, "on_enter": "on_finished"},
] ]
transitions = [ transitions = [
{"trigger": "to_unsure", "source": "*", "dest": PhaserState.UNSURE.value}, {"trigger": "to_unsure", "source": "*", "dest": RouterState.UNSURE.value},
{ {
"trigger": "to_quick_review", "trigger": "to_quick_review",
"source": "*", "source": "*",
"dest": PhaserState.QUICK_REVIEW.value, "dest": RouterState.QUICK_REVIEW.value,
}, },
{ {
"trigger": "to_recognition", "trigger": "to_recognition",
"source": "*", "source": "*",
"dest": PhaserState.RECOGNITION.value, "dest": RouterState.RECOGNITION.value,
}, },
{ {
"trigger": "to_final_review", "trigger": "to_final_review",
"source": "*", "source": "*",
"dest": PhaserState.FINAL_REVIEW.value, "dest": RouterState.FINAL_REVIEW.value,
}, },
{ {
"trigger": "to_finished", "trigger": "to_finished",
"source": "*", "source": "*",
"dest": PhaserState.FINISHED.value, "dest": RouterState.FINISHED.value,
}, },
] ]
@@ -83,45 +83,45 @@ class Phaser(Machine):
self, self,
states=states, states=states,
transitions=transitions, transitions=transitions,
initial=PhaserState.UNSURE.value, initial=RouterState.UNSURE.value,
) )
self.to_unsure() self.to_unsure()
def on_unsure(self): def on_unsure(self):
"""进入UNSURE状态时的回调""" """进入UNSURE状态时的回调"""
logger.debug("Phaser 进入 UNSURE 状态") logger.debug("Router 进入 UNSURE 状态")
def on_quick_review(self): def on_quick_review(self):
"""进入QUICK_REVIEW状态时的回调""" """进入QUICK_REVIEW状态时的回调"""
logger.debug("Phaser 进入 QUICK_REVIEW 状态") logger.debug("Router 进入 QUICK_REVIEW 状态")
def on_recognition(self): def on_recognition(self):
"""进入RECOGNITION状态时的回调""" """进入RECOGNITION状态时的回调"""
logger.debug("Phaser 进入 RECOGNITION 状态") logger.debug("Router 进入 RECOGNITION 状态")
def on_final_review(self): def on_final_review(self):
"""进入FINAL_REVIEW状态时的回调""" """进入FINAL_REVIEW状态时的回调"""
logger.debug("Phaser 进入 FINAL_REVIEW 状态") logger.debug("Router 进入 FINAL_REVIEW 状态")
def on_finished(self): def on_finished(self):
"""进入FINISHED状态时的回调""" """进入FINISHED状态时的回调"""
for i in self.atoms: for i in self.atoms:
i.lock(1) i.lock(1)
i.revise() i.revise()
logger.debug("Phaser 进入 FINISHED 状态") logger.debug("Router 进入 FINISHED 状态")
def current_procession(self): def current_procession(self):
logger.debug("Phaser.current_procession 被调用") logger.debug("Router.current_procession 被调用")
for i in self.processions: for i in self.processions:
i: Procession i: Procession
if i.state != ProcessionState.FINISHED.value: if i.state != ProcessionState.FINISHED.value:
# if i.phase == PhaserState.UNSURE: 此判断是不必要的 因为没有这种 Procession # if i.phase == RouterState.UNSURE: 此判断是不必要的 因为没有这种 Procession
if i.phase == PhaserState.QUICK_REVIEW: if i.phase == RouterState.QUICK_REVIEW:
self.to_quick_review() self.to_quick_review()
elif i.phase == PhaserState.RECOGNITION: elif i.phase == RouterState.RECOGNITION:
self.to_recognition() self.to_recognition()
elif i.phase == PhaserState.FINAL_REVIEW: elif i.phase == RouterState.FINAL_REVIEW:
self.to_final_review() self.to_final_review()
logger.debug("找到未完成的 Procession: phase=%s", i.phase) logger.debug("找到未完成的 Procession: phase=%s", i.phase)
@@ -130,7 +130,7 @@ class Phaser(Machine):
# 所有Procession都已完成 # 所有Procession都已完成
self.to_finished() self.to_finished()
logger.debug("所有 Procession 已完成, 状态设置为 FINISHED") logger.debug("所有 Procession 已完成, 状态设置为 FINISHED")
return Procession([AtomPlaceholder()], PhaserState.FINISHED) return Procession([AtomPlaceholder()], RouterState.FINISHED)
def __repr__(self, style="pipe", ends="\n"): def __repr__(self, style="pipe", ends="\n"):
from tabulate import tabulate as tabu from tabulate import tabulate as tabu
@@ -139,7 +139,7 @@ class Phaser(Machine):
lst = [ lst = [
{ {
"Type": "Phaser", "Type": "Router",
"State": self.state, "State": self.state,
"Processions": list(map(lambda f: (f.name_), self.processions)), "Processions": list(map(lambda f: (f.name_), self.processions)),
"Current Procession": "None" if not self.current_procession() else self.current_procession().name_, # type: ignore "Current Procession": "None" if not self.current_procession() else self.current_procession().name_, # type: ignore

View File

@@ -5,7 +5,7 @@ from heurams.services.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
class PhaserState(Enum): class RouterState(Enum):
UNSURE = "unsure" UNSURE = "unsure"
QUICK_REVIEW = "quick_review" QUICK_REVIEW = "quick_review"
RECOGNITION = "recognition" RECOGNITION = "recognition"
@@ -18,7 +18,7 @@ class ProcessionState(Enum):
FINISHED = "finished" FINISHED = "finished"
class FissionState(Enum): class ExpanderState(Enum):
EXAMMODE = "exammode" EXAMMODE = "exammode"
RETRONLY = "retronly" RETRONLY = "retronly"

View File

@@ -0,0 +1 @@
"""会话记录模块"""