Mercurial > hg > ltpda
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 |