forked from M-Labs/artiq
sync_struct,gui: refactor Subscriber data distribution to support access to parameter DB from GUI file
This commit is contained in:
parent
186aa7fdb7
commit
1b122dd887
|
@ -9,6 +9,7 @@ from gi.repository import Gtk
|
|||
|
||||
from artiq.protocols.file_db import FlatFileDB
|
||||
from artiq.protocols.pc_rpc import AsyncioClient
|
||||
from artiq.protocols.sync_struct import Subscriber
|
||||
from artiq.gui.tools import LayoutManager
|
||||
from artiq.gui.scheduler import SchedulerWindow
|
||||
from artiq.gui.parameters import ParametersWindow
|
||||
|
@ -67,6 +68,13 @@ def main():
|
|||
atexit.register(
|
||||
lambda: loop.run_until_complete(parameters_win.sub_close()))
|
||||
|
||||
parameters_sub = Subscriber("parameters",
|
||||
parameters_win.init_parameters_store)
|
||||
loop.run_until_complete(
|
||||
parameters_sub.connect(args.server, args.port_notify))
|
||||
atexit.register(
|
||||
lambda: loop.run_until_complete(parameters_sub.close()))
|
||||
|
||||
def exit(*args):
|
||||
lmgr.save()
|
||||
Gtk.main_quit(*args)
|
||||
|
|
|
@ -88,7 +88,8 @@ class ExplorerWindow(Window):
|
|||
@asyncio.coroutine
|
||||
def sub_connect(self, host, port):
|
||||
self.explist_subscriber = Subscriber("explist",
|
||||
self.init_explist_store)
|
||||
[self.init_explist_store,
|
||||
self.init_explist_data])
|
||||
yield from self.explist_subscriber.connect(host, port)
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -102,14 +103,16 @@ class ExplorerWindow(Window):
|
|||
self.pane_contents.show_all()
|
||||
|
||||
def init_explist_store(self, init):
|
||||
self.explist_syncer = _ExplistStoreSyncer(self.explist_store, init,
|
||||
keep_data=True)
|
||||
return self.explist_syncer
|
||||
return _ExplistStoreSyncer(self.explist_store, init)
|
||||
|
||||
def init_explist_data(self, init):
|
||||
self.explist_data = init
|
||||
return init
|
||||
|
||||
def explist_row_activated(self, widget, index, column):
|
||||
self.controls = None
|
||||
name = self.explist_store[index][0]
|
||||
gui_file = self.explist_syncer.data[name]["gui_file"]
|
||||
gui_file = self.explist_data[name]["gui_file"]
|
||||
if gui_file is None:
|
||||
self.set_pane_contents(Gtk.Label("No GUI controls"))
|
||||
else:
|
||||
|
@ -128,7 +131,7 @@ class ExplorerWindow(Window):
|
|||
store, selected = self.explist_tree.get_selection().get_selected()
|
||||
if selected is not None:
|
||||
name = store[selected][0]
|
||||
data = self.explist_syncer.data[name]
|
||||
data = self.explist_data[name]
|
||||
if self.controls is None:
|
||||
arguments = {}
|
||||
else:
|
||||
|
|
|
@ -59,21 +59,13 @@ class ParametersWindow(Window):
|
|||
|
||||
@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)
|
||||
try:
|
||||
self.lastchanges_subscriber = Subscriber(
|
||||
"parameters_simplehist", self.init_lastchanges_store)
|
||||
yield from self.lastchanges_subscriber.connect(host, port)
|
||||
except:
|
||||
yield from self.parameters_subscriber.close()
|
||||
raise
|
||||
|
||||
@asyncio.coroutine
|
||||
def sub_close(self):
|
||||
yield from self.lastchanges_subscriber.close()
|
||||
yield from self.parameters_subscriber.close()
|
||||
|
||||
def init_parameters_store(self, init):
|
||||
return _ParameterStoreSyncer(self.parameters_store, init)
|
||||
|
|
|
@ -79,9 +79,7 @@ class ListSyncer:
|
|||
|
||||
|
||||
class DictSyncer:
|
||||
def __init__(self, store, init, keep_data=False):
|
||||
if keep_data:
|
||||
self.data = init
|
||||
def __init__(self, store, init):
|
||||
self.store = store
|
||||
self.store.clear()
|
||||
self.order = []
|
||||
|
@ -115,8 +113,6 @@ class DictSyncer:
|
|||
self.order.insert(j, (key, ord_el))
|
||||
|
||||
def __delitem__(self, key):
|
||||
if hasattr(self, "data"):
|
||||
del self.data[key]
|
||||
i = self._find_index(key)
|
||||
del self.store[i]
|
||||
del self.order[i]
|
||||
|
|
|
@ -49,13 +49,18 @@ class Subscriber:
|
|||
:param target_builder: A function called during initialization that takes
|
||||
the object received from the publisher and returns the corresponding
|
||||
local structure to use. Can be identity.
|
||||
Multiple functions can be specified in a list for the ``Subscriber``
|
||||
to update several local objects simultaneously.
|
||||
:param notify_cb: An optional function called every time a mod is received
|
||||
from the publisher. The mod is passed as parameter.
|
||||
|
||||
"""
|
||||
def __init__(self, notifier_name, target_builder, notify_cb=None):
|
||||
self.notifier_name = notifier_name
|
||||
self.target_builder = target_builder
|
||||
if isinstance(target_builder, list):
|
||||
self.target_builders = target_builder
|
||||
else:
|
||||
self.target_builders = [target_builder]
|
||||
self.notify_cb = notify_cb
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -87,7 +92,7 @@ class Subscriber:
|
|||
|
||||
@asyncio.coroutine
|
||||
def _receive_cr(self):
|
||||
target = None
|
||||
targets = []
|
||||
while True:
|
||||
line = yield from self._reader.readline()
|
||||
if not line:
|
||||
|
@ -95,8 +100,9 @@ class Subscriber:
|
|||
mod = pyon.decode(line.decode())
|
||||
|
||||
if mod["action"] == "init":
|
||||
target = self.target_builder(mod["struct"])
|
||||
targets = [tb(mod["struct"]) for tb in self.target_builders]
|
||||
else:
|
||||
for target in targets:
|
||||
process_mod(target, mod)
|
||||
|
||||
if self.notify_cb is not None:
|
||||
|
|
Loading…
Reference in New Issue