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) } }