此篇专栏的内容为前三篇专栏介绍的区块加载的四种任务每种结束后都有的相同流程,没看之前专栏的记得看前面的专栏。
当每一种区块加载任务完成后,在加载线程都会进行相同的处理,主要作用就是发布新的区块加载任务。
依然在加载线程里,当区块加载任务完成后,如果这一个阶段加载成功了,函数会把区块的loadstate从奇数加一改成偶数(就是该阶段从正在进行到完成)。但是如果没有成功,它便会将loadstate从奇数减一改成偶数(从该阶段的正在进行改到上个阶段的完成)
在这种情况下,它会将该区块的区块坐标和区块加载状态加入主区块管理器的等待加载队列。并且执行区块加载任务发布流程(详情见第四篇专栏)。
如果区块加载任务成功了(状态+1),函数便会进行邻域推进检测。在进行完后便会执行区块加载任务发布流程。
要特别说的是区块生成阶段。如果在Dbchunkstorage里查询这个区块周围相邻的8个区块都存在,便直接跳过区块装饰到状态4。
首先该函数会以要处理的区块为中心,从mainchunksource获取以这个区块为中心的3*3的区块加入一个新建的临时gridarea。这个过程中mainchunksource的相关成员变量会被上自旋锁。这个gridarea记录由区块、区块删除器组成的结构体。
随后它会遍历3*3的区块,对于每个区块做如下处理:
将区块删除器中的计数器+1.
获取区块,如果没有就将区块删除器的计数器-1。如果有,判断它是在什么生成状态。
如果是2,它会先判断自己的区块坐标的奇偶性。如果都是偶数,便会检查自己周围相邻的8个区块的区块加载状态是不是大于等于2,如果都是便将自己的区块坐标和状态加入区块加载的等待列表,如果不都是就返回。
如果z是偶数x不是便检测周围8个区块加载状态是否大于等于2,且z+方向的区块和x-方向的区块加载状态大于等于4,如果都满足就和上面的执行一样的
如果xz都是奇数便检查x+z+, z+, x-z+, x+z-,z-, x-z-方向的区块是不是状态大于等于4,x+和x-是不是大于等于2
如果z是奇数x是偶数,就检查周围8个区块是不是状态都大于等于4。
如果该区块状态为4或6,就遍历检查周围8个区块状态是否都大于等于4或者6,如果是就加入待加载列表。
区块状态在加载线程中最终被从7变成8,但是游戏为了防止出现漏洞将8到9的过程最终放到了服务器线程里。
当区块完成光照初始化后,它不会再将自己加入区块加载等待队列,而是新建一个任务加入服务器线程的任务队列,在调度器阶段执行。
它会首先将区块状态从8变成9,随后将该区块的区块坐标和状态从ChunkGenerationGridMap中删除。到这里服务器线程的mainchunksource对应的blocksource就可以访问它了,也就算加载完成了。
在维度更新(dimension::tick)中的一个更新阶段中,会执行一个额外的区块加载任务发布流程。