12.7. Kanavan takaisinkutsut¶
protocol.register() -funktiolle annettu backend-objekti on Python-luokka. Protokollakirjasto ei kysy luokalta, mitä metodeja se toteuttaa; se tarkastelee instanssia ja kytkee löytämänsä metodit. Juuri tämä introspektio tekee backend-rajapinnasta joustavan: pienin hyödyllinen backend on kaksi metodia, monimutkaisin on kaksitoista, ja sovellus ottaa kunkin ominaisuuden käyttöön yksi metodi kerrallaan.
12.7.1. Introspektion säännöt¶
Kun protocol.register() suoritetaan, kirjasto käy läpi kiinteän listan kutsuttavien metodien nimiä ja sitoo jokaisen, jonka se löytää backend-instanssista:
read-metodin lisääminen luokkaan kytkee päälleCHANNEL_FLAG_READ-lipun. Isäntäkutsuchannel_read()-metodiin tavoittaa backendin vain, jos tämä lippu on asetettu.write-metodin lisääminen kytkee päälleCHANNEL_FLAG_WRITE-lipun, mikä ottaa käyttöönchannel_write()-metodin.lock- jaunlock-metodien lisääminen kytkee päälleCHANNEL_FLAG_LOCK-lipun, jolloin isäntä voi lukita kanavan usean paketin atomista lukua varten.poll-metodin lisääminen antaa isännän kysyä edullisesti ”onko mitään valmiina?”, ilman että koko luku pakotetaan suorittamaan.
Puuttuvat metodit eivät ole virheitä – protokollakirjasto jättää vain vastaavan ominaisuuden pois käytöstä. Backend, jossa on vain size ja read, on täysin kelvollinen; se on vain luettava datakanava.
12.7.2. Vain luettava sensorikanava¶
Sensorikanava, joka julkaisee tuoreen lukeman aina kun isäntä pyytää ja torjuu isännän kirjoitukset, käyttää neljää takaisinkutsuista:
import protocol
import struct
class TempChannel:
def __init__(self, read_sensor):
self._read_sensor = read_sensor
self._buf = b''
self._fresh = False
def poll(self):
# Tell the host whether a reading is waiting.
return self._fresh
def size(self):
# Sample fresh data on every host-side size query.
value = self._read_sensor()
self._buf = struct.pack('<f', value)
self._fresh = True
return len(self._buf)
def read(self, offset, size):
end = offset + size
if end >= len(self._buf):
self._fresh = False
return self._buf[offset:end]
protocol.register(name='temp', backend=TempChannel(read_temperature))
Käydään läpi, mitä kukin metodi tekee:
pollpalauttaa tuoreuslipun. Isäntä kutsuu sitä ennen lukemista ja ohittaa luvun kokonaan, kun se palauttaaFalse. Tämä säästää edestakaisen viestinnän kustannuksen tapauksessa ”ei vielä uutta dataa”.sizeluo puskurin uudelleen pyynnöstä ja ilmoittaa sen pituuden. Näytteenoton tekeminen tässä tarkoittaa, ettei backend tarvitse taustatehtävää – isäntäkutsu ohjaa jokaista mittausta.readpalauttaa siivun puskurista. Protokollakirjasto saattaa kutsua sitä useammin kuin kerran, kun puskuri on suurempi kuin neuvoteltu enimmäishyötykuorma;offset-argumentti kulkee fragmenttien läpi.write-metodin puuttuminen tarkoittaa, että isännän kirjoitukset torjutaan kehystyskerroksessa, ennen kuin backend on mukana.
12.7.3. Täysi takaisinkutsujen joukko¶
Viitteeksi jokainen metodi, jota kirjasto etsii backendista:
Metodi |
Palauttaa |
Tarkoitus |
|---|---|---|
|
object |
Valinnainen kertaluonteinen alustus, kun kanava ensimmäisen kerran sitoutuu isäntään. Palauta mikä tahansa muu kuin |
|
bool |
Palauta |
|
bool |
Varaa kanava atomista usean paketin siirtoa varten. |
|
bool |
Vapauta aiempi |
|
int |
Kanavasta tällä hetkellä luettavissa olevien tavujen määrä. |
|
tuple |
Enintään neljä kokonaislukua, jotka kuvaavat datarakennetta (esim. kuvan korkeus, leveys, tavumäärä). Isäntä käyttää näitä tyypitettyjen puskurien purkamiseen. |
|
bytes |
Palauta enintään size tavua alkaen kohdasta offset. Kutsutaan kerran fragmenttia kohden, kun hyötykuorma ylittää neuvotellun enimmäismäärän. |
|
bytes |
|
|
int |
Isäntä kirjoitti data kohtaan offset. |
|
int |
Sovelluskohtainen operaatiokoodi luku/kirjoitus-mallin ulkopuolella. Negatiivinen paluuarvo on virhe. |
|
object |
Hylkää kaikki puskuroitu data. Kutsutaan, kun isäntä haluaa nollata kanavan. |
|
bool |
Merkityksellinen vain backendeissä, jotka edustavat fyysistä siirtotietä (sisäänrakennetut USB-kanavat). Sovelluskanavat eivät tarvitse tätä. |
Tässä on koko backend-rajapinta. Kaksitoista metodinimeä, kaikki valinnaisia, ja protokollakirjasto päättää, mitä kukin kanava voi tehdä sen perusteella, mitkä niistä ovat läsnä.