Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83048054a2 | |||
| 13c3647f74 | |||
| 87381ee328 |
@@ -1,2 +1 @@
|
|||||||
from autodoc.autodoc import *
|
from autodoc.autodoc import *
|
||||||
from autodoc.configdb import *
|
|
||||||
|
|||||||
+1
-4
@@ -11,7 +11,6 @@ import sys
|
|||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
import autodoc
|
import autodoc
|
||||||
from configdb import ConfigDB
|
|
||||||
|
|
||||||
__version__ = "0.0.0"
|
__version__ = "0.0.0"
|
||||||
|
|
||||||
@@ -79,9 +78,7 @@ def main():
|
|||||||
filename = args.output
|
filename = args.output
|
||||||
else:
|
else:
|
||||||
filename = os.path.splitext(os.path.basename(args.filename))[0]
|
filename = os.path.splitext(os.path.basename(args.filename))[0]
|
||||||
# autodoc.document(filename, args, config)
|
autodoc.document(filename, args, config)
|
||||||
|
|
||||||
cfgdb = ConfigDB()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
"""
|
|
||||||
Autodoc functions
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
import common as doc
|
|
||||||
from doc_state import *
|
|
||||||
from doc_state_machine import doc_state_machine
|
|
||||||
|
|
||||||
|
|
||||||
def __doc_app_state__(state, tab=" │ "):
|
|
||||||
res = ""
|
|
||||||
if "+Threads" in state:
|
|
||||||
for i, tname in enumerate(state["+Threads"]):
|
|
||||||
if tname[0] == "+":
|
|
||||||
ch = "├─●" if i < len(state["+Threads"]) - 1 else "╰─●"
|
|
||||||
res += f"{tab} {ch} {tname[1:]}\n"
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def __doc_application__(label, app):
|
|
||||||
logging.info(f"Documenting real time application {label}")
|
|
||||||
mdapp = f'\n## Real-time application: "{label[1:]}"\n\n'
|
|
||||||
mdapp += f"Below are descrbed the states and threads of the real-time application {label[1:]}.\n"
|
|
||||||
|
|
||||||
mdapp += "\n"
|
|
||||||
mdapp += "```\n"
|
|
||||||
# mdapp += f'╭{"─"*(len(label)-1)}╮\n'
|
|
||||||
# mdapp += f"│{label[1:]}│\n"
|
|
||||||
# mdapp += f'╰┬{"─"*(len(label)-2)}╯\n'
|
|
||||||
states = app["+States"]
|
|
||||||
|
|
||||||
for i, (state, obj) in enumerate(states.items()):
|
|
||||||
if state[0] == "+":
|
|
||||||
mdapp += f" - {state[1:]}\n"
|
|
||||||
for thread in obj["+Threads"]:
|
|
||||||
if thread[0] == "+":
|
|
||||||
mdapp += f" - {thread[1:]}\n"
|
|
||||||
ch = "├─▷" if i < len(states) - 1 else "╰─▷"
|
|
||||||
tab = " │ " if i < len(states) - 1 else " "
|
|
||||||
if label[0] == "+":
|
|
||||||
mdapp += f" {ch} {label[1:]}\n"
|
|
||||||
mdapp += __doc_app_state__(obj, tab)
|
|
||||||
mdapp += "```\n"
|
|
||||||
for label, obj in states.items():
|
|
||||||
if label[0] == "+":
|
|
||||||
mdapp += f'\n### State: "{label[1:]}"\n'
|
|
||||||
mdapp += doc_state(label, obj, app)
|
|
||||||
return mdapp
|
|
||||||
|
|
||||||
|
|
||||||
def document(fname, args, config):
|
|
||||||
"""Document MARTe object."""
|
|
||||||
doc.set_path(os.path.join(args.destination, fname))
|
|
||||||
doc.set_config(args)
|
|
||||||
if not os.path.isdir(doc.path()):
|
|
||||||
os.mkdir(doc.path())
|
|
||||||
now = datetime.now() # current date and time
|
|
||||||
today = now.strftime("%d/%m/%Y")
|
|
||||||
mddoc = "---\n"
|
|
||||||
mddoc += "toc: true\n"
|
|
||||||
mddoc += f"title: {fname} Documentation\n"
|
|
||||||
mddoc += "author: MARTe AutoDOC\n"
|
|
||||||
mddoc += "titlepage: true\n"
|
|
||||||
mddoc += f"date: {today}\n"
|
|
||||||
mddoc += "geometry: margin=2cm\n"
|
|
||||||
mddoc += "---\n\n"
|
|
||||||
|
|
||||||
mddoc += f"# {fname}\n"
|
|
||||||
for label, obj in config.items():
|
|
||||||
if "Class" in obj:
|
|
||||||
if obj["Class"] == "RealTimeApplication":
|
|
||||||
mddoc += __doc_application__(label, obj)
|
|
||||||
if obj["Class"] == "StateMachine":
|
|
||||||
mddoc += f'\n## State-Machine: "{label[1:]}"\n'
|
|
||||||
mddoc += doc_state_machine(label[1:], obj)
|
|
||||||
fpath = os.path.join(doc.path(), f"{fname}.md")
|
|
||||||
outpath = os.path.join(doc.path(), fname)
|
|
||||||
logging.info(f"Saving markdown: {fpath}")
|
|
||||||
with open(fpath, "w") as file:
|
|
||||||
file.write(mddoc)
|
|
||||||
if doc.build():
|
|
||||||
logging.info(f"Generating html: {outpath}.html")
|
|
||||||
os.system(
|
|
||||||
f"pandoc --css pandoc/styling.css --resource-path={doc.path()} --embed-resource --to html5 -s {fpath} -o {outpath}.html"
|
|
||||||
)
|
|
||||||
logging.info(f"Generating pdf: {outpath}.pdf")
|
|
||||||
os.system(
|
|
||||||
f"pandoc -H pandoc/disable_float.tex --resource-path={doc.path()} -s {fpath} -o {outpath}.pdf"
|
|
||||||
)
|
|
||||||
+1
-4
@@ -1,5 +1,4 @@
|
|||||||
import logging
|
import logging
|
||||||
import sys
|
|
||||||
|
|
||||||
__PATH__ = "."
|
__PATH__ = "."
|
||||||
__CONFIG__ = None
|
__CONFIG__ = None
|
||||||
@@ -30,14 +29,12 @@ def type_bytes_count(mtype):
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def signal_byte_size(parent_id, sig_id, sig):
|
def signal_byte_size(sig):
|
||||||
noe = 1 if "NumberOfElements" not in sig else int(sig["NumberOfElements"])
|
noe = 1 if "NumberOfElements" not in sig else int(sig["NumberOfElements"])
|
||||||
nod = 1 if "NumberOfDimensions" not in sig else int(sig["NumberOfDimensions"])
|
nod = 1 if "NumberOfDimensions" not in sig else int(sig["NumberOfDimensions"])
|
||||||
nod = nod if nod > 0 else 1
|
nod = nod if nod > 0 else 1
|
||||||
noe = noe if noe > 0 else 1
|
noe = noe if noe > 0 else 1
|
||||||
nos = 1 if "Samples" not in sig else int(sig["Samples"])
|
nos = 1 if "Samples" not in sig else int(sig["Samples"])
|
||||||
if "Type" not in sig:
|
|
||||||
logging.warning(f"no type defined for signal {parent_id}.{sig_id}")
|
|
||||||
if "Type" in sig:
|
if "Type" in sig:
|
||||||
bytes = type_bytes_count(sig["Type"])
|
bytes = type_bytes_count(sig["Type"])
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
from re import search
|
|
||||||
|
|
||||||
from MARTe.StandardParser import logging
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigDB:
|
|
||||||
def __new__(cls):
|
|
||||||
if not hasattr(cls, "instance"):
|
|
||||||
cls.instance = super(ConfigDB, cls).__new__(cls)
|
|
||||||
return cls.instance
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
ConfigDB.__INST__ = self
|
|
||||||
self.__db__ = {}
|
|
||||||
|
|
||||||
def get(self, path: str):
|
|
||||||
ipath = path.split(".")
|
|
||||||
obj = self.__db__
|
|
||||||
for p in ipath:
|
|
||||||
if p in obj:
|
|
||||||
obj = obj[p]
|
|
||||||
else:
|
|
||||||
logging.error(f"no key {p} found for {path}")
|
|
||||||
return None
|
|
||||||
return obj
|
|
||||||
|
|
||||||
def insert(self, key: dict, obj):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MARTeOBJ:
|
|
||||||
def __init__(self, fname, id, cfg):
|
|
||||||
self.__name__ = id
|
|
||||||
self.__mcls__ = cfg["Class"]
|
|
||||||
self.__struct__ = {}
|
|
||||||
for key, itm in cfg.items():
|
|
||||||
if key != "Class":
|
|
||||||
if isinstance(itm, dict) and "Class" in itm:
|
|
||||||
self.__struct__[key] = MARTeOBJ(fname, key, itm)
|
|
||||||
else:
|
|
||||||
self.__struct__[key] = itm
|
|
||||||
|
|
||||||
def pretty_print(self, spacing=""):
|
|
||||||
str = f"{spacing}{self.__name__}[{self.__mcls__}]:\n"
|
|
||||||
for key, itm in self.__struct__.items():
|
|
||||||
if isinstance(itm, MARTeOBJ):
|
|
||||||
str += itm.pretty_print(spacing + " ")
|
|
||||||
else:
|
|
||||||
str += f"{spacing} {key}: {itm}\n"
|
|
||||||
return str
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
str = f"{self.__name__}[{self.__mcls__}]:\n"
|
|
||||||
for key, itm in self.__struct__.items():
|
|
||||||
str += f" {key}: {itm}\n"
|
|
||||||
return str
|
|
||||||
|
|
||||||
|
|
||||||
def parse_config(fname: str, config: dict):
|
|
||||||
for key, obj in config.items():
|
|
||||||
ConfigDB().insert(key, obj)
|
|
||||||
+13
-13
@@ -111,7 +111,7 @@ def __doc_iogam__(id, obj, edges, thread):
|
|||||||
while input_size <= output_size and in_i < len(inputs):
|
while input_size <= output_size and in_i < len(inputs):
|
||||||
in_label = input_names[in_i]
|
in_label = input_names[in_i]
|
||||||
input = inputs[in_label]
|
input = inputs[in_label]
|
||||||
input_size += doc.signal_byte_size(id, in_label, input)
|
input_size += doc.signal_byte_size(input)
|
||||||
in_i += 1
|
in_i += 1
|
||||||
alias = doc.signal_alias(in_label, input)
|
alias = doc.signal_alias(in_label, input)
|
||||||
mtype = doc.signal_type(input)
|
mtype = doc.signal_type(input)
|
||||||
@@ -134,7 +134,7 @@ def __doc_iogam__(id, obj, edges, thread):
|
|||||||
while output_size < input_size and out_i < len(outputs):
|
while output_size < input_size and out_i < len(outputs):
|
||||||
out_label = output_names[out_i]
|
out_label = output_names[out_i]
|
||||||
output = outputs[out_label]
|
output = outputs[out_label]
|
||||||
output_size += doc.signal_byte_size(id, out_label, output)
|
output_size += doc.signal_byte_size(output)
|
||||||
out_i += 1
|
out_i += 1
|
||||||
alias = doc.signal_alias(out_label, output)
|
alias = doc.signal_alias(out_label, output)
|
||||||
mtype = doc.signal_type(output)
|
mtype = doc.signal_type(output)
|
||||||
@@ -154,14 +154,14 @@ def __doc_iogam__(id, obj, edges, thread):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
orows.append(orow)
|
orows.append(orow)
|
||||||
fill = "#eee"
|
fill = "#eeeeee"
|
||||||
fcolor = "#000"
|
fcolor = "#000000"
|
||||||
total = max(len(orows), len(irows))
|
total = max(len(orows), len(irows))
|
||||||
if bold or total > 1:
|
if bold or total > 1:
|
||||||
fill = "#eee"
|
fill = "#eeeeee"
|
||||||
bold = True
|
bold = True
|
||||||
else:
|
else:
|
||||||
fill = "#eee"
|
fill = "#eeeeee"
|
||||||
|
|
||||||
inode = f"{id}_{counter} [shape=plaintext,"
|
inode = f"{id}_{counter} [shape=plaintext,"
|
||||||
inode += f'tooltip=" IOGAM::{id} ", label=<'
|
inode += f'tooltip=" IOGAM::{id} ", label=<'
|
||||||
@@ -321,7 +321,7 @@ def __doc_mathgam__(id, obj, edges, thread):
|
|||||||
|
|
||||||
node = __gam__(id, label, obj["Class"])
|
node = __gam__(id, label, obj["Class"])
|
||||||
node += (
|
node += (
|
||||||
"<tr><td colspan='2' align='left' balign='left' bgcolor='#fef'><font face='mono' point-size='9'>"
|
"<tr><td colspan='2' align='left' balign='left' bgcolor='#ffeeff'><font face='mono' point-size='9'>"
|
||||||
+ __sanitize__(obj["Expression"])
|
+ __sanitize__(obj["Expression"])
|
||||||
+ "</font></td></tr><hr/> "
|
+ "</font></td></tr><hr/> "
|
||||||
)
|
)
|
||||||
@@ -413,12 +413,12 @@ def __process_gamds__(name, cls, signals, edges):
|
|||||||
"</td></tr>"
|
"</td></tr>"
|
||||||
)
|
)
|
||||||
if node:
|
if node:
|
||||||
label = f"""<table border="0" cellpadding="4" cellborder="1" cellspacing="0" bgcolor="#eee">
|
label = f"""<table border="0" cellpadding="4" cellborder="1" cellspacing="0" bgcolor="#eeeeee">
|
||||||
<tr><td><b>{name}</b><br/>{cls}</td></tr>
|
<tr><td><b>{name}</b><br/>{cls}</td></tr>
|
||||||
{node}
|
{node}
|
||||||
</table>
|
</table>
|
||||||
"""
|
"""
|
||||||
node = f'{name} [shape=plaintext, label=<{label}>, color="#0af"];\n'
|
node = f'{name} [shape=plaintext, label=<{label}>, color="#00aaff"];\n'
|
||||||
return node, edges
|
return node, edges
|
||||||
|
|
||||||
|
|
||||||
@@ -470,7 +470,7 @@ def __process_ds__(name, obj, edges):
|
|||||||
sig_type = sigs[sig_name]
|
sig_type = sigs[sig_name]
|
||||||
node += f"{sig_name} ({doc.type_to_string(sig_type)})"
|
node += f"{sig_name} ({doc.type_to_string(sig_type)})"
|
||||||
node += "</td></tr>\n"
|
node += "</td></tr>\n"
|
||||||
node += '</table>>, color="#0af"];\n'
|
node += '</table>>, color="#00aaff"];\n'
|
||||||
if not multi_thread and node:
|
if not multi_thread and node:
|
||||||
node = f"subgraph cluster_{thread}" + "{\n" + node + "};\n"
|
node = f"subgraph cluster_{thread}" + "{\n" + node + "};\n"
|
||||||
return node, edges
|
return node, edges
|
||||||
@@ -561,7 +561,7 @@ def __simple_gam__(label, obj):
|
|||||||
id = f"fn{doc.format_name(label)}"
|
id = f"fn{doc.format_name(label)}"
|
||||||
style = "style=rounded"
|
style = "style=rounded"
|
||||||
if cls == "IOGAM":
|
if cls == "IOGAM":
|
||||||
style = 'style="rounded,filled", fillcolor="#eee"'
|
style = 'style="rounded,filled", fillcolor="#eeeeee"'
|
||||||
elif cls == "MessageGAM":
|
elif cls == "MessageGAM":
|
||||||
style = 'style="rounded,filled", fillcolor=lightyellow'
|
style = 'style="rounded,filled", fillcolor=lightyellow'
|
||||||
if "InputSignals" in obj:
|
if "InputSignals" in obj:
|
||||||
@@ -593,10 +593,10 @@ def __simple_ds__(label, obj, edges):
|
|||||||
multi_thread = True
|
multi_thread = True
|
||||||
|
|
||||||
fillcolor = "lightblue"
|
fillcolor = "lightblue"
|
||||||
bordercolor = "#0af"
|
bordercolor = "#00aaff"
|
||||||
style = "penwidth=2"
|
style = "penwidth=2"
|
||||||
if cls == "GAMDataSource":
|
if cls == "GAMDataSource":
|
||||||
fillcolor = "#eee"
|
fillcolor = "#eeeeee"
|
||||||
node = f"{id}[label=<<B>{label}</B><BR/>{cls}>, "
|
node = f"{id}[label=<<B>{label}</B><BR/>{cls}>, "
|
||||||
node += f'{style}, fillcolor="{fillcolor}", color="{bordercolor}"]\n'
|
node += f'{style}, fillcolor="{fillcolor}", color="{bordercolor}"]\n'
|
||||||
if thread and not multi_thread:
|
if thread and not multi_thread:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,186 +0,0 @@
|
|||||||
{
|
|
||||||
"$App": {
|
|
||||||
"Class": "RealTimeApplication",
|
|
||||||
"+Data": {
|
|
||||||
"Class": "ReferenceContainer",
|
|
||||||
"+RTTimer": {
|
|
||||||
"Class": "LinuxTimer",
|
|
||||||
"SleepNature": "Busy",
|
|
||||||
"CPUMask": 2,
|
|
||||||
"Locked": 1,
|
|
||||||
"Signals": {
|
|
||||||
"Counter": {
|
|
||||||
"Type": "uint32"
|
|
||||||
},
|
|
||||||
"Time": {
|
|
||||||
"Type": "uint32"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"+Timing": {
|
|
||||||
"Class": "TimingDataSource",
|
|
||||||
"Locked": 1
|
|
||||||
},
|
|
||||||
"+DDB0": {
|
|
||||||
"Class": "GAMDataSource",
|
|
||||||
"Locked": 1,
|
|
||||||
"Signals": {
|
|
||||||
"Time": {
|
|
||||||
"Type": "uint32"
|
|
||||||
},
|
|
||||||
"Times": {
|
|
||||||
"Type": "uint32",
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"NumberOfElements": 3
|
|
||||||
},
|
|
||||||
"Amplitudes": {
|
|
||||||
"Type": "float32",
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"NumberOfElements": 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"+EpicsIn": {
|
|
||||||
"Class": "EPICSCA::EPICSCAInput",
|
|
||||||
"Locked": 1,
|
|
||||||
"Signals": {
|
|
||||||
"Amplitude": {
|
|
||||||
"Type": "float32",
|
|
||||||
"PVName": "Amplitude"
|
|
||||||
},
|
|
||||||
"Frequency": {
|
|
||||||
"Type": "float32",
|
|
||||||
"PVName": "Frequency"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"DefaultDataSource": "DDB0",
|
|
||||||
"+Logger": {
|
|
||||||
"Class": "OnChangeLoggerDataSource",
|
|
||||||
"Locked": 1,
|
|
||||||
"Signals": {
|
|
||||||
"Times": {
|
|
||||||
"Type": "uint32",
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"NumberOfElements": 3
|
|
||||||
},
|
|
||||||
"Amplitudes": {
|
|
||||||
"Type": "float32",
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"NumberOfElements": 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"+Functions": {
|
|
||||||
"+TimerGAM": {
|
|
||||||
"Class": "IOGAM",
|
|
||||||
"InputSignals": {
|
|
||||||
"Time": {
|
|
||||||
"Frequency": 100,
|
|
||||||
"DataSource": "RTTimer",
|
|
||||||
"Type": "uint32",
|
|
||||||
"Alias": "Time"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"OutputSignals": {
|
|
||||||
"Time": {
|
|
||||||
"DataSource": "DDB0",
|
|
||||||
"Type": "uint32",
|
|
||||||
"Alias": "Time"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"+Chai": {
|
|
||||||
"Class": "ChaiGAM",
|
|
||||||
"Code": "global g = 4;\nfun() {\n\tg = g + 1;\n\ty[0] = -A;\n \ty[1] = A;\n\ty[2] = -A;\n\tt[0] = g;\n\tif (freq <= 0) {\n\t\tt[1] = 0;\n\t\tt[2] = 0;\n\t} else {\n\t\tt[1] = int(5e5 / freq);\n\t\tt[2] = int(1e6 / freq);\n\t}\n}",
|
|
||||||
"InputSignals": {
|
|
||||||
"A": {
|
|
||||||
"DataSource": "EpicsIn",
|
|
||||||
"Type": "float32",
|
|
||||||
"Alias": "Amplitude"
|
|
||||||
},
|
|
||||||
"freq": {
|
|
||||||
"DataSource": "EpicsIn",
|
|
||||||
"Type": "float32",
|
|
||||||
"Alias": "Frequency"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"OutputSignals": {
|
|
||||||
"t": {
|
|
||||||
"NumberOfElements": 3,
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"DataSource": "DDB0",
|
|
||||||
"Type": "uint32",
|
|
||||||
"Alias": "Times"
|
|
||||||
},
|
|
||||||
"y": {
|
|
||||||
"NumberOfElements": 3,
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"DataSource": "DDB0",
|
|
||||||
"Type": "float32",
|
|
||||||
"Alias": "Amplitudes"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Class": "ReferenceContainer",
|
|
||||||
"+LogGAM": {
|
|
||||||
"Class": "IOGAM",
|
|
||||||
"InputSignals": {
|
|
||||||
"t": {
|
|
||||||
"NumberOfElements": 3,
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"DataSource": "DDB0",
|
|
||||||
"Type": "uint32",
|
|
||||||
"Alias": "Times"
|
|
||||||
},
|
|
||||||
"y": {
|
|
||||||
"NumberOfElements": 3,
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"DataSource": "DDB0",
|
|
||||||
"Type": "float32",
|
|
||||||
"Alias": "Amplitudes"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"OutputSignals": {
|
|
||||||
"times": {
|
|
||||||
"NumberOfElements": 3,
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"DataSource": "Logger",
|
|
||||||
"Type": "uint32",
|
|
||||||
"Alias": "Times"
|
|
||||||
},
|
|
||||||
"amplitudes": {
|
|
||||||
"NumberOfElements": 3,
|
|
||||||
"NumberOfDimensions": 1,
|
|
||||||
"DataSource": "Logger",
|
|
||||||
"Type": "float32",
|
|
||||||
"Alias": "Amplitudes"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"+States": {
|
|
||||||
"Class": "ReferenceContainer",
|
|
||||||
"+Exec": {
|
|
||||||
"Class": "RealTimeState",
|
|
||||||
"+Threads": {
|
|
||||||
"+Comm": {
|
|
||||||
"Class": "RealTimeThread",
|
|
||||||
"CPUs": 1,
|
|
||||||
"Functions": [
|
|
||||||
"TimerGAM",
|
|
||||||
"Chai",
|
|
||||||
"LogGAM"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Class": "ReferenceContainer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"+Scheduler": {
|
|
||||||
"Class": "GAMScheduler",
|
|
||||||
"TimingDataSource": "Timing"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
packages:
|
|
||||||
core:
|
|
||||||
description: "MARTe2 Core Package"
|
|
||||||
namespace: ""
|
|
||||||
url: "https://vcis-gitlab.f4e.europa.eu/aneto/MARTe2"
|
|
||||||
datasources:
|
|
||||||
GAMDataSource:
|
|
||||||
brief: "DataSource implementation for the exchange of signals between GAM components."
|
|
||||||
prameters:
|
|
||||||
HeapName:
|
|
||||||
type: "string"
|
|
||||||
comment: "GetStandardHeap() if not defined"
|
|
||||||
default: ""
|
|
||||||
AllowNoProducer:
|
|
||||||
type: "bool"
|
|
||||||
mandatory: false
|
|
||||||
default: 0
|
|
||||||
ResetUnusedVariableAtStateChange:
|
|
||||||
type: "bool"
|
|
||||||
mandatory: false
|
|
||||||
default: 1
|
|
||||||
Signals:
|
|
||||||
mode: "any"
|
|
||||||
components:
|
|
||||||
description: "MARTe2 Components"
|
|
||||||
url: "https://vcis-gitlab.f4e.europa.eu/aneto/MARTe2-components"
|
|
||||||
namespace: ""
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
import gi
|
|
||||||
|
|
||||||
gi.require_version("Gtk", "3.0")
|
|
||||||
gi.require_version("Gdk", "3.0")
|
|
||||||
|
|
||||||
from gi.repository import Gdk, Gtk
|
|
||||||
|
|
||||||
|
|
||||||
class ControlPanel(Gtk.Box):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
||||||
# Place the control panel in the top right
|
|
||||||
self.set_halign(Gtk.Align.END)
|
|
||||||
self.set_valign(Gtk.Align.START)
|
|
||||||
|
|
||||||
# Add the .control-panel CSS class to this widget
|
|
||||||
context = self.get_style_context()
|
|
||||||
context.add_class("control-panel")
|
|
||||||
|
|
||||||
def add_group(self, group):
|
|
||||||
self.pack_start(group, False, False, 0)
|
|
||||||
|
|
||||||
|
|
||||||
class ControlPanelGroup(Gtk.Expander):
|
|
||||||
def __init__(self, title: str):
|
|
||||||
Gtk.Expander.__init__(self, label=title)
|
|
||||||
self._inner = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
|
||||||
|
|
||||||
# Set the size request to 200 pixels wide
|
|
||||||
self.set_size_request(200, -1)
|
|
||||||
|
|
||||||
# Add a bit of margin after the header
|
|
||||||
self._inner.set_margin_top(5)
|
|
||||||
|
|
||||||
self.add(self._inner)
|
|
||||||
|
|
||||||
def add_row(self, widget):
|
|
||||||
self._inner.pack_start(widget, False, False, 0)
|
|
||||||
|
|
||||||
|
|
||||||
class MyControlPanel(ControlPanel):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self._first_panel = ControlPanelGroup("Some Buttons")
|
|
||||||
self._first_panel.add_row(Gtk.Button(label="Button 1"))
|
|
||||||
self._first_panel.add_row(Gtk.Button(label="Button 2"))
|
|
||||||
self.add_group(self._first_panel)
|
|
||||||
|
|
||||||
self._second_panel = ControlPanelGroup("Extra Settings")
|
|
||||||
self._second_panel.add_row(Gtk.Button(label="Button 3"))
|
|
||||||
self._second_panel.add_row(Gtk.Button(label="Button 4"))
|
|
||||||
self._second_panel.add_row(Gtk.CheckButton.new_with_label("First checkbox"))
|
|
||||||
self._second_panel.add_row(Gtk.CheckButton.new_with_label("Second checkbox"))
|
|
||||||
|
|
||||||
combo = Gtk.ComboBoxText()
|
|
||||||
combo.append("first", "First Choice")
|
|
||||||
combo.append("second", "Second Choice")
|
|
||||||
combo.append("third", "Third Choice")
|
|
||||||
combo.append("forth", "This one is quite long")
|
|
||||||
combo.set_active_id("first")
|
|
||||||
self._second_panel.add_row(combo)
|
|
||||||
|
|
||||||
self.add_group(self._second_panel)
|
|
||||||
|
|
||||||
|
|
||||||
class MapEditor(Gtk.DrawingArea):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self.set_events(
|
|
||||||
Gdk.EventMask.BUTTON_PRESS_MASK
|
|
||||||
| Gdk.EventMask.BUTTON_RELEASE_MASK
|
|
||||||
| Gdk.EventMask.POINTER_MOTION_MASK
|
|
||||||
)
|
|
||||||
|
|
||||||
self._camera_x = 0 # The X coordinate of the camera
|
|
||||||
self._camera_y = 0 # The Y coordinate of the camera
|
|
||||||
self._mouse_x = 0 # The X coordinate of the pointer
|
|
||||||
self._mouse_y = 0 # The Y coordinate of the pointer
|
|
||||||
self._button = None # The currently held mouse button
|
|
||||||
|
|
||||||
# Connect to the draw and mouse events
|
|
||||||
self.connect("draw", self.on_draw)
|
|
||||||
self.connect("button-press-event", self.on_button_press_event)
|
|
||||||
self.connect("button-release-event", self.on_button_release_event)
|
|
||||||
self.connect("motion-notify-event", self.on_motion_notify_event)
|
|
||||||
|
|
||||||
def on_button_press_event(self, widget, event):
|
|
||||||
self._mouse_x = event.x
|
|
||||||
self._mouse_y = event.y
|
|
||||||
self._button = event.button
|
|
||||||
|
|
||||||
def on_button_release_event(self, widget, event):
|
|
||||||
self._mouse_x = 0
|
|
||||||
self._mouse_y = 0
|
|
||||||
self._button = None
|
|
||||||
|
|
||||||
def on_motion_notify_event(self, widget, event):
|
|
||||||
if self._button == Gdk.BUTTON_SECONDARY:
|
|
||||||
self._camera_x += event.x - self._mouse_x
|
|
||||||
self._camera_y += event.y - self._mouse_y
|
|
||||||
self._mouse_x = event.x
|
|
||||||
self._mouse_y = event.y
|
|
||||||
self.queue_draw()
|
|
||||||
|
|
||||||
def on_draw(self, widget, context):
|
|
||||||
# Get the width and height of the widget
|
|
||||||
width = self.get_allocated_width()
|
|
||||||
height = self.get_allocated_height()
|
|
||||||
|
|
||||||
# Render a rectangle for the background of the editor
|
|
||||||
context.set_source_rgb(0.11, 0.11, 0.11)
|
|
||||||
context.rectangle(0, 0, width, height)
|
|
||||||
context.fill()
|
|
||||||
|
|
||||||
# Render our grids
|
|
||||||
context.set_line_width(1)
|
|
||||||
for color, step in [(0.2, 10), (0.3, 100)]:
|
|
||||||
context.set_source_rgb(color, color, color)
|
|
||||||
y = int(self._camera_y % step) + 0.5
|
|
||||||
while y < height:
|
|
||||||
context.move_to(0, y)
|
|
||||||
context.line_to(width, y)
|
|
||||||
y += step
|
|
||||||
x = int(self._camera_x % step) + 0.5
|
|
||||||
while x < width:
|
|
||||||
context.move_to(x, 0)
|
|
||||||
context.line_to(x, height)
|
|
||||||
x += step
|
|
||||||
context.stroke()
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(Gtk.Window):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
self.set_title("Collapsible Controls Overlay Demo")
|
|
||||||
|
|
||||||
# Set the default window size to 800x800
|
|
||||||
self.set_default_size(800, 800)
|
|
||||||
# When our window is destroyed, exit the main event loop
|
|
||||||
self.connect("destroy", Gtk.main_quit)
|
|
||||||
|
|
||||||
# Create our map editor and control panel instances
|
|
||||||
self._editor = MapEditor()
|
|
||||||
self._controls = MyControlPanel()
|
|
||||||
|
|
||||||
# Create the overlay widget
|
|
||||||
self._overlay = Gtk.Overlay()
|
|
||||||
|
|
||||||
# Add our editor and control panel as overlays
|
|
||||||
self._overlay.add_overlay(self._editor)
|
|
||||||
self._overlay.add_overlay(self._controls)
|
|
||||||
|
|
||||||
# Add the overlay as the immediate child of the window
|
|
||||||
self.add(self._overlay)
|
|
||||||
|
|
||||||
|
|
||||||
def install_css():
|
|
||||||
screen = Gdk.Screen.get_default()
|
|
||||||
provider = Gtk.CssProvider()
|
|
||||||
provider.load_from_data(
|
|
||||||
b"""
|
|
||||||
.control-panel {
|
|
||||||
background-color: rgba(255,255,255,0.8);
|
|
||||||
padding: 4px;
|
|
||||||
border-bottom-left-radius: 4px;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
Gtk.StyleContext.add_provider_for_screen(screen, provider, 600)
|
|
||||||
|
|
||||||
|
|
||||||
install_css()
|
|
||||||
window = MainWindow()
|
|
||||||
window.show_all()
|
|
||||||
Gtk.main()
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user