comparison m-toolbox/classes/@LTPDAworkbench/parseBlocks.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 function [cmds, rbs] = parseBlocks(blocks, wb, varID)
2
3 cmds = {};
4 rbs = [];
5 Nrbs = awtinvoke(blocks, 'size');
6
7
8 % loop over blocks
9 for jj=1:Nrbs
10 block = awtinvoke(blocks, 'get', jj-1);
11
12 if ~block.isCommentedOut
13 rbs = [rbs block];
14 bname = char(block.getName);
15 % if exist(bname) > 1 || ~isvarname(bname)
16 % error('The block named "%s" is not a valid variable name. \nPlease rename it.', bname);
17 % end
18
19 % if this is a MATBlock we treat it differently since it has
20 % no plist.
21 if isa(block, 'mpipeline.canvas.MATBlock')
22
23 cmds = parseMATblock(cmds, block, varID);
24
25 elseif isa(block, 'mpipeline.canvas.PipelineBlock')
26
27 cmds = parsePipelineBlock(cmds, block, varID);
28
29 elseif isa(block, 'mpipeline.canvas.MATfcn')
30
31 cmds = parseMATfcn(cmds, block, varID);
32
33 elseif isa(block, 'mpipeline.canvas.MTerminal')
34 % Terminals are not executed. They are skipped over when asking
35 % for source and child blocks; that's handled on the java side.
36 elseif isa(block, 'mpipeline.canvas.MConstant')
37 % Don't do anything, we did this at the beginning of
38 % execution
39 elseif isa(block, 'mpipeline.canvas.Mux')
40
41 cmds = parseMux(cmds, block, varID);
42
43 elseif isa(block, 'mpipeline.canvas.Demux')
44
45 cmds = parseDemux(cmds, block, varID);
46
47 elseif isa(block, 'mpipeline.canvas.ToWorkspace')
48
49 cmds = parseToWorkspace(cmds, block, varID);
50
51 else
52
53 cmds = parseLTPDAblock(cmds, block, wb, varID);
54
55 end % End if on block type
56 end % End if block commented out
57 end % End loop over blocks
58 end
59
60
61 %--------------------------------------------------------------------------
62 % Parse a ToWorkspace block
63 %
64 function cmds = parseToWorkspace(cmds, block, varID)
65
66 % loop over inputs to make input vars
67 inputs = block.getInputs();
68
69 % Loop over the inputs to get the variable names of the inputs
70 for kk=0:inputs.size()-1
71 ip = inputs.get(kk);
72 % get the block which is connected to this input
73 srcblock = block.getSourceBlock(ip.getNumber);
74 % get the port number at the source block
75 srcportNumber = block.getSourceBlockPortNumber(ip.getNumber);
76 if ~isempty(srcblock)
77 varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber);
78
79 % get class of the object
80 cl = evalin('base', [ 'class(' varname ')']);
81
82 % get new var name
83 % - this means split the outvar at the last '.'
84 nv = getVar(varname);
85
86 if ismember(cl, utils.helper.ltpda_userclasses)
87 cmd = [nv ' = copy(' varname ',1);'];
88 else
89 cmd = [nv ' = ' varname ';'];
90 end
91
92 cmds = [cmds {cmd}];
93 end
94 end
95
96 assignin('base', 'cmds', cmds);
97 clear();
98 cmds = evalin('base', 'cmds');
99
100 end
101
102
103 function nv = getVar(ov)
104
105 nv = '';
106
107 for kk=length(ov):-1:1
108 if ov(kk) == '.'
109 break
110 else
111 nv = [nv ov(kk)];
112 end
113 end
114
115 nv = nv(end:-1:1);
116
117 end
118
119 %--------------------------------------------------------------------------
120 % Parse a Demux block
121 %
122 function cmds = parseDemux(cmds, block, varID)
123
124 % loop over inputs to make input vars
125 inputs = block.getInputs();
126
127 % Demux has one input
128 ip = inputs.get(0);
129 % get the block which is connected to this input
130 srcblock = block.getSourceBlock(ip.getNumber);
131 % get the port number at the source block
132 srcportNumber = block.getSourceBlockPortNumber(ip.getNumber);
133 if ~isempty(srcblock)
134 varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber);
135 incmd = [varname];
136 end
137
138 % make output vars
139 outputs = block.getOutputs();
140 for kk=1:outputs.size()
141 outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1);
142 cmds = [cmds {[outvar ' = ' incmd '(' num2str(kk) ');']}];
143 end
144
145
146 end
147
148 %--------------------------------------------------------------------------
149 % Parse a Mux block
150 %
151 function cmds = parseMux(cmds, block, varID)
152
153 % loop over inputs to make input vars
154 inputs = block.getInputs();
155 incmd = '[';
156 varnames = {};
157
158 % Loop over the inputs to get the variable names of the inputs
159 for kk=0:inputs.size()-1
160 ip = inputs.get(kk);
161 % get the block which is connected to this input
162 srcblock = block.getSourceBlock(ip.getNumber);
163 % get the port number at the source block
164 srcportNumber = block.getSourceBlockPortNumber(ip.getNumber);
165 if ~isempty(srcblock)
166 varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber);
167 varnames = [varnames {varname}];
168 incmd = [incmd varname ','];
169 end
170 end
171 if incmd(end)==','
172 incmd = incmd(1:end-1);
173 end
174 incmd = strtrim(incmd);
175 incmd = [incmd ']'];
176 % make output vars
177 outputs = block.getOutputs();
178 if outputs.size() > 1
179 error('### Mux blocks should have only one output.');
180 elseif outputs.size() == 1
181 outcmd = '[';
182 for kk=1:outputs.size()
183 outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1);
184 outcmd = [outcmd outvar ' '];
185 end
186 outcmd = strtrim(outcmd);
187 outcmd = [outcmd '] = '];
188 else
189 outcmd = '';
190 end
191
192 cmds = [cmds {[outcmd incmd ';']}];
193
194
195 end
196
197
198 %--------------------------------------------------------------------------
199 % Parse a command from a MATBlock block
200 %
201 function cmds = parsePipelineBlock(cmds, block, varID)
202
203 % get variable name
204 outvar = LTPDAworkbench.getWS_VarName(varID, block, 0);
205
206 % Get source port that this block links to
207 sp = block.getSourcePort;
208 % get the parent of that port
209 sb = sp.getParent;
210 % get var name
211 srcvar = LTPDAworkbench.getWS_VarName(varID, sb, sp.getNumber);
212
213 % build command string
214 cmd = [outvar ' = ' srcvar ';'];
215
216 % we should check if the srcvar exists
217 try
218 evalin('base', [srcvar ';']);
219 catch
220 utils.helper.errorDlg(sprintf('Source variable [%s] doesn''t exist. Did you run the required pipeline?', srcvar), 'Pipeline Source Error');
221 end
222
223 cmds = [cmds {cmd}];
224
225 end
226
227
228 %--------------------------------------------------------------------------
229 % Parse a command from a MATBlock block
230 %
231 function cmds = parseMATblock(cmds, block, varID)
232
233 % get variable name
234 outvar = LTPDAworkbench.getWS_VarName(varID, block, 0);
235 % get expression
236 exp = char(block.getExpression());
237
238 % can this expression be evaluated or is it a string?
239 try
240 evalin('base', [exp ';']);
241 cmd = [outvar ' = ' exp ';'];
242 catch
243 cmd = [outvar ' = ''' exp ''';'];
244 end
245 cmds = [cmds {cmd}];
246
247 end
248
249
250 %--------------------------------------------------------------------------
251 % Parse a command from an LTPDA block
252 %
253 function cmds = parseLTPDAblock(cmds, block, wb, varID)
254
255 % We have a normal LTPDA block with a plist etc....
256
257 blockclass = char(block.getMinfo().getMclass);
258 % build command
259 cmd = strrep(char(block.getAlgoName), ' ', '_');
260
261 % make plist for this block
262 jpl = block.getPlist();
263 pl = LTPDAworkbench.jpl2mpl(jpl);
264 spl = string(pl);
265
266 % We need to skip any PORT_# when making the inputs
267 tks = regexpi(spl, 'PORT_(\d+)', 'tokens');
268 skipports = [];
269 for kk=1:numel(tks)
270 skipports = [skipports str2double(tks{kk}{1})];
271 end
272 % skipports = skipports + 1;
273 % loop over inputs to make input vars
274 inputs = block.getInputs();
275 incmd = '(';
276 varnames = {};
277
278 % Loop over the inputs to get the variable names of the inputs
279 for kk=0:inputs.size()-1
280 ip = inputs.get(kk);
281 if ~any(ip.getNumber==skipports)
282 % get the block which is connected to this input
283 srcblock = block.getSourceBlock(ip.getNumber);
284 % get the port number at the source block
285 srcportNumber = block.getSourceBlockPortNumber(ip.getNumber);
286 if ~isempty(srcblock)
287 varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber);
288 varnames = [varnames {varname}];
289 incmd = [incmd varname ','];
290 end
291 end
292 end
293 incmd = strtrim(incmd);
294 incmd = [incmd spl ')'];
295 % make output vars
296 outputs = block.getOutputs();
297 if outputs.size() > 0
298 outcmd = '[';
299 for kk=1:outputs.size()
300 output = outputs.get(kk-1);
301 outvar = LTPDAworkbench.getWS_VarName(varID, block, output.getNumber);
302 bits = regexp(outvar, '\.', 'split');
303 if exist(outvar) > 1 && ~allAreVarNames(bits)
304 error('The block named "%s" is not a valid variable name. \nPlease rename it.', outvar);
305 end
306 outcmd = [outcmd outvar ' '];
307 end
308 outcmd = strtrim(outcmd);
309 outcmd = [outcmd '] = '];
310 else
311 outcmd = '';
312 end
313
314 % Modify plist constructors looking for PORT_#
315 for kk=1:pl.nparams
316 if ischar(pl.params(kk).getVal)
317 idxs = regexpi(pl.params(kk).getVal, '(PORT_\d*)', 'tokens');
318 repstr = pl.params(kk).getVal;
319 for ii=1:numel(idxs)
320 pstr = idxs{ii}{1};
321 % get port number
322 [s,r] = strtok(pstr, '_');
323 portNumber = str2num(r(2:end));
324 % Now we need to find the name of the output variable at the
325 % other end of this pipe
326 sb = block.getSourceBlock(portNumber);
327 if ~isa(sb, 'mpipeline.canvas.MElementWithPorts')
328 error('### Block %s has an input PORT_%d specified in the plist, \nbut the block has no such input, or the input is not connected to a source block', char(block.getName()), portNumber);
329 end
330 sbp = block.getSourceBlockPortNumber(portNumber);
331 sbpn = LTPDAworkbench.getWS_VarName(varID, sb, sbp);
332 % replace the PORT_# string with the correct variable name
333 repstr = strrep(repstr, pstr, char(sbpn));
334 end
335 % If we modified the parameter value string, then we need to
336 % remove the string quotes, and replace this in the string
337 % representation of the plist (spl)
338 if ~strcmp(repstr, pl.params(kk).getVal)
339 repstr = strrep(repstr, '''', '');
340 spl = strrep(spl, ['''' pl.params(kk).getVal ''''], repstr);
341 end
342
343 % rebuild incmd
344 incmd = '(';
345 for ll=1:numel(varnames)
346 incmd = [incmd varnames{ll} ','];
347 end
348 incmd = strtrim(incmd);
349 incmd = [incmd spl ')'];
350 end
351 end
352 comment = ['% ' blockclass];
353
354 % We do something different if this is a modifier
355 if block.isModifier
356
357 mcmd = [cmd incmd ';' comment];
358 if outputs.size() > 1
359 error('Block %s is set as a modifier but has more than one output. This is not possible.', char(block.getName));
360 end
361 cmds = [cmds {mcmd}];
362 for kk=1:numel(varnames)
363 ecmd = [outvar '(' num2str(kk) ') = ' varnames{kk} ';'];
364 cmds = [cmds {ecmd}];
365 end
366
367 else
368 cmds = [cmds {[outcmd cmd incmd ';' comment]}];
369 end
370
371 % add command to set name of block if this is a constructor
372 cat = char(block.getMinfo.getMcategory);
373 if outputs.size() == 1 && strcmpi(cat, 'constructor') && (strcmpi(pl.find('name'), 'None') || isempty(pl.find('name')))
374 cmd = {[outvar '.setName(''' char(block.getName()) ''')']};
375 cmds = [cmds cmd];
376 end
377
378 % add command to attach workbench if necessary
379 if block.isAttachWorkbench
380
381 % get the workbench in XML format
382 if isa(wb, 'LTPDAworkbench')
383 xmlout = char(wb.mp.workbenchAsXMLString);
384 end
385
386 for kk=1:outputs.size()
387 outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1);
388 bits = regexp(outvar, '\.', 'split');
389 if exist(outvar) > 1 && ~allAreVarNames(bits)
390 error('The block named "%s" is not a valid variable name. \nPlease rename it.', outvar);
391 end
392 cmd = {[outvar '.setMdlfile(''' strrep(xmlout, '''', '''''') ''');']};
393 cmds = [cmds cmd];
394 end
395
396 end
397
398 end
399
400 function res = allAreVarNames(cs)
401
402 res = true;
403 for jj=1:numel(cs)
404 if ~isvarname(cs{jj})
405 res = false;
406 break;
407 end
408 end
409
410 end
411
412 %--------------------------------------------------------------------------
413 % Parse a command from a MATfcn block
414 %
415 function cmds = parseMATfcn(cmds, block, varID)
416
417 % build command
418 cmd = char(block.getFcnName);
419
420 % loop over inputs to make input vars
421 inputs = block.getInputs();
422 incmd = '(';
423 varnames = {};
424
425 % Loop over the inputs to get the variable names of the inputs
426 for kk=0:inputs.size()-1
427 ip = inputs.get(kk);
428 % get the block which is connected to this input
429 srcblock = block.getSourceBlock(ip.getNumber);
430 % get the port number at the source block
431 srcportNumber = block.getSourceBlockPortNumber(ip.getNumber);
432 if ~isempty(srcblock)
433 varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber);
434 varnames = [varnames {varname}];
435 incmd = [incmd varname ','];
436 end
437 end
438 if incmd(end)==','
439 incmd = incmd(1:end-1);
440 end
441 incmd = strtrim(incmd);
442 incmd = [incmd ')'];
443 % make output vars
444 outputs = block.getOutputs();
445 if outputs.size() > 0
446 outcmd = '[';
447 for kk=1:outputs.size()
448 outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1);
449 outcmd = [outcmd outvar ' '];
450 end
451 outcmd = strtrim(outcmd);
452 outcmd = [outcmd '] = '];
453 else
454 outcmd = '';
455 end
456
457 cmds = [cmds {[outcmd cmd incmd ';']}];
458 end
459