Ignore:
Timestamp:
04/07/12 08:48:34 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

Implemented better connection and connection failure handling.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/mlx/fsuipc.py

    r51 r59  
    5959            return None
    6060
     61    # The number of times a read is attempted
    6162    NUM_READATTEMPTS = 3
     63
     64    # The number of connection attempts
     65    NUM_CONNECTATTEMPTS = 3
     66
     67    # The interval between successive connect attempts
     68    CONNECT_INTERVAL = 0.25
    6269
    6370    @staticmethod
     
    172179            return cmp(self._nextFire, other._nextFire)
    173180
    174     def __init__(self, connectionListener):
     181    def __init__(self, connectionListener,
     182                 connectAttempts = -1, connectInterval = 0.2):
    175183        """Construct the handler with the given connection listener."""
    176184        threading.Thread.__init__(self)
    177185
    178186        self._connectionListener = connectionListener
     187        self._connectAttempts = connectAttempts
     188        self._connectInterval = connectInterval
    179189
    180190        self._requestCondition = threading.Condition()
    181191        self._connectionRequested = False
    182         self._connected = False
     192        self._connected = False       
    183193
    184194        self._requests = []
     
    266276        """Disconnect from the flight simulator."""
    267277        with self._requestCondition:
     278            self._requests = []
    268279            if self._connectionRequested:
    269                 self._connectionRequested = False
     280                self._connectionRequested = False               
    270281                self._requestCondition.notify()
     282
     283    def clearRequests(self):
     284        """Clear the outstanding one-shot requests."""
     285        with self._requestCondition:
     286            self._requests = []
    271287
    272288    def run(self):
     
    286302                self._requestCondition.wait()
    287303           
    288     def _connect(self):
     304    def _connect(self, autoReconnection = False):
    289305        """Try to connect to the flight simulator via FSUIPC
    290306
     
    292308        not due to no longer requested.
    293309        """
     310        attempts = 0
    294311        while self._connectionRequested:
    295312            try:
     313                attempts += 1
    296314                pyuipc.open(pyuipc.SIM_ANY)
    297315                description = "(FSUIPC version: 0x%04x, library version: 0x%04x, FS version: %d)" % \
    298316                    (pyuipc.fsuipc_version, pyuipc.lib_version,
    299317                     pyuipc.fs_version)
    300                 Handler._callSafe(lambda:     
    301                                   self._connectionListener.connected(const.SIM_MSFS9,
    302                                                                      description))
     318                if not autoReconnection:
     319                    Handler._callSafe(lambda:     
     320                                      self._connectionListener.connected(const.SIM_MSFS9,
     321                                                                         description))
    303322                self._connected = True
    304323                return True
    305324            except Exception, e:
    306325                print "fsuipc.Handler._connect: connection failed: " + str(e)
    307                 time.sleep(0.1)
     326                if attempts<self.NUM_CONNECTATTEMPTS:
     327                    time.sleep(self.CONNECT_INTERVAL)
     328                else:
     329                    self._connectionRequested = False
     330                    if autoReconnection:
     331                        Handler._callSafe(lambda:     
     332                                          self._connectionListener.disconnected())
     333                    else:
     334                        Handler._callSafe(lambda:     
     335                                          self._connectionListener.connectionFailed())
    308336
    309337        return False
     
    337365        if self._connected:
    338366            pyuipc.close()
    339             Handler._callSafe(lambda: self._connectionListener.disconnected())
    340367            self._connected = False
    341 
    342     def _failRequests(self, request):
    343         """Fail the outstanding, single-shot requuests."""
    344         request.fail()
    345         with self._requestCondition:
    346             for request in self._requests:
    347                 try:
    348                     self._requestCondition.release()
    349                     request.fail()
    350                 finally:
    351                     self._requestCondition.acquire()
    352             self._requests = []       
    353 
     368           
    354369    def _processRequest(self, request, time):
    355370        """Process the given request.
     
    377392
    378393            if needReconnect:
     394                with self._requestCondition:
     395                    self._requests.insert(0, request)
    379396                self._disconnect()
    380                 self._failRequests(request)
    381                 self._connect()
     397                self._connect(autoReconnection = True)
    382398        finally:
    383399            self._requestCondition.acquire()
     
    437453                   (0x0580, "d") ]           # Heading
    438454
    439     def __init__(self, connectionListener):
     455    def __init__(self, connectionListener, connectAttempts = -1,
     456                 connectInterval = 0.2):
    440457        """Construct the simulator.
    441458       
     
    460477        self._aircraft = None
    461478
    462         self._handler = Handler(connectionListener)
     479        self._handler = Handler(connectionListener,
     480                                connectAttempts = connectAttempts,
     481                                connectInterval = connectInterval)
    463482        self._handler.start()
    464483
     
    484503        self._aircraftModel = None
    485504        self._handler.connect()
    486         self._startDefaultNormal()
     505        if self._normalRequestID is None:
     506            self._startDefaultNormal()
     507
     508    def reconnect(self):
     509        """Initiate a reconnection to the simulator.
     510
     511        It does not reset already set up data, just calls connect() on the
     512        handler."""
     513        self._handler.connect()
     514
     515    def requestZFW(self, callback):
     516        """Send a request for the ZFW."""
     517        self._handler.requestRead([(0x3bfc, "d")], self._handleZFW, extra = callback)
    487518                                                           
    488519    def startMonitoring(self):
     
    683714        else:
    684715            self._addFlareRate(data[2])
     716
     717    def _handleZFW(self, data, callback):
     718        """Callback for a ZFW retrieval request."""
     719        zfw = data[0] * const.LBSTOKG / 256.0
     720        callback(zfw)
    685721                                                 
    686722#------------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.