frontend: initial commit
This commit is contained in:
parent
8d70acc5d2
commit
1ad243f043
21 changed files with 30437 additions and 0 deletions
108
frontend/src/hooks/use-osc-reducer.js
Normal file
108
frontend/src/hooks/use-osc-reducer.js
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
import { useState, useReducer, useEffect } from 'react'
|
||||
import osc from '../lib/osc'
|
||||
import Debug from 'debug'
|
||||
|
||||
// const STATE = '/s'
|
||||
// const COMMAND = '/c'
|
||||
|
||||
const debug = Debug('ui:osc:reducer')
|
||||
|
||||
/**
|
||||
* Listen on a OSC value change over time.
|
||||
*/
|
||||
export function useOscValue (address, defaultValue, opts = {}) {
|
||||
// TODO: Global store.
|
||||
const [state, setState] = useState(defaultValue)
|
||||
useEffect(() => {
|
||||
// const stateAddress = STATE + address
|
||||
// console.log('useOscValue init', stateAddress)
|
||||
const unwatch = osc.on(address, message => {
|
||||
const { address, args } = message
|
||||
if (opts.single) setState(args[0])
|
||||
else setState(args)
|
||||
// setState(state => ({ ...state, [address]: args }))
|
||||
})
|
||||
return unwatch
|
||||
}, [address])
|
||||
return state
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to an OSC value.
|
||||
*/
|
||||
export function useOscWritable (address, defaultValue, opts = {}) {
|
||||
const state = useOscValue(address, defaultValue, opts)
|
||||
return [state, setState]
|
||||
|
||||
function setState (nextValue) {
|
||||
if (typeof nextValue === 'function') nextValue = nextValue(state)
|
||||
// const commandAddress = COMMAND + address
|
||||
// const parts = address.split('/')
|
||||
// const last = parts.pop()
|
||||
// const cmdAddress = [...parts, 'cmd', last].join('/')
|
||||
console.log('useOscWritable write', address, nextValue)
|
||||
osc.send(address, nextValue)
|
||||
}
|
||||
}
|
||||
|
||||
export function useOscReducer (reducer, initialState, prefix = '') {
|
||||
const [state, localDispatch] = useReducer(reducer, initialState)
|
||||
|
||||
const prefixLen = prefix.split('/').length
|
||||
|
||||
// Listen for all state change messages and dispatch into the reducer.
|
||||
useEffect(() => {
|
||||
const wildcardAddress = prefix + '/*'
|
||||
const unwatch = osc.on(wildcardAddress, message => {
|
||||
const { address, args } = message
|
||||
const key = address.split('/').slice(prefixLen + 1).join('/')
|
||||
localDispatch({ cmd: 'set', address: key, args })
|
||||
})
|
||||
return unwatch
|
||||
})
|
||||
|
||||
return [state, dispatch]
|
||||
|
||||
function dispatch (action) {
|
||||
console.log('useOscReducer dispatch', action)
|
||||
send(action)
|
||||
}
|
||||
|
||||
function send (action) {
|
||||
const { address, args } = action
|
||||
const fullAddress = COMMAND + prefix + address
|
||||
osc.send(fullAddress, args)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Broken, fix address paths.
|
||||
export function useOscReducerOld (reducer, initialState, prefix) {
|
||||
const [state, localDispatch] = useReducer(reducer, initialState)
|
||||
|
||||
// const [remoteState, remoteDispatch] = useReducer(reducer, initialState)
|
||||
//
|
||||
useEffect(() => {
|
||||
const path = prefix + '/state/*'
|
||||
const unwatch = osc.on(path, message => {
|
||||
const { address, args } = message
|
||||
// console.log('RECVV!!!!', message)
|
||||
const key = address.split('/').pop()
|
||||
localDispatch({ cmd: 'set', key, args })
|
||||
})
|
||||
return unwatch
|
||||
}, [])
|
||||
|
||||
return [state, dispatch]
|
||||
|
||||
function dispatch (action) {
|
||||
console.log('dispatch', action)
|
||||
send(action)
|
||||
// localDispatch(action)
|
||||
}
|
||||
|
||||
function send (action) {
|
||||
const { cmd, args } = action
|
||||
const address = [prefix, 'cmd', cmd].join('/')
|
||||
osc.send(address, args)
|
||||
}
|
||||
}
|
||||
47
frontend/src/hooks/use-peak.js
Normal file
47
frontend/src/hooks/use-peak.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import osc from '../lib/osc'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
class PeakStore {
|
||||
constructor () {
|
||||
this.watchers = []
|
||||
}
|
||||
watch (fn) {
|
||||
this.watchers.push(fn)
|
||||
return () => (this.watchers = this.watchers.filter(w => w !== fn))
|
||||
}
|
||||
set (val) {
|
||||
this.val = val
|
||||
for (const watcher of this.watchers) {
|
||||
watcher(val)
|
||||
}
|
||||
}
|
||||
get () {
|
||||
return this.val
|
||||
}
|
||||
}
|
||||
|
||||
const peaks = new PeakStore()
|
||||
|
||||
osc.on('/peaks', message => {
|
||||
const { args } = message
|
||||
const buf = args[0]
|
||||
const nextPeaks = {}
|
||||
for (let offset = 0; offset < 48; offset++) {
|
||||
let pos = offset * 2
|
||||
let val = buf[pos] * 256 + buf[pos + 1]
|
||||
val = (val / 800) - 70
|
||||
nextPeaks[offset] = val
|
||||
}
|
||||
console.log('RECV PEAKS', nextPeaks)
|
||||
peaks.set(nextPeaks)
|
||||
})
|
||||
|
||||
export function usePeak (offset) {
|
||||
const [peak, setPeak] = useState(-70)
|
||||
useEffect(() => {
|
||||
const unwatch = peaks.watch(peaks => {
|
||||
setPeak(peaks[offset])
|
||||
})
|
||||
})
|
||||
return peak
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue