diff --git a/AlgebraicDataflowArchitectureModel/models/Accounts.model b/AlgebraicDataflowArchitectureModel/models/Accounts.model index dba68ba..24710ee 100644 --- a/AlgebraicDataflowArchitectureModel/models/Accounts.model +++ b/AlgebraicDataflowArchitectureModel/models/Accounts.model @@ -1,5 +1,5 @@ channel CIO1 { - out accounts(l:Map, signup(id:Int, name:Str)) = append(l, {"name": name}) + out accounts(l:List, signup(name:Str)) = append(l, {"name": name}) } channel CIO2(uid:Int) { diff --git a/AlgebraicDataflowArchitectureModel/models/SimpleUI.model b/AlgebraicDataflowArchitectureModel/models/SimpleUI.model index ac3c51d..9b54346 100644 --- a/AlgebraicDataflowArchitectureModel/models/SimpleUI.model +++ b/AlgebraicDataflowArchitectureModel/models/SimpleUI.model @@ -1,3 +1,9 @@ +init { + screen := {"widgets": {"001": {"type": "button", "text": "OK", "state": 0}, + "002": {"type": "textInput", "text": "", "state": 0}}, + "layout": true} +} + native channel ScreenUpdate { in screen(curSc: Json, update(curSc, nextSc)) = nextSc } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 2776604..0962ce2 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -783,6 +783,15 @@ return resourceHierarchies.get(hierarchy); } + public ResourceHierarchy getOrPutResourceHierarchy(ResourceHierarchy resourceHierarchy) { + String hierarchy = resourceHierarchy.toString(); + if (resourceHierarchies.get(hierarchy) != null) { + return resourceHierarchies.get(hierarchy); + } + resourceHierarchies.put(hierarchy, resourceHierarchy); + return resourceHierarchy; + } + public List getResourcePaths() { return resourcePaths; } diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java index de5b736..91dd47d 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/ListTerm.java @@ -21,6 +21,10 @@ return getChild(index); } + public int size() { + return children.size(); + } + @Override public Object clone() { ListTerm newTerm = new ListTerm(); diff --git a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java index ec5f920..a1184ad 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java @@ -15,6 +15,7 @@ import models.dataConstraintModel.ChannelMember; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.JsonAccessor; +import models.dataConstraintModel.JsonTerm; import models.dataConstraintModel.ResourceHierarchy; import models.dataConstraintModel.ResourcePath; import models.dataConstraintModel.StateTransition; @@ -135,16 +136,21 @@ if (stream.checkNext().equals(RIGHT_CURLY_BRACKET)) return null; boolean isNative = false; - String channelOrInitKeyword = stream.next(); - if (channelOrInitKeyword.equals(NATIVE)) { + String channelOrInitOrNativeKeyword = stream.next(); + if (channelOrInitOrNativeKeyword.equals(NATIVE)) { // A native channel isNative = true; - channelOrInitKeyword = stream.next(); + channelOrInitOrNativeKeyword = stream.next(); } - if (!channelOrInitKeyword.equals(CHANNEL) && !channelOrInitKeyword.equals(SUB_CHANNEL)) { - if (!channelOrInitKeyword.equals(INIT)) throw new ExpectedChannel(stream.getLine()); + if (!channelOrInitOrNativeKeyword.equals(CHANNEL) && !channelOrInitOrNativeKeyword.equals(SUB_CHANNEL)) { + if (!channelOrInitOrNativeKeyword.equals(INIT)) throw new ExpectedChannel(stream.getLine()); parseInit(model); - channelOrInitKeyword = stream.next(); + channelOrInitOrNativeKeyword = stream.next(); + if (channelOrInitOrNativeKeyword.equals(NATIVE)) { + // A native channel + isNative = true; + channelOrInitOrNativeKeyword = stream.next(); + } } if (!stream.hasNext()) throw new ExpectedChannelName(stream.getLine()); @@ -523,21 +529,35 @@ } } +// private Expression parseJsonTerm(TokenStream stream, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon { +// Term jsonTerm = new Constant(DataConstraintModel.nil); +// jsonTerm.setType(DataConstraintModel.typeJson); +// while (stream.checkNext() != null && !stream.checkNext().equals(RIGHT_CURLY_BRACKET)) { +// String key = stream.next(); +// Constant keyExp = new Constant(key); +// keyExp.setType(DataConstraintModel.typeString); +// if (stream.checkNext() == null || !stream.checkNext().equals(COLON)) throw new ExpectedColon(stream.getLine()); +// String colon = stream.next(); +// Expression value = parseTerm(stream, model); +// Term nextTerm = new Term(DataConstraintModel.addMember); +// nextTerm.addChild(jsonTerm); +// nextTerm.addChild(keyExp); +// nextTerm.addChild(value); +// jsonTerm = nextTerm; +// if (stream.checkNext() == null || !stream.checkNext().equals(COMMA)) break; +// String comma = stream.next(); +// } +// return jsonTerm; +// } + private Expression parseJsonTerm(TokenStream stream, DataTransferModel model) throws ExpectedRightBracket, WrongJsonExpression, ExpectedColon { - Term jsonTerm = new Constant(DataConstraintModel.nil); - jsonTerm.setType(DataConstraintModel.typeJson); + JsonTerm jsonTerm = new JsonTerm(); while (stream.checkNext() != null && !stream.checkNext().equals(RIGHT_CURLY_BRACKET)) { String key = stream.next(); - Constant keyExp = new Constant(key); - keyExp.setType(DataConstraintModel.typeString); if (stream.checkNext() == null || !stream.checkNext().equals(COLON)) throw new ExpectedColon(stream.getLine()); String colon = stream.next(); Expression value = parseTerm(stream, model); - Term nextTerm = new Term(DataConstraintModel.addMember); - nextTerm.addChild(jsonTerm); - nextTerm.addChild(keyExp); - nextTerm.addChild(value); - jsonTerm = nextTerm; + jsonTerm.addMember(key, value); if (stream.checkNext() == null || !stream.checkNext().equals(COMMA)) break; String comma = stream.next(); } @@ -612,6 +632,7 @@ if (stream.checkNext().equals(LEFT_BRACKET)) break; if (stream.checkNext().equals(COLON)) break; } while (stream.next().equals(DOT)); + hierarchy = model.getOrPutResourceHierarchy(hierarchy); return hierarchy; } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java index 23254b8..14e30bb 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Resource.java @@ -5,6 +5,7 @@ import java.util.Map; import models.algebra.Constant; +import models.algebra.Expression; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.ResourceHierarchy; @@ -48,7 +49,12 @@ } } } else { - state = new PrimitiveResourceState((Constant) resourceHierarchy.getInitialValue()); + Expression initValue = resourceHierarchy.getInitialValue(); + if (initValue != null && initValue instanceof Constant) { + state = new PrimitiveResourceState((Constant) resourceHierarchy.getInitialValue()); + } else { + state = new PrimitiveResourceState(null); + } } } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java index 368b3a6..bb90111 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/Simulator.java @@ -49,7 +49,15 @@ for (ResourceHierarchy res: model.getResourceHierarchies()) { if (res.getParent() == null) { // root resource - curState.addResource(new Resource(res)); + Resource resource = new Resource(res); + curState.addResource(resource); + Expression initilValue = res.getInitialValue(); + if (initilValue != null) { + if (initilValue instanceof Term) { + initilValue = ((Term) initilValue).reduce(); + } + curState.updateResourceState(resource.getResourceIdentifier(), initilValue); + } } } for (Channel channel: model.getChannels()) { diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java index 4ae4020..5f25bdb 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/SystemState.java @@ -13,6 +13,9 @@ import models.algebra.Term; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; +import models.dataConstraintModel.JsonTerm; +import models.dataConstraintModel.ListTerm; +import models.dataConstraintModel.MapTerm; import models.dataConstraintModel.ResourceHierarchy; import models.dataFlowModel.DataTransferChannel; import simulator.states.CompositeResourceState; @@ -78,6 +81,21 @@ Type resType = resourceIdentifier.getResourceStateType(); if (resType != null && DataConstraintModel.typeList.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof ListTerm) { + ListTerm listValue = (ListTerm) resStateValue; + Resource res = getResource(resourceIdentifier); + ResourceState state = res.getState(); + ResourceIdentifier createdResource = null; + for (int i = 0; i < listValue.size(); i++) { + Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, + childExp, + resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.get(i)); + ((ListResourceState) state).addChildState(childInfo.getKey()); + createdResource = childInfo.getValue(); + } + return createdResource; } else if (resStateValue instanceof Term) { Term listValue = (Term) resStateValue; if (listValue.getSymbol().equals(DataConstraintModel.append)) { @@ -85,10 +103,10 @@ ResourceState state = res.getState(); Expression childExp = null; if (state instanceof ListResourceState) { - childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size())); + childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt); } else if (state instanceof PrimitiveResourceState && ((PrimitiveResourceState) state).getValue().getSymbol().equals(DataConstraintModel.nil)) { // If the value of state is nil. - childExp = new Constant("0"); + childExp = new Constant("0", DataConstraintModel.typeInt); ResourceState parentState = res.getParent().getState(); ResourceState newState = new ListResourceState(); if (parentState instanceof CompositeResourceState) { @@ -111,6 +129,36 @@ } } else if (resType != null && DataConstraintModel.typeMap.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof JsonTerm) { + JsonTerm mapValue = (JsonTerm) resStateValue; + Resource res = getResource(resourceIdentifier); + ResourceState state = res.getState(); + ResourceIdentifier createdResource = null; + for (String key: mapValue.keySet()) { + Expression childExp = new Constant(key, DataConstraintModel.typeString); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, + childExp, + resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); + ((MapResourceState) state).addChildState(key, childInfo.getKey()); + createdResource = childInfo.getValue(); + } + return createdResource; + } else if (resStateValue instanceof MapTerm) { + MapTerm mapValue = (MapTerm) resStateValue; + Resource res = getResource(resourceIdentifier); + ResourceState state = res.getState(); + ResourceIdentifier createdResource = null; + for (String key: mapValue.keySet()) { + Expression childExp = new Constant(key, DataConstraintModel.typeString); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, + childExp, + resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); + ((MapResourceState) state).addChildState(key, childInfo.getKey()); + createdResource = childInfo.getValue(); + } + return createdResource; } else if (resStateValue instanceof Term) { Term mapValue = (Term) resStateValue; if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { @@ -144,6 +192,33 @@ } } else if (resType != null && DataConstraintModel.typeJson.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof JsonTerm) { + JsonTerm jsonValue = (JsonTerm) resStateValue; + Resource res = getResource(resourceIdentifier); + ResourceState state = res.getState(); + ResourceIdentifier createdResource = null; + for (String key: jsonValue.keySet()) { + String memberName = key.replace("\"", ""); + ResourceHierarchy childResourceHierarchy = null; + for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { + if (childRes.getResourceName().equals(memberName)) { + childResourceHierarchy = childRes; + break; + } + } + if (childResourceHierarchy == null) { + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); + Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.get(key)); + ResourceState childState = childInfo.getKey(); + if (res.getChildrenMap() != null && res.getChildrenMap().get(memberName) != null) { + res.getChildrenMap().get(memberName).changeState(childState); + } + ((JsonResourceState) state).addChildState(memberName, childState); + createdResource = childInfo.getValue(); + } + return createdResource; } else if (resStateValue instanceof Term) { Term jsonValue = (Term) resStateValue; Resource res = getResource(resourceIdentifier); @@ -200,19 +275,34 @@ } public Map.Entry createResourceState(ResourceIdentifier resourceIdentifier, Expression resStateValue) { - Type resType = null; - if (resStateValue instanceof Term) { - resType = ((Term) resStateValue).getType(); - resStateValue = ((Term) resStateValue).reduce(); - } +// Type resType = null; +// if (resStateValue instanceof Term) { +// resType = ((Term) resStateValue).getType(); +// resStateValue = ((Term) resStateValue).reduce(); +// } + Type resType = resourceIdentifier.getResourceStateType(); if (resType != null) { if (DataConstraintModel.typeList.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof ListTerm) { + ListTerm listValue = (ListTerm) resStateValue; + ListResourceState state = new ListResourceState(); + Map.Entry createInfo = null; + for (int i = 0; i < listValue.size(); i++) { + Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, + childExp, + resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + Map.Entry childInfo = createResourceState(childResourceIdentifier, listValue.get(i)); + state.addChildState(childInfo.getKey()); + createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); + } + return createInfo; } else if (resStateValue instanceof Term) { Term listValue = (Term) resStateValue; if (listValue.getSymbol().equals(DataConstraintModel.append)) { ListResourceState state = new ListResourceState(); - Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size())); + Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt); ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); @@ -223,6 +313,34 @@ } } else if (DataConstraintModel.typeMap.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof JsonTerm) { + JsonTerm mapValue = (JsonTerm) resStateValue; + MapResourceState state = new MapResourceState(); + Map.Entry createInfo = null; + for (String key: mapValue.keySet()) { + Expression childExp = new Constant(key, DataConstraintModel.typeString); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, + childExp, + resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); + state.addChildState(key, childInfo.getKey()); + createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); + } + return createInfo; + } else if (resStateValue instanceof MapTerm) { + MapTerm mapValue = (MapTerm) resStateValue; + MapResourceState state = new MapResourceState(); + Map.Entry createInfo = null; + for (String key: mapValue.keySet()) { + Expression childExp = new Constant(key, DataConstraintModel.typeString); + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, + childExp, + resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); + Map.Entry childInfo = createResourceState(childResourceIdentifier, mapValue.get(key)); + state.addChildState(key, childInfo.getKey()); + createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); + } + return createInfo; } else if (resStateValue instanceof Term) { Term mapValue = (Term) resStateValue; if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { @@ -241,6 +359,33 @@ } } else if (DataConstraintModel.typeJson.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { + } else if (resStateValue instanceof JsonTerm) { + JsonTerm jsonValue = (JsonTerm) resStateValue; + MapResourceState state = new MapResourceState(); + Map.Entry createInfo = null; + for (String key: jsonValue.keySet()) { + String memberName = key.replace("\"", ""); + ResourceHierarchy childResourceHierarchy = null; + for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) { + if (childRes.getResourceName().equals(memberName)) { + childResourceHierarchy = childRes; + break; + } + } + if (childResourceHierarchy == null) { + childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName); + } + ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy); + Map.Entry childInfo = createResourceState(childResourceIdentifier, jsonValue.get(key)); + ResourceState childState = childInfo.getKey(); + Resource res = getResource(resourceIdentifier); + if (res != null && res.getChildrenMap() != null && res.getChildrenMap().get(memberName) != null) { + res.getChildrenMap().get(memberName).changeState(childState); + } + state.addChildState(memberName, childState); + createInfo = new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); + } + return createInfo; } else if (resStateValue instanceof Term) { Term jsonValue = (Term) resStateValue; JsonResourceState state = new JsonResourceState(); diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlElement.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlElement.java index 0373165..9696e1f 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlElement.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlElement.java @@ -1,7 +1,9 @@ package simulator.interfaces.html; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import models.algebra.Constant; import models.dataConstraintModel.JsonTerm; @@ -13,6 +15,7 @@ private final String id; private String text; private Map styles; + private Set classes; private IRestEventListener restEventListener; HtmlElement(String type, String id, String text){ @@ -20,6 +23,7 @@ this.id = id; this.text = text; styles = new HashMap<>(); + classes = new HashSet<>(); } public void setStyle(String property, String value) { @@ -30,6 +34,14 @@ styles.remove(property); } + public void addClass(String className) { + classes.add(className); + } + + public void removeClass(String className) { + classes.remove(className); + } + public MapTerm toMap() { MapTerm res = new MapTerm(); res.insert("\"type\"", new Constant("\"" + type + "\"")); @@ -40,6 +52,8 @@ stylesMap.insert(prop, new Constant(styles.get(prop))); } res.insert("\"styles\"", stylesMap); + String classTmp = "\"" + String.join(" ", classes) + "\""; + res.insert("\"class\"", new Constant(classTmp)); return res; } diff --git a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlPresenter.java b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlPresenter.java index b6c4736..d892e7d 100644 --- a/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlPresenter.java +++ b/AlgebraicDataflowArchitectureModel/src/simulator/interfaces/html/HtmlPresenter.java @@ -15,6 +15,7 @@ import models.dataFlowModel.DataTransferChannel; import simulator.Event; import simulator.Resource; +import simulator.ResourceIdentifier; import simulator.Simulator; import simulator.SystemState; import simulator.interfaces.INativeReceiver; @@ -50,8 +51,8 @@ setTextChannel = (DataTransferChannel) simulator.getModel().getChannel(setTextChannelName); textEventChannel = (DataTransferChannel) simulator.getModel().getInputChannel(textEventChannelName); simulator.addNativeReceiver(this, screenUpdateChannel); - elements = elems; + initScreen(); } @@ -90,7 +91,7 @@ } if (!newWidSet.isEmpty()) { - addNewWidgets(newWidSet, nextSystemState, event, newWidgets, addElements); + addNewWidgets(newWidSet, nextSystemState, event.getInputResource().getResourceIdentifier(), newWidgets, addElements); } } @@ -102,15 +103,69 @@ } } + private void initScreen() { + Expression initScExp = simulator.getCurState().getResource("screen").getState().getValue(); + if (initScExp instanceof JsonTerm) { + JsonTerm sendData = new JsonTerm(); + sendData.addMember("\"method\"", new Constant("\"updateHtml\"")); + JsonTerm sendElements = new JsonTerm(); + ListTerm addElements = new ListTerm(); + ListTerm delElements = new ListTerm(); - private void addNewWidgets(Set newWidSet, SystemState nextSystemState, Event event, Expression newWidgets, ListTerm addElements) { + JsonTerm nextSc = (JsonTerm) initScExp; + Expression newWidgets = nextSc.get("widgets"); - Resource screenResource = nextSystemState.getResource(event.getInputResource().getResourceIdentifier()); + if (newWidgets instanceof MapTerm) { + + Set newWidSet = new HashSet<>(((MapTerm) newWidgets).keySet()); + + if (!newWidSet.isEmpty()) { + addNewWidgets(newWidSet, simulator.getCurState().getResource("screen"), newWidgets, addElements); + } + } + + sendElements.addMember("\"add\"", addElements); + sendElements.addMember("\"delete\"", delElements); + sendData.addMember("\"data\"", sendElements); + ws.send(sendData.toString()); + } + } + + private void addNewWidgets(Set newWidSet, Resource screenResource, Expression newWidgets, ListTerm addElements) { + Resource widgetsResource = screenResource.getChildrenMap().get("widgets"); for(String newWid: newWidSet) { Expression value = ((MapTerm) newWidgets).get(newWid); - if(value instanceof JsonTerm) { - JsonTerm widget = (JsonTerm) value; + if(value instanceof MapTerm) { + MapTerm widget = (MapTerm) value; + Resource widgetResource = widgetsResource.getChildrenMap().get(newWid); + Expression type = widget.get("type"); + + switch(type.toString()) { + case "\"button\"": + addButton(widget, newWid, addElements, widgetResource); + break; + case "\"label\"": + addLabel(widget, newWid, addElements, widgetResource); + break; + case "\"textInput\"": + addTextInput(widget, newWid, addElements, widgetResource); + break; + } + } + } + + } + + + private void addNewWidgets(Set newWidSet, SystemState nextSystemState, ResourceIdentifier ri, Expression newWidgets, ListTerm addElements) { + + Resource screenResource = nextSystemState.getResource(ri); + Resource widgetsResource = screenResource.getChildrenMap().get("widgets"); + for(String newWid: newWidSet) { + Expression value = ((MapTerm) newWidgets).get(newWid); + if(value instanceof MapTerm) { + MapTerm widget = (MapTerm) value; Resource widgetResource = widgetsResource.getChildrenMap().get(newWid); Expression type = widget.get("\"type\""); @@ -130,10 +185,25 @@ } - private void addButton(JsonTerm widget, String wid, ListTerm addElements, Resource widgetResource) { - String text = widget.get("\"text\"").toString(); + private void addButton(MapTerm widget, String wid, ListTerm addElements, Resource widgetResource) { + String text = widget.get("text").toString(); HtmlElement button = new HtmlElement("button", wid, text); + Set keySet = widget.keySet(); + button.setStyle("\"position\"", "\"absolute\""); + if(keySet.contains("x")) { + button.setStyle("\"left\"", "\"" + widget.get("x") + "px\""); + } + if(keySet.contains("y")) { + button.setStyle("\"top\"", "\"" + widget.get("y") + "px\""); + } + if(keySet.contains("width")) { + button.setStyle("\"width\"", "\"" + widget.get("width") + "px\""); + } + if(keySet.contains("height")) { + button.setStyle("\"height\"", "\"" + widget.get("height") + "px\""); + } + //ボタンが押されたり離されたりした時を検知 ResourcePath resPath = mouseEventChannel.getOutputResources().iterator().next(); button.setRestEventListener(new HtmlElementMouseSender(simulator, mouseEventChannel, resPath, widgetResource)); @@ -162,10 +232,25 @@ addElements.append(button.toMap()); } - private void addLabel(JsonTerm widget, String wid, ListTerm addElements, Resource widgetResource) { - String text = widget.get("\"text\"").toString(); + private void addLabel(MapTerm widget, String wid, ListTerm addElements, Resource widgetResource) { + String text = widget.get("text").toString(); HtmlElement label = new HtmlElement("label", wid, text); + Set keySet = widget.keySet(); + label.setStyle("\"position\"", "\"absolute\""); + if(keySet.contains("x")) { + label.setStyle("\"left\"", "\"" + widget.get("x") + "px\""); + } + if(keySet.contains("y")) { + label.setStyle("\"top\"", "\"" + widget.get("y") + "px\""); + } + if(keySet.contains("width")) { + label.setStyle("\"width\"", "\"" + widget.get("width") + "px\""); + } + if(keySet.contains("height")) { + label.setStyle("\"height\"", "\"" + widget.get("height") + "px\""); + } + //ボタンが透明になったことを通知 HtmlElementVisibilityReceiver nativeVisibilityReceiver = new HtmlElementVisibilityReceiver(label, ws); simulator.addNativeReceiver(nativeVisibilityReceiver, setVisibleChannel, widgetResource); @@ -190,10 +275,25 @@ addElements.append(label.toMap()); } - private void addTextInput(JsonTerm widget, String wid, ListTerm addElements, Resource widgetResource) { - String text = widget.get("\"text\"").toString(); + private void addTextInput(MapTerm widget, String wid, ListTerm addElements, Resource widgetResource) { + String text = widget.get("text").toString(); HtmlElement textInput = new HtmlElement("textInput", wid, text); + Set keySet = widget.keySet(); + textInput.setStyle("\"position\"", "\"absolute\""); + if(keySet.contains("x")) { + textInput.setStyle("\"left\"", "\"" + widget.get("x") + "px\""); + } + if(keySet.contains("y")) { + textInput.setStyle("\"top\"", "\"" + widget.get("y") + "px\""); + } + if(keySet.contains("width")) { + textInput.setStyle("\"width\"", "\"" + widget.get("width") + "px\""); + } + if(keySet.contains("height")) { + textInput.setStyle("\"height\"", "\"" + widget.get("height") + "px\""); + } + //文字の変更を検知 ResourcePath resPath = textEventChannel.getOutputResources().iterator().next(); textInput.setRestEventListener(new HtmlElementTextSender(simulator, textEventChannel, resPath, widgetResource));