网易我的世界论坛

标题: [Hzi可乐][技术分享]一个大型任务处理轮子(重置) [打印本页]

作者: uni_kevin    时间: 2021-4-17 18:27
标题: [Hzi可乐][技术分享]一个大型任务处理轮子(重置)
大家好我是花子家的可乐,今天在敲project的时候翻出了以前造的一个小轮子,用于把比较大的任务列表切片分到不同帧处理,比如说一次要放很多方块,或者创建很多实体,绑定很多文字面板什么的,貌似还挺有用,于是贴出来分享给大家~
创建一个TaskManager.py文件放到类似utils之类的文件夹下:


  1. # coding=utf-8
  2. import mod.server.extraServerApi as serverApi


  3. class TaskManager:
  4.     def __init__(self, speed=1):
  5.         """

  6.         :type speed: int
  7.         """
  8.         self.__speed = speed
  9.         self.__taskList = list()
  10.         self.__commandComp = serverApi.GetEngineCompFactory().CreateCommand(serverApi.GetLevelId())
  11.         self.__isCloseWhenDone = False
  12.         self.__callLater = serverApi.GetEngineCompFactory().CreateGame(serverApi.GetLevelId()).AddRepeatedTimer(1 / 20.0, self.__TickEvent)

  13.     def __TickEvent(self):
  14.         if len(self.__taskList) < self.__speed:
  15.             for task in self.__taskList:
  16.                 task.Execute()
  17.             del self.__taskList[:]
  18.             if self.__isCloseWhenDone:
  19.                 serverApi.GetEngineCompFactory().CreateGame(serverApi.GetLevelId()).CancelTimer(self.__callLater)
  20.                 del self
  21.         else:
  22.             for task in self.__taskList[0:self.__speed]:
  23.                 task.Execute()
  24.             del self.__taskList[0:self.__speed]

  25.     def SetSpeed(self, speed, sync=False):
  26.         """

  27.         :param sync: bool
  28.         :type speed: int
  29.         """
  30.         if sync:
  31.             self.__speed = speed
  32.         else:
  33.             self.AppendFunction(self.SetSpeed, speed, True)

  34.     def AppendCommand(self, command, playerId=None, showOutput=False):
  35.         self.__taskList.append(TaskCommand(command, playerId, showOutput, self.__commandComp))

  36.     def AppendFunction(self, func, *args, **kwargs):
  37.         self.__taskList.append(TaskFunction(func, args, kwargs))

  38.     def CloseWhenDone(self):
  39.         self.__isCloseWhenDone = True


  40. class TaskFunction:
  41.     def __init__(self, function, args=None, kwargs=None):
  42.         self.function = function
  43.         self.args = args if args is not None else []
  44.         self.b = kwargs if kwargs is not None else {}

  45.     def Execute(self):
  46.         self.function(*self.args, **self.b)


  47. class TaskCommand:
  48.     def __init__(self, command, playerId, showOutput, comp):
  49.         self.command = command
  50.         self.playerId = playerId
  51.         self.showOutput = showOutput
  52.         self.comp = comp

  53.     def Execute(self):
  54.         self.comp.SetCommand(self.command, self.playerId, self.showOutput)
复制代码


使用方法比较简单,首先创建一个实例,把速度(每tick处理多少个任务)(1s 20个tick)作为参数传进去,像这样:
  1. taskManager = TaskManager(speed=1)
复制代码

对外接口有
  1. taskManager.AppendFunction(...)  # 添加一个任务,类似官方timer组件传参即可
  2. taskManager.AppendCommand(...) # 添加一个指令任务
  3. taskManager.SetSpeed(3, sync=False) # 中途修改速度, 第二个参数是否不等待任务执行到此马上更改
  4. 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