网易我的世界论坛
标题:
[Hzi可乐][技术分享]一个大型任务处理轮子(重置)
[打印本页]
作者:
uni_kevin
时间:
2021-4-17 18:27
标题:
[Hzi可乐][技术分享]一个大型任务处理轮子(重置)
大家好我是花子家的可乐,今天在敲project的时候翻出了以前造的一个小轮子,用于把比较大的任务列表切片分到不同帧处理,比如说一次要放很多方块,或者创建很多实体,绑定很多文字面板什么的,貌似还挺有用,于是贴出来分享给大家~
创建一个TaskManager.py文件放到类似utils之类的文件夹下:
# coding=utf-8
import mod.server.extraServerApi as serverApi
class TaskManager:
def __init__(self, speed=1):
"""
:type speed: int
"""
self.__speed = speed
self.__taskList = list()
self.__commandComp = serverApi.GetEngineCompFactory().CreateCommand(serverApi.GetLevelId())
self.__isCloseWhenDone = False
self.__callLater = serverApi.GetEngineCompFactory().CreateGame(serverApi.GetLevelId()).AddRepeatedTimer(1 / 20.0, self.__TickEvent)
def __TickEvent(self):
if len(self.__taskList) < self.__speed:
for task in self.__taskList:
task.Execute()
del self.__taskList[:]
if self.__isCloseWhenDone:
serverApi.GetEngineCompFactory().CreateGame(serverApi.GetLevelId()).CancelTimer(self.__callLater)
del self
else:
for task in self.__taskList[0:self.__speed]:
task.Execute()
del self.__taskList[0:self.__speed]
def SetSpeed(self, speed, sync=False):
"""
:param sync: bool
:type speed: int
"""
if sync:
self.__speed = speed
else:
self.AppendFunction(self.SetSpeed, speed, True)
def AppendCommand(self, command, playerId=None, showOutput=False):
self.__taskList.append(TaskCommand(command, playerId, showOutput, self.__commandComp))
def AppendFunction(self, func, *args, **kwargs):
self.__taskList.append(TaskFunction(func, args, kwargs))
def CloseWhenDone(self):
self.__isCloseWhenDone = True
class TaskFunction:
def __init__(self, function, args=None, kwargs=None):
self.function = function
self.args = args if args is not None else []
self.b = kwargs if kwargs is not None else {}
def Execute(self):
self.function(*self.args, **self.b)
class TaskCommand:
def __init__(self, command, playerId, showOutput, comp):
self.command = command
self.playerId = playerId
self.showOutput = showOutput
self.comp = comp
def Execute(self):
self.comp.SetCommand(self.command, self.playerId, self.showOutput)
复制代码
使用方法比较简单,首先创建一个实例,把速度(每tick处理多少个任务)(1s 20个tick)作为参数传进去,像这样:
taskManager = TaskManager(speed=1)
复制代码
对外接口有
taskManager.AppendFunction(...) # 添加一个任务,类似官方timer组件传参即可
taskManager.AppendCommand(...) # 添加一个指令任务
taskManager.SetSpeed(3, sync=False) # 中途修改速度, 第二个参数是否不等待任务执行到此马上更改
taskManager.CloseWhenDone() # 设置执行完全部任务后释放资源, 销毁后就不能再添加任务了
复制代码
比方说,这样写种一棵树:
[attach]1352645[/attach]
效果看起来是这样的:
[attach]1352646[/attach]
还不错吧(应该?)
第一次写分享贴,我是萌新,技术一般般的,没法和圈里的大佬们比,如果有写的不对的地方还请多多包涵和指正qwq
鹅鹅鹅论坛的编辑好坑,上一个写错了还没法编辑麻烦管理员帮我删一下吧orz
作者:
sevenstars
时间:
2021-4-24 00:06
实际上就是个取舍问题
作者:
sevenstars
时间:
2021-4-24 00:10
把玩家卡死,可以保证最快处理完任务。
分批量处理任务,玩家等待时间较长
而且如果调的时间短了一样卡,无非是0fps和个位数fps的区别
对于一些大型任务,最好的办法还是让玩家选择是否低效率处理,或者直接通知玩家这个任务大约要卡多久,然后再卡死会好一点。
欢迎光临 网易我的世界论坛 (http://mc.netease.com/)
Powered by Discuz! X3.3