From ef610e2261b72c22b2354e236f116803b1fac7cf Mon Sep 17 00:00:00 2001 From: Alexandre HERISSE Date: Tue, 10 Sep 2013 17:22:54 +0200 Subject: [PATCH] * Bug #12796 fixed - Mismatch with superblock ports between implicit and explicit ports. Change-Id: I454c3a0b0f9cfc5222ba3e34cde04970a0de74a2 --- scilab/CHANGES_5.5.X | 5 +- .../org/scilab/modules/xcos/block/SuperBlock.java | 346 ++++++++++++++++++-- .../modules/xcos/block/io/ContextUpdate.java | 6 +- .../org/scilab/modules/xcos/graph/XcosDiagram.java | 10 +- .../modules/xcos/io/scicos/DiagramElement.java | 4 +- .../modules/xcos/utils/BlockPositioning.java | 68 ++-- 6 files changed, 379 insertions(+), 60 deletions(-) diff --git a/scilab/CHANGES_5.5.X b/scilab/CHANGES_5.5.X index b3d53ae..2a1daca 100644 --- a/scilab/CHANGES_5.5.X +++ b/scilab/CHANGES_5.5.X @@ -196,7 +196,10 @@ Xcos * Bug #12732 fixed - Improper Copyright comments in the files generated by the code generation tool. -* Bug #12797 fixed - I/O blocks generated by "Selection to Superblocks" had a +* Bug #12796 fixed - There was some mismatches between implicit + and explicit ports of superblocks. + +* Bug #12797 fixed - I/O blocks generated by "Selection to Superblocks" had wrong size. * Bug #12868 fixed - There were several problems with PULSE_SC block. diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/SuperBlock.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/SuperBlock.java index 6ef38d7..3d3088c 100644 --- a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/SuperBlock.java +++ b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/SuperBlock.java @@ -13,6 +13,7 @@ package org.scilab.modules.xcos.block; import java.io.IOException; +import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.logging.Logger; @@ -345,42 +346,337 @@ public final class SuperBlock extends BasicBlock { } /** - * update super block ports in parent diagram + * Function that insert one port on the concerned superblock + * and gives it the right order. + * + * @param order + * @param basicblock */ - public void updateExportedPort() { - if (child == null) { - return; + private void insertOnePort(int order, BasicBlock basicblock) { + try { + for (IOBlocks b : IOBlocks.values()) { + if (basicblock.getClass().equals(b.getReferencedClass())) { + BasicPort port; + port = b.getReferencedPortClass().newInstance(); + port.setOrdering(order); + insert(port); + } + } + } catch (InstantiationException e) { + Logger.getLogger(SuperBlock.class.getName()).severe(e.toString()); + } catch (IllegalAccessException e) { + Logger.getLogger(SuperBlock.class.getName()).severe(e.toString()); + } catch (Exception e) + { + Logger.getLogger(SuperBlock.class.getName()).severe(e.toString()); } - if (getParentDiagram() == null) { - setParentDiagram(Xcos.findParent(this)); + } + + /** + * Function that remove one port on the concerned superblock + * + * @param order + * @param basicport + * @param basicblock + * @return + */ + private boolean removeOnePort(int order, BasicPort basicport, BasicBlock basicblock) { + boolean port_deleted = false; + + for (IOBlocks b : IOBlocks.values()) { + if (basicport.getClass().equals(b.getReferencedPortClass())) { + if (!basicblock.getClass().equals(b.getReferencedClass())) { + // delete the port + removePort(basicport); + port_deleted = true; + } + } } - final Map> blocksMap = IOBlocks.getAllBlocks(this); + return port_deleted; + } + + /** + * + * @param basicport + */ + private void removeOnePort(BasicPort basicport) { + // delete the port + removePort(basicport); + } + + /** + * Function that returns a hashtable of IOBlocks contained in the superdiagram + * depending on their direction. + * + * @param blockMap + * a map of blocks + * @return the hashtable + */ + private Hashtable> extractContextBlocks() { + // get a map of all the IOBlocks of the superdiagram + final Map> blocksMap = IOBlocks.getAllBlocks(this); + + // create a map of all the blocks of the superdiagram depending on their type + Hashtable> context_block = new Hashtable> (); + + if (!context_block.containsKey(XcosDiagram.IN)) { + List cell_list = blocksMap.get(IOBlocks.ExplicitInBlock); + cell_list.addAll(blocksMap.get(IOBlocks.ImplicitInBlock)); + context_block.put(XcosDiagram.IN, cell_list); + } + if (!context_block.containsKey(XcosDiagram.OUT)) { + List cell_list = blocksMap.get(IOBlocks.ExplicitOutBlock); + cell_list.addAll(blocksMap.get(IOBlocks.ImplicitOutBlock)); + context_block.put(XcosDiagram.OUT, cell_list); + } + if (!context_block.containsKey(XcosDiagram.EIN)) { + List cell_list = blocksMap.get(IOBlocks.EventInBlock); + context_block.put(XcosDiagram.EIN, cell_list); + } + if (!context_block.containsKey(XcosDiagram.EOUT)) { + List cell_list = blocksMap.get(IOBlocks.EventOutBlock); + context_block.put(XcosDiagram.EOUT, cell_list); + } + + return context_block; + } + + /** + * Function that returns a hashtable of the superblock ports + * depending on their direction. + * + * @param portsMap + * a map of ports + * @return the hashtable + */ + private Hashtable> extractContextPorts() { + // get a map of all the ports of the superblock final Map> portsMap = IOBlocks.getAllPorts(this); - for (IOBlocks block : IOBlocks.values()) { - final int blockCount = blocksMap.get(block).size(); - int portCount = portsMap.get(block).size(); - // add ports if required - while (blockCount > portCount) { - try { - BasicPort port; - port = block.getReferencedPortClass().newInstance(); - addPort(port); - } catch (InstantiationException e) { - Logger.getLogger(SuperBlock.class.getName()).severe(e.toString()); - } catch (IllegalAccessException e) { - Logger.getLogger(SuperBlock.class.getName()).severe(e.toString()); + // create a map of all the ports of the superblock depending on their type + Hashtable> context_port = new Hashtable> (); + + if (!context_port.containsKey(XcosDiagram.IN)) { + List cell_list = portsMap.get(IOBlocks.ExplicitInBlock); + cell_list.addAll(portsMap.get(IOBlocks.ImplicitInBlock)); + context_port.put(XcosDiagram.IN, cell_list); + } + if (!context_port.containsKey(XcosDiagram.OUT)) { + List cell_list = portsMap.get(IOBlocks.ExplicitOutBlock); + cell_list.addAll(portsMap.get(IOBlocks.ImplicitOutBlock)); + context_port.put(XcosDiagram.OUT, cell_list); + } + if (!context_port.containsKey(XcosDiagram.EIN)) { + List cell_list = portsMap.get(IOBlocks.EventInBlock); + context_port.put(XcosDiagram.EIN, cell_list); + } + if (!context_port.containsKey(XcosDiagram.EOUT)) { + List cell_list = portsMap.get(IOBlocks.EventOutBlock); + context_port.put(XcosDiagram.EOUT, cell_list); + } + + return context_port; + } + + /** + * Function that add a port to a superblock. The function should be called only when + * the number of superdiagram blocks is higher than the superblock port number. + * + * @param key + * direction of the block ports + * @param context_block + * the list of blocks + * @param context_port + * the list of ports + */ + private void addPorts(String key, Hashtable> context_block, Map> context_port) + { + // iterate on the superdiagram blocks + for (mxICell cell : context_block.get(key)) { + if (cell instanceof BasicBlock) { + BasicBlock basicblock = (BasicBlock) cell; + int order = (int) ((ScilabDouble) basicblock.getIntegerParameters()).getRealPart()[0][0]; + + // get the new added block if found + List port_list = context_port.get(key); + boolean port_found = false; + for (mxICell port : port_list) { + if (port instanceof BasicPort) { + BasicPort basicport = (BasicPort) port; + if (order == basicport.getOrdering()) { + port_found = true; + break; + } + } + } + + if (port_found == false) { + // add the port on the superblock + insertOnePort(order, basicblock); + } + } + } + } + + /** + * Function that remove a port to a superblock. The function should be called only when + * the number of superdiagram blocks is less than the superblock port number. + * + * @param key + * direction of the block ports + * @param context_block + * the list of blocks + * @param context_port + * the list of ports + */ + private void removePorts(String key, Hashtable> context_block, Map> context_port) { + // iterate on the superblock ports + for (mxICell cell : context_port.get(key)) { + if (cell instanceof BasicPort) { + BasicPort basicport = (BasicPort) cell; + int order = basicport.getOrdering(); + + // get the port to remove + List block_list = context_block.get(key); + boolean block_found = false; + for (mxICell block : block_list) { + if (block instanceof BasicBlock) { + BasicBlock basicblock = (BasicBlock) block; + int block_order = (int) ((ScilabDouble) basicblock.getIntegerParameters()).getRealPart()[0][0]; + if (order == block_order) + { + block_found = true; + break; + } + } + } + + if (block_found == false) { + // delete the port + removeOnePort(basicport); + } + } + } + } + + /** + * Function that remove dead ports from the superblock. A dead port is a port which has not + * a corresponding superdiagram IOBlock + * + * @param key + * direction of the block ports + * @param context_block + * the list of blocks + * @param context_port + * the list of ports + */ + private void removeDeadPorts(String key, Hashtable> context_block, Map> context_port) { + // first remove dead ports + for (mxICell cell : context_port.get(key)) { + if (cell instanceof BasicPort) { + BasicPort basicport = (BasicPort) cell; + int order = basicport.getOrdering(); + + // get the port to remove + List block_list = context_block.get(key); + boolean block_found = false; + for (mxICell block : block_list) { + if (block instanceof BasicBlock) { + BasicBlock basicblock = (BasicBlock) block; + int block_order = (int) ((ScilabDouble) basicblock.getIntegerParameters()).getRealPart()[0][0]; + if (order == block_order) { + block_found = true; + break; + } + } + } + + if (block_found == false) { + // delete the port + removeOnePort(basicport); + } + } + } + } + + /** + * Function that replace a port of a superblock + * if its numbering has changed + * + * @param key + * direction of the block ports + * @param context_block + * the list of blocks + * @param context_port + * the list of ports + */ + private void replacePort(String key, Hashtable> context_block, Map> context_port) { + // iterate on the superdiagram blocks + for (mxICell cell : context_block.get(key)) { + if (cell instanceof BasicBlock) { + BasicBlock basicblock = (BasicBlock) cell; + int order = (int) ((ScilabDouble) basicblock.getIntegerParameters()).getRealPart()[0][0]; + + // verify superblock port coherence + List port_list = context_port.get(key); + BasicPort basicport = null; + boolean port_found = false; + for (mxICell port : port_list) { + if (port instanceof BasicPort) { + basicport = (BasicPort) port; + if (order == basicport.getOrdering()) { + port_found = true; + break; + } + } + } + + if (port_found == true) { + boolean port_deleted = false; + port_deleted = removeOnePort(order, basicport, basicblock); + + // add the port on the superblock if deleted + if (port_deleted == true) { + insertOnePort(order, basicblock); + } + } else { + insertOnePort(order, basicblock); } - portCount++; } + } + } + + /** + * Function that updates super block ports in parent diagram + */ + public void updateExportedPort() { + if (child == null) { + return; + } + if (getParentDiagram() == null) { + setParentDiagram(Xcos.findParent(this)); + } - // remove ports if required - while (portCount > blockCount) { - removePort((BasicPort) portsMap.get(block).get(portCount - 1)); - portCount--; + // extracting blocks from the superdiagram + Hashtable> context_block = extractContextBlocks(); + // extracting ports from the superblock + Hashtable> context_port = extractContextPorts(); + + for (String key : context_block.keySet()) { + if (context_block.get(key).size() > context_port.get(key).size()) { + // adding ports of the superblock + addPorts(key, context_block, context_port); + } else if (context_block.get(key).size() < context_port.get(key).size()) { + // removing ports of the superblock + removePorts(key, context_block, context_port); + } else { + // reordering ports of the superblock + removeDeadPorts(key, context_block, context_port); + replacePort(key, context_block, context_port); } } + getParentDiagram().fireEvent(new mxEventObject(XcosEvent.SUPER_BLOCK_UPDATED, XcosConstants.EVENT_BLOCK_UPDATED, this)); } diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/io/ContextUpdate.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/io/ContextUpdate.java index e6014f2..f8df45e 100644 --- a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/io/ContextUpdate.java +++ b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/block/io/ContextUpdate.java @@ -297,8 +297,8 @@ public abstract class ContextUpdate extends BasicBlock { * the parent * @return the port list mapped by port type */ - public static Map> getAllBlocks(SuperBlock parent) { - final EnumMap> ret = new EnumMap>(IOBlocks.class); + public static Map> getAllBlocks(SuperBlock parent) { + final EnumMap> ret = new EnumMap>(IOBlocks.class); SuperBlockDiagram graph = parent.getChild(); if (graph == null) { @@ -308,7 +308,7 @@ public abstract class ContextUpdate extends BasicBlock { /* Allocation */ for (IOBlocks b : IOBlocks.values()) { - ret.put(b, new ArrayList()); + ret.put(b, new ArrayList()); } /* Loop all over the children */ diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java index a7dd64e..b0519e1 100644 --- a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java +++ b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/graph/XcosDiagram.java @@ -124,10 +124,10 @@ public class XcosDiagram extends ScilabGraph { private static final String MODIFIED = "modified"; private static final String CELLS = "cells"; - protected static final String IN = "in"; - protected static final String OUT = "out"; - protected static final String EIN = "ein"; - protected static final String EOUT = "eout"; + public static final String IN = "in"; + public static final String OUT = "out"; + public static final String EIN = "ein"; + public static final String EOUT = "eout"; /** * Prefix used to tag text node. @@ -256,7 +256,7 @@ public class XcosDiagram extends ScilabGraph { * the block list * @return the sorted block list (same instance) */ - private List iparSort(final List blocks) { + public List iparSort(final List blocks) { Collections.sort(blocks, new Comparator() { @Override public int compare(BasicBlock o1, BasicBlock o2) { diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/DiagramElement.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/DiagramElement.java index ed1482b..763780e 100644 --- a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/DiagramElement.java +++ b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/scicos/DiagramElement.java @@ -356,11 +356,11 @@ public final class DiagramElement extends AbstractElement { // Assume that the children are sorted after decode // blk.sortChildren(); final Map> ports = IOBlocks.getAllPorts(parent); - final Map> blocks = IOBlocks.getAllBlocks(parent); + final Map> blocks = IOBlocks.getAllBlocks(parent); for (final IOBlocks io : IOBlocks.values()) { final List port = ports.get(io); - final List block = blocks.get(io); + final List block = blocks.get(io); final int len = Math.min(port.size(), block.size()); for (int i = 0; i < len; i++) { diff --git a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/utils/BlockPositioning.java b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/utils/BlockPositioning.java index 934823a..f4fdb17 100644 --- a/scilab/modules/xcos/src/java/org/scilab/modules/xcos/utils/BlockPositioning.java +++ b/scilab/modules/xcos/src/java/org/scilab/modules/xcos/utils/BlockPositioning.java @@ -14,6 +14,7 @@ package org.scilab.modules.xcos.utils; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; @@ -47,6 +48,25 @@ public final class BlockPositioning { } /** + * + */ + public static class PortComparator implements Comparator { + @Override + public int compare(BasicPort arg0, BasicPort arg1) { + int order_0 = arg0.getOrdering(); + int order_1 = arg1.getOrdering(); + + if (order_0 < order_1) { + return -1; + } else if (order_0 > order_1) { + return 1; + } else { + return 0; + } + } + } + + /** * Dispatch ports on Block's _WEST_ side. * * @param block @@ -63,6 +83,11 @@ public final class BlockPositioning { gridSize = block.getParentDiagram().getGridSize(); } + // BasicBlock.sortsort(List children) takes into account different + // parameters to order the ports list. We only need to order the ports + // given their ordering. + Collections.sort(ports, new PortComparator()); + final mxGeometry blockGeom = block.getGeometry(); assert blockGeom != null; final int portsSize = ports.size(); @@ -75,12 +100,7 @@ public final class BlockPositioning { final mxGeometry portGeom = port.getGeometry(); double nonVariantPosition = -portGeom.getWidth(); - final int order; - if (port.getOrdering() <= portsSize) { - order = port.getOrdering() - 1; - } else { - order = i; - } + final int order = i; double alignedPosition = calculateAlignedPosition(gridSize, segLength, order); portGeom.setX(nonVariantPosition); @@ -139,6 +159,11 @@ public final class BlockPositioning { gridSize = block.getParentDiagram().getGridSize(); } + // BasicBlock.sortsort(List children) takes into account different + // parameters to order the ports list. We only need to order the ports + // given their ordering. + Collections.sort(ports, new PortComparator()); + final mxGeometry blockGeom = block.getGeometry(); assert blockGeom != null; final int portsSize = ports.size(); @@ -151,12 +176,7 @@ public final class BlockPositioning { final mxGeometry portGeom = port.getGeometry(); double nonVariantPosition = -portGeom.getHeight(); - final int order; - if (port.getOrdering() <= portsSize) { - order = port.getOrdering() - 1; - } else { - order = i; - } + final int order = i; double alignedPosition = calculateAlignedPosition(gridSize, segLength, order); portGeom.setX(alignedPosition); @@ -183,6 +203,11 @@ public final class BlockPositioning { gridSize = block.getParentDiagram().getGridSize(); } + // BasicBlock.sortsort(List children) takes into account different + // parameters to order the ports list. We only need to order the ports + // given their ordering. + Collections.sort(ports, new PortComparator()); + final mxGeometry blockGeom = block.getGeometry(); assert blockGeom != null; final int portsSize = ports.size(); @@ -195,12 +220,7 @@ public final class BlockPositioning { final mxGeometry portGeom = port.getGeometry(); double nonVariantPosition = blockGeom.getWidth(); - final int order; - if (port.getOrdering() <= portsSize) { - order = port.getOrdering() - 1; - } else { - order = i; - } + final int order = i; double alignedPosition = calculateAlignedPosition(gridSize, segLength, order); portGeom.setX(nonVariantPosition); @@ -227,6 +247,11 @@ public final class BlockPositioning { gridSize = block.getParentDiagram().getGridSize(); } + // BasicBlock.sortsort(List children) takes into account different + // parameters to order the ports list. We only need to order the ports + // given their ordering. + Collections.sort(ports, new PortComparator()); + final mxGeometry blockGeom = block.getGeometry(); assert blockGeom != null; final int portsSize = ports.size(); @@ -239,12 +264,7 @@ public final class BlockPositioning { final mxGeometry portGeom = port.getGeometry(); double nonVariantPosition = blockGeom.getHeight(); - final int order; - if (port.getOrdering() <= portsSize) { - order = port.getOrdering() - 1; - } else { - order = i; - } + final int order = i; double alignedPosition = calculateAlignedPosition(gridSize, segLength, order); portGeom.setX(alignedPosition); -- 1.7.9.5