mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-30 23:51:54 +08:00
chore(gdb): add LVAnim wrapper with print_info, print_entries and dump anims command
This commit is contained in:
@@ -34,6 +34,7 @@ from .lvgl import (
|
|||||||
LVEventList,
|
LVEventList,
|
||||||
event_code_name,
|
event_code_name,
|
||||||
EVENT_CODE_NAMES,
|
EVENT_CODE_NAMES,
|
||||||
|
LVAnim,
|
||||||
)
|
)
|
||||||
from . import cmds as cmds
|
from . import cmds as cmds
|
||||||
|
|
||||||
@@ -71,4 +72,5 @@ __all__ = [
|
|||||||
"LVEventList",
|
"LVEventList",
|
||||||
"event_code_name",
|
"event_code_name",
|
||||||
"EVENT_CODE_NAMES",
|
"EVENT_CODE_NAMES",
|
||||||
|
"LVAnim",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,8 +2,14 @@ import gdb
|
|||||||
|
|
||||||
from .core import DumpObj
|
from .core import DumpObj
|
||||||
from .display import DumpDisplayBuf
|
from .display import DumpDisplayBuf
|
||||||
from .misc import InfoStyle, DumpCache, CheckPrefix, CheckCache
|
|
||||||
from .draw import InfoDrawUnit, DumpDrawTask
|
from .draw import InfoDrawUnit, DumpDrawTask
|
||||||
|
from .misc import (
|
||||||
|
InfoStyle,
|
||||||
|
DumpCache,
|
||||||
|
CheckPrefix,
|
||||||
|
CheckCache,
|
||||||
|
DumpAnim,
|
||||||
|
)
|
||||||
from .debugger import Debugger
|
from .debugger import Debugger
|
||||||
from .drivers import Lvglobal
|
from .drivers import Lvglobal
|
||||||
|
|
||||||
@@ -25,6 +31,7 @@ DumpDisplayBuf()
|
|||||||
DumpCache()
|
DumpCache()
|
||||||
CheckPrefix()
|
CheckPrefix()
|
||||||
CheckCache()
|
CheckCache()
|
||||||
|
DumpAnim()
|
||||||
DumpDrawTask()
|
DumpDrawTask()
|
||||||
|
|
||||||
# Infos
|
# Infos
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
from .lv_style import InfoStyle
|
from .lv_style import InfoStyle
|
||||||
from .lv_cache import DumpCache, CheckPrefix, CheckCache
|
from .lv_cache import DumpCache, CheckPrefix, CheckCache
|
||||||
|
from .lv_anim import DumpAnim
|
||||||
|
|
||||||
__all__ = ["InfoStyle", "DumpCache", "CheckPrefix", "CheckCache"]
|
__all__ = [
|
||||||
|
"InfoStyle",
|
||||||
|
"DumpCache",
|
||||||
|
"CheckPrefix",
|
||||||
|
"CheckCache",
|
||||||
|
"DumpAnim",
|
||||||
|
]
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import gdb
|
||||||
|
|
||||||
|
from lvglgdb.lvgl import curr_inst
|
||||||
|
from lvglgdb.lvgl.misc.lv_anim import LVAnim
|
||||||
|
|
||||||
|
|
||||||
|
class DumpAnim(gdb.Command):
|
||||||
|
"""dump all active animations
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
dump anims - list all animations in a table
|
||||||
|
dump anims --detail - print detailed info for each animation
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(DumpAnim, self).__init__(
|
||||||
|
"dump anims", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION
|
||||||
|
)
|
||||||
|
|
||||||
|
def invoke(self, args, from_tty):
|
||||||
|
anims = list(curr_inst().anims())
|
||||||
|
if not anims:
|
||||||
|
print("No active animations.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.strip() == "--detail":
|
||||||
|
for anim in anims:
|
||||||
|
anim.print_info()
|
||||||
|
print()
|
||||||
|
else:
|
||||||
|
LVAnim.print_entries(anims)
|
||||||
@@ -35,6 +35,7 @@ from .misc import (
|
|||||||
LVEventList,
|
LVEventList,
|
||||||
event_code_name,
|
event_code_name,
|
||||||
EVENT_CODE_NAMES,
|
EVENT_CODE_NAMES,
|
||||||
|
LVAnim,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@@ -76,4 +77,5 @@ __all__ = [
|
|||||||
"LVEventList",
|
"LVEventList",
|
||||||
"event_code_name",
|
"event_code_name",
|
||||||
"EVENT_CODE_NAMES",
|
"EVENT_CODE_NAMES",
|
||||||
|
"LVAnim",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -61,6 +61,12 @@ class LVGL:
|
|||||||
|
|
||||||
return LVImageCache(self.lv_global.img_cache)
|
return LVImageCache(self.lv_global.img_cache)
|
||||||
|
|
||||||
|
def anims(self):
|
||||||
|
from ..misc.lv_anim import LVAnim
|
||||||
|
|
||||||
|
for anim in LVList(self.lv_global.anim_state.anim_ll, "lv_anim_t"):
|
||||||
|
yield LVAnim(anim)
|
||||||
|
|
||||||
def image_header_cache(self):
|
def image_header_cache(self):
|
||||||
from ..misc.lv_image_header_cache import LVImageHeaderCache
|
from ..misc.lv_image_header_cache import LVImageHeaderCache
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from .lv_event import (
|
|||||||
event_code_name,
|
event_code_name,
|
||||||
EVENT_CODE_NAMES,
|
EVENT_CODE_NAMES,
|
||||||
)
|
)
|
||||||
|
from .lv_anim import LVAnim
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"LVList",
|
"LVList",
|
||||||
@@ -51,4 +52,5 @@ __all__ = [
|
|||||||
"LVEventList",
|
"LVEventList",
|
||||||
"event_code_name",
|
"event_code_name",
|
||||||
"EVENT_CODE_NAMES",
|
"EVENT_CODE_NAMES",
|
||||||
|
"LVAnim",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
from prettytable import PrettyTable
|
||||||
|
|
||||||
|
from lvglgdb.value import Value, ValueInput
|
||||||
|
|
||||||
|
|
||||||
|
def _fmt_cb(cb: Value) -> str:
|
||||||
|
"""Format a callback pointer as symbol or hex."""
|
||||||
|
addr = int(cb)
|
||||||
|
if not addr:
|
||||||
|
return "-"
|
||||||
|
return cb.format_string(symbols=True, address=True)
|
||||||
|
|
||||||
|
|
||||||
|
class LVAnim(Value):
|
||||||
|
"""LVGL animation wrapper"""
|
||||||
|
|
||||||
|
def __init__(self, anim: ValueInput):
|
||||||
|
super().__init__(Value.normalize(anim, "lv_anim_t"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def var(self) -> Value:
|
||||||
|
return self.super_value("var")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def exec_cb(self) -> Value:
|
||||||
|
return self.super_value("exec_cb")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def start_cb(self) -> Value:
|
||||||
|
return self.super_value("start_cb")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def completed_cb(self) -> Value:
|
||||||
|
return self.super_value("completed_cb")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deleted_cb(self) -> Value:
|
||||||
|
return self.super_value("deleted_cb")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path_cb(self) -> Value:
|
||||||
|
return self.super_value("path_cb")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user_data(self) -> Value:
|
||||||
|
return self.super_value("user_data")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def start_value(self) -> int:
|
||||||
|
return int(self.super_value("start_value"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_value(self) -> int:
|
||||||
|
return int(self.super_value("current_value"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def end_value(self) -> int:
|
||||||
|
return int(self.super_value("end_value"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def duration(self) -> int:
|
||||||
|
return int(self.super_value("duration"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def act_time(self) -> int:
|
||||||
|
return int(self.super_value("act_time"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reverse_duration(self) -> int:
|
||||||
|
return int(self.super_value("reverse_duration"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reverse_delay(self) -> int:
|
||||||
|
return int(self.super_value("reverse_delay"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def repeat_delay(self) -> int:
|
||||||
|
return int(self.super_value("repeat_delay"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def repeat_cnt(self) -> int:
|
||||||
|
return int(self.super_value("repeat_cnt"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_paused(self) -> bool:
|
||||||
|
return bool(int(self.super_value("is_paused")))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reverse_play_in_progress(self) -> bool:
|
||||||
|
return bool(int(self.super_value("reverse_play_in_progress")))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def early_apply(self) -> bool:
|
||||||
|
return bool(int(self.super_value("early_apply")))
|
||||||
|
|
||||||
|
def _status_str(self) -> str:
|
||||||
|
"""Short status string for table display."""
|
||||||
|
if self.is_paused:
|
||||||
|
return "paused"
|
||||||
|
if self.reverse_play_in_progress:
|
||||||
|
return "reverse"
|
||||||
|
return "running"
|
||||||
|
|
||||||
|
def print_info(self):
|
||||||
|
"""Print detailed info for a single animation."""
|
||||||
|
print(f"Animation @{hex(int(self.address))}")
|
||||||
|
print(f" var = {self.var}")
|
||||||
|
print(f" exec_cb = {_fmt_cb(self.exec_cb)}")
|
||||||
|
print(f" path_cb = {_fmt_cb(self.path_cb)}")
|
||||||
|
print(f" start_cb = {_fmt_cb(self.start_cb)}")
|
||||||
|
print(f" completed_cb = {_fmt_cb(self.completed_cb)}")
|
||||||
|
print(f" deleted_cb = {_fmt_cb(self.deleted_cb)}")
|
||||||
|
print(f" user_data = {self.user_data}")
|
||||||
|
print(f" value = {self.start_value} -> {self.current_value} -> {self.end_value}")
|
||||||
|
print(f" duration = {self.duration}ms act_time={self.act_time}ms")
|
||||||
|
repeat = "inf" if self.repeat_cnt == 0xFFFF else str(self.repeat_cnt)
|
||||||
|
print(f" repeat = {repeat} repeat_delay={self.repeat_delay}ms")
|
||||||
|
print(f" reverse = dur={self.reverse_duration}ms delay={self.reverse_delay}ms")
|
||||||
|
print(f" status = {self._status_str()} early_apply={self.early_apply}")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def print_entries(anims):
|
||||||
|
"""Print animations as a PrettyTable."""
|
||||||
|
table = PrettyTable()
|
||||||
|
table.field_names = [
|
||||||
|
"#",
|
||||||
|
"var",
|
||||||
|
"exec_cb",
|
||||||
|
"value(start/cur/end)",
|
||||||
|
"duration",
|
||||||
|
"act_time",
|
||||||
|
"repeat",
|
||||||
|
"status",
|
||||||
|
]
|
||||||
|
table.align = "l"
|
||||||
|
|
||||||
|
for i, anim in enumerate(anims):
|
||||||
|
cb_str = _fmt_cb(anim.exec_cb)
|
||||||
|
repeat = "inf" if anim.repeat_cnt == 0xFFFF else str(anim.repeat_cnt)
|
||||||
|
value_str = f"{anim.start_value}/{anim.current_value}/{anim.end_value}"
|
||||||
|
table.add_row(
|
||||||
|
[
|
||||||
|
i,
|
||||||
|
anim.var,
|
||||||
|
cb_str,
|
||||||
|
value_str,
|
||||||
|
f"{anim.duration}ms",
|
||||||
|
f"{anim.act_time}ms",
|
||||||
|
repeat,
|
||||||
|
anim._status_str(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
if not table.rows:
|
||||||
|
print("No active animations.")
|
||||||
|
else:
|
||||||
|
print(table)
|
||||||
Reference in New Issue
Block a user