185 lines
6.9 KiB
Python
185 lines
6.9 KiB
Python
|
|
# -*- 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)
|