feat(debug): 支持网易 Minecraft 调试启动
新增 debug 子命令,自动准备开发世界、注册内置调试 MOD,并将项目行为包和资源包链接到网易运行目录,方便启动游戏后直接进入调试世界。 调试 MOD 资源随仓库一起嵌入,避免依赖本机绝对路径;Windows junction 写入剥离 verbatim 前缀后的 DOS 路径,保证 Minecraft 能正确读取链接包。
This commit is contained in:
185
debug_mod/DEBUG_ENV_SCRIPT/QuModLibs/Systems/Loader/Client.py
Normal file
185
debug_mod/DEBUG_ENV_SCRIPT/QuModLibs/Systems/Loader/Client.py
Normal file
@@ -0,0 +1,185 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import mod.client.extraClientApi as clientApi
|
||||
from ...Util import errorPrint, TRY_EXEC_FUN, getObjectPathName
|
||||
from ...IN import RuntimeService
|
||||
from .SharedRes import (
|
||||
CallObjData,
|
||||
EasyListener,
|
||||
SERVER_CALL_EVENT,
|
||||
CLIENT_CALL_EVENT,
|
||||
NAMESPACE,
|
||||
SYSTEMNAME
|
||||
)
|
||||
lambda: "By Zero123"
|
||||
ClientSystem = clientApi.GetClientSystemCls()
|
||||
engineSpaceName, engineSystemName = clientApi.GetEngineNamespace(), clientApi.GetEngineSystemName()
|
||||
|
||||
def clientImportModule(filePath):
|
||||
""" 客户端文件导入 """
|
||||
return clientApi.ImportModule(filePath)
|
||||
|
||||
class LoaderSystem(ClientSystem, EasyListener):
|
||||
""" QuMod加载器系统
|
||||
加载器承担了系统文件的加载以及事件监听 系统通信
|
||||
"""
|
||||
@staticmethod
|
||||
def getSystem():
|
||||
# type: () -> LoaderSystem
|
||||
""" 获取加载器系统 如果未注册将会自动注册并返回 """
|
||||
system = clientApi.GetSystem(NAMESPACE, SYSTEMNAME)
|
||||
if system:
|
||||
return system
|
||||
return clientApi.RegisterSystem(NAMESPACE, SYSTEMNAME, LoaderSystem.__module__ + "." + LoaderSystem.__name__)
|
||||
|
||||
_REG_CALL_FUNCS = {}
|
||||
_REG_STATIC_LISTEN_FUNCS = {}
|
||||
_DY_IMP_CACHE = {}
|
||||
|
||||
@staticmethod
|
||||
def dyImportModule(modulePath):
|
||||
if not modulePath in LoaderSystem._DY_IMP_CACHE:
|
||||
LoaderSystem._DY_IMP_CACHE[modulePath] = clientImportModule(modulePath)
|
||||
return LoaderSystem._DY_IMP_CACHE[modulePath]
|
||||
|
||||
@staticmethod
|
||||
def REG_DESTROY_CALL_FUNC(func=lambda: None):
|
||||
""" 适用于静态函数的注册销毁时回调 """
|
||||
keyName = getObjectPathName(func)
|
||||
if not keyName in LoaderSystem._REG_CALL_FUNCS:
|
||||
# callFunc = lambda: LoaderSystem._REG_CALL_FUNCS[keyName]()
|
||||
LoaderSystem.getSystem().addDestroyCall(func)
|
||||
LoaderSystem._REG_CALL_FUNCS[keyName] = func
|
||||
|
||||
@staticmethod
|
||||
def REG_STATIC_LISTEN_FUNC(eventName="", funcObj=lambda: None):
|
||||
""" 注册静态监听函数 """
|
||||
keyName = getObjectPathName(funcObj)
|
||||
if not keyName in LoaderSystem._REG_STATIC_LISTEN_FUNCS:
|
||||
# callFunc = lambda *args: LoaderSystem._REG_STATIC_LISTEN_FUNCS[keyName](*args)
|
||||
LoaderSystem.getSystem().nativeStaticListen(eventName, funcObj)
|
||||
LoaderSystem._REG_STATIC_LISTEN_FUNCS[keyName] = funcObj
|
||||
|
||||
def __init__(self, namespace, systemName):
|
||||
ClientSystem.__init__(self, namespace, systemName)
|
||||
EasyListener.__init__(self)
|
||||
RuntimeService._clientStarting = True
|
||||
self.namespace = namespace
|
||||
self.systemName = systemName
|
||||
self._systemList = RuntimeService._clientSystemList
|
||||
self._initState = False
|
||||
self._regInitState = False
|
||||
self._waitTime = 0.0
|
||||
self._callQueue = [] # type: list[CallObjData]
|
||||
self._onDestroyCall = []
|
||||
self._onDestroyCall_LAST = []
|
||||
""" 后置销毁触发 通常是内部使用确保在用户业务之后执行 """
|
||||
self._initSystemListen()
|
||||
self.systemInit()
|
||||
|
||||
def _initSystemListen(self):
|
||||
self.ListenForEvent(NAMESPACE, SYSTEMNAME, SERVER_CALL_EVENT, self, self._systemCallListener)
|
||||
|
||||
def _easyListenForEvent(self, eventName="", parent=None, func=lambda: None):
|
||||
return self.ListenForEvent(engineSpaceName, engineSystemName, eventName, parent, func)
|
||||
|
||||
def _easyUnListenForEvent(self, eventName="", parent=None, func=lambda: None):
|
||||
return self.UnListenForEvent(engineSpaceName, engineSystemName, eventName, parent, func)
|
||||
|
||||
def sendCall(self, apiName="", args=tuple(), kwargs=dict()):
|
||||
""" 向服务器端请求调用 """
|
||||
sendData = self._packageCallArgs(apiName, args, kwargs)
|
||||
self.NotifyToServer(CLIENT_CALL_EVENT, sendData)
|
||||
|
||||
def addDestroyCall(self, funObj, doubleCheck=True):
|
||||
""" 添加销毁触发 """
|
||||
if doubleCheck and funObj in self._onDestroyCall:
|
||||
return
|
||||
self._onDestroyCall.append(funObj)
|
||||
|
||||
def removeDestroyCall(self, funObj):
|
||||
""" 移除销毁触发 """
|
||||
if funObj in self._onDestroyCall:
|
||||
self._onDestroyCall.remove(funObj)
|
||||
|
||||
def Destroy(self):
|
||||
# 用户级destroy执行
|
||||
for obj in self._onDestroyCall:
|
||||
TRY_EXEC_FUN(obj)
|
||||
self._onDestroyCall = []
|
||||
# 高权限destroy执行
|
||||
for obj in self._onDestroyCall_LAST:
|
||||
TRY_EXEC_FUN(obj)
|
||||
self._onDestroyCall_LAST = []
|
||||
RuntimeService._clientStarting = False
|
||||
|
||||
def getSystemList(self):
|
||||
# type: () -> list[tuple[str, str | None]]
|
||||
return self._systemList
|
||||
|
||||
def removeCallObjByUid(self, _uid = ""):
|
||||
""" 尝试移除特定uid的callObj 如果存在 """
|
||||
for i, obj in enumerate(self._callQueue):
|
||||
if obj._uid == _uid:
|
||||
del self._callQueue[i]
|
||||
break
|
||||
|
||||
def proxyRegister(self, funcObj):
|
||||
""" 代理注册 """
|
||||
from functools import wraps
|
||||
@wraps(funcObj)
|
||||
def newFun(*args, **kwargs):
|
||||
callObj = CallObjData(funcObj, args, kwargs)
|
||||
self._callQueue.append(callObj)
|
||||
return callObj
|
||||
return newFun
|
||||
|
||||
def unsafeUpdate(self, callObjData):
|
||||
# type: (CallObjData) -> bool
|
||||
""" 不安全的强制刷新 """
|
||||
if callObjData in self._callQueue:
|
||||
self._callQueue.remove(callObjData)
|
||||
callObjData.callObj(*callObjData.args, **callObjData.kwargs)
|
||||
return True
|
||||
return False
|
||||
|
||||
def Update(self):
|
||||
self.regSystemInit()
|
||||
if self._callQueue:
|
||||
for obj in self._callQueue:
|
||||
try:
|
||||
obj.callObj(*obj.args, **obj.kwargs)
|
||||
except Exception as e:
|
||||
errorPrint("{} call执行异常 {}".format(obj.callObj, e))
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
self._callQueue = []
|
||||
return ClientSystem.Update(self)
|
||||
|
||||
def systemInit(self):
|
||||
self._initState = True
|
||||
|
||||
def regSystemInit(self):
|
||||
""" 系统信息注册初始化 """
|
||||
if self._regInitState:
|
||||
return
|
||||
# 加载Before事件
|
||||
for funcObj in RuntimeService._clientLoadBefore:
|
||||
TRY_EXEC_FUN(funcObj)
|
||||
# 因历史原因systemName已废弃 此处仅兼容旧版项目
|
||||
for path, _ in self._systemList:
|
||||
sysObj = None
|
||||
try:
|
||||
sysObj = clientImportModule(path)
|
||||
if sysObj == None:
|
||||
errorPrint("[客户端] 系统文件加载失败(API异常): {}".format(path))
|
||||
continue
|
||||
except Exception as e:
|
||||
errorPrint("[客户端] 系统文件错误: {} ({})".format(path, e))
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
continue
|
||||
# if not systemName: systemName = uuid4().hex
|
||||
self._regInitState = True
|
||||
# 加载Finish事件
|
||||
for funcObj in RuntimeService._clientLoadFinish:
|
||||
TRY_EXEC_FUN(funcObj)
|
||||
200
debug_mod/DEBUG_ENV_SCRIPT/QuModLibs/Systems/Loader/Server.py
Normal file
200
debug_mod/DEBUG_ENV_SCRIPT/QuModLibs/Systems/Loader/Server.py
Normal file
@@ -0,0 +1,200 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import mod.server.extraServerApi as serverApi
|
||||
from ...Util import errorPrint, TRY_EXEC_FUN, getObjectPathName
|
||||
from ...IN import RuntimeService
|
||||
from .SharedRes import (
|
||||
CallObjData,
|
||||
EasyListener,
|
||||
SERVER_CALL_EVENT,
|
||||
CLIENT_CALL_EVENT,
|
||||
NAMESPACE,
|
||||
SYSTEMNAME
|
||||
)
|
||||
lambda: "By Zero123"
|
||||
ServerSystem = serverApi.GetServerSystemCls()
|
||||
engineSpaceName, engineSystemName = serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName()
|
||||
|
||||
def serverImportModule(filePath):
|
||||
""" 服务端文件导入 """
|
||||
return serverApi.ImportModule(filePath)
|
||||
|
||||
class LoaderSystem(ServerSystem, EasyListener):
|
||||
""" QuMod加载器系统
|
||||
加载器承担了系统文件的加载以及事件监听 系统通信
|
||||
"""
|
||||
@staticmethod
|
||||
def getSystem():
|
||||
# type: () -> LoaderSystem
|
||||
""" 获取加载器系统 如果未注册将会自动注册并返回 """
|
||||
system = serverApi.GetSystem(NAMESPACE, SYSTEMNAME)
|
||||
if system:
|
||||
return system
|
||||
return serverApi.RegisterSystem(NAMESPACE, SYSTEMNAME, LoaderSystem.__module__ + "." + LoaderSystem.__name__)
|
||||
|
||||
_REG_CALL_FUNCS = {}
|
||||
_REG_STATIC_LISTEN_FUNCS = {}
|
||||
_DY_IMP_CACHE = {}
|
||||
|
||||
@staticmethod
|
||||
def dyImportModule(modulePath):
|
||||
if not modulePath in LoaderSystem._DY_IMP_CACHE:
|
||||
LoaderSystem._DY_IMP_CACHE[modulePath] = serverImportModule(modulePath)
|
||||
return LoaderSystem._DY_IMP_CACHE[modulePath]
|
||||
|
||||
@staticmethod
|
||||
def REG_DESTROY_CALL_FUNC(func=lambda: None):
|
||||
""" 适用于静态函数的注册销毁时回调 """
|
||||
keyName = getObjectPathName(func)
|
||||
if not keyName in LoaderSystem._REG_CALL_FUNCS:
|
||||
# callFunc = lambda: LoaderSystem._REG_CALL_FUNCS[keyName]()
|
||||
LoaderSystem.getSystem().addDestroyCall(func)
|
||||
LoaderSystem._REG_CALL_FUNCS[keyName] = func
|
||||
|
||||
@staticmethod
|
||||
def REG_STATIC_LISTEN_FUNC(eventName="", funcObj=lambda: None):
|
||||
""" 注册静态监听函数 """
|
||||
keyName = getObjectPathName(funcObj)
|
||||
if not keyName in LoaderSystem._REG_STATIC_LISTEN_FUNCS:
|
||||
# callFunc = lambda *args: LoaderSystem._REG_STATIC_LISTEN_FUNCS[keyName](*args)
|
||||
LoaderSystem.getSystem().nativeStaticListen(eventName, funcObj)
|
||||
LoaderSystem._REG_STATIC_LISTEN_FUNCS[keyName] = funcObj
|
||||
|
||||
def __init__(self, namespace, systemName):
|
||||
ServerSystem.__init__(self, namespace, systemName)
|
||||
EasyListener.__init__(self)
|
||||
RuntimeService._serverStarting = True
|
||||
self.namespace = namespace
|
||||
self.systemName = systemName
|
||||
self.rpcPlayerId = None
|
||||
self._systemList = RuntimeService._serverSystemList
|
||||
self._initState = False
|
||||
self._regInitState = False
|
||||
self._waitTime = 0.0
|
||||
self._onDestroyCall = []
|
||||
self._onDestroyCall_LAST = []
|
||||
""" 后置销毁触发 通常是内部使用确保在用户业务之后执行 """
|
||||
self._initSystemListen()
|
||||
self.systemInit()
|
||||
|
||||
def _systemCallListenerHook(self, args={}):
|
||||
target = "__id__"
|
||||
if target in args:
|
||||
self.rpcPlayerId = args[target]
|
||||
return
|
||||
self.rpcPlayerId = None
|
||||
|
||||
def _initSystemListen(self):
|
||||
self.ListenForEvent(NAMESPACE, SYSTEMNAME, CLIENT_CALL_EVENT, self, self._systemCallListener)
|
||||
|
||||
def _easyListenForEvent(self, eventName="", parent=None, func=lambda: None):
|
||||
return self.ListenForEvent(engineSpaceName, engineSystemName, eventName, parent, func)
|
||||
|
||||
def _easyUnListenForEvent(self, eventName="", parent=None, func=lambda: None):
|
||||
return self.UnListenForEvent(engineSpaceName, engineSystemName, eventName, parent, func)
|
||||
|
||||
def sendCall(self, playerId="", apiName="", args=tuple(), kwargs=dict()):
|
||||
""" 向指定玩家客户端请求调用 当playerId声明为*时代表全体玩家 """
|
||||
sendData = self._packageCallArgs(apiName, args, kwargs)
|
||||
if playerId == "*":
|
||||
self.BroadcastToAllClient(SERVER_CALL_EVENT, sendData)
|
||||
return
|
||||
self.NotifyToClient(playerId, SERVER_CALL_EVENT, sendData)
|
||||
|
||||
def sendMultiClientsCall(self, playerListId=[], apiName="", args=tuple(), kwargs=dict()):
|
||||
""" 批量向多个玩家客户端发包相同的调用数据 """
|
||||
sendData = self._packageCallArgs(apiName, args, kwargs)
|
||||
self.NotifyToMultiClients(playerListId, SERVER_CALL_EVENT, sendData)
|
||||
|
||||
def addDestroyCall(self, funObj, doubleCheck=True):
|
||||
""" 添加销毁触发 """
|
||||
if doubleCheck and funObj in self._onDestroyCall:
|
||||
return
|
||||
self._onDestroyCall.append(funObj)
|
||||
|
||||
def removeDestroyCall(self, funObj):
|
||||
""" 移除销毁触发 """
|
||||
if funObj in self._onDestroyCall:
|
||||
self._onDestroyCall.remove(funObj)
|
||||
|
||||
def Destroy(self):
|
||||
# 用户级destroy执行
|
||||
for obj in self._onDestroyCall:
|
||||
TRY_EXEC_FUN(obj)
|
||||
self._onDestroyCall = []
|
||||
# 高权限destroy执行
|
||||
for obj in self._onDestroyCall_LAST:
|
||||
TRY_EXEC_FUN(obj)
|
||||
self._onDestroyCall_LAST = []
|
||||
RuntimeService._serverStarting = False
|
||||
|
||||
def getSystemList(self):
|
||||
# type: () -> list[tuple[str, str | None]]
|
||||
return self._systemList
|
||||
|
||||
def removeCallObjByUid(self, _uid = ""):
|
||||
""" 尝试移除特定uid的callObj 如果存在 """
|
||||
for i, obj in enumerate(self._callQueue):
|
||||
if obj._uid == _uid:
|
||||
del self._callQueue[i]
|
||||
break
|
||||
|
||||
def proxyRegister(self, funcObj):
|
||||
""" 代理注册 """
|
||||
from functools import wraps
|
||||
@wraps(funcObj)
|
||||
def newFun(*args, **kwargs):
|
||||
callObj = CallObjData(funcObj, args, kwargs)
|
||||
self._callQueue.append(callObj)
|
||||
return callObj
|
||||
return newFun
|
||||
|
||||
def unsafeUpdate(self, callObjData):
|
||||
# type: (CallObjData) -> bool
|
||||
""" 不安全的强制刷新 """
|
||||
if callObjData in self._callQueue:
|
||||
self._callQueue.remove(callObjData)
|
||||
callObjData.callObj(*callObjData.args, **callObjData.kwargs)
|
||||
return True
|
||||
return False
|
||||
|
||||
def Update(self):
|
||||
self.regSystemInit()
|
||||
if self._callQueue:
|
||||
for obj in self._callQueue:
|
||||
try:
|
||||
obj.callObj(*obj.args, **obj.kwargs)
|
||||
except Exception as e:
|
||||
errorPrint("{} call执行异常 {}".format(obj.callObj, e))
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
self._callQueue = []
|
||||
return ServerSystem.Update(self)
|
||||
|
||||
def systemInit(self):
|
||||
self._initState = True
|
||||
|
||||
def regSystemInit(self):
|
||||
""" 系统信息注册初始化 """
|
||||
if self._regInitState:
|
||||
return
|
||||
# 加载Before事件
|
||||
for funcObj in RuntimeService._serverLoadBefore:
|
||||
TRY_EXEC_FUN(funcObj)
|
||||
# 因历史原因systemName已废弃 此处仅兼容旧版项目
|
||||
for path, _ in self._systemList:
|
||||
sysObj = None
|
||||
try:
|
||||
sysObj = serverImportModule(path)
|
||||
if sysObj == None:
|
||||
errorPrint("[服务端] 系统文件加载失败(API异常): {}".format(path))
|
||||
continue
|
||||
except Exception as e:
|
||||
errorPrint("[服务端] 系统文件错误: {} ({})".format(path, e))
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
continue
|
||||
# if not systemName: systemName = uuid4().hex
|
||||
self._regInitState = True
|
||||
# 加载Finish事件
|
||||
for funcObj in RuntimeService._serverLoadFinish:
|
||||
TRY_EXEC_FUN(funcObj)
|
||||
175
debug_mod/DEBUG_ENV_SCRIPT/QuModLibs/Systems/Loader/SharedRes.py
Normal file
175
debug_mod/DEBUG_ENV_SCRIPT/QuModLibs/Systems/Loader/SharedRes.py
Normal file
@@ -0,0 +1,175 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from uuid import uuid4
|
||||
from ...IN import ModDirName
|
||||
from ...Util import QStruct
|
||||
|
||||
class CallObjData:
|
||||
def __init__(self, callObj, args = tuple(), kwargs = {}):
|
||||
self.callObj = callObj
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self._uid = None
|
||||
|
||||
class EmptyContext:
|
||||
pass
|
||||
|
||||
NAMESPACE = "Qu_" + ModDirName
|
||||
SYSTEMNAME = "{}_QLoader_system".format(ModDirName)
|
||||
SERVER_CALL_EVENT = "{}_QServer".format(ModDirName)
|
||||
CLIENT_CALL_EVENT = "{}_QClient".format(ModDirName)
|
||||
|
||||
class EasyListener:
|
||||
def __init__(self):
|
||||
self._callQueue = [] # type: list[CallObjData]
|
||||
self._emptyContext = EmptyContext()
|
||||
self._QCustomAPI = {} # type: dict[str, function]
|
||||
|
||||
def regCustomApi(self, apiName="", func=lambda: None):
|
||||
""" 注册自定义API """
|
||||
self._QCustomAPI[apiName] = func
|
||||
|
||||
def removeCustomApi(self, apiName=""):
|
||||
""" 删除指定API如果存在 """
|
||||
if apiName in self._QCustomAPI:
|
||||
del self._QCustomAPI[apiName]
|
||||
|
||||
def getCustomApi(self, apiName=""):
|
||||
""" 获取自定义API如果存在 """
|
||||
return self._QCustomAPI.get(apiName)
|
||||
|
||||
def localCall(self, apiName="", *args, **kwargs):
|
||||
""" 本地调用 请确保API函数存在注册 否则抛出异常 """
|
||||
return self._QCustomAPI[apiName](*args, **kwargs)
|
||||
|
||||
def _systemCallListener(self, args={}):
|
||||
""" 系统call机制监听器(接收消息处理) """
|
||||
api = args["api"]
|
||||
ag = EasyListener._unPackRefArgs(args["args"])
|
||||
kwargs = EasyListener._unPackRefDictArgs(args["kw"])
|
||||
self._systemCallListenerHook(args)
|
||||
return self.localCall(api, *ag, **kwargs)
|
||||
|
||||
def _systemCallListenerHook(self, _={}):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _unPackRefArgs(data):
|
||||
# type: (list) -> list
|
||||
""" Ref解包Args数据 """
|
||||
for i, v in enumerate(data):
|
||||
if QStruct.isSignData(v):
|
||||
data[i] = QStruct.loadSignData(v).onNetUnPack()
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def _unPackRefDictArgs(data):
|
||||
# type: (dict) -> dict
|
||||
""" Ref解包Dict Args数据 """
|
||||
for k, v in data.items():
|
||||
if QStruct.isSignData(v):
|
||||
data[k] = QStruct.loadSignData(v).onNetUnPack()
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def _packArgs(data):
|
||||
# type: (tuple | list) -> list
|
||||
""" 打包Args数据 """
|
||||
newDataList = []
|
||||
for v in data:
|
||||
if isinstance(v, QStruct):
|
||||
newDataList.append(v.signDumps())
|
||||
continue
|
||||
newDataList.append(v)
|
||||
return newDataList
|
||||
|
||||
@staticmethod
|
||||
def _packDictArgs(data):
|
||||
# type: (dict) -> dict
|
||||
""" 打包Dict数据 keyName=xxx """
|
||||
newDict = {}
|
||||
for k, v in data.items():
|
||||
if isinstance(v, QStruct):
|
||||
newDict[k] = v.signDumps()
|
||||
continue
|
||||
newDict[k] = v
|
||||
return newDict
|
||||
|
||||
def _packageCallArgs(self, apiName="", args=tuple(), kwargs=dict()):
|
||||
""" 打包API参数(发送消息处理) """
|
||||
return {"api":apiName,"args":EasyListener._packArgs(args),"kw":EasyListener._packDictArgs(kwargs)}
|
||||
|
||||
def mallocRandomMetName(self):
|
||||
""" 动态分配随机方法名 """
|
||||
randomName = ""
|
||||
while not randomName or hasattr(self, randomName):
|
||||
randomName = "Q_{}".format(uuid4().hex)
|
||||
return randomName
|
||||
|
||||
def _allocMethodWithOUTFunction(self, callFunc=lambda *_: None):
|
||||
""" 基于外部函数分配一个映射的内部方法(介于网易Listen必须依赖内部方法 故有了该方法) """
|
||||
newFuncName = self.mallocRandomMetName()
|
||||
newFunc = lambda *args, **kwargs: callFunc(*args, **kwargs)
|
||||
newFunc.__name__ = newFuncName
|
||||
setattr(self, newFuncName, newFunc)
|
||||
return newFunc
|
||||
|
||||
def _delMethod(self, methodFunc=lambda *_: None):
|
||||
""" 对照与_allocMethodWithOUTFunction的反向删除 """
|
||||
try:
|
||||
delattr(self, methodFunc.__name__)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def nativeStaticListen(self, eventName="", callFunc=lambda *_: None):
|
||||
""" 原生静态监听注册 不支持运行时注销 """
|
||||
def _reg():
|
||||
self._easyListenForEvent(eventName, self, self._allocMethodWithOUTFunction(callFunc))
|
||||
self._callQueue.append(CallObjData(_reg))
|
||||
|
||||
def nativeListen(self, eventName="", parent=None, callFunc=lambda *_: None, updateNow=False):
|
||||
# type: (str, object, object, bool) -> CallObjData | None
|
||||
""" 原生动态监听 当updateNow声明为False时将会添加到系统队列安全的等待注册 """
|
||||
if not parent:
|
||||
parent = self._emptyContext
|
||||
newFuncName = "QListen{}_{}".format(id(parent), callFunc.__name__)
|
||||
newFunc = lambda *args: callFunc(*args)
|
||||
newFunc.__name__ = newFuncName
|
||||
if hasattr(self, newFuncName):
|
||||
print("[Error] 请勿在单个可执行对象上监听重复的事件")
|
||||
return None
|
||||
def _reg():
|
||||
setattr(self, newFuncName, newFunc)
|
||||
self._easyListenForEvent(eventName, self, newFunc)
|
||||
waitCallObj = CallObjData(_reg)
|
||||
waitCallObj._uid = newFuncName
|
||||
self._callQueue.append(waitCallObj)
|
||||
if updateNow:
|
||||
self.unsafeUpdate(waitCallObj)
|
||||
return waitCallObj
|
||||
|
||||
def unNativeListen(self, eventName="", parent=None, callFunc=lambda *_: None):
|
||||
# type: (str, object, object) -> None
|
||||
""" 取消特定方法的原生动态监听 """
|
||||
if not parent:
|
||||
parent = self._emptyContext
|
||||
newFuncName = "QListen{}_{}".format(id(parent), callFunc.__name__)
|
||||
if hasattr(self, newFuncName):
|
||||
# 已注册完毕的监听处理
|
||||
self._easyUnListenForEvent(eventName, self, getattr(self, newFuncName))
|
||||
delattr(self, newFuncName)
|
||||
return
|
||||
# 在队列中等待注册的监听处理
|
||||
self.removeCallObjByUid(newFuncName)
|
||||
|
||||
def unsafeUpdate(self, callObjData):
|
||||
# type: (CallObjData) -> bool
|
||||
pass
|
||||
|
||||
def _easyListenForEvent(self, eventName="", parent=None, func=lambda: None):
|
||||
pass
|
||||
|
||||
def _easyUnListenForEvent(self, eventName="", parent=None, func=lambda: None):
|
||||
pass
|
||||
|
||||
def removeCallObjByUid(self, _uid = ""):
|
||||
pass
|
||||
Reference in New Issue
Block a user