+ protected void addHighLevelStateListener(Object state, String stateID, Consumer<Object> stateChanged)
+ {
+ AtomicReference<Object> lastHLSRef = new AtomicReference<>(getHighLevelState(state, stateID));
+ Consumer<ObservableAtomicReference<Object>> refObs = r ->
+ {
+ Object newHLS = getHighLevelState(stateID);
+ if (!Objects.equals(lastHLSRef.getAndSet(newHLS), newHLS))
+ stateChanged.accept(newHLS);
+ };
+ stateObsPerHLSListenerPerStateID.computeIfAbsent(stateID, s -> new HashMap<>()).put(stateChanged, refObs);
+ this.state.addObserver(refObs);
+ }
+
+ protected void removeHighLevelStateListener(Object state, String stateID, Consumer<Object> stateChanged)
+ {
+ getHighLevelState(state, stateID);// if this throws, we know there is no HLS with this name
+ var stateObsPerHLSListener = stateObsPerHLSListenerPerStateID.get(stateID);
+ if (stateObsPerHLSListener == null)
+ return;
+ Consumer<ObservableAtomicReference<Object>> refObs = stateObsPerHLSListener.remove(stateChanged);
+ this.state.removeObserver(refObs);
+ }
+