Created
August 18, 2025 03:32
-
-
Save derekmc/502f2851e668239c3e10bc3f82626820 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // early release is easier to understand than sync filter and processchord with a stack system. | |
| //early release pct 50% - Early release can only move up release events by a maximum of 50% of the time a key is held. | |
| //early release time: 15ms | |
| let log = [] | |
| let leftovers = [] | |
| let t0 = Date.now() | |
| let active = {} | |
| let earlyup = 15 //release key early | |
| let earlypct = 50 // max amount keyhold is reduced | |
| let repeatInput = '' | |
| let lastInput = '' | |
| let repeatdt = 500 | |
| let processdt = 1000 | |
| let repeatTimeout = null | |
| init() | |
| function json(x){ return JSON.stringify(x)} | |
| function repeat(){ | |
| if(repeatInput.length > 0){ | |
| input(repeatInput) | |
| clearTimeout(repeatTimeout) | |
| repeatTimeout = setTimeout(repeat, repeatdt) | |
| } | |
| } | |
| function init(){ | |
| window.addEventListener('keydown', keydown) | |
| window.addEventListener('keyup', keyup) | |
| setInterval(process, processdt) | |
| console.info('init') | |
| } | |
| function keydown(e){ | |
| if(active.hasOwnProperty(e.keyCode)) | |
| return | |
| let now = Date.now() | |
| active[e.keyCode] = now | |
| keyevent('+', e.keyCode, now) | |
| } | |
| function keyup(e){ | |
| let t1 = active[e.keyCode] | |
| delete active[e.keyCode] | |
| let dt = Date.now() - t1 | |
| dt = Math.max(earlypct * dt/100, dt - earlyup) | |
| keyevent('-', e.keyCode, t1 + dt) | |
| release() | |
| } | |
| function keyevent(action, code, t){ | |
| console.info(`key: ${action}${code}`) | |
| t -= t0 | |
| log.push({action, code, t}) | |
| } | |
| function logsort(logarray){ | |
| logarray.sort((a,b)=>a.t - b.t) | |
| } | |
| function process(){ | |
| let now = Date.now() | |
| let keep = [] | |
| let stack = [] | |
| let emitted = leftovers[0] ?? false | |
| let l = [...leftovers.slice(1), ...log] | |
| logsort(l) | |
| if(l.length){ | |
| console.info('emitted', emitted, 'log', logstr(l)) | |
| //console.info('leftovers', json(leftovers)) | |
| } | |
| for(let i=0; i<l.length; ++i){ | |
| let a = l[i] | |
| let old = now - a.t | |
| if(old < earlyup){ // do not process events until they are older than earlyup interval | |
| keep.push(a) | |
| console.info(`early ${a.code}`) | |
| continue | |
| } | |
| //console.info('action', json(a)) | |
| if(a.action == '+'){ | |
| stack.push(a.code) | |
| keep.push(a) | |
| //console.info(`keep ${a.code}`) | |
| if(i >= leftovers.length - 1) emitted = false | |
| } | |
| if(a.action == '-'){ | |
| if(!emitted) emit(stack.join(' ')) | |
| emitted = true | |
| stack = stack.filter(x=>x!=a.code) | |
| keep = keep.filter(x=>x.code!=a.code) | |
| release() | |
| } | |
| } | |
| log = [] | |
| leftovers = [emitted, ...keep] | |
| } | |
| function release(){ | |
| repeatInput = '' | |
| } | |
| function emit(seq){ | |
| if(seq == lastInput){ | |
| repeatInput = seq | |
| clearTimeout(repeatTimeout) | |
| repeatTimeout = setTimeout(repeat, repeatdt) | |
| } | |
| lastInput = seq | |
| input(seq) | |
| } | |
| function input(seq){ | |
| console.info("input: " + seq + " [TODO]") | |
| } | |
| function logstr(l){ | |
| return l.map(x=>`${x.action}${x.code}/${x.t}`).join(' ') | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment