ddd
This commit is contained in:
parent
0a343ecbc5
commit
c3a6f5ff37
80 changed files with 2512 additions and 1625 deletions
56
test/frame-drag-scheduler-test.js
Normal file
56
test/frame-drag-scheduler-test.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
'use strict';
|
||||
|
||||
const {assert}=require('./helpers/app-source');
|
||||
const {createFrameScheduler}=require('../client/input/frame-scheduler');
|
||||
const {createDragScheduler,STATES}=require('../client/input/drag');
|
||||
|
||||
function fakeClock(){
|
||||
let now=0,nextId=1;
|
||||
const frames=new Map(),timers=new Map();
|
||||
return{
|
||||
now:()=>now,
|
||||
requestFrame:callback=>{const id=nextId++;frames.set(id,callback);return id},
|
||||
cancelFrame:id=>frames.delete(id),
|
||||
setDelay:(callback,delay)=>{const id=nextId++;timers.set(id,{callback,at:now+delay});return id},
|
||||
clearDelay:id=>timers.delete(id),
|
||||
advance(milliseconds){
|
||||
now+=milliseconds;
|
||||
for(const[id,entry]of[...timers])if(entry.at<=now){timers.delete(id);entry.callback()}
|
||||
const pending=[...frames];frames.clear();for(const[,callback]of pending)callback(now);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const clock=fakeClock(),commits=[];
|
||||
const scheduler=createFrameScheduler({
|
||||
requestFrame:clock.requestFrame,cancelFrame:clock.cancelFrame,setDelay:clock.setDelay,clearDelay:clock.clearDelay,
|
||||
now:clock.now,interval:1000/60,tolerance:1.25,watchdogDelay:18,
|
||||
commit:(value,timestamp)=>commits.push({value,timestamp})
|
||||
});
|
||||
for(let index=0;index<40;index++){scheduler.push(index);clock.advance(2)}
|
||||
clock.advance(20);
|
||||
assert(commits.length<=6,'High-rate input produced more than one presentation commit per nominal 60 Hz interval');
|
||||
assert(commits.at(-1).value===39,'Latest-value frame scheduling lost the newest input');
|
||||
for(let index=1;index<commits.length;index++)assert(commits[index].timestamp-commits[index-1].timestamp>=15,'Presentation commits exceeded the 60 Hz tolerance');
|
||||
|
||||
const dragClock=fakeClock(),states=[];
|
||||
const drag=createDragScheduler({
|
||||
requestFrame:dragClock.requestFrame,cancelFrame:dragClock.cancelFrame,setDelay:dragClock.setDelay,clearDelay:dragClock.clearDelay,
|
||||
now:dragClock.now,interval:1000/60,tolerance:1.25,watchdogDelay:18,maxSamples:4,
|
||||
trim:samples=>{while(samples.length>4)samples.splice(1,1)},
|
||||
onFrame:session=>states.push(session.inspect().state)
|
||||
});
|
||||
drag.arm(7);
|
||||
assert(drag.inspect().state==='armed','Drag did not enter armed state');
|
||||
for(let index=0;index<8;index++)drag.push({pointerId:7,clientX:index,clientY:index});
|
||||
assert(drag.inspect().state==='running'&&drag.inspect().logicalCount===4&&drag.latest().clientX===7,'Drag scheduler did not separate bounded logical samples from latest visual input');
|
||||
dragClock.advance(17);
|
||||
assert(states[0]==='running','Drag scheduler did not commit through its running frame lane');
|
||||
assert(drag.beginDrain({pointerId:7,clientX:8,clientY:8})&&drag.inspect().state==='draining','Drag did not enter draining state');
|
||||
assert(drag.drainLogical().at(-1).clientX===8,'Release drain lost final input intent');
|
||||
drag.beginSettling();assert(drag.inspect().state==='settling','Drag did not enter settling state');
|
||||
drag.settle();assert(drag.inspect().state==='idle','Settled drag did not return to idle');
|
||||
drag.arm(9);drag.cancel();assert(drag.inspect().state==='cancelled','Cancelled drag did not expose its terminal state');
|
||||
assert(STATES.join(',')==='idle,armed,running,draining,settling,cancelled','Drag lifecycle states changed unexpectedly');
|
||||
|
||||
console.log('Shared 60 Hz frame scheduler and explicit drag lifecycle behavior passed');
|
||||
Loading…
Add table
Add a link
Reference in a new issue