""" Autodoc functions """ import logging def __doc_app_state__(state, tab=' │ '): if '+Threads' in state: for i, tname in enumerate(state['+Threads']): if tname[0] == '+': ch = '├─●' if i < len(state['+Threads']) - 1 else '╰─●' print(f'{tab} {ch} {tname[1:]}') def __doc_state__(label, state, app, full=False): if '+Threads' in state: for tname, obj in state['+Threads'].items(): if tname[0] == '+': print() print(f"#### Thread `{tname[1:]}`\n") print(f'Visual representation of the thread `{tname[1:]}`:\n') print('```graphviz') print('digraph structs {') print(' rankdir=LR;') print(' node [shape=record];') datasources = {} if 'Functions' in obj: fns = obj['Functions'] for fn in fns: obj = app['+Functions'][f'+{fn}'] node = f' fn{fn} [label="{fn}\n{obj["Class"]}' if full: node += ' | ' outputs = '' inputs = '' if "InputSignals" in obj: for i, (l, sig) in enumerate(obj["InputSignals"].items()): if sig['DataSource'] not in datasources: datasources[sig['DataSource']] = {} sn = sig['Alias'] if 'Alias' in sig else l if sn not in datasources[sig['DataSource']]: datasources[sig['DataSource']][sn] = [f'fn{fn}:in{i}'] else: datasources[sig['DataSource']][sn].append(f'fn{fn}:in{i}') if i != 0: inputs += ' | ' inputs += f' {l} ({sig["Type"]})' if "OutputSignals" in obj: for i, (l, sig) in enumerate(obj["OutputSignals"].items()): if sig['DataSource'] not in datasources: datasources[sig['DataSource']] = {} if l not in datasources[sig['DataSource']]: datasources[sig['DataSource']][l] = [f'fn{fn}:out{i}'] else: datasources[sig['DataSource']][l].append(f'fn{fn}:out{i}') if i != 0: outputs += ' | ' outputs += f' {l} ({sig["Type"]})' node += '{ { '+inputs+' } | { '+ outputs +' } }"];' else: node += '"];' if "InputSignals" in obj: for i, (l, sig) in enumerate(obj["InputSignals"].items()): if sig['DataSource'] not in datasources: datasources[sig['DataSource']] = [] if (fn, 'in') not in datasources[sig['DataSource']]: datasources[sig['DataSource']].append((fn, 'in')) if "OutputSignals" in obj: for i, (l, sig) in enumerate(obj["OutputSignals"].items()): if sig['DataSource'] not in datasources: datasources[sig['DataSource']] = [] if (fn, 'out') not in datasources[sig['DataSource']]: datasources[sig['DataSource']].append((fn, 'out')) print(node) for l, obj in datasources.items(): logging.debug(f"datasource: {l}") ds = app['+Data'][f'+{l}'] arrows = '' node = f' ds{l} [label="{l}\n{ds["Class"]}' if full: node += ' | ' for i, s in enumerate(obj): if i > 0: node += " | " node += f' {s}' for c in obj[s]: if c.split(':')[1].startswith('in'): arrows += f' ds{l}:sig{i} -> {c};\n' else: arrows += f' {c} -> ds{l}:sig{i};\n' else: for (fn, dir) in obj: if dir == 'in': arrows += f' ds{l} -> fn{fn};\n' else: arrows += f' fn{fn} -> ds{l};\n' node += '" color=blue];' print(node) print(arrows) print('}\n```') def __doc_application__(label, app): print() print(f"## Real-time application: `{label[1:]}`") print() print(f"Below are descrbed the states and threads of the real-time application {label[1:]}.") print("```") print(f'╭{"─"*(len(label)-1)}╮') print(f'│{label[1:]}│') print(f'╰┬{"─"*(len(label)-2)}╯') states = app['+States'] for i, (label, obj) in enumerate(states.items()): ch = '├─▷' if i < len(states) - 1 else '╰─▷' tab = ' │ ' if i < len(states) - 1 else ' ' if label[0] == '+': print(f' {ch} {label[1:]}') __doc_app_state__(obj, tab) print("```") for label, obj in states.items(): if label[0] == '+': print() print(f'### State `{label[1:]}`') __doc_state__(label, obj, app) def document(label, obj): """Document MARTe object.""" if obj['Class'] == 'RealTimeApplication': __doc_application__(label, obj) if obj['Class'] == 'StateMachine': print() print(f"## State-Machine `{label[1:]}`")