diff --git a/artiq/gui/parameters.py b/artiq/gui/parameters.py index 00bb73bab..a57350146 100644 --- a/artiq/gui/parameters.py +++ b/artiq/gui/parameters.py @@ -1,6 +1,44 @@ +import asyncio +from operator import itemgetter + from gi.repository import Gtk from artiq.gui.tools import Window +from artiq.management.sync_struct import Subscriber + + +class _ParameterStoreSyncer: + def __init__(self, parameters_store, init): + self.parameters_store = parameters_store + self.parameters_store.clear() + for name, value in sorted(init.items(), key=itemgetter(0)): + self.parameters_store.append(self._convert(name, value)) + + def _convert(self, name, value): + return [name, str(value)] + + def _find_index(self, name): + for i, e in enumerate(self.parameters_store): + if e[0] == name: + return i + raise KeyError + + def __setitem__(self, name, value): + try: + i = self._find_index(name) + except KeyError: + pass + else: + del self.parameters_store[i] + j = len(self.parameters_store) + for i, e in enumerate(self.parameters_store): + if e[0] > name: + j = i + break + self.parameters_store.insert(j, self._convert(name, value)) + + def __delitem__(self, key): + del self.parameters_store[self._find_index(key)] class ParametersWindow(Window): @@ -17,3 +55,16 @@ class ParametersWindow(Window): scroll = Gtk.ScrolledWindow() scroll.add(tree) self.add(scroll) + + @asyncio.coroutine + def sub_connect(self, host, port): + self.parameters_subscriber = Subscriber("parameters", + self.init_parameters_store) + yield from self.parameters_subscriber.connect(host, port) + + @asyncio.coroutine + def sub_close(self): + yield from self.parameters_subscriber.close() + + def init_parameters_store(self, init): + return _ParameterStoreSyncer(self.parameters_store, init) diff --git a/frontend/artiq_gui.py b/frontend/artiq_gui.py index b303f1381..ea3a1db76 100755 --- a/frontend/artiq_gui.py +++ b/frontend/artiq_gui.py @@ -2,6 +2,7 @@ import argparse import asyncio +import atexit import gbulb from gi.repository import Gtk @@ -29,23 +30,27 @@ def main(): asyncio.set_event_loop_policy(gbulb.GtkEventLoopPolicy()) loop = asyncio.get_event_loop() - try: - scheduler_win = SchedulerWindow() - scheduler_win.connect("delete-event", Gtk.main_quit) - scheduler_win.show_all() + atexit.register(lambda: loop.close()) - parameters_win = ParametersWindow() - parameters_win.connect("delete-event", Gtk.main_quit) - parameters_win.show_all() + scheduler_win = SchedulerWindow() + scheduler_win.connect("delete-event", Gtk.main_quit) + scheduler_win.show_all() - loop.run_until_complete(scheduler_win.sub_connect( - args.server, args.port_notify)) - try: - loop.run_forever() - finally: - loop.run_until_complete(scheduler_win.sub_close()) - finally: - loop.close() + parameters_win = ParametersWindow() + parameters_win.connect("delete-event", Gtk.main_quit) + parameters_win.show_all() + + loop.run_until_complete(scheduler_win.sub_connect( + args.server, args.port_notify)) + atexit.register( + lambda: loop.run_until_complete(scheduler_win.sub_close())) + + loop.run_until_complete(parameters_win.sub_connect( + args.server, args.port_notify)) + atexit.register( + lambda: loop.run_until_complete(parameters_win.sub_close())) + + loop.run_forever() if __name__ == "__main__": main()