Blame view

天文台pc/tianwentai-ui/node_modules/motion-dom/dist/es/frameloop/render-step.mjs 3.14 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  import { statsBuffer } from '../stats/buffer.mjs';
  
  function createRenderStep(runNextFrame, stepName) {
      /**
       * We create and reuse two queues, one to queue jobs for the current frame
       * and one for the next. We reuse to avoid triggering GC after x frames.
       */
      let thisFrame = new Set();
      let nextFrame = new Set();
      /**
       * Track whether we're currently processing jobs in this step. This way
       * we can decide whether to schedule new jobs for this frame or next.
       */
      let isProcessing = false;
      let flushNextFrame = false;
      /**
       * A set of processes which were marked keepAlive when scheduled.
       */
      const toKeepAlive = new WeakSet();
      let latestFrameData = {
          delta: 0.0,
          timestamp: 0.0,
          isProcessing: false,
      };
      let numCalls = 0;
      function triggerCallback(callback) {
          if (toKeepAlive.has(callback)) {
              step.schedule(callback);
              runNextFrame();
          }
          numCalls++;
          callback(latestFrameData);
      }
      const step = {
          /**
           * Schedule a process to run on the next frame.
           */
          schedule: (callback, keepAlive = false, immediate = false) => {
              const addToCurrentFrame = immediate && isProcessing;
              const queue = addToCurrentFrame ? thisFrame : nextFrame;
              if (keepAlive)
                  toKeepAlive.add(callback);
              queue.add(callback);
              return callback;
          },
          /**
           * Cancel the provided callback from running on the next frame.
           */
          cancel: (callback) => {
              nextFrame.delete(callback);
              toKeepAlive.delete(callback);
          },
          /**
           * Execute all schedule callbacks.
           */
          process: (frameData) => {
              latestFrameData = frameData;
              /**
               * If we're already processing we've probably been triggered by a flushSync
               * inside an existing process. Instead of executing, mark flushNextFrame
               * as true and ensure we flush the following frame at the end of this one.
               */
              if (isProcessing) {
                  flushNextFrame = true;
                  return;
              }
              isProcessing = true;
              // Swap this frame and the next to avoid GC
              const prevFrame = thisFrame;
              thisFrame = nextFrame;
              nextFrame = prevFrame;
              // Execute this frame
              thisFrame.forEach(triggerCallback);
              /**
               * If we're recording stats then
               */
              if (stepName && statsBuffer.value) {
                  statsBuffer.value.frameloop[stepName].push(numCalls);
              }
              numCalls = 0;
              // Clear the frame so no callbacks remain. This is to avoid
              // memory leaks should this render step not run for a while.
              thisFrame.clear();
              isProcessing = false;
              if (flushNextFrame) {
                  flushNextFrame = false;
                  step.process(frameData);
              }
          },
      };
      return step;
  }
  
  export { createRenderStep };
  //# sourceMappingURL=render-step.mjs.map