Xcos: remove block default values
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / block / io / ContextUpdate.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Clement DAVID
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.block.io;
14
15 import java.beans.PropertyChangeEvent;
16 import java.beans.PropertyChangeListener;
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.Serializable;
20 import java.util.ArrayList;
21 import java.util.EnumMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
26 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
27 import org.scilab.modules.types.scilabTypes.ScilabDouble;
28 import org.scilab.modules.types.scilabTypes.ScilabList;
29 import org.scilab.modules.types.scilabTypes.ScilabType;
30 import org.scilab.modules.xcos.block.BasicBlock;
31 import org.scilab.modules.xcos.block.SuperBlock;
32 import org.scilab.modules.xcos.graph.SuperBlockDiagram;
33 import org.scilab.modules.xcos.io.scicos.H5RWHandler;
34 import org.scilab.modules.xcos.port.BasicPort;
35 import org.scilab.modules.xcos.port.command.CommandPort;
36 import org.scilab.modules.xcos.port.control.ControlPort;
37 import org.scilab.modules.xcos.port.input.ExplicitInputPort;
38 import org.scilab.modules.xcos.port.input.ImplicitInputPort;
39 import org.scilab.modules.xcos.port.output.ExplicitOutputPort;
40 import org.scilab.modules.xcos.port.output.ImplicitOutputPort;
41 import org.scilab.modules.xcos.utils.FileUtils;
42 import org.scilab.modules.xcos.utils.XcosEvent;
43
44 import com.mxgraph.model.mxGraphModel;
45 import com.mxgraph.model.mxICell;
46 import com.mxgraph.model.mxIGraphModel;
47 import com.mxgraph.util.mxEventObject;
48
49 /**
50  * Common class for the SuperBlock I/O blocks (represent ports)
51  */
52 public abstract class ContextUpdate extends BasicBlock {
53
54         private static final long serialVersionUID = 6076826729067963560L;
55
56         /**
57          * Implement a listener which update the value and refresh the view when the
58          * index of the port change.
59          */
60         private static final class IndexChangeAdapter implements PropertyChangeListener, Serializable {
61                 private static IndexChangeAdapter instance;
62                 
63                 /**
64                  * Default constructor.
65                  */
66                 private IndexChangeAdapter() { }
67                 
68                 /**
69                  * @return the instance
70                  */
71                 public static synchronized IndexChangeAdapter getInstance() {
72                         if (instance == null) {
73                                 instance = new IndexChangeAdapter();
74                         }
75                         return instance;
76                 }
77                 
78                 /**
79                  * Update the value and refresh the graph view.
80                  * 
81                  * @param evt the event
82                  * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
83                  */
84                 @Override
85                 public void propertyChange(PropertyChangeEvent evt) {
86                         ScilabType data = (ScilabType) evt.getNewValue();
87                         ContextUpdate ioBlock = (ContextUpdate) evt.getSource();
88                         
89                         if (!data.isEmpty()) {
90                                 int newIndex = (int) ((ScilabDouble) data).getRealPart()[0][0];
91                                 
92                                 int oldIndex;
93                                 if (evt.getOldValue() instanceof ScilabDouble
94                                                 && !((ScilabDouble) evt.getOldValue()).isEmpty()) {
95                                         oldIndex = (int) ((ScilabDouble) evt.getOldValue()).getRealPart()[0][0];
96                                 } else {
97                                         oldIndex = -1;
98                                 }
99                                 
100                                 ioBlock.setValue(newIndex);
101                                 
102                                 if (ioBlock.getParentDiagram() != null) {
103                                         ioBlock.getParentDiagram().fireEvent(
104                                                         new mxEventObject(XcosEvent.IO_PORT_VALUE_UPDATED,
105                                                                         "block", ioBlock, "oldIndex", oldIndex,
106                                                                         "newIndex", newIndex));
107                                 }
108                         }
109                 }
110                 
111         }
112         
113         /**
114          * This enum represent all the subclasses of ContextUpdate .
115          * 
116          * It is used to easily loop over a BasicBlock I/O blocks
117          */
118         public enum IOBlocks {
119                 /** Map a control port to an event input block */
120                 EventInBlock(EventInBlock.class, ControlPort.class),
121                 /** Map a command port to an event output block */
122                 EventOutBlock(EventOutBlock.class, CommandPort.class),
123                 /** Map an explicit input port to an explicit input block */
124                 ExplicitInBlock(ExplicitInBlock.class, ExplicitInputPort.class),
125                 /** Map an explicit output port to an explicit output block */
126                 ExplicitOutBlock(ExplicitOutBlock.class, ExplicitOutputPort.class),
127                 /** Map an implicit input port to an implicit input block */
128                 ImplicitInBlock(ImplicitInBlock.class, ImplicitInputPort.class),
129                 /** Map an implicit output port to an implicit output block */
130                 ImplicitOutBlock(ImplicitOutBlock.class, ImplicitOutputPort.class);
131
132                 private final Class< ? extends ContextUpdate> ioBlock;
133                 private final Class< ? extends BasicPort> port;
134
135                 /**
136                  * @param ioBlock
137                  *            input/output block
138                  * @param port
139                  *            the associated port class
140                  */
141                 private IOBlocks(Class< ? extends ContextUpdate> ioBlock,
142                                 Class< ? extends BasicPort> port) {
143                         this.ioBlock = ioBlock;
144                         this.port = port;
145                 }
146                 
147                 /**
148                  * Get all the port of the SuperBlock parent.
149                  * 
150                  * @param parent
151                  *            the parent
152                  * @return the port list mapped by port type
153                  */
154                 public static Map<IOBlocks, List<mxICell>> getAllPorts(SuperBlock parent) {
155                         final EnumMap<IOBlocks, List<mxICell>> ret = new EnumMap<IOBlocks, List<mxICell>>(
156                                         IOBlocks.class);
157
158                         /* Allocation */
159                         for (IOBlocks b : IOBlocks.values()) {
160                                 ret.put(b, new ArrayList<mxICell>());
161                         }
162
163                         /* Loop all over the children */
164                         final int childCount = parent.getChildCount();
165
166                         for (int i = 0; i < childCount; i++) {
167                                 final mxICell child = parent.getChildAt(i);
168
169                                 /* if compatible add it to the list */
170                                 for (IOBlocks b : IOBlocks.values()) {
171                                         if (child.getClass().equals(b.getReferencedPortClass())) {
172                                                 ret.get(b).add(child);
173                                         }
174                                 }
175                         }
176
177                         return ret;
178                 }
179
180                 /**
181                  * Get all the I/O blocks of the SuperBlock parent.
182                  * 
183                  * @param parent
184                  *            the parent
185                  * @return the port list mapped by port type
186                  */
187                 public static Map<IOBlocks, List<mxICell>> getAllBlocks(SuperBlock parent) {
188                         final EnumMap<IOBlocks, List<mxICell>> ret = new EnumMap<IOBlocks, List<mxICell>>(
189                                         IOBlocks.class);
190
191                         final SuperBlockDiagram graph = parent.getChild();
192                         if (graph == null) {
193                                 parent.createChildDiagram();
194                         }
195                         
196                         /* Allocation */
197                         for (IOBlocks b : IOBlocks.values()) {
198                                 ret.put(b, new ArrayList<mxICell>());
199                         }
200
201                         /* Loop all over the children */
202                         final Object defaultParent = graph.getDefaultParent();
203                         final mxIGraphModel defaultModel = graph.getModel();
204                         final Object[] children = mxGraphModel.getChildCells(
205                                         defaultModel, defaultParent, true, false);
206                         
207                         for (int i = 0; i < children.length; i++) {
208                                 final mxICell child = (mxICell) children[i];
209
210                                 /* if compatible add it to the list */
211                                 for (IOBlocks b : IOBlocks.values()) {
212                                         if (child.getClass().equals(b.getReferencedClass())) {
213                                                 ret.get(b).add(child);
214                                         }
215                                 }
216                         }
217
218                         return ret;
219                 }
220
221                 /**
222                  * @return referenced class
223                  */
224                 public Class< ? extends ContextUpdate> getReferencedClass() {
225                         return ioBlock;
226                 }
227
228                 /**
229                  * @return the port referenced class
230                  */
231                 public Class< ? extends BasicPort> getReferencedPortClass() {
232                         return port;
233                 }
234         }
235         
236         /**
237          * Constructor.
238          */
239         public ContextUpdate() {
240                 super();
241                 
242                 getParametersPCS().addPropertyChangeListener("integerParameters",
243                                 IndexChangeAdapter.getInstance());
244         }
245
246         /**
247          * Initialize the block with the default values
248          */
249         @Override
250         protected void setDefaultValues() {
251                 super.setDefaultValues();
252                 setNbZerosCrossing(new ScilabDouble(0));
253                 setNmode(new ScilabDouble(0));
254                 setODState(new ScilabList());
255                 setValue(1);
256         }
257
258         /**
259          * @param context
260          *            new context
261          */
262         public void onContextChange(String[] context) {
263                 // prevent to open twice
264                 if (isLocked()) {
265                         return;
266                 }
267
268                 final File tempOutput;
269                 final File tempInput;
270                 final File tempContext;
271                 try {
272                         tempInput = FileUtils.createTempFile();
273                         tempInput.deleteOnExit();
274
275                         // Write scs_m
276                         tempOutput = exportBlockStruct();
277                         // Write context
278                         tempContext = exportContext(context);
279
280                         String cmd = ScilabInterpreterManagement.buildCall("xcosBlockEval",
281                                         tempOutput.getAbsolutePath(), tempInput.getAbsolutePath(),
282                                         getInterfaceFunctionName().toCharArray(), tempContext.getAbsolutePath());
283
284                         try {
285                                 ScilabInterpreterManagement.synchronousScilabExec(cmd);
286                         } catch (InterpreterException e) {
287                                 e.printStackTrace();
288                         }
289                         BasicBlock modifiedBlock = new H5RWHandler(tempInput).readBlock();
290                         updateBlockSettings(modifiedBlock);
291
292                 } catch (IOException e) {
293                         e.printStackTrace();
294                 }
295         }
296 }