From f877814d55d1469069fccfe0bc59bcf492d7b381 Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Sat, 09 Feb 2008 17:18:11 +0000 Subject: Move name logic into dobject --- diff --git a/dobject.py b/dobject.py index ede4512..a89c6cf 100644 --- a/dobject.py +++ b/dobject.py @@ -6,8 +6,11 @@ import logging import threading import thread -def NoneFunction(*args): - return +def PassFunction(*args): + pass + +def ReturnFunction(x): + return x class TubeBox: """ A TubeBox is a box that either contains a Tube or does not. @@ -95,13 +98,13 @@ class TimeHandler(dbus.gobject_service.ExportedGObject): def get_offset(self): """Get the difference between local time and group time""" - self._logger.debug("offset= " + str(self.offset)) + self._logger.debug("get_offset " + str(self.offset)) return self.offset def set_offset(self, offset): """Set the difference between local time and group time, and assert that this is correct""" - self._logger.debug("set_offset " + str(self.offset)) + self._logger.debug("set_offset " + str(offset)) self._offset_lock.acquire() self.offset = offset self._know_offset = True @@ -126,7 +129,7 @@ class TimeHandler(dbus.gobject_service.ExportedGObject): self._logger.debug("telling offset") remote = self.tube.get_object(sender, self.PATH) start_time += self.offset - remote.receive_time(asktime, start_time, time.time() + self.offset, reply_handler=NoneFunction, error_handler=NoneFunction) + remote.receive_time(asktime, start_time, time.time() + self.offset, reply_handler=PassFunction, error_handler=PassFunction) finally: return @@ -190,9 +193,9 @@ class UnorderedHandler(dbus.gobject_service.ExportedGObject): self.tube = None self.object = None - self._tube_box.register_listener(self.get_tube) + self._tube_box.register_listener(self.set_tube) - def get_tube(self, tube, is_initiator): + def set_tube(self, tube, is_initiator): """Callback for the TubeBox""" self.tube = tube self.add_to_connection(self.tube, self.PATH) @@ -213,6 +216,16 @@ class UnorderedHandler(dbus.gobject_service.ExportedGObject): self.object = obj if self.tube is not None: self.ask_history() + + def get_path(self): + """Returns the DBus path of this handler. The path is the closest thing + to a unique identifier for each abstract DObject.""" + return self.PATH + + def get_tube(self): + """Returns the TubeBox used to create this handler. This method is + necessary if one DObject wishes to create another.""" + return self._tube_box @dbus.service.signal(dbus_interface=IFACE, signature='v') def send(self, message): @@ -239,7 +252,7 @@ class UnorderedHandler(dbus.gobject_service.ExportedGObject): return remote = self.tube.get_object(sender, self.PATH) h = self.object.get_history() - remote.receive_history(h, reply_handler=NoneFunction, error_handler=NoneFunction) + remote.receive_history(h, reply_handler=PassFunction, error_handler=PassFunction) finally: return @@ -261,3 +274,119 @@ class UnorderedHandler(dbus.gobject_service.ExportedGObject): self._logger.debug("members_changed") for (handle, name) in added: self.tell_history(sender=name) + +def empty_translator(x, pack): + return x + +class HighScore(): + def __init__(self, handler, initval, initscore, value_translator=empty_translator, score_translator=empty_translator): + self._logger = logging.getLogger('stopwatch.HighScore') + self._lock = threading.Lock() + self._value = initval + self._score = initscore + + self._val_trans = value_translator + self._score_trans = score_translator + + self._handler = handler + self._handler.register(self) + + self._listeners = [] + + def _set_value_from_net(self, val, score): + self._logger.debug("set_value_from_net " + str(val) + " " + str(score)) + if self._actually_set_value(val, score): + self._trigger() + + def receive_message(self, message): + self._logger.debug("receive_message " + str(message)) + self._set_value_from_net(self._val_trans(message[0], False), self._score_trans(message[1], False)) + + add_history = receive_message + + def set_value(self, val, score): + self._logger.debug("set_value " + str(val) + " " + str(score)) + if self._actually_set_value(val, score): + self._handler.send(self.get_history()) + + def _actually_set_value(self, value, score): + self._logger.debug("_actually_set_value " + str(value)+ " " + str(score)) + self._lock.acquire() + if self._score < score: + self._value = value + self._score = score + self._lock.release() + return True + else: + self._logger.debug("not changing value") + self._lock.release() + return False + + def get_value(self): + return self._value + + def get_score(self): + return self._score + + def get_pair(self): + self._lock.acquire() + pair = (self._value, self._score) + self._lock.release() + return pair + + def get_history(self): + p = self.get_pair() + return (self._val_trans(p[0], True), self._score_trans(p[1], True)) + + def register_listener(self, L): + self._lock.acquire() + self._listeners.append(L) + self._lock.release() + (v,s) = self.get_pair() + L(v,s) + + def _trigger(self): + (v,s) = self.get_pair() + for L in self._listeners: + L(v,s) + +def float_translator(f, pack): + if pack: + return dbus.Double(f) + else: + return float(f) + +def string_translator(s, pack): + if pack: + return dbus.String(s) + else: + return str(s) + +class Latest: + def __init__(self, handler, initval, inittime=float('-inf'), time_handler=None, translator=empty_translator): + if time_handler is None: + self._time_handler = TimeHandler(handler.get_path(), handler.get_tube()) + else: + self._time_handler = time_handler + + self._listeners = [] + self._lock = threading.Lock() + + self._highscore = HighScore(handler, initval, inittime, translator, float_translator) + self._highscore.register_listener(self._highscore_cb) + + def get_value(self): + return self._highscore.get_value() + + def set_value(self, val): + self._highscore.set_value(val, self._time_handler.time()) + + def register_listener(self, L): + self._lock.acquire() + self._listeners.append(L) + self._lock.release() + L(self.get_value()) + + def _highscore_cb(self, val, score): + for L in self._listeners: + L(val) diff --git a/stopwatch.py b/stopwatch.py index 98fb98a..4d1d211 100644 --- a/stopwatch.py +++ b/stopwatch.py @@ -33,58 +33,6 @@ from gettext import gettext IFACE = "org.laptop.StopWatch" PATH = "/org/laptop/StopWatch" -class NameModel(): - def __init__(self, name, handler): - self._logger = logging.getLogger('stopwatch.NameModel') - self._lock = threading.Lock() - self._name = name - self._time = float('-inf') - self._handler = handler - self._handler.register(self) - - self._view_listener = None - - def get_history(self): - return dbus.Struct((self._name, self._time), signature='sd') - - def set_name_from_net(self, name, t): - self._logger.debug("set_name_from_net " + name) - if self.set_name(name, t): - self._trigger() - - def receive_message(self, message): - self.set_name_from_net(str(message[0]), float(message[1])) - - add_history = receive_message - - def set_name_from_UI(self, name, t): - self._logger.debug("set_name_from_UI " + name) - if self.set_name(name, t): - self._handler.send(self.get_history()) - - def set_name(self, name, t): - self._logger.debug("set_name " + name) - self._lock.acquire() - if self._time < t: - self._name = str(name) - self._time = float(t) - self._lock.release() - return True - else: - self._lock.release() - return False - - def get_name(self): - return (self._name, self._time) - - def register_view_listener(self, L): - self._view_listener = L - self._trigger() - - def _trigger(self): - if self._view_listener is not None: - thread.start_new_thread(self._view_listener, (self._name,)) - class WatchModel(): STATE_PAUSED = 1 STATE_RUNNING = 2 @@ -226,7 +174,7 @@ class OneWatchView(): self._name = gtk.Entry() self._name_changed_handler = self._name.connect('changed', self._name_cb) self._name_lock = threading.Lock() - self._name_model.register_view_listener(self.update_name) + self._name_model.register_listener(self._update_name_cb) check = gtk.Image() check.set_from_file('check.svg') @@ -312,7 +260,12 @@ class OneWatchView(): self._label_lock.release() self._update_lock.release() + def _update_name_cb(self, name): + self._logger.debug("_update_name_cb " + name) + thread.start_new_thread(self.update_name, (name,)) + def update_name(self, name): + self._logger.debug("update_name " + name) self._name_lock.acquire() self._name.set_editable(False) self._name.handler_block(self._name_changed_handler) @@ -375,8 +328,7 @@ class OneWatchView(): return True def _name_cb(self, widget): - t = time.time() - self._name_model.set_name_from_UI(widget.get_text(), self._offset + t) + self._name_model.set_value(widget.get_text()) return True def pause(self): @@ -422,7 +374,7 @@ class GUIView(): self._watches = [] for i in xrange(GUIView.NUM_WATCHES): name_handler = dobject.UnorderedHandler("name"+str(i), tubebox) - name_model = NameModel(gettext("Stopwatch") + " " + locale.str(i+1), name_handler) + name_model = dobject.Latest(name_handler, gettext("Stopwatch") + " " + locale.str(i+1), time_handler=timer, translator=dobject.string_translator) self._names.append(name_model) watch_handler = dobject.UnorderedHandler("watch"+str(i), tubebox) watch_model = WatchModel(watch_handler) @@ -437,7 +389,7 @@ class GUIView(): self._pause_lock = threading.Lock() def get_names(self): - return [n.get_name() for n in self._names] + return [n.get_value() for n in self._names] def set_names(self, namestate): for i in xrange(GUIView.NUM_WATCHES): -- cgit v0.9.1