1 package org.simantics.document.server.state;
3 import java.io.IOException;
6 import org.simantics.databoard.Bindings;
7 import org.simantics.databoard.binding.Binding;
8 import org.simantics.databoard.binding.error.BindingConstructionException;
9 import org.simantics.databoard.binding.mutable.Variant;
10 import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
11 import org.simantics.databoard.serialization.SerializerConstructionException;
12 import org.simantics.simulator.toolkit.StandardRealm;
13 import org.simantics.simulator.toolkit.db.StandardVariableNodeManager;
14 import org.simantics.simulator.variable.exceptions.NodeManagerException;
15 import org.slf4j.LoggerFactory;
17 public class StateNodeManager extends StandardVariableNodeManager<StateNode, StateNodeManagerSupport> {
19 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StateNodeManager.class);
21 public StateNodeManager(StandardRealm<StateNode, StateNodeManagerSupport> realm, StateNode root) {
25 public void setState(String key, Object value) {
27 getRealm().syncExec(() -> {
29 StateRootNode rootNode = (StateRootNode) getRoot();
30 StatePropertyNode propertyNode = rootNode.getProperty(key);
31 if (propertyNode == null) {
32 setValue(rootNode.createProperty(key), value, Bindings.OBJECT);
33 refreshVariable(rootNode);
35 setValue(propertyNode, value, Bindings.OBJECT);
37 } catch (NodeManagerException e) {
38 LOGGER.error("Failed to set state.", e);
41 } catch (InterruptedException e) {
42 LOGGER.error("Setting state was interrupted.", e);
45 private class PropertyRunnable implements Runnable {
47 StatePropertyNode propertyNode;
49 public PropertyRunnable(String key) {
55 StateRootNode rootNode = (StateRootNode) getRoot();
56 propertyNode = rootNode.getProperty(key);
60 public StatePropertyNode getState(String key) {
62 PropertyRunnable r = new PropertyRunnable(key);
63 getRealm().syncExec(r);
64 return r.propertyNode;
65 } catch (InterruptedException e) {
66 LOGGER.error("Getting state was interrupted.", e);
71 public byte[] serialize() {
72 final byte [][] result = new byte[1][];
74 getRealm().syncExec(() -> {
75 State state = new State();
76 StateRootNode root = (StateRootNode) getRoot();
77 for (StateNode node : root.getProperties().values()) {
78 StatePropertyNode property = (StatePropertyNode)node;
80 Binding binding = Bindings.getInstanceBinding(property.getValue());
81 if (binding != null) {
82 state.properties.put(property.getName(), new Variant(binding, property.getValue()));
84 } catch (BindingConstructionException e) {
90 result[0] = Bindings.getSerializerUnchecked(State.BINDING).serialize(state);
91 } catch (RuntimeSerializerConstructionException | IOException e) {
94 } catch (InterruptedException e) {
95 LOGGER.error("Serializing state was interrupted.", e);
100 public void deserialize(byte[] bytes) {
102 getRealm().syncExec(() -> {
103 StateRootNode rootNode = (StateRootNode) getRoot();
106 State state = (State) Bindings.getSerializer(State.BINDING).deserialize(bytes);
107 for (Map.Entry<String, Variant> entry : state.properties.entrySet()) {
108 String key = entry.getKey();
109 Object value = entry.getValue().getValue();
111 setValue(rootNode.createProperty(key), value, Bindings.OBJECT);
112 } catch (NodeManagerException e) {
113 LOGGER.error("Failed to deserialize state.", e);
116 refreshVariable(rootNode);
117 } catch (IOException e1) {
118 LOGGER.error("Failed to deserialize state.", e1);
119 } catch (SerializerConstructionException e1) {
120 LOGGER.error("Failed to deserialize state.", e1);
123 } catch (InterruptedException e) {
124 LOGGER.error("Deserializing state was interrupted.", e);
128 public void clearState() {
130 getRealm().syncExec(() -> {
131 StateRootNode rootNode = (StateRootNode) getRoot();
133 refreshVariable(rootNode);
135 } catch (InterruptedException e) {
136 LOGGER.error("Clearing state was interrupted.", e);
140 public void removeState(String key) {
142 getRealm().syncExec(() -> {
143 StateRootNode rootNode = (StateRootNode) getRoot();
144 if (rootNode.removeProperty(key)) {
145 refreshVariable(rootNode);
148 } catch (InterruptedException e) {
149 LOGGER.error("Removing state was interrupted.", e);