From 02a74b0519144ce6d47e14db00998e57d8f1bb1a Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Wed, 15 Jul 2015 18:20:46 -0400 Subject: [PATCH 01/16] First working version of removed templates --- nengo_gui/components/ace_editor.py | 22 ++++++------- nengo_gui/components/action.py | 30 ++++++++--------- nengo_gui/components/component.py | 30 +++++++---------- nengo_gui/components/netgraph.py | 26 ++++++++------- nengo_gui/components/pointer.py | 17 +++++----- nengo_gui/components/raster.py | 15 +++++---- nengo_gui/components/sim_control.py | 22 +++++++------ nengo_gui/components/slider.py | 21 +++++++----- nengo_gui/components/value.py | 23 ++++++++----- nengo_gui/components/voltage.py | 18 +++++----- nengo_gui/components/xyvalue.py | 18 +++++----- nengo_gui/config.py | 6 ++-- nengo_gui/page.py | 51 ++++++++++++++--------------- nengo_gui/server.py | 8 ++--- 14 files changed, 159 insertions(+), 148 deletions(-) diff --git a/nengo_gui/components/ace_editor.py b/nengo_gui/components/ace_editor.py index 2b659652..a652fa6e 100644 --- a/nengo_gui/components/ace_editor.py +++ b/nengo_gui/components/ace_editor.py @@ -2,17 +2,20 @@ import nengo -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component import nengo_gui.exec_env class AceEditor(Component): - def __init__(self, page, config, uid): + config_params = {} + def __init__(self): # the IPython integration requires this component to be early # in the list - super(AceEditor, self).__init__(page, config, uid, component_order=-8) - self.uid = uid - if self.page.gui.interactive: - self.current_code = self.page.code + super(AceEditor, self).__init__(component_order=-8) + + def initialize(self, page, config, uid): + super(AceEditor, self).initialize(page, config, uid) + if page.gui.interactive: + self.current_code = page.code self.serve_code = True self.last_error = None self.last_stdout = None @@ -48,7 +51,7 @@ def update_client(self, client): def javascript(self): args = json.dumps(dict(active=self.page.gui.interactive)) - return 'ace_editor = new Nengo.Ace("%s", %s)' % (self.uid, args) + return 'ace_editor = new Nengo.Ace("%s", %s)' % (id(self), args) def message(self, msg): if not self.page.gui.interactive: @@ -67,7 +70,4 @@ def message(self, msg): else: self.page.net_graph.update_code(self.current_code) - -class AceEditorTemplate(Template): - cls = AceEditor - config_params = {} +AceEditorTemplate = AceEditor diff --git a/nengo_gui/components/action.py b/nengo_gui/components/action.py index 8e5492a0..71d16242 100644 --- a/nengo_gui/components/action.py +++ b/nengo_gui/components/action.py @@ -64,7 +64,7 @@ def __init__(self, page, component, new_cfg, old_cfg): def load(self, cfg): for k, v in iteritems(cfg): - setattr(self.page.config[self.component.template], k, v) + setattr(self.page.config[self.component], k, v) self.net_graph.modified_config() self.send("config", config=cfg) @@ -107,10 +107,10 @@ def apply(self): def undo(self): page = self.net_graph.page - component = page.add_template(self.component.template) + component = page.add_component(self.component) - page.locals[self.uid] = component.template - page.default_labels[component.template] = self.uid + page.locals[self.uid] = component + page.default_labels[component] = self.uid page.changed = True self.send('js', code=component.javascript()) @@ -123,8 +123,8 @@ def __init__(self, net_graph, uid, type, x, y, width, height, **kwargs): self.type = type self.x, self.y = x, y self.width, self.height = width, height - cls = getattr(nengo_gui.components, self.type + 'Template') - self.template = cls(self.obj, **kwargs) + cls = getattr(nengo_gui.components, self.type) + self.component = cls(self.obj, **kwargs) # If only one instance of the component is allowed, and another had to be # destroyed to create this one, keep track of it here so it can be undone @@ -141,19 +141,19 @@ def __init__(self, net_graph, uid, type, x, y, width, height, **kwargs): def act_create_graph(self): if self.graph_uid is None: - self.net_graph.page.generate_uid(self.template, prefix='_viz_') - self.graph_uid = self.net_graph.page.get_uid(self.template) + self.net_graph.page.generate_uid(self.component, prefix='_viz_') + self.graph_uid = self.net_graph.page.get_uid(self.component) else: - self.net_graph.page.locals[self.graph_uid] = self.template - self.net_graph.page.default_labels[self.template] = ( + self.net_graph.page.locals[self.graph_uid] = self.component + self.net_graph.page.default_labels[self.component] = ( self.graph_uid) - self.net_graph.page.config[self.template].x = self.x - self.net_graph.page.config[self.template].y = self.y - self.net_graph.page.config[self.template].width = self.width - self.net_graph.page.config[self.template].height = self.height + self.net_graph.page.config[self.component].x = self.x + self.net_graph.page.config[self.component].y = self.y + self.net_graph.page.config[self.component].width = self.width + self.net_graph.page.config[self.component].height = self.height self.net_graph.modified_config() - c = self.net_graph.page.add_template(self.template) + c = self.net_graph.page.add_component(self.component) self.net_graph.page.changed = True self.send('js', code=c.javascript()) diff --git a/nengo_gui/components/component.py b/nengo_gui/components/component.py index 70ecd40a..85c9ebc7 100644 --- a/nengo_gui/components/component.py +++ b/nengo_gui/components/component.py @@ -1,14 +1,18 @@ import json class Component(object): - def __init__(self, page, config, uid, component_order=0): - self.config = config - self.uid = uid - self.page = page + default_params = dict(x=0, y=0, width=100, height=100, label_visible=True) + + def __init__(self, component_order=0): # the order this component will be defined in the javascript self.component_order = component_order self.replace_with = None + def initialize(self, page, config, uid): + self.config = config + self.page = page + self.uid = uid + def update_client(self, client): pass def message(self, msg): @@ -28,22 +32,10 @@ def javascript_config(self, cfg): cfg[attr] = getattr(self.config, attr) return json.dumps(cfg) + def code_python_args(self, uids): + return [] -class Template(object): - default_params = dict(x=0, y=0, width=100, height=100, label_visible=True) - cls = None # subclasses are expected to set this to be the class of - # the object that should be created. - - def __init__(self, *args, **kwargs): - self.args = args - self.kwargs = kwargs - def create(self, page): - uid = '_uid_%d' % id(self) - c = self.cls(page, page.config[self], uid, - *self.args, **self.kwargs) - c.template = self - return c def code_python(self, uids): - args = [uids[x] for x in self.args] + args = self.code_python_args(uids) name = self.__class__.__name__ return 'nengo_gui.components.%s(%s)' % (name, ','.join(args)) diff --git a/nengo_gui/components/netgraph.py b/nengo_gui/components/netgraph.py index 22258f8f..a38c40e2 100644 --- a/nengo_gui/components/netgraph.py +++ b/nengo_gui/components/netgraph.py @@ -7,7 +7,7 @@ import nengo import json -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component from nengo_gui.disposable_js import infomodal import nengo_gui.layout @@ -15,16 +15,14 @@ class NetGraph(Component): + config_params = {} configs = {} - def __init__(self, page, config, uid): + def __init__(self): # this component must be before all the normal graphs (so that # those other graphs are on top of the NetGraph), so its # order is between that of SimControl and the default (0) - super(NetGraph, self).__init__(page, config, uid, component_order=-5) - self.layout = nengo_gui.layout.Layout(self.page.model) - self.to_be_expanded = collections.deque([self.page.model]) - self.to_be_sent = collections.deque() + super(NetGraph, self).__init__(component_order=-5) # this lock ensures safety between check_for_reload() and update_code() self.code_lock = threading.Lock() @@ -32,9 +30,16 @@ def __init__(self, page, config, uid): self.uids = {} self.parents = {} - self.networks_to_search = [self.page.model] self.initialized_pan_and_zoom = False + def initialize(self, page, config, uid): + super(NetGraph, self).initialize(page, config, uid) + self.layout = nengo_gui.layout.Layout(self.page.model) + self.to_be_expanded = collections.deque([self.page.model]) + self.to_be_sent = collections.deque() + + self.networks_to_search = [self.page.model] + try: self.last_modify_time = os.path.getmtime(self.page.filename) except OSError: @@ -290,7 +295,7 @@ def update_client(self, client): self.expand_network(network, client) def javascript(self): - return 'new Nengo.NetGraph(main, {uid:"%s"});' % self.uid + return 'new Nengo.NetGraph(main, {uid:"%s"});' % id(self) def message(self, msg): try: @@ -453,7 +458,4 @@ def create_connection(self, client, conn, parent): info = dict(uid=uid, pre=pres, post=posts, type='conn', parent=parent) client.write(json.dumps(info)) - -class NetGraphTemplate(Template): - cls = NetGraph - config_params = dict() +NetGraphTemplate = NetGraph diff --git a/nengo_gui/components/pointer.py b/nengo_gui/components/pointer.py index b3720a9a..d5f1ab5c 100644 --- a/nengo_gui/components/pointer.py +++ b/nengo_gui/components/pointer.py @@ -6,12 +6,13 @@ from nengo.spa.module import Module import numpy as np -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component class Pointer(Component): - def __init__(self, page, config, uid, obj, **kwargs): - super(Pointer, self).__init__(page, config, uid) + config_params = dict(show_pairs=False, **Component.default_params) + def __init__(self, obj, **kwargs): + super(Pointer, self).__init__() self.obj = obj self.label = page.get_label(obj) self.data = collections.deque() @@ -65,10 +66,13 @@ def update_client(self, client): client.write(data, binary=False) def javascript(self): - info = dict(uid=self.uid, label=self.label) + info = dict(uid=id(self), label=self.label) json = self.javascript_config(info) return 'new Nengo.Pointer(main, sim, %s);' % json + def code_python_args(self, uids): + return [uids[self.obj], 'target=%s' % self.target] + def message(self, msg): if len(msg) == 0: self.override_target = None @@ -85,7 +89,4 @@ def applicable_targets(obj): else: return [] - -class PointerTemplate(Template): - cls = Pointer - config_params = dict(show_pairs=False, **Template.default_params) +PointerTemplate = Pointer diff --git a/nengo_gui/components/raster.py b/nengo_gui/components/raster.py index 748a7014..f95d06b5 100644 --- a/nengo_gui/components/raster.py +++ b/nengo_gui/components/raster.py @@ -4,12 +4,13 @@ import nengo import numpy as np -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component class Raster(Component): - def __init__(self, page, config, uid, obj, n_neurons=None): - super(Raster, self).__init__(page, config, uid) + config_params = dict(**Component.default_params) + def __init__(self, obj, n_neurons=None): + super(Raster, self).__init__() self.neuron_type = obj.neuron_type self.obj = obj.neurons self.data = collections.deque() @@ -41,12 +42,12 @@ def update_client(self, client): client.write(data, binary=True) def javascript(self): - info = dict(uid=self.uid, n_neurons=self.n_neurons, label=self.label, + info = dict(uid=id(self), n_neurons=self.n_neurons, label=self.label, max_neurons=self.max_neurons) json = self.javascript_config(info) return 'new Nengo.Raster(main, sim, %s);' % json + def code_python_args(self, uids): + return [uids[self.obj]] -class RasterTemplate(Template): - cls = Raster - config_params = dict(**Template.default_params) +RasterTemplate = Raster diff --git a/nengo_gui/components/sim_control.py b/nengo_gui/components/sim_control.py index 463248b9..7e3182cf 100644 --- a/nengo_gui/components/sim_control.py +++ b/nengo_gui/components/sim_control.py @@ -8,22 +8,21 @@ import os.path import json -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component import nengo_gui.exec_env class SimControl(Component): - def __init__(self, page, config, uid, dt=0.001): + config_params = dict(shown_time=0.5, kept_time=4.0) + def __init__(self, dt=0.001): # this component must be the very first one defined, so # its component_order is the smallest overall - super(SimControl, self).__init__(page, config, uid, component_order=-10) + super(SimControl, self).__init__(component_order=-10) self.paused = True self.last_tick = None self.rate = 0.0 self.model_dt = dt self.rate_tau = 1.0 self.last_send_rate = None - self.shown_time = config.shown_time - self.kept_time = config.kept_time self.sim_ticks = 0 self.skipped = 1 self.time = 0.0 @@ -31,6 +30,12 @@ def __init__(self, page, config, uid, dt=0.001): self.next_ping_time = None self.send_config_options = False + def initialize(self, page, config, uid): + super(SimControl, self).initialize(page, config, uid) + self.shown_time = config.shown_time + self.kept_time = config.kept_time + + def add_nengo_objects(self, page): with page.model: self.node = nengo.Node(self.control, size_out=0) @@ -99,7 +104,7 @@ def get_status(self): return 'running' def javascript(self): - info = dict(uid=self.uid) + info = dict(uid=id(self)) fn = json.dumps(self.page.filename) js = self.javascript_config(info) return ('sim = new Nengo.SimControl(control, %s);\n' @@ -131,7 +136,4 @@ def backend_options_html(self): items.append(item) return ''.join(items) - -class SimControlTemplate(Template): - cls = SimControl - config_params = dict(shown_time=0.5, kept_time=4.0) +SimControlTemplate = SimControl diff --git a/nengo_gui/components/slider.py b/nengo_gui/components/slider.py index 1d61d58f..036d58e3 100644 --- a/nengo_gui/components/slider.py +++ b/nengo_gui/components/slider.py @@ -2,23 +2,27 @@ import struct import collections -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component class Slider(Component): - def __init__(self, page, config, uid, node): - super(Slider, self).__init__(page, config, uid) + config_params = dict(max_value=1, min_value=-1, **Component.default_params) + def __init__(self, node): + super(Slider, self).__init__() self.node = node self.base_output = node.output self.override = [None] * node.size_out self.last_time = None self.value = np.zeros(node.size_out) - self.label = page.get_label(node) self.start_value = np.zeros(node.size_out, dtype=float) self.struct = struct.Struct('<%df' % (1 + node.size_out)) self.data = collections.deque() if not callable(self.base_output): self.start_value[:] = self.base_output + def initialize(self, page, config, uid): + super(Slider, self).initialize(page, config, uid) + self.label = page.get_label(self.node) + def add_nengo_objects(self, page): self.node.output = self.override_output @@ -41,7 +45,7 @@ def override_output(self, t, *args): return self.value def javascript(self): - info = dict(uid=self.uid, n_sliders=len(self.override), + info = dict(uid=id(self), n_sliders=len(self.override), label=self.label, start_value=[float(x) for x in self.start_value]) json = self.javascript_config(info) @@ -62,6 +66,7 @@ def message(self, msg): value = float(value) self.override[index] = value -class SliderTemplate(Template): - cls = Slider - config_params = dict(max_value=1, min_value=-1, **Template.default_params) + def code_python_args(self, uids): + return [uids[self.node]] + +SliderTemplate = Slider diff --git a/nengo_gui/components/value.py b/nengo_gui/components/value.py index cd9b714a..cdb3fa9b 100644 --- a/nengo_gui/components/value.py +++ b/nengo_gui/components/value.py @@ -4,18 +4,24 @@ import nengo import numpy as np -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component class Value(Component): - def __init__(self, page, config, uid, obj): - super(Value, self).__init__(page, config, uid) + config_params = dict(max_value=1, + min_value=-1, + **Component.default_params) + def __init__(self, obj): + super(Value, self).__init__() self.obj = obj - self.label = page.get_label(obj) self.data = collections.deque() self.n_lines = int(obj.size_out) self.struct = struct.Struct('<%df' % (1 + self.n_lines)) + def initialize(self, page, config, uid): + super(Value, self).initialize(page, config, uid) + self.label = page.get_label(self.obj) + def add_nengo_objects(self, page): with page.model: self.node = nengo.Node(self.gather_data, @@ -35,11 +41,12 @@ def update_client(self, client): client.write(item, binary=True) def javascript(self): - info = dict(uid=self.uid, label=self.label, + info = dict(uid=id(self), label=self.label, n_lines=self.n_lines, synapse=0) json = self.javascript_config(info) return 'new Nengo.Value(main, sim, %s);' % json -class ValueTemplate(Template): - cls = Value - config_params = dict(max_value=1, min_value=-1, **Template.default_params) + def code_python_args(self, uids): + return [uids[self.obj]] + +ValueTemplate = Value diff --git a/nengo_gui/components/voltage.py b/nengo_gui/components/voltage.py index 94ee8369..8f420be3 100644 --- a/nengo_gui/components/voltage.py +++ b/nengo_gui/components/voltage.py @@ -4,12 +4,14 @@ import numpy as np import struct -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component class Voltage(Component): - def __init__(self, page, config, uid, obj, n_neurons=5): - super(Voltage, self).__init__(page, config, uid) + config_params = dict( + max_value=5.0, min_value=0.0, **Component.default_params) + def __init__(self, obj, n_neurons=5): + super(Voltage, self).__init__() self.obj = obj.neurons self.data = [] self.label = page.get_label(obj) @@ -45,13 +47,11 @@ def update_client(self, client): client.write(packet, binary=True) def javascript(self): - info = dict(uid=self.uid, label=self.label, + info = dict(uid=id(self), label=self.label, n_lines=self.n_neurons, synapse=0) json = self.javascript_config(info) return 'new Nengo.Value(main, sim, %s);' % json - -class VoltageTemplate(Template): - cls = Voltage - config_params = dict( - max_value=5.0, min_value=0.0, **Template.default_params) + def code_python_args(self, uids): + return [uids[self.obj.ensemble]] +VoltageTemplate = Voltage diff --git a/nengo_gui/components/xyvalue.py b/nengo_gui/components/xyvalue.py index f16b7829..d7de6335 100644 --- a/nengo_gui/components/xyvalue.py +++ b/nengo_gui/components/xyvalue.py @@ -4,12 +4,14 @@ import nengo import numpy as np -from nengo_gui.components.component import Component, Template +from nengo_gui.components.component import Component class XYValue(Component): - def __init__(self, page, config, uid, obj): - super(XYValue, self).__init__(page, config, uid) + config_params = dict(max_value=1, min_value=-1, index_x=0, index_y=1, + **Component.default_params) + def __init__(self, obj): + super(XYValue, self).__init__() self.obj = obj self.label = page.get_label(obj) self.data = collections.deque() @@ -35,11 +37,11 @@ def update_client(self, client): client.write(data, binary=True) def javascript(self): - info = dict(uid=self.uid, n_lines=self.n_lines, label=self.label) + info = dict(uid=id(self), n_lines=self.n_lines, label=self.label) json = self.javascript_config(info) return 'new Nengo.XYValue(main, sim, %s);' % json -class XYValueTemplate(Template): - cls = XYValue - config_params = dict(max_value=1, min_value=-1, index_x=0, index_y=1, - **Template.default_params) + def code_python_args(self, uids): + return [uids[self.obj]] + +XYValueTemplate = XYValue diff --git a/nengo_gui/config.py b/nengo_gui/config.py index 97731cc6..9d0024e7 100644 --- a/nengo_gui/config.py +++ b/nengo_gui/config.py @@ -22,8 +22,8 @@ def __init__(self): for clsname, cls in inspect.getmembers(nengo_gui.components): if inspect.isclass(cls): - if issubclass(cls, nengo_gui.components.component.Template): - if cls != nengo_gui.components.component.Template: + if issubclass(cls, nengo_gui.components.component.Component): + if cls != nengo_gui.components.component.Component: self.configures(cls) for k, v in cls.config_params.items(): self[cls].set_param(k, nengo.params.Parameter(v)) @@ -43,7 +43,7 @@ def dumps(self, uids): % (uid, self[obj].expanded)) lines.append('_viz_config[%s].has_layout=%s' % (uid, self[obj].has_layout)) - elif isinstance(obj, nengo_gui.components.component.Template): + elif isinstance(obj, nengo_gui.components.component.Component): lines.append('%s = %s' % (uid, obj.code_python(uids))) for k in obj.config_params.keys(): v = getattr(self[obj], k) diff --git a/nengo_gui/page.py b/nengo_gui/page.py index 473bc5e7..83b9072a 100644 --- a/nengo_gui/page.py +++ b/nengo_gui/page.py @@ -56,8 +56,8 @@ def __init__(self, gui, filename, reset_cfg=False): self.default_labels = None # dict of names to use for unlabelled objs self.config = None # nengo_gui.Config for storing layout self.components = None # list of Components - self.uid_prefix_counter = None # used for generating uids for templates - self.template_uids = None # mapping from Templates to text + self.uid_prefix_counter = None # used for generating uids for components + self.component_uids = None # mapping from Components to text self.config_save_needed = False self.config_save_time = None # time of last config file save @@ -152,26 +152,26 @@ def load(self): def create_components(self): """Generate the actual Components from the Templates""" + #TODO: change the name of this self.components = [] - self.template_uids = {} + self.component_uids = {} for k, v in self.locals.items(): - if isinstance(v, nengo_gui.components.component.Template): - self.template_uids[v] = k - c = v.create(self) - self.gui.component_uids[c.uid] = c - self.components.append(c) + if isinstance(v, nengo_gui.components.component.Component): + self.component_uids[v] = k + self.gui.component_uids[id(v)] = v + self.components.append(v) # this ensures NetGraph, AceEditor, and SimControl are first self.components.sort(key=lambda x: x.component_order) - def add_template(self, template): + def add_component(self, component): """Add a new Component to an existing Page.""" - c = template.create(self) - self.gui.component_uids[c.uid] = c - - self.components.append(c) - - return c + #TODO: do we need to return anything here? make a uid? + self.gui.component_uids[id(component)] = component + uid = self.get_uid(component) + component.initialize(self, self.config[component], uid=uid) + self.components.append(component) + return component def execute(self, code): """Run the given code to generate self.model and self.locals. @@ -234,14 +234,14 @@ def load_config(self): # make sure the required Components exist if '_viz_sim_control' not in self.locals: - template = nengo_gui.components.SimControlTemplate() - self.locals['_viz_sim_control'] = template + c = nengo_gui.components.SimControl() + self.locals['_viz_sim_control'] = c if '_viz_net_graph' not in self.locals: - template = nengo_gui.components.NetGraphTemplate() - self.locals['_viz_net_graph'] = template + c = nengo_gui.components.NetGraph() + self.locals['_viz_net_graph'] = c if '_viz_ace_editor' not in self.locals: - template = nengo_gui.components.AceEditorTemplate() - self.locals['_viz_ace_editor'] = template + c = nengo_gui.components.AceEditor() + self.locals['_viz_ace_editor'] = c if self.model is not None: if config[self.model].pos is None: @@ -250,8 +250,9 @@ def load_config(self): config[self.model].size = (1.0, 1.0) for k, v in self.locals.items(): - if isinstance(v, nengo_gui.components.component.Template): + if isinstance(v, nengo_gui.components.component.Component): self.default_labels[v] = k + v.initialize(page=self, config=config[v], uid=k) return config @@ -379,10 +380,8 @@ def remove_uid(self, uid): def remove_component(self, component): """Remove a component from the layout.""" - del self.gui.component_uids[component.uid] - template = component.template - uid = self.get_uid(template) - self.remove_uid(uid) + del self.gui.component_uids[id(component)] + self.remove_uid(component.uid) self.components.remove(component) def config_change(self, component, new_cfg, old_cfg): diff --git a/nengo_gui/server.py b/nengo_gui/server.py index c841bf9f..2d527af4 100644 --- a/nengo_gui/server.py +++ b/nengo_gui/server.py @@ -98,7 +98,7 @@ def ws_viz_component(self, client, uid): gui = self.server.gui - component = gui.component_uids[uid] + component = gui.component_uids[int(uid)] while True: try: if gui.finished: @@ -112,9 +112,9 @@ def ws_viz_component(self, client, uid): if msg.startswith('config:'): cfg = json.loads(msg[7:]) old_cfg = {} - for k in component.template.config_params.keys(): + for k in component.config_params.keys(): v = getattr( - component.page.config[component.template], k) + component.page.config[component], k) old_cfg[k] = v if not(cfg == old_cfg): # Register config change to the undo stack @@ -122,7 +122,7 @@ def ws_viz_component(self, client, uid): component, cfg, old_cfg) for k, v in cfg.items(): setattr( - component.page.config[component.template], + component.page.config[component], k, v) component.page.modified_config() elif msg.startswith('remove'): From 68a87b71b92e663f1f7786ce30b76b749b8ab727 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Thu, 16 Jul 2015 15:14:13 -0400 Subject: [PATCH 02/16] All graphs working without templates --- nengo_gui/components/pointer.py | 5 ++++- nengo_gui/components/raster.py | 7 +++++-- nengo_gui/components/voltage.py | 5 ++++- nengo_gui/components/xyvalue.py | 5 ++++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/nengo_gui/components/pointer.py b/nengo_gui/components/pointer.py index d5f1ab5c..3dc3ae73 100644 --- a/nengo_gui/components/pointer.py +++ b/nengo_gui/components/pointer.py @@ -14,12 +14,15 @@ class Pointer(Component): def __init__(self, obj, **kwargs): super(Pointer, self).__init__() self.obj = obj - self.label = page.get_label(obj) self.data = collections.deque() self.override_target = None self.target = kwargs.get('args', 'default') self.vocab_out = obj.outputs[self.target][1] self.vocab_in = obj.inputs[self.target][1] + + def initialize(self, page, config, uid): + super(Pointer, self).initialize(page, config, uid) + self.label = page.get_label(self.obj) self.vocab_out.include_pairs = config.show_pairs def add_nengo_objects(self, page): diff --git a/nengo_gui/components/raster.py b/nengo_gui/components/raster.py index f95d06b5..44f24931 100644 --- a/nengo_gui/components/raster.py +++ b/nengo_gui/components/raster.py @@ -14,12 +14,15 @@ def __init__(self, obj, n_neurons=None): self.neuron_type = obj.neuron_type self.obj = obj.neurons self.data = collections.deque() - self.label = page.get_label(obj) self.max_neurons = obj.n_neurons if n_neurons is None: n_neurons = min(self.max_neurons, 10) self.n_neurons = n_neurons + def initialize(self, page, config, uid): + super(Raster, self).initialize(page, config, uid) + self.label = page.get_label(self.obj.ensemble) + def add_nengo_objects(self, page): with page.model: self.node = nengo.Node(self.gather_data, size_in=self.max_neurons) @@ -48,6 +51,6 @@ def javascript(self): return 'new Nengo.Raster(main, sim, %s);' % json def code_python_args(self, uids): - return [uids[self.obj]] + return [uids[self.obj.ensemble]] RasterTemplate = Raster diff --git a/nengo_gui/components/voltage.py b/nengo_gui/components/voltage.py index 8f420be3..18a6a0d9 100644 --- a/nengo_gui/components/voltage.py +++ b/nengo_gui/components/voltage.py @@ -14,11 +14,14 @@ def __init__(self, obj, n_neurons=5): super(Voltage, self).__init__() self.obj = obj.neurons self.data = [] - self.label = page.get_label(obj) self.max_neurons = int(self.obj.size_out) self.n_neurons = min(n_neurons, self.max_neurons) self.struct = struct.Struct('<%df' % (1 + self.n_neurons)) + def initialize(self, page, config, uid): + super(Voltage, self).initialize(page, config, uid) + self.label = page.get_label(self.obj.ensemble) + def add_nengo_objects(self, page): with page.model: self.probe = nengo.Probe(self.obj[:self.n_neurons], 'voltage') diff --git a/nengo_gui/components/xyvalue.py b/nengo_gui/components/xyvalue.py index d7de6335..70f1c052 100644 --- a/nengo_gui/components/xyvalue.py +++ b/nengo_gui/components/xyvalue.py @@ -13,11 +13,14 @@ class XYValue(Component): def __init__(self, obj): super(XYValue, self).__init__() self.obj = obj - self.label = page.get_label(obj) self.data = collections.deque() self.n_lines = int(obj.size_out) self.struct = struct.Struct('<%df' % (1 + self.n_lines)) + def initialize(self, page, config, uid): + super(XYValue, self).initialize(page, config, uid) + self.label = page.get_label(self.obj) + def add_nengo_objects(self, page): with page.model: self.node = nengo.Node(self.gather_data, From 0c7f11548dafdd8708094a45814a27cb6b4e1930 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Thu, 16 Jul 2015 16:28:21 -0400 Subject: [PATCH 03/16] Handled reloading --- nengo_gui/components/action.py | 12 +++---- nengo_gui/components/netgraph.py | 55 +++++++++++++++++++------------- nengo_gui/page.py | 2 -- nengo_gui/static/nengo.js | 13 +++++--- nengo_gui/static/netgraph.js | 2 +- 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/nengo_gui/components/action.py b/nengo_gui/components/action.py index 71d16242..d5ed4a18 100644 --- a/nengo_gui/components/action.py +++ b/nengo_gui/components/action.py @@ -107,13 +107,13 @@ def apply(self): def undo(self): page = self.net_graph.page - component = page.add_component(self.component) + page.add_component(self.component) - page.locals[self.uid] = component - page.default_labels[component] = self.uid + page.locals[self.uid] = self.component + page.default_labels[self.component] = self.uid page.changed = True - self.send('js', code=component.javascript()) + self.send('js', code=self.component.javascript()) class CreateGraph(Action): @@ -153,9 +153,9 @@ def act_create_graph(self): self.net_graph.page.config[self.component].height = self.height self.net_graph.modified_config() - c = self.net_graph.page.add_component(self.component) + self.net_graph.page.add_component(self.component) self.net_graph.page.changed = True - self.send('js', code=c.javascript()) + self.send('js', code=self.component.javascript()) def apply(self): if self.duplicate is not None: diff --git a/nengo_gui/components/netgraph.py b/nengo_gui/components/netgraph.py index a38c40e2..86e31f0b 100644 --- a/nengo_gui/components/netgraph.py +++ b/nengo_gui/components/netgraph.py @@ -78,6 +78,7 @@ def reload(self, code=None): def _reload(self, code=None): old_locals = self.page.locals + old_default_labels = self.page.default_labels if code is None: with open(self.page.filename) as f: @@ -150,13 +151,6 @@ def _reload(self, code=None): self.to_be_expanded.append(self.page.model) - # record the names of the current templates so we can map them to - # the new templates below. Note that we have to do this before - # updating name_finder and config, as that will wipe out the old - # uids. - template_uids = [self.page.get_uid(c.template) - for c in self.page.components] - self.page.name_finder = name_finder self.page.default_labels = name_finder.known_name self.page.config = self.page.load_config() @@ -164,39 +158,56 @@ def _reload(self, code=None): self.layout = nengo_gui.layout.Layout(self.page.model) self.page.code = code - removed_items = list(removed_uids.keys()) + orphan_components = [] + + removed_items = list(removed_uids.values()) for c in self.page.components: - for item in c.template.args: + for item in c.code_python_args(old_default_labels): if item in removed_items: self.to_be_sent.append(dict(type='delete_graph', - uid=c.uid)) + uid=id(c), + report_back=False)) + orphan_components.append(c) break components = [] + # the old names for the old components + component_uids = [c.uid for c in self.page.components] for k, v in list(self.page.locals.items()): - if isinstance(v, nengo_gui.components.component.Template): - t_uid = self.page.get_uid(v) - # find the corresponding template in the old list - index = template_uids.index(t_uid) + if isinstance(v, nengo_gui.components.component.Component): + + # the object has been removed, so the Component should + # be removed as well + if v in orphan_components: + continue + + # this is a Component that was previously removed, + # but is still in the config file, so let's recover it + if k not in component_uids: + self.page.add_component(v) + self.to_be_sent.append(dict(type='js', + code=v.javascript())) + components.append(v) + continue + + # otherwise, find the corresponding old Component + index = component_uids.index(k) old_component = self.page.components[index] - self.page.locals[t_uid] = v - self.page.default_labels[v] = t_uid - if isinstance(v, (nengo_gui.components.SimControlTemplate, nengo_gui.components.AceEditorTemplate, nengo_gui.components.NetGraphTemplate)): - old_component.template = v + # just keep these ones components.append(old_component) - else: + # replace these components with the newly generated ones try: - c = self.page.add_template(v) - old_component.replace_with = c + self.page.add_component(v) + old_component.replace_with = v except: traceback.print_exc() print('failed to recreate plot for %s' % v) - components.append(c) + components.append(v) components.sort(key=lambda x: x.component_order) diff --git a/nengo_gui/page.py b/nengo_gui/page.py index 83b9072a..0468fe0b 100644 --- a/nengo_gui/page.py +++ b/nengo_gui/page.py @@ -166,12 +166,10 @@ def create_components(self): def add_component(self, component): """Add a new Component to an existing Page.""" - #TODO: do we need to return anything here? make a uid? self.gui.component_uids[id(component)] = component uid = self.get_uid(component) component.initialize(self, self.config[component], uid=uid) self.components.append(component) - return component def execute(self, code): """Run the given code to generate self.model and self.locals. diff --git a/nengo_gui/static/nengo.js b/nengo_gui/static/nengo.js index 79c952af..4eac2ea2 100644 --- a/nengo_gui/static/nengo.js +++ b/nengo_gui/static/nengo.js @@ -243,13 +243,16 @@ Nengo.Component.prototype.generate_menu = function() { return items; }; -Nengo.Component.prototype.remove = function(undo_flag) { +Nengo.Component.prototype.remove = function(undo_flag, report_back) { undo_flag = typeof undo_flag !== 'undefined' ? undo_flag : false; + report_back = typeof report_back !== 'undefined' ? report_back : true; - if (undo_flag === true) { - this.ws.send('remove_undo'); - } else { - this.ws.send('remove'); + if (report_back) { + if (undo_flag === true) { + this.ws.send('remove_undo'); + } else { + this.ws.send('remove'); + } } this.parent.removeChild(this.div); var index = Nengo.Component.components.indexOf(this); diff --git a/nengo_gui/static/netgraph.js b/nengo_gui/static/netgraph.js index 9a71e196..0a21b82e 100644 --- a/nengo_gui/static/netgraph.js +++ b/nengo_gui/static/netgraph.js @@ -335,7 +335,7 @@ Nengo.NetGraph.prototype.on_message = function(event) { var uid = data.uid; for (var i = 0; i < Nengo.Component.components.length; i++) { if (Nengo.Component.components[i].uid === uid) { - Nengo.Component.components[i].remove(true); + Nengo.Component.components[i].remove(true, data.report_back); break; } } From 3e0d7461c3a32594354e4798427cb25ea37581d3 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Thu, 16 Jul 2015 18:17:37 -0400 Subject: [PATCH 04/16] Fixed undo tracking --- nengo_gui/components/action.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nengo_gui/components/action.py b/nengo_gui/components/action.py index d5ed4a18..7dbaf924 100644 --- a/nengo_gui/components/action.py +++ b/nengo_gui/components/action.py @@ -56,7 +56,7 @@ def undo(self): class ConfigAction(Action): def __init__(self, page, component, new_cfg, old_cfg): - super(ConfigAction, self).__init__(page.net_graph, component.uid) + super(ConfigAction, self).__init__(page.net_graph, id(component)) self.component = component self.page = page self.new_cfg = new_cfg @@ -67,6 +67,7 @@ def load(self, cfg): setattr(self.page.config[self.component], k, v) self.net_graph.modified_config() self.send("config", config=cfg) + print 'config', self.component.uid, cfg def apply(self): self.load(self.new_cfg) @@ -99,7 +100,7 @@ def undo(self): class RemoveGraph(Action): def __init__(self, net_graph, component): - super(RemoveGraph, self).__init__(net_graph, component.uid) + super(RemoveGraph, self).__init__(net_graph, id(component)) self.component = component def apply(self): @@ -135,7 +136,7 @@ def __init__(self, net_graph, uid, type, x, y, width, height, **kwargs): if (isinstance(component, nengo_gui.components.slider.Slider) and component.node is self.obj): self.duplicate = RemoveGraph(net_graph, component) - self.send('delete_graph', uid=component.uid) + self.send('delete_graph', uid=id(component)) self.act_create_graph() From ce295ede326ab20f33ed8068a40a90b47b2406ae Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Thu, 16 Jul 2015 18:22:11 -0400 Subject: [PATCH 05/16] fix undo graph creation --- nengo_gui/components/action.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nengo_gui/components/action.py b/nengo_gui/components/action.py index 7dbaf924..aa2b913b 100644 --- a/nengo_gui/components/action.py +++ b/nengo_gui/components/action.py @@ -67,7 +67,6 @@ def load(self, cfg): setattr(self.page.config[self.component], k, v) self.net_graph.modified_config() self.send("config", config=cfg) - print 'config', self.component.uid, cfg def apply(self): self.load(self.new_cfg) @@ -164,7 +163,7 @@ def apply(self): self.act_create_graph() def undo(self): - self.send('delete_graph', uid=self.graph_uid) + self.send('delete_graph', uid=id(self.component)) if self.duplicate is not None: self.duplicate.undo() From 97bb1ab835d553ad8146e979db69ab928bc5a181 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Thu, 16 Jul 2015 18:46:41 -0400 Subject: [PATCH 06/16] Fixed saving boolean parameters to config --- nengo_gui/config.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nengo_gui/config.py b/nengo_gui/config.py index 9d0024e7..70d31b32 100644 --- a/nengo_gui/config.py +++ b/nengo_gui/config.py @@ -47,6 +47,10 @@ def dumps(self, uids): lines.append('%s = %s' % (uid, obj.code_python(uids))) for k in obj.config_params.keys(): v = getattr(self[obj], k) - lines.append('_viz_config[%s].%s = %g' % (uid, k, v)) + if isinstance(v, bool): + val = '%s' % v + else: + val = '%g' % v + lines.append('_viz_config[%s].%s = %s' % (uid, k, val)) return '\n'.join(lines) From 57ecff3431fb7713ef213530ffc0a65d18037ecd Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Thu, 16 Jul 2015 19:06:03 -0400 Subject: [PATCH 07/16] Fixed removing sliders that were created by undo --- nengo_gui/components/action.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nengo_gui/components/action.py b/nengo_gui/components/action.py index aa2b913b..5e9a677f 100644 --- a/nengo_gui/components/action.py +++ b/nengo_gui/components/action.py @@ -109,8 +109,8 @@ def undo(self): page = self.net_graph.page page.add_component(self.component) - page.locals[self.uid] = self.component - page.default_labels[self.component] = self.uid + page.locals[self.component.uid] = self.component + page.default_labels[self.component] = self.component.uid page.changed = True self.send('js', code=self.component.javascript()) From ff903391fc389cfbcd5a0bc63b4b9e4b93c37008 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Thu, 16 Jul 2015 19:06:29 -0400 Subject: [PATCH 08/16] Fixed other plots causing Sliders to disappear --- nengo_gui/components/action.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/nengo_gui/components/action.py b/nengo_gui/components/action.py index 5e9a677f..fda1461d 100644 --- a/nengo_gui/components/action.py +++ b/nengo_gui/components/action.py @@ -131,11 +131,12 @@ def __init__(self, net_graph, uid, type, x, y, width, height, **kwargs): self.duplicate = None # Remove any existing sliders associated with the same node - for component in self.net_graph.page.components: - if (isinstance(component, nengo_gui.components.slider.Slider) - and component.node is self.obj): - self.duplicate = RemoveGraph(net_graph, component) - self.send('delete_graph', uid=id(component)) + if type == 'Slider': + for component in self.net_graph.page.components: + if (isinstance(component, nengo_gui.components.slider.Slider) + and component.node is self.obj): + self.duplicate = RemoveGraph(net_graph, component) + self.send('delete_graph', uid=id(component)) self.act_create_graph() From 2997381f658526f6e6e550e3d5491118be14a722 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Fri, 17 Jul 2015 16:10:52 -0400 Subject: [PATCH 09/16] Cleaned up Template backwards compat; added docs --- nengo_gui/components/__init__.py | 30 +++++++--- nengo_gui/components/ace_editor.py | 2 - nengo_gui/components/component.py | 86 ++++++++++++++++++++++++++--- nengo_gui/components/netgraph.py | 2 - nengo_gui/components/pointer.py | 4 +- nengo_gui/components/raster.py | 4 +- nengo_gui/components/sim_control.py | 2 - nengo_gui/components/slider.py | 4 +- nengo_gui/components/value.py | 4 +- nengo_gui/components/voltage.py | 3 +- nengo_gui/components/xyvalue.py | 4 +- nengo_gui/page.py | 4 +- 12 files changed, 107 insertions(+), 42 deletions(-) diff --git a/nengo_gui/components/__init__.py b/nengo_gui/components/__init__.py index 1aa5d566..9cfb48e5 100644 --- a/nengo_gui/components/__init__.py +++ b/nengo_gui/components/__init__.py @@ -1,9 +1,21 @@ -from .slider import Slider, SliderTemplate -from .value import Value, ValueTemplate -from .xyvalue import XYValue, XYValueTemplate -from .sim_control import SimControl, SimControlTemplate -from .raster import Raster, RasterTemplate -from .voltage import Voltage, VoltageTemplate -from .pointer import Pointer, PointerTemplate -from .netgraph import NetGraph, NetGraphTemplate -from .ace_editor import AceEditor, AceEditorTemplate +import inspect +import sys + +from .component import Component +from .slider import Slider +from .value import Value +from .xyvalue import XYValue +from .sim_control import SimControl +from .raster import Raster +from .voltage import Voltage +from .pointer import Pointer +from .netgraph import NetGraph +from .ace_editor import AceEditor + +# Old versions of the .cfg files used Templates which had slightly different +# names than the Components currently usef. This code is needed to +# successfully parse those old .cfg files +this_module = sys.modules[__name__] +for name, obj in inspect.getmembers(this_module, inspect.isclass): + if issubclass(obj, Component): + setattr(this_module, name + 'Template', obj) diff --git a/nengo_gui/components/ace_editor.py b/nengo_gui/components/ace_editor.py index a652fa6e..18566a33 100644 --- a/nengo_gui/components/ace_editor.py +++ b/nengo_gui/components/ace_editor.py @@ -69,5 +69,3 @@ def message(self, msg): self.page.net_graph.update_code(self.current_code) else: self.page.net_graph.update_code(self.current_code) - -AceEditorTemplate = AceEditor diff --git a/nengo_gui/components/component.py b/nengo_gui/components/component.py index 85c9ebc7..748a4f8c 100644 --- a/nengo_gui/components/component.py +++ b/nengo_gui/components/component.py @@ -1,41 +1,111 @@ import json class Component(object): - default_params = dict(x=0, y=0, width=100, height=100, label_visible=True) + """Abstract handler for a particular Component of the user interface. + + Each part of the user interface has part of the code on the server-side + (in Python) and a part on the client-side (in Javascript). These two sides + communicate via WebSockets, and the server-side is always a subclass of + Component. + + Each Component can be configured via the nengo.Config system. Components + can add required nengo objects into the model to allow them to gather + the required data from the running model. Communication from server to + client is done via Component.update_client(), which is called regularly + by the Server.ws_viz_component handler. Communication from client to + server is via Component.message(). + """ + + # The parameters that will be stored in the .cfg file for this Component + # Subclasses should override this as needed. + config_params = dict(x=0, y=0, width=100, height=100, label_visible=True) def __init__(self, component_order=0): - # the order this component will be defined in the javascript + # when generating Javascript for all the Components in a Page, they + # will be sorted by component_order. This way some Components can + # be defined before others. self.component_order = component_order + + # If we have reloaded the model (while typing in the editor), we need + # to swap out the old Component with the new one. self.replace_with = None def initialize(self, page, config, uid): - self.config = config - self.page = page - self.uid = uid + """Connect the Component to a Page.""" + self.config = config # the nengo.Config[component] for this component + self.page = page # the Page this component is in + self.uid = uid # The Python string referencing this component def update_client(self, client): + """Send any required information to the client. + + This method is called regularly by Server.ws_viz_component(). You + send text data to the client-side via a WebSocket as follows: + client.write(data) + You send binary data as: + client.write(data, binary=True) + """ pass def message(self, msg): + """Receive data from the client. + + Any data sent by the client ove the WebSocket will be passed into + this method. + """ print('unhandled message', msg) def finish(self): + """Close this Component""" pass def add_nengo_objects(self, page): + """Add or modify the nengo model before build. + + Components may need to modify the underlying nengo.Network by adding + Nodes and Connections or modifying the structure in other ways. + This method will be called for all Components just before the build + phase. + """ pass def remove_nengo_objects(self, page): + """Undo the effects of add_nengo_objects. + + After the build is complete, remove the changes to the nengo.Network + so that it is all set to be built again in the future. + """ pass def javascript_config(self, cfg): + """Convert the nengo.Config information into javascript. + + This is needed so we can send that config information to the client. + """ for attr in self.config._clsparams.params: cfg[attr] = getattr(self.config, attr) return json.dumps(cfg) - def code_python_args(self, uids): - return [] - def code_python(self, uids): + """Generate Python code for this Component. + + This is used in the .cfg file to generate a valid Python expression + that re-creates this Component. + + The input uids is a dictionary from Python objects to strings that + refer to those Python objects (the reverse of the locals() dictionary) + """ args = self.code_python_args(uids) name = self.__class__.__name__ return 'nengo_gui.components.%s(%s)' % (name, ','.join(args)) + + def code_python_args(self, uids): + """Return a list of strings giving the constructor arguments. + + This is used by code_python to re-create the Python string that + generated this Component, so it can be saved in the .cfg file. + + The input uids is a dictionary from Python objects to strings that + refer to those Python objects (the reverse of the locals() dictionary) + """ + return [] + diff --git a/nengo_gui/components/netgraph.py b/nengo_gui/components/netgraph.py index 86e31f0b..43617768 100644 --- a/nengo_gui/components/netgraph.py +++ b/nengo_gui/components/netgraph.py @@ -468,5 +468,3 @@ def create_connection(self, client, conn, parent): posts = self.get_parents(post)[:-1] info = dict(uid=uid, pre=pres, post=posts, type='conn', parent=parent) client.write(json.dumps(info)) - -NetGraphTemplate = NetGraph diff --git a/nengo_gui/components/pointer.py b/nengo_gui/components/pointer.py index 3dc3ae73..b8f65c0c 100644 --- a/nengo_gui/components/pointer.py +++ b/nengo_gui/components/pointer.py @@ -10,7 +10,7 @@ class Pointer(Component): - config_params = dict(show_pairs=False, **Component.default_params) + config_params = dict(show_pairs=False, **Component.config_params) def __init__(self, obj, **kwargs): super(Pointer, self).__init__() self.obj = obj @@ -91,5 +91,3 @@ def applicable_targets(obj): return list(obj.outputs.keys()) else: return [] - -PointerTemplate = Pointer diff --git a/nengo_gui/components/raster.py b/nengo_gui/components/raster.py index 44f24931..cdd02958 100644 --- a/nengo_gui/components/raster.py +++ b/nengo_gui/components/raster.py @@ -8,7 +8,7 @@ class Raster(Component): - config_params = dict(**Component.default_params) + config_params = dict(**Component.config_params) def __init__(self, obj, n_neurons=None): super(Raster, self).__init__() self.neuron_type = obj.neuron_type @@ -52,5 +52,3 @@ def javascript(self): def code_python_args(self, uids): return [uids[self.obj.ensemble]] - -RasterTemplate = Raster diff --git a/nengo_gui/components/sim_control.py b/nengo_gui/components/sim_control.py index 7e3182cf..5272886c 100644 --- a/nengo_gui/components/sim_control.py +++ b/nengo_gui/components/sim_control.py @@ -135,5 +135,3 @@ def backend_options_html(self): item = '' % (selected, module) items.append(item) return ''.join(items) - -SimControlTemplate = SimControl diff --git a/nengo_gui/components/slider.py b/nengo_gui/components/slider.py index 036d58e3..ebc7af2a 100644 --- a/nengo_gui/components/slider.py +++ b/nengo_gui/components/slider.py @@ -5,7 +5,7 @@ from nengo_gui.components.component import Component class Slider(Component): - config_params = dict(max_value=1, min_value=-1, **Component.default_params) + config_params = dict(max_value=1, min_value=-1, **Component.config_params) def __init__(self, node): super(Slider, self).__init__() self.node = node @@ -68,5 +68,3 @@ def message(self, msg): def code_python_args(self, uids): return [uids[self.node]] - -SliderTemplate = Slider diff --git a/nengo_gui/components/value.py b/nengo_gui/components/value.py index cdb3fa9b..7dcc33d8 100644 --- a/nengo_gui/components/value.py +++ b/nengo_gui/components/value.py @@ -10,7 +10,7 @@ class Value(Component): config_params = dict(max_value=1, min_value=-1, - **Component.default_params) + **Component.config_params) def __init__(self, obj): super(Value, self).__init__() self.obj = obj @@ -48,5 +48,3 @@ def javascript(self): def code_python_args(self, uids): return [uids[self.obj]] - -ValueTemplate = Value diff --git a/nengo_gui/components/voltage.py b/nengo_gui/components/voltage.py index 18a6a0d9..202eeef4 100644 --- a/nengo_gui/components/voltage.py +++ b/nengo_gui/components/voltage.py @@ -9,7 +9,7 @@ class Voltage(Component): config_params = dict( - max_value=5.0, min_value=0.0, **Component.default_params) + max_value=5.0, min_value=0.0, **Component.config_params) def __init__(self, obj, n_neurons=5): super(Voltage, self).__init__() self.obj = obj.neurons @@ -57,4 +57,3 @@ def javascript(self): def code_python_args(self, uids): return [uids[self.obj.ensemble]] -VoltageTemplate = Voltage diff --git a/nengo_gui/components/xyvalue.py b/nengo_gui/components/xyvalue.py index 70f1c052..00b1b578 100644 --- a/nengo_gui/components/xyvalue.py +++ b/nengo_gui/components/xyvalue.py @@ -9,7 +9,7 @@ class XYValue(Component): config_params = dict(max_value=1, min_value=-1, index_x=0, index_y=1, - **Component.default_params) + **Component.config_params) def __init__(self, obj): super(XYValue, self).__init__() self.obj = obj @@ -46,5 +46,3 @@ def javascript(self): def code_python_args(self, uids): return [uids[self.obj]] - -XYValueTemplate = XYValue diff --git a/nengo_gui/page.py b/nengo_gui/page.py index 0468fe0b..58d16ba4 100644 --- a/nengo_gui/page.py +++ b/nengo_gui/page.py @@ -156,7 +156,7 @@ def create_components(self): self.components = [] self.component_uids = {} for k, v in self.locals.items(): - if isinstance(v, nengo_gui.components.component.Component): + if isinstance(v, nengo_gui.components.Component): self.component_uids[v] = k self.gui.component_uids[id(v)] = v self.components.append(v) @@ -248,7 +248,7 @@ def load_config(self): config[self.model].size = (1.0, 1.0) for k, v in self.locals.items(): - if isinstance(v, nengo_gui.components.component.Component): + if isinstance(v, nengo_gui.components.Component): self.default_labels[v] = k v.initialize(page=self, config=config[v], uid=k) From 6d7e75c67a545cfb1e2b2300dc746102e8cf04a7 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Fri, 17 Jul 2015 16:21:43 -0400 Subject: [PATCH 10/16] Added code comments for value.py --- nengo_gui/components/value.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/nengo_gui/components/value.py b/nengo_gui/components/value.py index 7dcc33d8..56a40278 100644 --- a/nengo_gui/components/value.py +++ b/nengo_gui/components/value.py @@ -8,43 +8,68 @@ class Value(Component): + """The server-side system for a Value plot.""" + + # the parameters to be stored in the .cfg file config_params = dict(max_value=1, min_value=-1, **Component.config_params) + def __init__(self, obj): super(Value, self).__init__() + # the object whose decoded value should be displayed self.obj = obj + + # the pending data to be sent to the client self.data = collections.deque() + + # the number of data values to send self.n_lines = int(obj.size_out) + + # the binary data format to sent in. In this case, it is a list of + # floats, with the first float being the time stamp and the rest + # being the vector values, one per dimension. self.struct = struct.Struct('<%df' % (1 + self.n_lines)) def initialize(self, page, config, uid): super(Value, self).initialize(page, config, uid) + # use the label of the object being plotted as our label self.label = page.get_label(self.obj) def add_nengo_objects(self, page): + # create a Node and a Connection so the Node will be given the + # data we want to show while the model is running. with page.model: self.node = nengo.Node(self.gather_data, size_in=self.obj.size_out) self.conn = nengo.Connection(self.obj, self.node, synapse=0.01) def remove_nengo_objects(self, page): + # undo the changes made by add_nengo_objects page.model.connections.remove(self.conn) page.model.nodes.remove(self.node) def gather_data(self, t, x): + # This is the Node function for the Node created in add_nengo_objects + # It will be called by the running model, and will store the data + # that should be sent to the client self.data.append(self.struct.pack(t, *x)) def update_client(self, client): + # while there is data that should be sent to the client while len(self.data) > 0: item = self.data.popleft() + # send the data to the client client.write(item, binary=True) def javascript(self): + # generate the javascript that will create the client-side object info = dict(uid=id(self), label=self.label, n_lines=self.n_lines, synapse=0) json = self.javascript_config(info) return 'new Nengo.Value(main, sim, %s);' % json def code_python_args(self, uids): + # generate the list of strings for the .cfg file to save this Component + # (this is the text that would be passed in to the constructor) return [uids[self.obj]] From 1d3923b6e9580d566c7056d50a3e2f1a655d6012 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Mon, 20 Jul 2015 13:18:32 -0400 Subject: [PATCH 11/16] renamed report_back to notify_server --- nengo_gui/components/netgraph.py | 2 +- nengo_gui/static/nengo.js | 6 +++--- nengo_gui/static/netgraph.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nengo_gui/components/netgraph.py b/nengo_gui/components/netgraph.py index 43617768..9894eeea 100644 --- a/nengo_gui/components/netgraph.py +++ b/nengo_gui/components/netgraph.py @@ -166,7 +166,7 @@ def _reload(self, code=None): if item in removed_items: self.to_be_sent.append(dict(type='delete_graph', uid=id(c), - report_back=False)) + notify_server=False)) orphan_components.append(c) break diff --git a/nengo_gui/static/nengo.js b/nengo_gui/static/nengo.js index 4eac2ea2..941d8c67 100644 --- a/nengo_gui/static/nengo.js +++ b/nengo_gui/static/nengo.js @@ -243,11 +243,11 @@ Nengo.Component.prototype.generate_menu = function() { return items; }; -Nengo.Component.prototype.remove = function(undo_flag, report_back) { +Nengo.Component.prototype.remove = function(undo_flag, notify_server) { undo_flag = typeof undo_flag !== 'undefined' ? undo_flag : false; - report_back = typeof report_back !== 'undefined' ? report_back : true; + notify_server = typeof notify_server !== 'undefined' ? notify_server : true; - if (report_back) { + if (notify_server) { if (undo_flag === true) { this.ws.send('remove_undo'); } else { diff --git a/nengo_gui/static/netgraph.js b/nengo_gui/static/netgraph.js index 0a21b82e..a222a30e 100644 --- a/nengo_gui/static/netgraph.js +++ b/nengo_gui/static/netgraph.js @@ -335,7 +335,7 @@ Nengo.NetGraph.prototype.on_message = function(event) { var uid = data.uid; for (var i = 0; i < Nengo.Component.components.length; i++) { if (Nengo.Component.components[i].uid === uid) { - Nengo.Component.components[i].remove(true, data.report_back); + Nengo.Component.components[i].remove(true, data.notify_server); break; } } From 5f3cdbdbd8d1d1129705583b64540b4b3f1f12f6 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Mon, 20 Jul 2015 15:02:50 -0400 Subject: [PATCH 12/16] Simplified backwards compatibility --- nengo_gui/components/__init__.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/nengo_gui/components/__init__.py b/nengo_gui/components/__init__.py index 9cfb48e5..a46052b6 100644 --- a/nengo_gui/components/__init__.py +++ b/nengo_gui/components/__init__.py @@ -1,6 +1,3 @@ -import inspect -import sys - from .component import Component from .slider import Slider from .value import Value @@ -13,9 +10,14 @@ from .ace_editor import AceEditor # Old versions of the .cfg files used Templates which had slightly different -# names than the Components currently usef. This code is needed to +# names than the Components currently use. This code allows us to # successfully parse those old .cfg files -this_module = sys.modules[__name__] -for name, obj in inspect.getmembers(this_module, inspect.isclass): - if issubclass(obj, Component): - setattr(this_module, name + 'Template', obj) +SliderTemplate = Slider +ValueTemplate = Value +XYValueTemplate = XYValue +SimControlTemplate = SimControl +RasterTemplate = Raster +VoltageTemplate = Voltage +PointerTemplate = Pointer +NetGraphTemplate = NetGraph +AceEditorTemplate = AceEditor From 6636279b8fe4e866ccf9d2f16cf02cd8a9a6327d Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Mon, 20 Jul 2015 15:27:44 -0400 Subject: [PATCH 13/16] renamed config_params to config_defaults --- nengo_gui/components/ace_editor.py | 2 +- nengo_gui/components/component.py | 2 +- nengo_gui/components/netgraph.py | 2 +- nengo_gui/components/pointer.py | 2 +- nengo_gui/components/raster.py | 2 +- nengo_gui/components/sim_control.py | 2 +- nengo_gui/components/slider.py | 4 +++- nengo_gui/components/value.py | 4 ++-- nengo_gui/components/voltage.py | 4 ++-- nengo_gui/components/xyvalue.py | 4 ++-- nengo_gui/config.py | 4 ++-- nengo_gui/server.py | 2 +- 12 files changed, 18 insertions(+), 16 deletions(-) diff --git a/nengo_gui/components/ace_editor.py b/nengo_gui/components/ace_editor.py index 18566a33..445780bd 100644 --- a/nengo_gui/components/ace_editor.py +++ b/nengo_gui/components/ace_editor.py @@ -6,7 +6,7 @@ import nengo_gui.exec_env class AceEditor(Component): - config_params = {} + config_defaults = {} def __init__(self): # the IPython integration requires this component to be early # in the list diff --git a/nengo_gui/components/component.py b/nengo_gui/components/component.py index 748a4f8c..dd67f02c 100644 --- a/nengo_gui/components/component.py +++ b/nengo_gui/components/component.py @@ -18,7 +18,7 @@ class Component(object): # The parameters that will be stored in the .cfg file for this Component # Subclasses should override this as needed. - config_params = dict(x=0, y=0, width=100, height=100, label_visible=True) + config_defaults = dict(x=0, y=0, width=100, height=100, label_visible=True) def __init__(self, component_order=0): # when generating Javascript for all the Components in a Page, they diff --git a/nengo_gui/components/netgraph.py b/nengo_gui/components/netgraph.py index 9894eeea..1113e149 100644 --- a/nengo_gui/components/netgraph.py +++ b/nengo_gui/components/netgraph.py @@ -15,7 +15,7 @@ class NetGraph(Component): - config_params = {} + config_defaults = {} configs = {} def __init__(self): diff --git a/nengo_gui/components/pointer.py b/nengo_gui/components/pointer.py index b8f65c0c..8a7df09c 100644 --- a/nengo_gui/components/pointer.py +++ b/nengo_gui/components/pointer.py @@ -10,7 +10,7 @@ class Pointer(Component): - config_params = dict(show_pairs=False, **Component.config_params) + config_defaults = dict(show_pairs=False, **Component.config_defaults) def __init__(self, obj, **kwargs): super(Pointer, self).__init__() self.obj = obj diff --git a/nengo_gui/components/raster.py b/nengo_gui/components/raster.py index cdd02958..c5b1cf97 100644 --- a/nengo_gui/components/raster.py +++ b/nengo_gui/components/raster.py @@ -8,7 +8,7 @@ class Raster(Component): - config_params = dict(**Component.config_params) + config_defaults = dict(**Component.config_defaults) def __init__(self, obj, n_neurons=None): super(Raster, self).__init__() self.neuron_type = obj.neuron_type diff --git a/nengo_gui/components/sim_control.py b/nengo_gui/components/sim_control.py index 5272886c..de722c10 100644 --- a/nengo_gui/components/sim_control.py +++ b/nengo_gui/components/sim_control.py @@ -12,7 +12,7 @@ import nengo_gui.exec_env class SimControl(Component): - config_params = dict(shown_time=0.5, kept_time=4.0) + config_defaults = dict(shown_time=0.5, kept_time=4.0) def __init__(self, dt=0.001): # this component must be the very first one defined, so # its component_order is the smallest overall diff --git a/nengo_gui/components/slider.py b/nengo_gui/components/slider.py index ebc7af2a..0e135fbd 100644 --- a/nengo_gui/components/slider.py +++ b/nengo_gui/components/slider.py @@ -5,7 +5,9 @@ from nengo_gui.components.component import Component class Slider(Component): - config_params = dict(max_value=1, min_value=-1, **Component.config_params) + config_defaults = dict(max_value=1, min_value=-1, + **Component.config_defaults) + def __init__(self, node): super(Slider, self).__init__() self.node = node diff --git a/nengo_gui/components/value.py b/nengo_gui/components/value.py index 56a40278..f558bc4d 100644 --- a/nengo_gui/components/value.py +++ b/nengo_gui/components/value.py @@ -11,9 +11,9 @@ class Value(Component): """The server-side system for a Value plot.""" # the parameters to be stored in the .cfg file - config_params = dict(max_value=1, + config_defaults = dict(max_value=1, min_value=-1, - **Component.config_params) + **Component.config_defaults) def __init__(self, obj): super(Value, self).__init__() diff --git a/nengo_gui/components/voltage.py b/nengo_gui/components/voltage.py index 202eeef4..4870247f 100644 --- a/nengo_gui/components/voltage.py +++ b/nengo_gui/components/voltage.py @@ -8,8 +8,8 @@ class Voltage(Component): - config_params = dict( - max_value=5.0, min_value=0.0, **Component.config_params) + config_defaults = dict( + max_value=5.0, min_value=0.0, **Component.config_defaults) def __init__(self, obj, n_neurons=5): super(Voltage, self).__init__() self.obj = obj.neurons diff --git a/nengo_gui/components/xyvalue.py b/nengo_gui/components/xyvalue.py index 00b1b578..bfaf2ae8 100644 --- a/nengo_gui/components/xyvalue.py +++ b/nengo_gui/components/xyvalue.py @@ -8,8 +8,8 @@ class XYValue(Component): - config_params = dict(max_value=1, min_value=-1, index_x=0, index_y=1, - **Component.config_params) + config_defaults = dict(max_value=1, min_value=-1, index_x=0, index_y=1, + **Component.config_defaults) def __init__(self, obj): super(XYValue, self).__init__() self.obj = obj diff --git a/nengo_gui/config.py b/nengo_gui/config.py index 70d31b32..f4ffea65 100644 --- a/nengo_gui/config.py +++ b/nengo_gui/config.py @@ -25,7 +25,7 @@ def __init__(self): if issubclass(cls, nengo_gui.components.component.Component): if cls != nengo_gui.components.component.Component: self.configures(cls) - for k, v in cls.config_params.items(): + for k, v in cls.config_defaults.items(): self[cls].set_param(k, nengo.params.Parameter(v)) def dumps(self, uids): @@ -45,7 +45,7 @@ def dumps(self, uids): % (uid, self[obj].has_layout)) elif isinstance(obj, nengo_gui.components.component.Component): lines.append('%s = %s' % (uid, obj.code_python(uids))) - for k in obj.config_params.keys(): + for k in obj.config_defaults.keys(): v = getattr(self[obj], k) if isinstance(v, bool): val = '%s' % v diff --git a/nengo_gui/server.py b/nengo_gui/server.py index 2d527af4..35b317c5 100644 --- a/nengo_gui/server.py +++ b/nengo_gui/server.py @@ -112,7 +112,7 @@ def ws_viz_component(self, client, uid): if msg.startswith('config:'): cfg = json.loads(msg[7:]) old_cfg = {} - for k in component.config_params.keys(): + for k in component.config_defaults.keys(): v = getattr( component.page.config[component], k) old_cfg[k] = v From babea3e1e07061fb8baf0ac675067c22f260b355 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Mon, 20 Jul 2015 15:39:52 -0400 Subject: [PATCH 14/16] Fixed bug in saving Pointer graphs --- nengo_gui/components/pointer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nengo_gui/components/pointer.py b/nengo_gui/components/pointer.py index 8a7df09c..155bc424 100644 --- a/nengo_gui/components/pointer.py +++ b/nengo_gui/components/pointer.py @@ -74,7 +74,7 @@ def javascript(self): return 'new Nengo.Pointer(main, sim, %s);' % json def code_python_args(self, uids): - return [uids[self.obj], 'target=%s' % self.target] + return [uids[self.obj], 'target=%s' % repr(self.target)] def message(self, msg): if len(msg) == 0: From 7c5c95c7e8ecf2fb30618a0cab05d58d2f7f36b8 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Mon, 20 Jul 2015 15:40:33 -0400 Subject: [PATCH 15/16] Renamed initialize to attach --- nengo_gui/components/ace_editor.py | 4 ++-- nengo_gui/components/component.py | 2 +- nengo_gui/components/netgraph.py | 4 ++-- nengo_gui/components/pointer.py | 4 ++-- nengo_gui/components/raster.py | 4 ++-- nengo_gui/components/sim_control.py | 4 ++-- nengo_gui/components/slider.py | 4 ++-- nengo_gui/components/value.py | 4 ++-- nengo_gui/components/voltage.py | 4 ++-- nengo_gui/components/xyvalue.py | 4 ++-- nengo_gui/page.py | 4 ++-- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/nengo_gui/components/ace_editor.py b/nengo_gui/components/ace_editor.py index 445780bd..906f84d4 100644 --- a/nengo_gui/components/ace_editor.py +++ b/nengo_gui/components/ace_editor.py @@ -12,8 +12,8 @@ def __init__(self): # in the list super(AceEditor, self).__init__(component_order=-8) - def initialize(self, page, config, uid): - super(AceEditor, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(AceEditor, self).attach(page, config, uid) if page.gui.interactive: self.current_code = page.code self.serve_code = True diff --git a/nengo_gui/components/component.py b/nengo_gui/components/component.py index dd67f02c..38e9240b 100644 --- a/nengo_gui/components/component.py +++ b/nengo_gui/components/component.py @@ -30,7 +30,7 @@ def __init__(self, component_order=0): # to swap out the old Component with the new one. self.replace_with = None - def initialize(self, page, config, uid): + def attach(self, page, config, uid): """Connect the Component to a Page.""" self.config = config # the nengo.Config[component] for this component self.page = page # the Page this component is in diff --git a/nengo_gui/components/netgraph.py b/nengo_gui/components/netgraph.py index 1113e149..7b6e99ec 100644 --- a/nengo_gui/components/netgraph.py +++ b/nengo_gui/components/netgraph.py @@ -32,8 +32,8 @@ def __init__(self): self.parents = {} self.initialized_pan_and_zoom = False - def initialize(self, page, config, uid): - super(NetGraph, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(NetGraph, self).attach(page, config, uid) self.layout = nengo_gui.layout.Layout(self.page.model) self.to_be_expanded = collections.deque([self.page.model]) self.to_be_sent = collections.deque() diff --git a/nengo_gui/components/pointer.py b/nengo_gui/components/pointer.py index 155bc424..1d9a8120 100644 --- a/nengo_gui/components/pointer.py +++ b/nengo_gui/components/pointer.py @@ -20,8 +20,8 @@ def __init__(self, obj, **kwargs): self.vocab_out = obj.outputs[self.target][1] self.vocab_in = obj.inputs[self.target][1] - def initialize(self, page, config, uid): - super(Pointer, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(Pointer, self).attach(page, config, uid) self.label = page.get_label(self.obj) self.vocab_out.include_pairs = config.show_pairs diff --git a/nengo_gui/components/raster.py b/nengo_gui/components/raster.py index c5b1cf97..311bf586 100644 --- a/nengo_gui/components/raster.py +++ b/nengo_gui/components/raster.py @@ -19,8 +19,8 @@ def __init__(self, obj, n_neurons=None): n_neurons = min(self.max_neurons, 10) self.n_neurons = n_neurons - def initialize(self, page, config, uid): - super(Raster, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(Raster, self).attach(page, config, uid) self.label = page.get_label(self.obj.ensemble) def add_nengo_objects(self, page): diff --git a/nengo_gui/components/sim_control.py b/nengo_gui/components/sim_control.py index de722c10..b546608d 100644 --- a/nengo_gui/components/sim_control.py +++ b/nengo_gui/components/sim_control.py @@ -30,8 +30,8 @@ def __init__(self, dt=0.001): self.next_ping_time = None self.send_config_options = False - def initialize(self, page, config, uid): - super(SimControl, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(SimControl, self).attach(page, config, uid) self.shown_time = config.shown_time self.kept_time = config.kept_time diff --git a/nengo_gui/components/slider.py b/nengo_gui/components/slider.py index 0e135fbd..6cfe5ca9 100644 --- a/nengo_gui/components/slider.py +++ b/nengo_gui/components/slider.py @@ -21,8 +21,8 @@ def __init__(self, node): if not callable(self.base_output): self.start_value[:] = self.base_output - def initialize(self, page, config, uid): - super(Slider, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(Slider, self).attach(page, config, uid) self.label = page.get_label(self.node) def add_nengo_objects(self, page): diff --git a/nengo_gui/components/value.py b/nengo_gui/components/value.py index f558bc4d..0db15f40 100644 --- a/nengo_gui/components/value.py +++ b/nengo_gui/components/value.py @@ -31,8 +31,8 @@ def __init__(self, obj): # being the vector values, one per dimension. self.struct = struct.Struct('<%df' % (1 + self.n_lines)) - def initialize(self, page, config, uid): - super(Value, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(Value, self).attach(page, config, uid) # use the label of the object being plotted as our label self.label = page.get_label(self.obj) diff --git a/nengo_gui/components/voltage.py b/nengo_gui/components/voltage.py index 4870247f..ebe7c590 100644 --- a/nengo_gui/components/voltage.py +++ b/nengo_gui/components/voltage.py @@ -18,8 +18,8 @@ def __init__(self, obj, n_neurons=5): self.n_neurons = min(n_neurons, self.max_neurons) self.struct = struct.Struct('<%df' % (1 + self.n_neurons)) - def initialize(self, page, config, uid): - super(Voltage, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(Voltage, self).attach(page, config, uid) self.label = page.get_label(self.obj.ensemble) def add_nengo_objects(self, page): diff --git a/nengo_gui/components/xyvalue.py b/nengo_gui/components/xyvalue.py index bfaf2ae8..ec5f00b3 100644 --- a/nengo_gui/components/xyvalue.py +++ b/nengo_gui/components/xyvalue.py @@ -17,8 +17,8 @@ def __init__(self, obj): self.n_lines = int(obj.size_out) self.struct = struct.Struct('<%df' % (1 + self.n_lines)) - def initialize(self, page, config, uid): - super(XYValue, self).initialize(page, config, uid) + def attach(self, page, config, uid): + super(XYValue, self).attach(page, config, uid) self.label = page.get_label(self.obj) def add_nengo_objects(self, page): diff --git a/nengo_gui/page.py b/nengo_gui/page.py index 58d16ba4..16614c63 100644 --- a/nengo_gui/page.py +++ b/nengo_gui/page.py @@ -168,7 +168,7 @@ def add_component(self, component): """Add a new Component to an existing Page.""" self.gui.component_uids[id(component)] = component uid = self.get_uid(component) - component.initialize(self, self.config[component], uid=uid) + component.attach(self, self.config[component], uid=uid) self.components.append(component) def execute(self, code): @@ -250,7 +250,7 @@ def load_config(self): for k, v in self.locals.items(): if isinstance(v, nengo_gui.components.Component): self.default_labels[v] = k - v.initialize(page=self, config=config[v], uid=k) + v.attach(page=self, config=config[v], uid=k) return config From 5d96ffd46ab271d8bca04f87d8b3887879f1a917 Mon Sep 17 00:00:00 2001 From: Terry Stewart Date: Mon, 20 Jul 2015 15:52:43 -0400 Subject: [PATCH 16/16] Simplified fix to pointer graph saving --- nengo_gui/components/pointer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nengo_gui/components/pointer.py b/nengo_gui/components/pointer.py index 1d9a8120..855d947e 100644 --- a/nengo_gui/components/pointer.py +++ b/nengo_gui/components/pointer.py @@ -74,7 +74,7 @@ def javascript(self): return 'new Nengo.Pointer(main, sim, %s);' % json def code_python_args(self, uids): - return [uids[self.obj], 'target=%s' % repr(self.target)] + return [uids[self.obj], 'target=%r' % self.target] def message(self, msg): if len(msg) == 0: