108 lines
3 KiB
JavaScript
108 lines
3 KiB
JavaScript
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)
|
|
}
|
|
}
|