查看: 1039|回复: 2
打印 上一主题 下一主题

[交流] [Hzi可乐][技术分享]一个大型任务处理轮子(重置)

[复制链接]

10

主题

37

回帖

24

积分

Lv.2 石器学徒

UID
7419367
小麦
1
金锭
175
下界之星
0
跳转到指定楼层
楼主
发表于 2021-4-17 18:27:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 IP:广东
大家好我是花子家的可乐,今天在敲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() # 设置执行完全部任务后释放资源, 销毁后就不能再添加任务了
复制代码

比方说,这样写种一棵树:

效果看起来是这样的:


还不错吧(应该?)
第一次写分享贴,我是萌新,技术一般般的,没法和圈里的大佬们比,如果有写的不对的地方还请多多包涵和指正qwq

鹅鹅鹅论坛的编辑好坑,上一个写错了还没法编辑麻烦管理员帮我删一下吧orz

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

评分

1

查看全部评分

22

主题

317

回帖

174

积分

Lv.4 怪物猎人

UID
373726
小麦
3
金锭
608
下界之星
0

开发者认证勋章

沙发
发表于 2021-4-24 00:06:55 | 只看该作者 IP:上海
实际上就是个取舍问题

22

主题

317

回帖

174

积分

Lv.4 怪物猎人

UID
373726
小麦
3
金锭
608
下界之星
0

开发者认证勋章

板凳
发表于 2021-4-24 00:10:27 | 只看该作者 IP:上海
把玩家卡死,可以保证最快处理完任务。
分批量处理任务,玩家等待时间较长
而且如果调的时间短了一样卡,无非是0fps和个位数fps的区别
对于一些大型任务,最好的办法还是让玩家选择是否低效率处理,或者直接通知玩家这个任务大约要卡多久,然后再卡死会好一点。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部