refactor(debug-mod): 使用原生 System 替换 QuMod
删除未使用的大型 QuMod 加载框架,改为直接注册客户端和服务端 System,并显式管理按键监听、输出包装与双端销毁。 IPC 网络线程仅负责收包,所有 ModAPI 回调由游戏线程 Update 派发,同时补充断线重连、分帧读取和幂等关闭。
This commit is contained in:
98
debug_mod/DEBUG_ENV_SCRIPT/Lifecycle.py
Normal file
98
debug_mod/DEBUG_ENV_SCRIPT/Lifecycle.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import threading
|
||||
|
||||
|
||||
_OUTPUT_PREFIX = "[Python] "
|
||||
_ACTIVE_SYSTEMS = set()
|
||||
_STATE_LOCK = threading.Lock()
|
||||
_ORIGINAL_STDOUT = None
|
||||
_ORIGINAL_STDERR = None
|
||||
|
||||
|
||||
class OutputWrapper(object):
|
||||
_emod_cli_debug_wrapper = True
|
||||
|
||||
def __init__(self, stream):
|
||||
self.stream = stream
|
||||
self.lock = threading.Lock()
|
||||
self.buffer = []
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.stream, name)
|
||||
|
||||
def write(self, data):
|
||||
with self.lock:
|
||||
parts = data.splitlines(True)
|
||||
for part in parts:
|
||||
if part.endswith("\n"):
|
||||
if self.buffer:
|
||||
line = "".join(self.buffer) + part
|
||||
self.buffer = []
|
||||
else:
|
||||
line = part
|
||||
self.stream.write(_OUTPUT_PREFIX + line)
|
||||
else:
|
||||
self.buffer.append(part)
|
||||
|
||||
def close(self):
|
||||
self.flush()
|
||||
return self.stream.close()
|
||||
|
||||
def flush(self):
|
||||
with self.lock:
|
||||
if self.buffer:
|
||||
self.stream.write(_OUTPUT_PREFIX + "".join(self.buffer))
|
||||
self.buffer = []
|
||||
self.stream.flush()
|
||||
|
||||
def writelines(self, lines):
|
||||
for line in lines:
|
||||
self.write(line)
|
||||
|
||||
def fileno(self):
|
||||
return self.stream.fileno()
|
||||
|
||||
|
||||
def _install_output_wrapper_locked():
|
||||
global _ORIGINAL_STDOUT, _ORIGINAL_STDERR
|
||||
|
||||
if not getattr(sys.stdout, "_emod_cli_debug_wrapper", False):
|
||||
_ORIGINAL_STDOUT = sys.stdout
|
||||
sys.stdout = OutputWrapper(sys.stdout)
|
||||
elif _ORIGINAL_STDOUT is None:
|
||||
_ORIGINAL_STDOUT = getattr(sys.stdout, "stream")
|
||||
|
||||
if not getattr(sys.stderr, "_emod_cli_debug_wrapper", False):
|
||||
_ORIGINAL_STDERR = sys.stderr
|
||||
sys.stderr = OutputWrapper(sys.stderr)
|
||||
elif _ORIGINAL_STDERR is None:
|
||||
_ORIGINAL_STDERR = getattr(sys.stderr, "stream")
|
||||
|
||||
|
||||
def install_output_wrapper():
|
||||
with _STATE_LOCK:
|
||||
_install_output_wrapper_locked()
|
||||
|
||||
|
||||
def activate(system):
|
||||
with _STATE_LOCK:
|
||||
_install_output_wrapper_locked()
|
||||
_ACTIVE_SYSTEMS.add(system)
|
||||
|
||||
|
||||
def deactivate(system):
|
||||
global _ORIGINAL_STDOUT, _ORIGINAL_STDERR
|
||||
|
||||
with _STATE_LOCK:
|
||||
_ACTIVE_SYSTEMS.discard(system)
|
||||
if _ACTIVE_SYSTEMS:
|
||||
return
|
||||
if _ORIGINAL_STDOUT is None or _ORIGINAL_STDERR is None:
|
||||
return
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
sys.stdout = _ORIGINAL_STDOUT
|
||||
sys.stderr = _ORIGINAL_STDERR
|
||||
_ORIGINAL_STDOUT = None
|
||||
_ORIGINAL_STDERR = None
|
||||
Reference in New Issue
Block a user