class WebSocketRegistry(object): def __init__(self): self.wsregistry = dict() self.wsregistry_lock = threading.Lock() self.on_new_client = EventHook() def register_ws(self, wstype, ws): self.wsregistry_lock.acquire() try: socketlist = self.wsregistry.get(wstype) if not socketlist: socketlist = [] self.wsregistry[wstype] = socketlist socketlist.append(ws) self.on_new_client.fire(wstype, ws) finally: self.wsregistry_lock.release() def unregister_ws(self, wstype, ws): self.wsregistry_lock.acquire() try: socketlist = self.wsregistry[wstype] socketlist.remove(ws) finally: self.wsregistry_lock.release() def broadcast(self, wstype, msg): send_count = 0; self.wsregistry_lock.acquire() try: erroneous_sockets = [] socketlist = self.wsregistry.get(wstype) if socketlist: for socket in socketlist: try: socket.write_message(msg) send_count += 1 except Exception as e: logger.exception('Error detected when sending to websocket of type %s: %s', wstype, str(e)) erroneous_sockets.append(socket) for erroneous_socket in erroneous_sockets: socketlist.remove(erroneous_socket) finally: self.wsregistry_lock.release() return send_count > 0
class GameObject(object): def __init__(self): self._x = self._y = 0 self.x_velocity = self.y_velocity = 0 self.new_objects = [] self._components = [] self.alive = True self.active = True self.on_collision = EventHook() def set_components(self, value): self._components = value for c in self._components: c.game_object = self components = property(lambda self: self._components, set_components) def update(self, elapsed_time): for c in self.components: c.update(elapsed_time) x = property(lambda self: self._get_x(), lambda self, x: self._set_x(x)) def _get_x(self): return self._x def _set_x(self, value): self._x = value y = property(lambda self: self._get_y(), lambda self, y: self._set_y(y)) def _get_y(self): return self._y def _set_y(self, value): self._y = value def _set_position(self, value): self.x = value[0] self.y = value[1] def _get_position(self): return self.x, self.y position = property(_get_position, _set_position) def get_rect(self): return Rect(0, 0, 0, 0) def handle_collision_with(self, other_obj): self.on_collision.fire(other_obj)
class EventSinkMethod(object): def __init__(self): self.lock = Lock() self.event_hook = None self.event = None self.one_time_subscriptions = [] def subscribe(self, callback): with self.lock: if not self.event_hook: self.event_hook = EventHook() self.event_hook += callback def unsubscribe(self, callback): with self.lock: if self.event_hook: self.event_hook += callback def subscribe_once(self, callback): with self.lock: self.one_time_subscriptions.append(callback) def wait(self, timeout): with self.lock: if not self.event: self.event = Event() else: self.event.clear() self.event.wait(timeout) def handle_call(self, *args, **kwargs): with self.lock: # check if a event_hook exist if self.event_hook: self.event_hook.fire(*args, **kwargs) # check if event exist if self.event: self.event.set() # check if any one time subcriptions exist if self.one_time_subscriptions: # loop thru all all callbacks and invoke for callback in self.one_time_subscriptions: callback(*args, **kwargs) # clear list del self.one_time_subscriptions[:]
class SetManager: def __init__(self): self.devices = set() self.events = EventHook() def update(self, current): scanned_devices = set(current) added = scanned_devices-self.devices removed = self.devices-scanned_devices self.devices -= removed self.devices |= added for d in removed: self.events.fire(d, False) for d in added: self.events.fire(d, True)
class ProgressSpan: def __init__(self,max=0,min=0,name=""): self.max = max self.min = min self.name = name self.current = min self.on_change = EventHook() def update(self, current): if current!=self.current: self.current = current self.on_change.fire(self) def __iadd__(self, other): self.update(self.current + other) return self
def __init__(self, master, headers, row, column): self.master = master self.headers = headers self.items_dict = {} self.tree = None self.container = ttk.Frame(self.master) self.container.grid(row=row, column=column, sticky=tk.W+tk.E+tk.N+tk.S) self._set_up_tree_widget() self._build_tree() # create a popup menu self.pop_menu = tk.Menu(self.tree, tearoff=0) self.pop_menu.add_command(label="New", command=self.new) self.pop_menu.add_command(label="Remove", command=self.remove) self.pop_menu.add_command(label="Remove All", command=self.remove_all) self.pop_menu.add_command(label="Edit", command=self.edit) self.pop_menu_add = tk.Menu(self.tree, tearoff=0) self.pop_menu_add.add_command(label="New", command=self.new) self.pop_menu_add.add_command(label="Remove All", command=self.remove_all) self.tree.bind("<Button-2>", self.pop_up) self.tree.bind("<Button-3>", self.pop_up) self.onChange = EventHook() self.tip = None
class UpdaterState: """ UpdaterState for the entire update process. """ def __init__(self): self.on_change = EventHook() self.state = None self.set_state(FlashState.not_connected) def set_state(self,state): old = self.state self.state = state if old!=state: self.notify() def notify(self): self.on_change.fire(self)
def __init__(self): self._x = self._y = 0 self.x_velocity = self.y_velocity = 0 self.new_objects = [] self._components = [] self.alive = True self.active = True self.on_collision = EventHook()
def __init__(self): self.devices = set() self.events = EventHook()
def __init__(self): self.wsregistry = dict() self.wsregistry_lock = threading.Lock() self.on_new_client = EventHook()
def __init__(self): self.on_change = EventHook() self.state = None self.set_state(FlashState.not_connected)
class GridBox(object): def __init__(self, master, headers, row, column): self.master = master self.headers = headers self.items_dict = {} self.tree = None self.container = ttk.Frame(self.master) self.container.grid(row=row, column=column, sticky=tk.W+tk.E+tk.N+tk.S) self._set_up_tree_widget() self._build_tree() # create a popup menu self.pop_menu = tk.Menu(self.tree, tearoff=0) self.pop_menu.add_command(label="New", command=self.new) self.pop_menu.add_command(label="Remove", command=self.remove) self.pop_menu.add_command(label="Remove All", command=self.remove_all) self.pop_menu.add_command(label="Edit", command=self.edit) self.pop_menu_add = tk.Menu(self.tree, tearoff=0) self.pop_menu_add.add_command(label="New", command=self.new) self.pop_menu_add.add_command(label="Remove All", command=self.remove_all) self.tree.bind("<Button-2>", self.pop_up) self.tree.bind("<Button-3>", self.pop_up) self.onChange = EventHook() self.tip = None def clearTip(self): self.setTip("") def setTipNotRequired(self): self.setTip("Not Required") def setTip(self, text): if self.tip != None: self.tip['text'] = text def item_count(self): return len(self.items_dict) def pop_up(self, event): item = self.tree.identify_row(event.y) if item: # mouse pointer over item self.tree.selection_set(item) self.tree.update() self.pop_menu.post(event.x_root, event.y_root) else: self.pop_menu_add.post(event.x_root, event.y_root) def get_selected_key(self): selection = self.tree.selection() if len(selection) > 0: return selection[0] else: return None def get_selected(self): key = self.get_selected_key() if key != None: return self.items_dict[key] else: return None def new(self): pass def get_item_values(self, item): return {} def edit_item(self, item): pass def remove_all(self): keys = self.items_dict.keys() for key in keys: self.remove_item(key) def remove_item(self, key): del self.items_dict[key] self.tree.delete(key) def remove(self): selection = self.get_selected_key() if selection != None: self.remove_item(selection) self.onChange.fire() def edit(self): try: item = self.get_selected() if item != None: self.edit_item(item) self.onChange.fire() print except ExceptionHandler.ExceptionType as e: ExceptionHandler.add(e, "Cannot edit item") def add_item(self, item): values = self.get_tree_values(item) key = self.tree.insert('', 'end', values = values) self.items_dict[key] = item self.adjust_width(values) self.default_sort() self.onChange.fire() def redraw_item(self, key): item = self.items_dict[key] values = self.get_tree_values(item) self.tree.item(key, text='', values=values) self.adjust_width(values) self.default_sort() def adjust_width(self, values): # adjust column's width if necessary to fit each value for ix, val in enumerate(values): if not val is None: try: col_w = tkFont.Font().measure(val) if self.tree.column(self.headers[ix],width=None)<col_w: self.tree.column(self.headers[ix], width=col_w) except ExceptionHandler.ExceptionType as e: ExceptionHandler.add("Cannot adjust column width {0}: {1}".format(val, e)) def get_tree_values(self, item): values = [] values_dict = self.get_item_values(item) for header in self.headers: values.append(values_dict[header]) return values def add_items(self, items): for item in items: self.add_item(item) def get_items(self): return self.items_dict.values() def double_click(self, event): key = self.tree.identify('item', event.x, event.y) if key in self.items_dict: item = self.items_dict[key] self.edit_item(item) def _set_up_tree_widget(self): tree_container = ttk.Frame(self.container) tree_container.grid(row=0, column=0, sticky=tk.W+tk.E+tk.N+tk.S) #tree_container.pack(fill='both', expand=True) # create a treeview with dual scrollbars self.tree = ttk.Treeview(tree_container, columns=self.headers, show="headings") vsb = ttk.Scrollbar(tree_container, orient="vertical", command=self.tree.yview) hsb = ttk.Scrollbar(tree_container, orient="horizontal", command=self.tree.xview) self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set) self.tree.grid(column=0, row=0, sticky='nsew') vsb.grid(column=1, row=0, sticky='ns') hsb.grid(column=0, row=1, sticky='ew') tree_container.grid_columnconfigure(0, weight=1) tree_container.grid_rowconfigure(0, weight=1) self.tree.bind("<Double-1>", self.double_click) def get_header_width(self, header): return tkFont.Font().measure(header.title()) * self.get_header_scale() def get_header_scale(self): return 1 def _build_tree(self): for col in self.headers: self.tree.heading(col, text=col.title(), command=lambda c=col: self.sortby(self.tree, c, 0)) # adjust the column's width to the header string self.tree.column(col, width=self.get_header_width(col)) def sortby(self, tree, col, descending): """sort tree contents when a column header is clicked on""" # grab values to sort data = [(tree.set(child, col), child) \ for child in tree.get_children('')] # if the data to be sorted is numeric change to float #data = change_numeric(data) # now sort the data in place data.sort(reverse=descending) for ix, item in enumerate(data): tree.move(item[1], '', ix) # switch the heading so it will sort in the opposite direction tree.heading(col, command=lambda col=col: self.sortby(tree, col, \ int(not descending))) def default_sort(self): if len(self.headers) < 1: return first_column = self.headers[0] self.sortby(self.tree, first_column, False)
def subscribe(self, callback): with self.lock: if not self.event_hook: self.event_hook = EventHook() self.event_hook += callback
def __init__(self,max=0,min=0,name=""): self.max = max self.min = min self.name = name self.current = min self.on_change = EventHook()
def __init__(self, max=0, min=0, name=""): self.max = max self.min = min self.name = name self.current = min self.on_change = EventHook()
class GridBox(object): def __init__(self, master, headers, row, column): self.master = master self.headers = headers self.items_dict = {} self.tree = None self.container = ttk.Frame(self.master) self.container.grid(row=row, column=column, sticky=tk.W + tk.E + tk.N + tk.S) self._set_up_tree_widget() self._build_tree() # create a popup menu self.pop_menu = tk.Menu(self.tree, tearoff=0) self.pop_menu.add_command(label="New", command=self.new) self.pop_menu.add_command(label="Remove", command=self.remove) self.pop_menu.add_command(label="Remove All", command=self.remove_all) self.pop_menu.add_command(label="Edit", command=self.edit) self.pop_menu_add = tk.Menu(self.tree, tearoff=0) self.pop_menu_add.add_command(label="New", command=self.new) self.pop_menu_add.add_command(label="Remove All", command=self.remove_all) self.tree.bind("<Button-2>", self.pop_up) self.tree.bind("<Button-3>", self.pop_up) self.onChange = EventHook() self.tip = None def clearTip(self): self.setTip("") def setTipNotRequired(self): self.setTip("Not Required") def setTip(self, text): if self.tip != None: self.tip['text'] = text def item_count(self): return len(self.items_dict) def pop_up(self, event): item = self.tree.identify_row(event.y) if item: # mouse pointer over item self.tree.selection_set(item) self.tree.update() self.pop_menu.post(event.x_root, event.y_root) else: self.pop_menu_add.post(event.x_root, event.y_root) def get_selected_key(self): selection = self.tree.selection() if len(selection) > 0: return selection[0] else: return None def get_selected(self): key = self.get_selected_key() if key != None: return self.items_dict[key] else: return None def new(self): pass def get_item_values(self, item): return {} def edit_item(self, item): pass def remove_all(self): keys = self.items_dict.keys() for key in keys: self.remove_item(key) def remove_item(self, key): del self.items_dict[key] self.tree.delete(key) def remove(self): selection = self.get_selected_key() if selection != None: self.remove_item(selection) self.onChange.fire() def edit(self): try: item = self.get_selected() if item != None: self.edit_item(item) self.onChange.fire() print except ExceptionHandler.ExceptionType as e: ExceptionHandler.add(e, "Cannot edit item") def add_item(self, item): values = self.get_tree_values(item) key = self.tree.insert('', 'end', values=values) self.items_dict[key] = item self.adjust_width(values) self.default_sort() self.onChange.fire() def redraw_item(self, key): item = self.items_dict[key] values = self.get_tree_values(item) self.tree.item(key, text='', values=values) self.adjust_width(values) self.default_sort() def adjust_width(self, values): # adjust column's width if necessary to fit each value for ix, val in enumerate(values): if not val is None: try: col_w = tkFont.Font().measure(val) if self.tree.column(self.headers[ix], width=None) < col_w: self.tree.column(self.headers[ix], width=col_w) except ExceptionHandler.ExceptionType as e: ExceptionHandler.add( "Cannot adjust column width {0}: {1}".format(val, e)) def get_tree_values(self, item): values = [] values_dict = self.get_item_values(item) for header in self.headers: values.append(values_dict[header]) return values def add_items(self, items): for item in items: self.add_item(item) self.default_sort() def get_items(self): return self.items_dict.values() def double_click(self, event): key = self.tree.identify('item', event.x, event.y) if key in self.items_dict: item = self.items_dict[key] self.edit_item(item) def _set_up_tree_widget(self): tree_container = ttk.Frame(self.container) tree_container.grid(row=0, column=0, sticky=tk.W + tk.E + tk.N + tk.S) #tree_container.pack(fill='both', expand=True) # create a treeview with dual scrollbars self.tree = ttk.Treeview(tree_container, columns=self.headers, show="headings") vsb = ttk.Scrollbar(tree_container, orient="vertical", command=self.tree.yview) hsb = ttk.Scrollbar(tree_container, orient="horizontal", command=self.tree.xview) self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set) self.tree.grid(column=0, row=0, sticky='nsew') vsb.grid(column=1, row=0, sticky='ns') hsb.grid(column=0, row=1, sticky='ew') tree_container.grid_columnconfigure(0, weight=1) tree_container.grid_rowconfigure(0, weight=1) self.tree.bind("<Double-1>", self.double_click) def get_header_width(self, header): return tkFont.Font().measure(header.title()) * self.get_header_scale() def get_header_scale(self): return 1 def _build_tree(self): for col in self.headers: self.tree.heading( col, text=col.title(), command=lambda c=col: self.sortby(self.tree, c, 0)) # adjust the column's width to the header string self.tree.column(col, width=self.get_header_width(col)) def change_numeric(self, data): new_items = [] for item in data: new_item = (float(item[0]), item[1]) new_items.append(new_item) return new_items def preprocess_sort_values(self, data): return data def sortby(self, tree, col, descending): """sort tree contents when a column header is clicked on""" # grab values to sort data = [(tree.set(child, col), child) \ for child in tree.get_children('')] # if the data to be sorted is numeric change to float #data = change_numeric(data) # now sort the data in place data = self.preprocess_sort_values(data) data.sort(reverse=descending) for ix, item in enumerate(data): tree.move(item[1], '', ix) # switch the heading so it will sort in the opposite direction tree.heading(col, command=lambda col=col: self.sortby(tree, col, \ int(not descending))) def default_sort(self): self.sort_by_column_index(0) def sort_by_column_index(self, index): if len(self.headers) < 1: return first_column = self.headers[index] self.sortby(self.tree, first_column, False)