diff --git a/AlgebraicDataflowArchitectureModel/models/SimpleUI.model b/AlgebraicDataflowArchitectureModel/models/SimpleUI.model index 584d8e3..3b0d023 100644 --- a/AlgebraicDataflowArchitectureModel/models/SimpleUI.model +++ b/AlgebraicDataflowArchitectureModel/models/SimpleUI.model @@ -1,5 +1,5 @@ native channel ScreenUpdate { - in screen(curSc: Json, update(nextSc)) = nextSc + in screen(curSc: Json, update(curSc, nextSc)) = nextSc } native channel SetVisible(wid: Str) { @@ -26,6 +26,6 @@ out screen.widgets(widgets: Map, addLabel(wid: Str, text: Str)) = insert(widgets, wid, {"type": "label", "text": text, "state": 0}) } -channel AddInputText { - out screen.widgets(widgets: Map, addInputText(wid: Str)) = insert(widgets, wid, {"type": "inputText", "state": 0}) -} +channel AddTextInput { + out screen.widgets(widgets: Map, addTextInput(wid: Str)) = insert(widgets, wid, {"type": "textInput", "text": "", "state": 0}) +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index eb5e29e..2776604 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -200,6 +200,8 @@ result = (Long.parseLong(sArg0) == Long.parseLong(sArg1)); } else if (arg0.getType().equals(typeInt) || arg1.getType().equals(typeInt)) { result = (Integer.parseInt(sArg0) == Integer.parseInt(sArg1)); + } else if (arg0.getType().equals(typeString) || arg1.getType().equals(typeString)) { + result = (sArg0.toString().equals(sArg1.toString())); } if (result) { return new Constant(true_); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java index 6c5d1eb..a5c1973 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonTerm.java @@ -38,6 +38,16 @@ return getChild(keyToIndex.get(key.toString())); } + @Override + public Object clone() { + JsonTerm newTerm = new JsonTerm(); + for (Expression e: children) { + newTerm.addChild((Expression) e.clone()); + } + newTerm.keyToIndex = new HashMap(keyToIndex); + return newTerm; + } + public String toString() { String jsonStr = "{"; String delim = ""; diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java index d70d476..de5b736 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java @@ -1,5 +1,7 @@ package models.dataConstraintModel; +import java.util.HashMap; + import models.algebra.Expression; import models.algebra.Symbol; import models.algebra.Term; @@ -19,6 +21,15 @@ return getChild(index); } + @Override + public Object clone() { + ListTerm newTerm = new ListTerm(); + for (Expression e: children) { + newTerm.addChild((Expression) e.clone()); + } + return newTerm; + } + public String toString() { String listStr = "["; String delim = ""; diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/MapTerm.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/MapTerm.java index 34792f6..3646146 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/MapTerm.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/MapTerm.java @@ -38,6 +38,16 @@ return getChild(keyToIndex.get(key.toString())); } + @Override + public Object clone() { + MapTerm newTerm = new MapTerm(); + for (Expression e: children) { + newTerm.addChild((Expression) e.clone()); + } + newTerm.keyToIndex = new HashMap(keyToIndex); + return newTerm; + } + public String toString() { String mapStr = "{"; String delim = ""; diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/ChannelState.java b/AlgebraicDataflowArchitectureModel/src/simulator/ChannelState.java index 9fd4993..101bb80 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/ChannelState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/ChannelState.java @@ -10,7 +10,7 @@ import models.dataConstraintModel.Selector; import models.dataFlowModel.DataTransferChannel; -public class ChannelState { +public class ChannelState implements Cloneable { private DataTransferChannel channel; private ReferenceStructure referenceStructure; @@ -52,7 +52,13 @@ referenceStructure.addDependingParamAndValue(channelValues, dependingVariable, itsValue); } - private static class ReferenceStructure { + public Object clone() { + ChannelState newChannelState = new ChannelState(channel); + newChannelState.referenceStructure = (ReferenceStructure) referenceStructure.clone(); + return newChannelState; + } + + private static class ReferenceStructure implements Cloneable { private Map dependingParamAndValues = null; private Map referenceStructure; @@ -130,5 +136,17 @@ public ReferenceStructure getReferenceStructure(Constant channelParam) { return referenceStructure.get(channelParam); } + + public Object clone() { + ReferenceStructure newReferenceStructure = new ReferenceStructure(); + newReferenceStructure.dependingParamAndValues = new HashMap<>(dependingParamAndValues); + if (referenceStructure != null) { + newReferenceStructure.referenceStructure = new HashMap<>(); + for (Map.Entry refEnt: referenceStructure.entrySet()) { + newReferenceStructure.referenceStructure.put(refEnt.getKey(), (ReferenceStructure) refEnt.getValue().clone()); + } + } + return newReferenceStructure; + } } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java index b0bce8c..643be88 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Event.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Event.java @@ -55,7 +55,7 @@ } ancestor = ancestor.getParent(); } - channelSelectorAndValues.add(new AbstractMap.SimpleEntry<>(sel, ancestor.getParameter())); + if (ancestor!= null) channelSelectorAndValues.add(new AbstractMap.SimpleEntry<>(sel, ancestor.getParameter())); } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java index 48dad8f..23254b8 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java @@ -1,16 +1,13 @@ package simulator; -import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import models.algebra.Constant; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.ResourceHierarchy; -import models.dataConstraintModel.ResourcePath; import simulator.states.*; public class Resource { @@ -20,6 +17,13 @@ private ResourceState state = null; private Constant parameter = null; + public Resource(Resource resource) { + this.resourceHierarchy = resource.resourceHierarchy; + this.parent = resource.parent; + this.state = (ResourceState) resource.state.clone(); + this.parameter = resource.parameter; + } + public Resource(ResourceHierarchy resourceHierarchy) { this.resourceHierarchy = resourceHierarchy; Type resType = resourceHierarchy.getResourceStateType(); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 2338858..e4fbd12 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -175,10 +175,10 @@ } else if (channel.isNative()) { // A native output event channel INativeReceiver receiver = nativeChannelReceivers.get(channel); // receiver for the channel - if (receiver != null) receiver.onReceiveFromModel(event); + if (receiver != null) receiver.onReceiveFromModel(event, nextSystemState); if (nativeReceivers.get(channel) != null) { receiver = nativeReceivers.get(channel).get(event.getInputResource()); // receiver for the channel and resource - if (receiver != null) receiver.onReceiveFromModel(event); + if (receiver != null) receiver.onReceiveFromModel(event, nextSystemState); } } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 8f5037e..4ae4020 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -31,8 +31,16 @@ } public SystemState(SystemState prevState) { - rootResources = new HashSet<>(prevState.getRootResources()); - channelStates = new HashMap<>(prevState.getChannelStates()); + for (Resource resource: prevState.getRootResources()) { + rootResources.add(new Resource(resource)); + } + for (Map.Entry channelEnt: prevState.getChannelStates().entrySet()) { + if (channelEnt.getValue() != null) { + channelStates.put(channelEnt.getKey(), (ChannelState) channelEnt.getValue().clone()); + } else { + channelStates.put(channelEnt.getKey(), null); + } + } } public Set getRootResources() { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/INativeReceiver.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/INativeReceiver.java index 50e651e..296506a 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/INativeReceiver.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/INativeReceiver.java @@ -1,7 +1,8 @@ package simulator.interfaces; import simulator.Event; +import simulator.SystemState; public interface INativeReceiver { - public void onReceiveFromModel(Event event); + public void onReceiveFromModel(Event event, SystemState nextSystemState); } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextReceiver.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextReceiver.java index e110a67..69badc8 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextReceiver.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextReceiver.java @@ -10,6 +10,7 @@ import models.algebra.Expression; import models.algebra.Term; import simulator.Event; +import simulator.SystemState; import simulator.interfaces.INativeReceiver; public class ComponentTextReceiver implements INativeReceiver { @@ -20,7 +21,7 @@ } @Override - public void onReceiveFromModel(Event event) { + public void onReceiveFromModel(Event event, SystemState nextSystemState) { Expression message = event.getMessage(); if (message instanceof Term) { Expression text = ((Term) message).getChild(0); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextSender.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextSender.java index 4e13f41..c6580fd 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextSender.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentTextSender.java @@ -1,8 +1,9 @@ package simulator.interfaces.swing; -import java.awt.TextField; -import java.awt.event.InputMethodEvent; -import java.awt.event.InputMethodListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; import models.algebra.Constant; import models.algebra.Expression; @@ -14,23 +15,52 @@ import simulator.Simulator; import simulator.interfaces.NativeSender; -public class ComponentTextSender extends NativeSender implements InputMethodListener { +public class ComponentTextSender extends NativeSender implements DocumentListener { public ComponentTextSender(Simulator simulator, DataTransferChannel channel, ResourcePath resourcePath, Resource resource) { super(simulator, channel, resourcePath, resource); } @Override - public void inputMethodTextChanged(InputMethodEvent event) { - Constant text = new Constant(((TextField) event.getSource()).getText(), DataConstraintModel.typeString); - Expression message = channel.getOutputChannelMembers().iterator().next().getStateTransition().getMessageExpression(); - message = (Term) message.clone(); - ((Term) message).setChild(0, text); - sendToModel(message); + public void insertUpdate(DocumentEvent e) { + Document d = e.getDocument(); + try { + Constant text = new Constant(d.getText(0, d.getLength()), DataConstraintModel.typeString); + Expression message = channel.getOutputChannelMembers().iterator().next().getStateTransition().getMessageExpression(); + message = (Term) message.clone(); + ((Term) message).setChild(0, text); + sendToModel(message); + } catch (BadLocationException e1) { + e1.printStackTrace(); + } } @Override - public void caretPositionChanged(InputMethodEvent event) { + public void removeUpdate(DocumentEvent e) { + Document d = e.getDocument(); + try { + Constant text = new Constant(d.getText(0, d.getLength()), DataConstraintModel.typeString); + Expression message = channel.getOutputChannelMembers().iterator().next().getStateTransition().getMessageExpression(); + message = (Term) message.clone(); + ((Term) message).setChild(0, text); + sendToModel(message); + } catch (BadLocationException e1) { + e1.printStackTrace(); + } + } + + @Override + public void changedUpdate(DocumentEvent e) { + Document d = e.getDocument(); + try { + Constant text = new Constant(d.getText(0, d.getLength()), DataConstraintModel.typeString); + Expression message = channel.getOutputChannelMembers().iterator().next().getStateTransition().getMessageExpression(); + message = (Term) message.clone(); + ((Term) message).setChild(0, text); + sendToModel(message); + } catch (BadLocationException e1) { + e1.printStackTrace(); + } } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentVisibilityReceiver.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentVisibilityReceiver.java index 2527a52..447dae1 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentVisibilityReceiver.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/ComponentVisibilityReceiver.java @@ -7,6 +7,7 @@ import models.algebra.Term; import models.dataConstraintModel.DataConstraintModel; import simulator.Event; +import simulator.SystemState; import simulator.interfaces.INativeReceiver; public class ComponentVisibilityReceiver implements INativeReceiver { @@ -17,7 +18,7 @@ } @Override - public void onReceiveFromModel(Event event) { + public void onReceiveFromModel(Event event, SystemState nextSystemState) { Expression message = event.getMessage(); if (message instanceof Term) { Expression visible = ((Term) message).getChild(0); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java index 68df398..e82372e 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/swing/SwingPresenter.java @@ -22,11 +22,13 @@ import simulator.Event; import simulator.Resource; import simulator.Simulator; +import simulator.SystemState; import simulator.interfaces.INativeReceiver; public class SwingPresenter implements INativeReceiver { public final String screenUpdateChannelName = "ScreenUpdate"; public final String setVisibleChannelName = "SetVisible"; + public final String setTextChannelName = "SetText"; public final String mouseEventChannelName = "MouseEvent"; public final String textEventChannelName = "TextEvent"; @@ -35,9 +37,10 @@ protected Map components; protected DataTransferChannel screenUpdateChannel; protected DataTransferChannel setVisibleChannel; + protected DataTransferChannel setTextChannel; protected DataTransferChannel mouseEventChannel; protected DataTransferChannel textEventChannel; - protected Map> channelAndResourcesForReceiving = new HashMap<>(); + protected Map> channelAndResourcesForReceiving = new HashMap<>(); public SwingPresenter(JPanel mainPanel, Simulator simulator) { this.mainPanel = mainPanel; @@ -45,92 +48,131 @@ components = new HashMap<>(); screenUpdateChannel = (DataTransferChannel) simulator.getModel().getChannel(screenUpdateChannelName); setVisibleChannel = (DataTransferChannel) simulator.getModel().getChannel(setVisibleChannelName); + setTextChannel = (DataTransferChannel) simulator.getModel().getChannel(setTextChannelName); mouseEventChannel = (DataTransferChannel) simulator.getModel().getInputChannel(mouseEventChannelName); textEventChannel = (DataTransferChannel) simulator.getModel().getInputChannel(textEventChannelName); simulator.addNativeReceiver(this, screenUpdateChannel); } @Override - public void onReceiveFromModel(Event event) { + public void onReceiveFromModel(Event event, SystemState nextSystemState) { Expression message = event.getMessage(); - if (message instanceof Term && ((Term) message).getChildren().size() == 1) { - message = ((Term) message).getChild(0); - if (message instanceof JsonTerm) { - // Remove old native receivers. - for (DataTransferChannel channel: channelAndResourcesForReceiving.keySet()) { - for (Resource resource: channelAndResourcesForReceiving.get(channel)) { - simulator.removeNativeReceiver(channel, resource); - } - } - channelAndResourcesForReceiving.clear(); - - // Reconstruct swing components. - JsonTerm screenContent = (JsonTerm) message; - Resource screenResource = simulator.getCurState().getResource(event.getInputResource().getResourceIdentifier()); - Expression widgets = screenContent.get("widgets"); - Resource widgetsResource = screenResource.getChildrenMap().get("widgets"); - if (widgets instanceof MapTerm) { - mainPanel.removeAll(); - for (String key: ((MapTerm) widgets).keySet()) { - Expression value = ((MapTerm) widgets).get(key); - if (value instanceof JsonTerm) { - JsonTerm widget = (JsonTerm) value; - Resource widgetResource = widgetsResource.getChildrenMap().get(key); - Expression type = widget.get("\"type\""); - if (type.toString().equals("\"button\"")) { - // Add a button component. - Expression text = widget.get("\"text\""); - JButton button = new JButton(text.toString().replace("\"", "")); - mainPanel.add(button); - components.put(key, button); - // Connect swing component and model. - ResourcePath resPath = mouseEventChannel.getOutputResources().iterator().next(); - button.addMouseListener(new ComponentMouseSender(simulator, mouseEventChannel, resPath, widgetResource)); // button => widgetResource - ComponentVisibilityReceiver nativeReceiver = new ComponentVisibilityReceiver(button); // widgetResource => button - simulator.addNativeReceiver(nativeReceiver, setVisibleChannel, widgetResource); - Set resources = channelAndResourcesForReceiving.get(setVisibleChannel); - if (resources == null) { - resources = new HashSet<>(); - channelAndResourcesForReceiving.put(setVisibleChannel, resources); + if (message instanceof Term && ((Term) message).getChildren().size() >= 2) { + Expression curScExp = ((Term) message).getChild(0); + Expression nextScExp = ((Term) message).getChild(1); + if (curScExp instanceof JsonTerm && nextScExp instanceof JsonTerm) { + JsonTerm curSc = (JsonTerm) curScExp; + JsonTerm nextSc = (JsonTerm) nextScExp; + Expression oldWidgets = curSc.get("widgets"); + Expression newWidgets = nextSc.get("widgets"); + if (oldWidgets instanceof MapTerm && newWidgets instanceof MapTerm) { + Set oldWidSet = new HashSet<>(((MapTerm) oldWidgets).keySet()); + Set newWidSet = new HashSet<>(((MapTerm) newWidgets).keySet()); + oldWidSet.removeAll(((MapTerm) newWidgets).keySet()); + newWidSet.removeAll(((MapTerm) oldWidgets).keySet()); + if (!oldWidSet.isEmpty() || !newWidSet.isEmpty()) { + // If the set of screen components is changed. + + // Remove old components and their native receivers. + for (String oldWid: oldWidSet) { + mainPanel.remove(components.get(oldWid)); + } + + for (DataTransferChannel channel: channelAndResourcesForReceiving.keySet()) { + Map widToResource = channelAndResourcesForReceiving.get(channel); + for (String oldWid: oldWidSet) { + Resource resource = widToResource.remove(oldWid); + if (resource != null) { + simulator.removeNativeReceiver(channel, resource); } - resources.add(widgetsResource); - } else if (type.toString().equals("\"label\"")) { - // Add a label component. - Expression text = widget.get("\"text\""); - JLabel label = new JLabel(text.toString().replace("\"", "")); - mainPanel.add(label); - components.put(key, label); - // Connect swing component and model. - ComponentVisibilityReceiver nativeReceiver = new ComponentVisibilityReceiver(label); - simulator.addNativeReceiver(nativeReceiver, setVisibleChannel, widgetResource); - Set resources = channelAndResourcesForReceiving.get(setVisibleChannel); - if (resources == null) { - resources = new HashSet<>(); - channelAndResourcesForReceiving.put(setVisibleChannel, resources); - } - resources.add(widgetsResource); - } else if (type.toString().equals("\"inputText\"")) { - // Add a text input component. - JTextField textField = new JTextField(10); - mainPanel.add(textField); - components.put(key, textField); - // Connect swing component and model. - ResourcePath resPath = textEventChannel.getOutputResources().iterator().next(); - textField.addInputMethodListener(new ComponentTextSender(simulator, textEventChannel, resPath, widgetResource)); // textField => widgetResource - ComponentVisibilityReceiver nativeReceiver = new ComponentVisibilityReceiver(textField); // widgetResource => textField - simulator.addNativeReceiver(nativeReceiver, setVisibleChannel, widgetResource); - Set resources = channelAndResourcesForReceiving.get(setVisibleChannel); - if (resources == null) { - resources = new HashSet<>(); - channelAndResourcesForReceiving.put(setVisibleChannel, resources); - } - resources.add(widgetsResource); } } + + // Add new swing components. + Resource screenResource = nextSystemState.getResource(event.getInputResource().getResourceIdentifier()); + Resource widgetsResource = screenResource.getChildrenMap().get("widgets"); + for (String newWid: newWidSet) { + Expression value = ((MapTerm) newWidgets).get(newWid); + if (value instanceof JsonTerm) { + JsonTerm widget = (JsonTerm) value; + Resource widgetResource = widgetsResource.getChildrenMap().get(newWid); + Expression type = widget.get("\"type\""); + if (type.toString().equals("\"button\"")) { + // Add a button component. + Expression text = widget.get("\"text\""); + JButton button = new JButton(text.toString().replace("\"", "")); + mainPanel.add(button); + components.put(newWid, button); + // Connect swing component and model. + ResourcePath resPath = mouseEventChannel.getOutputResources().iterator().next(); + button.addMouseListener(new ComponentMouseSender(simulator, mouseEventChannel, resPath, widgetResource)); // button => widgetResource + + ComponentVisibilityReceiver nativeVisibilityReceiver = new ComponentVisibilityReceiver(button); // widgetResource => button + simulator.addNativeReceiver(nativeVisibilityReceiver, setVisibleChannel, widgetResource); + Map resources = channelAndResourcesForReceiving.get(setVisibleChannel); + if (resources == null) { + resources = new HashMap<>(); + channelAndResourcesForReceiving.put(setVisibleChannel, resources); + } + resources.put(newWid, widgetsResource); + + ComponentTextReceiver nativeTextReceiver = new ComponentTextReceiver(button); // widgetResource => button + simulator.addNativeReceiver(nativeTextReceiver, setTextChannel, widgetResource); + resources = channelAndResourcesForReceiving.get(setTextChannel); + if (resources == null) { + resources = new HashMap<>(); + channelAndResourcesForReceiving.put(setTextChannel, resources); + } + resources.put(newWid, widgetsResource); + } else if (type.toString().equals("\"label\"")) { + // Add a label component. + Expression text = widget.get("\"text\""); + JLabel label = new JLabel(text.toString().replace("\"", "")); + mainPanel.add(label); + components.put(newWid, label); + + // Connect swing component and model. + ComponentVisibilityReceiver nativeVisibilityReceiver = new ComponentVisibilityReceiver(label); // widgetResource => label + simulator.addNativeReceiver(nativeVisibilityReceiver, setVisibleChannel, widgetResource); + Map resources = channelAndResourcesForReceiving.get(setVisibleChannel); + if (resources == null) { + resources = new HashMap<>(); + channelAndResourcesForReceiving.put(setVisibleChannel, resources); + } + resources.put(newWid, widgetsResource); + + ComponentTextReceiver nativeTextReceiver = new ComponentTextReceiver(label); // widgetResource => label + simulator.addNativeReceiver(nativeTextReceiver, setTextChannel, widgetResource); + resources = channelAndResourcesForReceiving.get(setTextChannel); + if (resources == null) { + resources = new HashMap<>(); + channelAndResourcesForReceiving.put(setTextChannel, resources); + } + resources.put(newWid, widgetsResource); + } else if (type.toString().equals("\"textInput\"")) { + // Add a text input component. + JTextField textField = new JTextField(10); + mainPanel.add(textField); + components.put(newWid, textField); + // Connect swing component and model. + ResourcePath resPath = textEventChannel.getOutputResources().iterator().next(); + textField.getDocument().addDocumentListener(new ComponentTextSender(simulator, textEventChannel, resPath, widgetResource)); // textField => widgetResource + + ComponentVisibilityReceiver nativeReceiver = new ComponentVisibilityReceiver(textField); // widgetResource => textField + simulator.addNativeReceiver(nativeReceiver, setVisibleChannel, widgetResource); + Map resources = channelAndResourcesForReceiving.get(setVisibleChannel); + if (resources == null) { + resources = new HashMap<>(); + channelAndResourcesForReceiving.put(setVisibleChannel, resources); + } + resources.put(newWid, widgetsResource); + } + } + } + mainPanel.invalidate(); + mainPanel.validate(); + mainPanel.repaint(); } - mainPanel.invalidate(); - mainPanel.validate(); - mainPanel.repaint(); } } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java index cf4ce2b..20909c6 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/JsonResourceState.java @@ -39,4 +39,12 @@ } } } + + public Object clone() { + JsonResourceState newJsonResourceState = new JsonResourceState(); + for (String key: children.keySet()) { + newJsonResourceState.children.put(key, (ResourceState) children.get(key).clone()); + } + return newJsonResourceState; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java index 0e45334..34eff54 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/ListResourceState.java @@ -45,4 +45,12 @@ } } } + + public Object clone() { + ListResourceState newListResourceState = new ListResourceState(); + for (ResourceState state: children) { + newListResourceState.children.add((ResourceState) state.clone()); + } + return newListResourceState; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java index e03d70e..6071c51 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/MapResourceState.java @@ -39,4 +39,12 @@ } } } + + public Object clone() { + MapResourceState newMapResourceState = new MapResourceState(); + for (String key: children.keySet()) { + newMapResourceState.children.put(key, (ResourceState) children.get(key).clone()); + } + return newMapResourceState; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java index d5aba63..adfb7f3 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/PrimitiveResourceState.java @@ -24,4 +24,8 @@ boolean hasChildren() { return false; } + + public Object clone() { + return this; + } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/states/State.java b/AlgebraicDataflowArchitectureModel/src/simulator/states/State.java index f9286dd..2dfa5c0 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/states/State.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/states/State.java @@ -2,6 +2,7 @@ import models.algebra.Expression; -abstract public class State { +abstract public class State implements Cloneable { abstract public Expression getValue(); + abstract public Object clone(); } diff --git a/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java b/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java index d9598b8..e014bab 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/NativeAccessTest.java @@ -81,7 +81,7 @@ }; INativeReceiver textReceiver = new INativeReceiver() { // Model to native code @Override - public void onReceiveFromModel(Event event) { // Receive a message from the model + public void onReceiveFromModel(Event event, SystemState nextSystemState) { // Receive a message from the model Expression message = event.getMessage(); System.out.println(message); }