fix(vpui): 建窗失败改为可见错误上报;Scene3D 加分步诊断打点
背景:Tk.mainloop 的循环条件是 window.is_active(win_id),而 is_active 对 win_id < 0 直接返回 0 ⇒ 一旦 create_window 失败,app 一次循环都不进、一句日志都不打就 process.exit(0)(现场:Scene3D spawn 后静默退出,「没有窗口」就是这么来的)。改动:window.vp 的 _attach / _connect / create_window 四个失败返回点补 [win] 错误上报(open 失败 / mmap 失败 / desk 未就绪超时 / 请求环压入失败 / CREATED 超时),这些是错误可见性而非临时噪音,长期保留;Scene3D/main.vp 加 _dbg 分步打点(start / tk ok / canvas ok / scene ok / geometry 后的 win_id 与 buf / 渲染线程 / mainloop 返回),用于定位它到底死在哪一步,定位完成后撤除。
This commit is contained in:
1 parent
2dacfa85fb
commit
2f20cf42aa
2 files changed
+28
-1
No files matched your search
@@ -1,8 +1,10 @@
|
||||
import vpsdk.window as window
|
||||
import vpsdk.process as process
|
||||
import vpsdk.vpui as vpui
|
||||
import vpsdk.devfs as devfs
|
||||
import string
|
||||
from stdint import *
|
||||
import viperlib
|
||||
import gfx
|
||||
|
||||
define SCENE_W = 640
|
||||
@@ -20,6 +22,11 @@ _time_val: float = float(0.0)
|
||||
# (x 变大后相邻采样点的相位差被量化 ⇒ 曲线塌成一条平线、热力图颜色失去层次)。
|
||||
define TIME_WRAP = float(12.566370614359172)
|
||||
|
||||
def _dbg(msg: const str):
|
||||
# 【诊断·临时】与 explorer 同路径的串口输出。app 在建窗失败时会**静默退出**
|
||||
# (Tk.mainloop 的循环条件是 win_id 有效,win_id=-1 时一次都不循环),所以必须分步打点。
|
||||
devfs.serial_puts(msg)
|
||||
|
||||
def _render_thread(arg: t.CPtr):
|
||||
global _time_val
|
||||
root: vpui.Tk* = _root_ptr
|
||||
@@ -34,13 +41,16 @@ def _render_thread(arg: t.CPtr):
|
||||
|
||||
@__attribute__(section(".text.startup"), aligned(16))
|
||||
export def _start() -> int:
|
||||
_dbg("[s3d] start\n")
|
||||
root: vpui.Tk = vpui.Tk()
|
||||
_dbg("[s3d] tk ok\n")
|
||||
root.title("3D Scene")
|
||||
root.set_style(window.STYLE_WIN11)
|
||||
root.bg_color = uint32(0x0F0F19)
|
||||
master: vpui.Tk* = &root
|
||||
|
||||
canvas: vpui.FBCanvas = vpui.FBCanvas(master, SCENE_W, SCENE_H)
|
||||
_dbg("[s3d] canvas ok\n")
|
||||
root.pack(0, vpui.PACK_TOP, vpui.FILL_BOTH, 1, 0, 0)
|
||||
|
||||
zbuf: float* = &_zbuf_mem
|
||||
@@ -51,8 +61,13 @@ export def _start() -> int:
|
||||
canvas.set_fb(fb, SCENE_W, SCENE_H)
|
||||
|
||||
s3d: gfx.Scene3D = gfx.Scene3D(fb, zbuf, SCENE_W, SCENE_H)
|
||||
_dbg("[s3d] scene ok\n")
|
||||
|
||||
root.geometry(100, 30, SCENE_W, SCENE_H + 32)
|
||||
_wbuf: [128]char
|
||||
viperlib.snprintf(&_wbuf, 128, "[s3d] geometry win_id=%d buf=0x%lx\n",
|
||||
root.win_id, uint64(root.buf))
|
||||
_dbg(&_wbuf)
|
||||
|
||||
global _root_ptr, _canvas_ptr, _s3d_ptr
|
||||
|
||||
@@ -61,8 +76,10 @@ export def _start() -> int:
|
||||
_s3d_ptr = &s3d
|
||||
|
||||
process.thread_create(_render_thread, None)
|
||||
_dbg("[s3d] render thread created\n")
|
||||
|
||||
root.mainloop()
|
||||
_dbg("[s3d] mainloop returned\n")
|
||||
|
||||
process.exit(0)
|
||||
return 0
|
||||
+11
-1
@@ -1,6 +1,7 @@
|
||||
import vpsdk.desk as desk
|
||||
import vpsdk.process as process
|
||||
import vpsdk.stdlib as stdlib # 不能删:app 的裸名 malloc 靠它把 stdlib 拉进链接图
|
||||
import vpsdk.devfs as devfs
|
||||
import string
|
||||
|
||||
|
||||
@@ -81,6 +82,7 @@ def _attach() -> int:
|
||||
if _state < 0: return -1
|
||||
b: uint64 = desk.desk_map(_fd)
|
||||
if b == 0:
|
||||
devfs.serial_puts("[win] desk mmap FAILED\n")
|
||||
_state = -1
|
||||
return -1
|
||||
i: int = 0
|
||||
@@ -88,6 +90,7 @@ def _attach() -> int:
|
||||
process.yield_cpu()
|
||||
i += 1
|
||||
if desk.desk_ready(b) == 0:
|
||||
devfs.serial_puts("[win] desk not ready (attach timeout)\n")
|
||||
_state = -1
|
||||
return -1
|
||||
_base = b
|
||||
@@ -101,6 +104,7 @@ def _connect() -> int:
|
||||
if _state < 0: return -1
|
||||
fd: int = desk.desk_open()
|
||||
if fd < 0:
|
||||
devfs.serial_puts("[win] open /dev/desk FAILED\n")
|
||||
_state = -1
|
||||
return -1
|
||||
_fd = fd
|
||||
@@ -132,9 +136,14 @@ def _slot(win: int) -> desk.WinSlot*:
|
||||
|
||||
|
||||
def create_window(x: int, y: int, w: int, h: int, title: const str, style: int) -> int:
|
||||
if _connect() != 0: return -1
|
||||
# 建窗失败必须**可见**:Tk.mainloop 的循环条件是 window.is_active(win_id),win_id = -1
|
||||
# 时一次都不循环就返回 ⇒ app 一句日志都没有就 exit(现场:Scene3D spawn 后静默退出)。
|
||||
if _connect() != 0:
|
||||
devfs.serial_puts("[win] create_window: connect FAILED\n")
|
||||
return -1
|
||||
if _my_pid < 0: return -1
|
||||
if _send(uint32(desk.DESK_REQ_CREATE), 0, x, y, w, h, title) != 0:
|
||||
devfs.serial_puts("[win] create_window: request ring push FAILED\n")
|
||||
return -1
|
||||
# 等 CREATED 答复(win_id 由 explorer 分配)。建窗通常在 app 初始化阶段、
|
||||
# 事件环是空的;这期间若弹到非 CREATED 事件(属于本进程的其它窗口输入)就丢弃,
|
||||
@@ -146,6 +155,7 @@ def create_window(x: int, y: int, w: int, h: int, title: const str, style: int)
|
||||
return _evt.a
|
||||
process.yield_cpu()
|
||||
i += 1
|
||||
devfs.serial_puts("[win] create_window: CREATED timeout\n")
|
||||
return -1
|
||||
|
||||
def get_winbuf(win_id: int) -> uint32*:
|
||||
|
||||
Reference in new issue
Block a user