class Agent(EventSource, EventListener): def __init__(self, config): from timer import TimerCollection from event import EventQueue self.state = STOPPED self.config = config self._info = None self.connections = [] self.event_queue = EventQueue() self.timers = TimerCollection() EventSource.__init__(self) EventListener.__init__(self) # Yes we are a listener to ourselves self.addListener(self) self.setState(STARTING) if self.config.getBindAddress() != None and \ self.config.getPort() != None: log.debug("Initializing server on %s:%d" % (self.config.getBindAddress(), self.config.getPort())) srv_sock = create_server_socket(self.config.getBindAddress(), self.config.getPort()) self.addConnection(ServerConnection(srv_sock)) log.debug("Server initialized") else: log.debug("Initialized non-server agent") def getConnections(self): return self.connections def getConnection(self, name): for c in self.connections: if c.getName() == name: return c return None def getConnectionByInfo(self, info): for c in self.connections: if isinstance(c, AgentConnection): if c.getAgentInfo() == info: return c return None def addConnection(self, conn): self.connections.append(conn) log.debug("Connection Added (%d)" % (len(self.connections))) def dropConnection(self, conn): self.connections.remove(conn) log.debug("Connection Dropped (%d)" % (len(self.connections))) def addEvent(self, event): self.event_queue.push(event) log.debug("Event Added (%d)" % (len(self.event_queue))) def addTimer(self, timer): self.timers.add(timer) log.debug("Timer Added (%d)" % (len(self.timers))) def dropTimer(self, timer): self.timers.remove(timer) log.debug("Timer Removed (%d)" % (len(self.timers))) def getConfig(self): return self.config def getInfo(self): if self._info is None: self._info = AgentInfo(self.getConfig()) return self._info def getState(self): return self.state def setState(self, state): self.addEvent(StateChangeEvent(self, self.state, state)) if self.state != state: self.state = state def isRunning(self): return isinstance(self.state, RunningState) # Event Handlers def handleConnectionReadEvent(self, event): log.debug("Handling Read Event") obj = event.getSource().read() if obj != None: self.addEvent(obj) def handleConnectionWriteEvent(self, event): log.debug("Handling Write Event") event.getSource().write() def handleConnectionExceptionEvent(self, event): log.debug("Handling Connection Exception Event") event.getSource().disconnect() self.dropConnection(event.getSource()) def handleConnectEvent(self, event): log.debug("Handling connect event") self.addConnection(event.getNewConnection()) def handleMessageRecievedEvent(self, event): # All we will do a receive event is log it. # Its up to one of our listeners to care about it. log.debug("Received a message of type %s" % str(event.getMessage().__class__)) if isinstance(event.getMessage(), Request): log.debug("Request: %s" % str(event.getMessage())) if isinstance(event.getMessage(), Response): log.debug("Response: %s" % str(event.getMessage())) def handleMessageSendEvent(self, event): log.debug("Sending a message of type %s" % str(event.getMessage().__class__)) if isinstance(event.getMessage(), Request): log.debug("Request: %s" % event.getMessage().getKey()) if isinstance(event.getMessage(), Response): log.debug("Response: %s" % str(event.getMessage())) if isinstance(event.getTarget(), Connection): event.getTarget().write(str(event.getMessage())) _handlers = { ConnectionReadEvent: handleConnectionReadEvent, ConnectionWriteEvent: handleConnectionWriteEvent, ConnectionExceptionEvent: handleConnectionExceptionEvent, MessageSendEvent: handleMessageSendEvent, MessageReceivedEvent: handleMessageRecievedEvent, ConnectEvent: handleConnectEvent } def getHandlers(self): return Agent._handlers def notify(self, evt): found = 0 hndlrs = self.getHandlers() for h in hndlrs.keys(): if isinstance(evt, h): hndlrs[h](self, evt) found = 1 def processEvent(self): """Process a single event from the event_queue""" log.debug("Going to handle an event") event = self.event_queue.pop() if event != None: try: log.debug("Handling event %s" % str(event)) self.notifyListeners(event) except Exception, e: log.exception("Error handling event")
class VoronoiDiagram(object): def __init__(self, pts, bounding_box=None, step_by_step=True): self.input = pts self.bounding_box = bounding_box self.edges = [] self._faces = dict() self._compute([ Point(*p) for p in pts ],bounding_box, step_by_step) def _compute(self, points, bounding_box=None, step_by_step=True): self.T = AVLBeachLine() self.Q = EventQueue(points) log('EventQueue: %s' % str(self.Q)) while not self.Q.is_empty: event = self.Q.pop() log('Popped %s id=%s' % (event,id(event))) if isinstance(event, SiteEvent): log('_handle_site_event') self._handle_site_event(event) else: log('_handle_circle_event') self._handle_circle_event(event) if step_by_step: self.animate(event, draw_bottoms=False) log('%s' % self.T.T.dumps()) log('beachline: %s' % self.T) log('-----') self.animate(SiteEvent((0,-100)), draw_circle_events=False) def _handle_site_event(self, evt): if self.T.is_empty: self.T.insert(evt.site) else: a = self.T.search(evt.site) if a.circle_event is not None: log('Deleting false alarm %s id=%s' % (a.circle_event,id(a.circle_event))) a.circle_event = None log('\tInserting %s into arc %s' % (evt.site, a)) x = self.T.insert(evt.site, within=a) self._create_twins(x.site,a.site) # check the triples where this new site is the far left and far right arc. self.check_circle(self.T.predecessor(x),evt.site.y) self.check_circle(self.T.sucessor(x),evt.site.y) def _handle_circle_event(self, evt): if evt.is_valid: log('\tRemoving arc %s' % evt.arc) log('\t\tbefore removal: %s' % self.T) pred,suc = self.T.delete(evt.arc) log('\t\t after removal: %s' % self.T) log('\t\tChecking for deleting arcs involving %s' % evt.arc) if pred.circle_event is not None: log('\t\t\tGotta delete pred %s' % pred.circle_event) pred.circle_event = None else: log('\t\t\tpred: no circle_event') if suc.circle_event is not None: log('\t\t\tGotta delete suc %s' % suc.circle_event) suc.circle_event = None else: log('\t\t\tsuc: no circle_event') new_half_edge = self._create_twins(suc.site, pred.site) new_half_edge._origin = evt.center # finish incident hedges ! log('\t\tUpdate incident edges') log('\t\t\tpred/suc %s %s' % (pred, suc)) for left, right in ((pred.site, evt.arc.site), (evt.arc.site, suc.site)): half_edge = None log('\t\t\tleft/right %s %s' % (left, right)) log('\t\t\tneighbours of %s' % self._faces[left]) for he in self._faces[left]._iter_neighbours(): log('\t\t\t\t%s twin: %s' % (he, he._twin)) if he._twin._site == right: #half_edge = he he._origin = evt.center log('\t\t\t Chosen to be updated was %s' % he) #half_edge._origin = evt.center self.check_circle(pred, evt.y) self.check_circle(suc, evt.y) else: log('\t%s was previously deleted' % evt) def _create_twins(self, site1, site2): half_edge = Hedge(None, None, site1, self._faces.get(site1, None)) half_edge._twin = Hedge(None, half_edge, site2, self._faces.get(site2, None)) self.edges.append(half_edge) self._faces[site1] = half_edge self._faces[site2] = half_edge._twin log('\t\tCreated new half-edge: %s' % half_edge) log('\t\t\t _faces = %s' % self._faces) return half_edge def _check_circle(self, predecessor, arc, sucessor, sweep_line_y): log('\t\tcheck circle for triple %s %s %s' % (predecessor,arc,sucessor)) if not predecessor or not sucessor or not arc: return a, b, c = predecessor.site, arc.site, sucessor.site if determinant(b - a, c - b) <= 0: circle = circumcircle(a,b,c) if circle is not None: self.Q.push(CircleEvent(arc,circle)) def check_circle(self, arc, sweep_line_y): predecessor = self.T.predecessor(arc) sucessor = self.T.sucessor(arc) self._check_circle(predecessor,arc,sucessor,sweep_line_y)