Skip to content

Commit

Permalink
fix assorted bugs in state handling
Browse files Browse the repository at this point in the history
  • Loading branch information
3ll3d00d committed Jun 3, 2023
1 parent 34f6781 commit 3ac9e44
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 25 deletions.
17 changes: 15 additions & 2 deletions ezbeq/camilladsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,26 @@ class CamillaDspState(DeviceState):

def __init__(self, name: str):
self.__name = name
self.has_volume = False
self.__has_volume = False
self.slot = CamillaDspSlotState()
self.slot.active = True
self.master_volume: float = 0.0
self.mute: bool = False

@property
def has_volume(self) -> bool:
return self.__has_volume

@has_volume.setter
def has_volume(self, has_volume: bool):
self.__has_volume = has_volume

def serialise(self) -> dict:
val = {
'type': 'camilladsp',
'name': self.__name,
'mute': self.mute,
'has_volume': self.has_volume,
'slots': [self.slot.as_dict()]
}
if self.has_volume is True:
Expand Down Expand Up @@ -127,6 +136,10 @@ def _load_initial_state(self) -> CamillaDspState:
return CamillaDspState(self.name)

def _merge_state(self, loaded: CamillaDspState, cached: dict) -> CamillaDspState:
if 'has_volume' in cached:
loaded.has_volume = cached['has_volume']
if 'masterVolume' in cached:
loaded.master_volume = cached['masterVolume']
if 'slots' in cached:
for slot in cached['slots']:
if 'id' in slot:
Expand All @@ -136,7 +149,7 @@ def _merge_state(self, loaded: CamillaDspState, cached: dict) -> CamillaDspState
if slot['gains']:
loaded.slot.gains = slot['gains']
if slot['mutes']:
loaded.slot.gains = slot['mutes']
loaded.slot.mutes = slot['mutes']
return loaded

@property
Expand Down
43 changes: 21 additions & 22 deletions ui/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import MainView from "./components/main";
import Levels from "./components/levels";
import Minidsp from "./components/minidsp";
import LevelsService from "./services/levels";
import StateService from "./services/state";

const useStyles = makeStyles((theme) => ({
root: {
Expand All @@ -28,7 +29,7 @@ const Root = ({children}) => {
)
}

const ws = new WebSocket("ws://" + window.location.host + "/ws");
const ss = new StateService(`ws://${window.location.host}/ws`);

const App = () => {
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
Expand All @@ -42,32 +43,23 @@ const App = () => {
[prefersDarkMode],
);

const replaceDevice = replacement => {
setAvailableDevices(Object.assign({}, availableDevices, {[replacement.name]: replacement}));
};

// errors
const [err, setErr] = useState(null);

ws.onmessage = event => {
const payload = JSON.parse(event.data);
switch (payload.message) {
case 'DeviceState':
replaceDevice(payload.data);
break;
case 'Error':
setErr(new Error(payload.data));
break;
default:
console.warn(`Unknown ws message ${event.data}`)
}
};

// catalogue data
const [entries, setEntries] = useState([]);
// device state
const [availableDevices, setAvailableDevices] = useState({});
const [selectedSlotId, setSelectedSlotId] = useState(null);

const replaceDevice = useMemo(() => replacement => {
setAvailableDevices(Object.assign({}, availableDevices, {[replacement.name]: replacement}));
}, [setAvailableDevices, availableDevices]);

useEffect(() => {
ss.init(setErr, replaceDevice);
}, [setErr, replaceDevice]);

// catalogue data
const [entries, setEntries] = useState([]);
// view selection
const [selectedDevice, setSelectedDevice] = useState(null);
const [selectedNav, setSelectedNav] = useState('catalogue');
Expand Down Expand Up @@ -111,7 +103,14 @@ const App = () => {
?
<MainView entries={entries}
setErr={setErr}
replaceDevice={replaceDevice}
replaceDevice={d => {
if (ss && ss.isConnected()) {
console.debug(`Discarding update, ws is connected`);
} else {
console.debug(`Accepting update, ws is disconnected`);
replaceDevice(d);
}
}}
availableDevices={availableDevices}
selectedDevice={selectedDevice}
setSelectedDevice={setSelectedDevice}
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/main/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const MainView = ({
};

useEffect(() => {
if (availableDevices && !selectedDevice) {
if (availableDevices) {
const deviceNames = Object.keys(availableDevices);
if (deviceNames.length > 0) {
setSelectedDevice(availableDevices[deviceNames[0]]);
Expand Down
50 changes: 50 additions & 0 deletions ui/src/services/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class StateService {

constructor(url) {
this.url = url;
this.ws = new WebSocket(url);
this.setErr = null;
this.replaceDevice = null;
this.ws.onerror = e => {
const msg = `Failed to connect to ${this.url}`;
if (this.setErr) {
this.setErr(new Error(msg));
} else {
console.error(msg);
}
};
this.ws.onopen = e => {
console.log(`Connected to ${this.url}`);
}
this.ws.onclose = e => {
console.log(`Closed connection to ${this.url} - ${e.code}`);
}
this.ws.onmessage = event => {
const payload = JSON.parse(event.data);
switch (payload.message) {
case 'DeviceState':
console.debug(`Replacing Device ${payload.data.name}`);
this.replaceDevice(payload.data);
break;
case 'Error':
this.setErr(new Error(payload.data));
break;
default:
console.warn(`Unknown ws message ${event.data}`)
}
};
}

init = (setErr, replaceDevice) => {
this.setErr = setErr;
this.replaceDevice = replaceDevice;
}

isConnected = () => this.ws.readyState === 1;

close = () => {
this.ws.close();
};
}

export default StateService;

0 comments on commit 3ac9e44

Please sign in to comment.