当前位置:   article > 正文

Cesium 源码分析 Cesium3DTilesetCache_cesium.cache

cesium.cache

        Cesium中的3DTiles数据加载的过程中会进行缓存,使用的是Cesium3DTilesetCache这个类,这个类中维护了一个双向链表DoublyLinkedList,链表的每个节点DoublyLinkedListNode包含了3部分内容,item(即tile)、previous、next,而DoublyLinkedList维护了链表的head和tail游标,并包含三个方法remove(移除节点)、add(添加节点)、slice(移动节点)。

        

        对于Cesium3DTilesetCache,这个类中使用了一个空节点sentinel(哨兵),这个节点的在链表中起到隔离作用,每一帧中这个哨兵节点都可能会移动,哨兵的左边是当前帧之前缓存的瓦片(数据已经下载完成)节点,右边是当前帧需要的瓦片节点,其中左边的节点受到瓦片集的最大内存选项maximumMemoryUsage和是否剔除的标记trimTiles以及sentinel的三方挟持,只要有一方不满足条件就会删除已经缓存的节点,在当前帧中会检索是否之前缓存的节点在当前帧中可以重复利用,如果是则会将该节点从哨兵的左边移动到哨兵的右边,当前帧处理完成后,哨兵节点会reset到链表的尾部,并进行新一轮的哨兵移动。

 

  1. /**
  2. * Stores tiles with content loaded.
  3. * 用来存储已经加载完成的带有数据的瓦片
  4. *
  5. * @private
  6. */
  7. function Cesium3DTilesetCache() {
  8. // [head, sentinel) -> tiles that weren't selected this frame and may be removed from the cache
  9. // (sentinel, tail] -> tiles that were selected this frame
  10. // 双向链表
  11. this._list = new DoublyLinkedList();
  12. // 哨兵(空节点)
  13. this._sentinel = this._list.add();
  14. this._trimTiles = false;
  15. }
  16. // 重置时把哨兵节点移动到末尾
  17. Cesium3DTilesetCache.prototype.reset = function () {
  18. // Move sentinel node to the tail so, at the start of the frame, all tiles
  19. // may be potentially replaced. Tiles are moved to the right of the sentinel
  20. // when they are selected so they will not be replaced.
  21. // 把哨兵节点移动到链表的末尾,在一帧的开始,所有的瓦片可能被替换,可见的瓦片将被移动到链表的右边,它们不能被替换
  22. this._list.splice(this._list.tail, this._sentinel);
  23. };
  24. // 节点移动到哨兵的后边(从原来缓存的数据中拿到可以使用的节点然后移动到哨兵的右边)
  25. Cesium3DTilesetCache.prototype.touch = function (tile) {
  26. var node = tile.cacheNode;
  27. if (defined(node)) {
  28. // 节点移动到哨兵节点的后面
  29. this._list.splice(this._sentinel, node);
  30. }
  31. };
  32. // 在末尾添加节点,这个节点一定在哨兵的后面
  33. Cesium3DTilesetCache.prototype.add = function (tile) {
  34. // 如果瓦片的缓存结点不存在就创建
  35. if (!defined(tile.cacheNode)) {
  36. tile.cacheNode = this._list.add(tile);
  37. }
  38. };
  39. // 卸载瓦片的缓存节点
  40. Cesium3DTilesetCache.prototype.unloadTile = function (
  41. tileset,
  42. tile,
  43. unloadCallback
  44. ) {
  45. var node = tile.cacheNode;
  46. // 未定义就返回
  47. if (!defined(node)) {
  48. return;
  49. }
  50. // 链表中移除节点
  51. this._list.remove(node);
  52. // 清空
  53. tile.cacheNode = undefined;
  54. // 回调
  55. unloadCallback(tileset, tile);
  56. };
  57. // 卸载瓦片集
  58. Cesium3DTilesetCache.prototype.unloadTiles = function (
  59. tileset,
  60. unloadCallback
  61. ) {
  62. var trimTiles = this._trimTiles;
  63. this._trimTiles = false;
  64. // 链表
  65. var list = this._list;
  66. // 最大缓存(MB转换为字节)
  67. var maximumMemoryUsageInBytes = tileset.maximumMemoryUsage * 1024 * 1024;
  68. // Traverse the list only to the sentinel since tiles/nodes to the
  69. // right of the sentinel were used this frame.
  70. // 遍历列表列表,只遍历哨兵左边的节点,因为哨兵右边的节点是正在使用的
  71. //
  72. // The sub-list to the left of the sentinel is ordered from LRU to MRU.
  73. // 哨兵
  74. var sentinel = this._sentinel;
  75. // 头节点
  76. var node = list.head;
  77. while (
  78. node !== sentinel && // 不是哨兵节点
  79. (tileset.totalMemoryUsageInBytes > maximumMemoryUsageInBytes || trimTiles) // 缓存没有超过界限就不删除
  80. ) {
  81. // 获取节点的数据
  82. var tile = node.item;
  83. // 遍历下一个节点
  84. node = node.next;
  85. // 卸载节点
  86. this.unloadTile(tileset, tile, unloadCallback);
  87. }
  88. };
  89. // 减少瓦片的缓存(cpu中)
  90. Cesium3DTilesetCache.prototype.trim = function () {
  91. this._trimTiles = true;
  92. };
  93. export default Cesium3DTilesetCache;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/545384
推荐阅读
相关标签
  

闽ICP备14008679号