Mercurial > hg > ltpda
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/@LTPDAworkbench/parseBlocks.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,459 @@ +function [cmds, rbs] = parseBlocks(blocks, wb, varID) + + cmds = {}; + rbs = []; + Nrbs = awtinvoke(blocks, 'size'); + + + % loop over blocks + for jj=1:Nrbs + block = awtinvoke(blocks, 'get', jj-1); + + if ~block.isCommentedOut + rbs = [rbs block]; + bname = char(block.getName); + % if exist(bname) > 1 || ~isvarname(bname) + % error('The block named "%s" is not a valid variable name. \nPlease rename it.', bname); + % end + + % if this is a MATBlock we treat it differently since it has + % no plist. + if isa(block, 'mpipeline.canvas.MATBlock') + + cmds = parseMATblock(cmds, block, varID); + + elseif isa(block, 'mpipeline.canvas.PipelineBlock') + + cmds = parsePipelineBlock(cmds, block, varID); + + elseif isa(block, 'mpipeline.canvas.MATfcn') + + cmds = parseMATfcn(cmds, block, varID); + + elseif isa(block, 'mpipeline.canvas.MTerminal') + % Terminals are not executed. They are skipped over when asking + % for source and child blocks; that's handled on the java side. + elseif isa(block, 'mpipeline.canvas.MConstant') + % Don't do anything, we did this at the beginning of + % execution + elseif isa(block, 'mpipeline.canvas.Mux') + + cmds = parseMux(cmds, block, varID); + + elseif isa(block, 'mpipeline.canvas.Demux') + + cmds = parseDemux(cmds, block, varID); + + elseif isa(block, 'mpipeline.canvas.ToWorkspace') + + cmds = parseToWorkspace(cmds, block, varID); + + else + + cmds = parseLTPDAblock(cmds, block, wb, varID); + + end % End if on block type + end % End if block commented out + end % End loop over blocks +end + + +%-------------------------------------------------------------------------- +% Parse a ToWorkspace block +% +function cmds = parseToWorkspace(cmds, block, varID) + + % loop over inputs to make input vars + inputs = block.getInputs(); + + % Loop over the inputs to get the variable names of the inputs + for kk=0:inputs.size()-1 + ip = inputs.get(kk); + % get the block which is connected to this input + srcblock = block.getSourceBlock(ip.getNumber); + % get the port number at the source block + srcportNumber = block.getSourceBlockPortNumber(ip.getNumber); + if ~isempty(srcblock) + varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber); + + % get class of the object + cl = evalin('base', [ 'class(' varname ')']); + + % get new var name + % - this means split the outvar at the last '.' + nv = getVar(varname); + + if ismember(cl, utils.helper.ltpda_userclasses) + cmd = [nv ' = copy(' varname ',1);']; + else + cmd = [nv ' = ' varname ';']; + end + + cmds = [cmds {cmd}]; + end + end + + assignin('base', 'cmds', cmds); + clear(); + cmds = evalin('base', 'cmds'); + +end + + +function nv = getVar(ov) + + nv = ''; + + for kk=length(ov):-1:1 + if ov(kk) == '.' + break + else + nv = [nv ov(kk)]; + end + end + + nv = nv(end:-1:1); + +end + +%-------------------------------------------------------------------------- +% Parse a Demux block +% +function cmds = parseDemux(cmds, block, varID) + + % loop over inputs to make input vars + inputs = block.getInputs(); + + % Demux has one input + ip = inputs.get(0); + % get the block which is connected to this input + srcblock = block.getSourceBlock(ip.getNumber); + % get the port number at the source block + srcportNumber = block.getSourceBlockPortNumber(ip.getNumber); + if ~isempty(srcblock) + varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber); + incmd = [varname]; + end + + % make output vars + outputs = block.getOutputs(); + for kk=1:outputs.size() + outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1); + cmds = [cmds {[outvar ' = ' incmd '(' num2str(kk) ');']}]; + end + + +end + +%-------------------------------------------------------------------------- +% Parse a Mux block +% +function cmds = parseMux(cmds, block, varID) + + % loop over inputs to make input vars + inputs = block.getInputs(); + incmd = '['; + varnames = {}; + + % Loop over the inputs to get the variable names of the inputs + for kk=0:inputs.size()-1 + ip = inputs.get(kk); + % get the block which is connected to this input + srcblock = block.getSourceBlock(ip.getNumber); + % get the port number at the source block + srcportNumber = block.getSourceBlockPortNumber(ip.getNumber); + if ~isempty(srcblock) + varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber); + varnames = [varnames {varname}]; + incmd = [incmd varname ',']; + end + end + if incmd(end)==',' + incmd = incmd(1:end-1); + end + incmd = strtrim(incmd); + incmd = [incmd ']']; + % make output vars + outputs = block.getOutputs(); + if outputs.size() > 1 + error('### Mux blocks should have only one output.'); + elseif outputs.size() == 1 + outcmd = '['; + for kk=1:outputs.size() + outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1); + outcmd = [outcmd outvar ' ']; + end + outcmd = strtrim(outcmd); + outcmd = [outcmd '] = ']; + else + outcmd = ''; + end + + cmds = [cmds {[outcmd incmd ';']}]; + + +end + + +%-------------------------------------------------------------------------- +% Parse a command from a MATBlock block +% +function cmds = parsePipelineBlock(cmds, block, varID) + + % get variable name + outvar = LTPDAworkbench.getWS_VarName(varID, block, 0); + + % Get source port that this block links to + sp = block.getSourcePort; + % get the parent of that port + sb = sp.getParent; + % get var name + srcvar = LTPDAworkbench.getWS_VarName(varID, sb, sp.getNumber); + + % build command string + cmd = [outvar ' = ' srcvar ';']; + + % we should check if the srcvar exists + try + evalin('base', [srcvar ';']); + catch + utils.helper.errorDlg(sprintf('Source variable [%s] doesn''t exist. Did you run the required pipeline?', srcvar), 'Pipeline Source Error'); + end + + cmds = [cmds {cmd}]; + +end + + +%-------------------------------------------------------------------------- +% Parse a command from a MATBlock block +% +function cmds = parseMATblock(cmds, block, varID) + + % get variable name + outvar = LTPDAworkbench.getWS_VarName(varID, block, 0); + % get expression + exp = char(block.getExpression()); + + % can this expression be evaluated or is it a string? + try + evalin('base', [exp ';']); + cmd = [outvar ' = ' exp ';']; + catch + cmd = [outvar ' = ''' exp ''';']; + end + cmds = [cmds {cmd}]; + +end + + +%-------------------------------------------------------------------------- +% Parse a command from an LTPDA block +% +function cmds = parseLTPDAblock(cmds, block, wb, varID) + + % We have a normal LTPDA block with a plist etc.... + + blockclass = char(block.getMinfo().getMclass); + % build command + cmd = strrep(char(block.getAlgoName), ' ', '_'); + + % make plist for this block + jpl = block.getPlist(); + pl = LTPDAworkbench.jpl2mpl(jpl); + spl = string(pl); + + % We need to skip any PORT_# when making the inputs + tks = regexpi(spl, 'PORT_(\d+)', 'tokens'); + skipports = []; + for kk=1:numel(tks) + skipports = [skipports str2double(tks{kk}{1})]; + end + % skipports = skipports + 1; + % loop over inputs to make input vars + inputs = block.getInputs(); + incmd = '('; + varnames = {}; + + % Loop over the inputs to get the variable names of the inputs + for kk=0:inputs.size()-1 + ip = inputs.get(kk); + if ~any(ip.getNumber==skipports) + % get the block which is connected to this input + srcblock = block.getSourceBlock(ip.getNumber); + % get the port number at the source block + srcportNumber = block.getSourceBlockPortNumber(ip.getNumber); + if ~isempty(srcblock) + varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber); + varnames = [varnames {varname}]; + incmd = [incmd varname ',']; + end + end + end + incmd = strtrim(incmd); + incmd = [incmd spl ')']; + % make output vars + outputs = block.getOutputs(); + if outputs.size() > 0 + outcmd = '['; + for kk=1:outputs.size() + output = outputs.get(kk-1); + outvar = LTPDAworkbench.getWS_VarName(varID, block, output.getNumber); + bits = regexp(outvar, '\.', 'split'); + if exist(outvar) > 1 && ~allAreVarNames(bits) + error('The block named "%s" is not a valid variable name. \nPlease rename it.', outvar); + end + outcmd = [outcmd outvar ' ']; + end + outcmd = strtrim(outcmd); + outcmd = [outcmd '] = ']; + else + outcmd = ''; + end + + % Modify plist constructors looking for PORT_# + for kk=1:pl.nparams + if ischar(pl.params(kk).getVal) + idxs = regexpi(pl.params(kk).getVal, '(PORT_\d*)', 'tokens'); + repstr = pl.params(kk).getVal; + for ii=1:numel(idxs) + pstr = idxs{ii}{1}; + % get port number + [s,r] = strtok(pstr, '_'); + portNumber = str2num(r(2:end)); + % Now we need to find the name of the output variable at the + % other end of this pipe + sb = block.getSourceBlock(portNumber); + if ~isa(sb, 'mpipeline.canvas.MElementWithPorts') + 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); + end + sbp = block.getSourceBlockPortNumber(portNumber); + sbpn = LTPDAworkbench.getWS_VarName(varID, sb, sbp); + % replace the PORT_# string with the correct variable name + repstr = strrep(repstr, pstr, char(sbpn)); + end + % If we modified the parameter value string, then we need to + % remove the string quotes, and replace this in the string + % representation of the plist (spl) + if ~strcmp(repstr, pl.params(kk).getVal) + repstr = strrep(repstr, '''', ''); + spl = strrep(spl, ['''' pl.params(kk).getVal ''''], repstr); + end + + % rebuild incmd + incmd = '('; + for ll=1:numel(varnames) + incmd = [incmd varnames{ll} ',']; + end + incmd = strtrim(incmd); + incmd = [incmd spl ')']; + end + end + comment = ['% ' blockclass]; + + % We do something different if this is a modifier + if block.isModifier + + mcmd = [cmd incmd ';' comment]; + if outputs.size() > 1 + error('Block %s is set as a modifier but has more than one output. This is not possible.', char(block.getName)); + end + cmds = [cmds {mcmd}]; + for kk=1:numel(varnames) + ecmd = [outvar '(' num2str(kk) ') = ' varnames{kk} ';']; + cmds = [cmds {ecmd}]; + end + + else + cmds = [cmds {[outcmd cmd incmd ';' comment]}]; + end + + % add command to set name of block if this is a constructor + cat = char(block.getMinfo.getMcategory); + if outputs.size() == 1 && strcmpi(cat, 'constructor') && (strcmpi(pl.find('name'), 'None') || isempty(pl.find('name'))) + cmd = {[outvar '.setName(''' char(block.getName()) ''')']}; + cmds = [cmds cmd]; + end + + % add command to attach workbench if necessary + if block.isAttachWorkbench + + % get the workbench in XML format + if isa(wb, 'LTPDAworkbench') + xmlout = char(wb.mp.workbenchAsXMLString); + end + + for kk=1:outputs.size() + outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1); + bits = regexp(outvar, '\.', 'split'); + if exist(outvar) > 1 && ~allAreVarNames(bits) + error('The block named "%s" is not a valid variable name. \nPlease rename it.', outvar); + end + cmd = {[outvar '.setMdlfile(''' strrep(xmlout, '''', '''''') ''');']}; + cmds = [cmds cmd]; + end + + end + +end + +function res = allAreVarNames(cs) + + res = true; + for jj=1:numel(cs) + if ~isvarname(cs{jj}) + res = false; + break; + end + end + +end + +%-------------------------------------------------------------------------- +% Parse a command from a MATfcn block +% +function cmds = parseMATfcn(cmds, block, varID) + + % build command + cmd = char(block.getFcnName); + + % loop over inputs to make input vars + inputs = block.getInputs(); + incmd = '('; + varnames = {}; + + % Loop over the inputs to get the variable names of the inputs + for kk=0:inputs.size()-1 + ip = inputs.get(kk); + % get the block which is connected to this input + srcblock = block.getSourceBlock(ip.getNumber); + % get the port number at the source block + srcportNumber = block.getSourceBlockPortNumber(ip.getNumber); + if ~isempty(srcblock) + varname = LTPDAworkbench.getWS_VarName(varID, srcblock, srcportNumber); + varnames = [varnames {varname}]; + incmd = [incmd varname ',']; + end + end + if incmd(end)==',' + incmd = incmd(1:end-1); + end + incmd = strtrim(incmd); + incmd = [incmd ')']; + % make output vars + outputs = block.getOutputs(); + if outputs.size() > 0 + outcmd = '['; + for kk=1:outputs.size() + outvar = LTPDAworkbench.getWS_VarName(varID, block, kk-1); + outcmd = [outcmd outvar ' ']; + end + outcmd = strtrim(outcmd); + outcmd = [outcmd '] = ']; + else + outcmd = ''; + end + + cmds = [cmds {[outcmd cmd incmd ';']}]; +end +