2015-04-21 26 views
7

Desidero elencare tutti i dati del sensore grezzo disponibili in un Memo per Android.Elencare i dati del sensore grezzo in Memo

Il seguente codice ha funzionato negli anni passati, ma non funziona con XE8. C'è probabilmente un bug interno del compilatore. C'è qualcosa che posso fare per farlo funzionare di nuovo, o c'è una soluzione alternativa?

uses 
    TypInfo; 

type 
    TOrientationSensorAccessor = class(TCustomOrientationSensor); 
    TLocationSensorAccessor = class(TCustomLocationSensor); 

procedure TForm2.Button1Click(Sender: TObject); 
var 
    p_location: TCustomLocationSensor.TProperty; 
    p_orientation: TCustomOrientationSensor.TProperty; 
    n, v: string; 
begin 
    Memo1.Lines.Clear; 

    if Assigned(OrientationSensor1.Sensor) then 
    begin 
    if not OrientationSensor1.Sensor.Started then OrientationSensor1.Sensor.Start; 

    // Error (only in XE8): Incompatible types 'TCustomLocationSensor.TProperty' and 'TCustomOrientationSensor.TProperty' 
    // In XE7 it works. 
    for p_orientation in OrientationSensor1.Sensor.AvailableProperties do 
    begin 
     n := 'OrientationSensor.'+GetEnumName(TypeInfo(TCustomOrientationSensor.TProperty), integer(p_orientation)) ; 
     v := FloatToStr(TOrientationSensorAccessor(OrientationSensor1.Sensor).GetDoubleProperty(p_orientation)); 
     Memo1.Lines.Values[n] := v; 
    end; 
    end; 

    if Assigned(LocationSensor1.Sensor) then 
    begin 
    if not LocationSensor1.Sensor.Started then LocationSensor1.Sensor.Start; 
    for p_location in LocationSensor1.Sensor.AvailableProperties do 
    begin 
     n := 'LocationSensor.'+GetEnumName(TypeInfo(TCustomLocationSensor.TProperty), integer(p_location)) ; 
     v := FloatToStr(TLocationSensorAccessor(LocationSensor1.Sensor).GetDoubleProperty(p_location)); 
     Memo1.Lines.Values[n] := v; 
    end; 
    end; 
end; 

Aggiornamento

Alcuni esperimenti:

(1) Quando io commento la prima "per", si compilerà:

// for p_orientation in OrientationSensor1.Sensor.AvailableProperties do 
// begin 
     n := 'OrientationSensor.'+GetEnumName(TypeInfo(TCustomOrientationSensor.TProperty), integer(p_orientation)) ; 
     v := FloatToStr(TOrientationSensorAccessor(OrientationSensor1.Sensor).GetDoubleProperty(p_orientation)); 
     Memo1.Lines.Values[n] := v; 
// end; 
    end; 

(2) Quando commento l'assegnazione di "n" e "v", verrà compilato anche:

for p_orientation in OrientationSensor1.Sensor.AvailableProperties do 
    begin 
//  n := 'OrientationSensor.'+GetEnumName(TypeInfo(TCustomOrientationSensor.TProperty), integer(p_orientation)) ; 
//  v := FloatToStr(TOrientationSensorAccessor(OrientationSensor1.Sensor).GetDoubleProperty(p_orientation)); 
//  Memo1.Lines.Values[n] := v; 
    end; 
    end; 

Poiché né "per", né "n" e "v" è la regione male, dove è l'errore, allora?

(3) Quando commento il secondo ciclo, verrà compilato di nuovo. Se commento il primo ciclo, verrà compilato anche. Ogni ciclo for funziona, ma in combinazione non funzionerà.

Sembra che l'errore sta accadendo solo se 5 fattori si combinano:

  • TypInfo
  • accessor
  • ciclo for
  • Uso di TypInfo (GetEnumName)
  • Sia per-loops sono usati.

Update 2

ecco il codice riproducibili più piccolo sono riuscito a trovare. Se una riga è commentata, compila:

program ProjectCompilerBug; 

{$APPTYPE CONSOLE} 

uses 
    System.Sensors, System.Sensors.Components; 

var 
    p_location: TCustomLocationSensor.TProperty; 
    p_orientation: TCustomOrientationSensor.TProperty; 
begin 
    // Compilation Error (only in XE8): 
    // "Incompatible types 'TCustomLocationSensor.TProperty' and 'TCustomOrientationSensor.TProperty'" 
    // In XE7 it compiles 
    for p_orientation in TOrientationSensor.Create(nil).Sensor.AvailableProperties do 
    begin 
    FloatToStr(1.23); 
    end; 

    for p_location in TLocationSensor.Create(nil).Sensor.AvailableProperties do 
    begin 
    end; 
end. 
+0

Puoi spiegarci meglio un po 'di più? Sto cercando di capirlo da molte ore. 'p_orientation' è un' TCustomOrientationSensor' e anche l'altro lato. Quando rimuovo cose irrilevanti come "TypInfo", funziona di nuovo. –

+0

Questa dichiarazione contraddice ciò che riporta nella domanda. –

+0

La mia affermazione è che non si compila più. Puoi testarlo da solo. Ho commentato alcune cose, ma non riesco a scoprire dove si trova il problema, quindi presumo un bug del compilatore. –

risposta

5

Sì, questo sembra un bug del compilatore XE8. Penso che tu abbia fatto un ottimo lavoro isolandolo, per cui ti raccomando. Dovrai inviare una segnalazione di bug al portale di qualità.

Per risolvere il problema penso che sarete in grado di mettere i loop in funzioni separate. La mia ipotesi è che la chiave sia la presenza di due per cicli in loop con variabili di ciclo tipizzate in modo diverso che è la chiave. Evitatelo e dovreste essere in grado di evitare il problema.

+0

Grazie mille per questa idea! Ora il codice viene compilato di nuovo nella nuova versione di Delphi. :-) Ho anche segnalato il bug: https://quality.embarcadero.com/browse/RSP-10575. Btw, pensi che l'utilizzo di accessori e typeinfo sia l'unica possibilità di leggere tutti i dati dei sensori disponibili? A mio parere, sembra essere uno stile di programmazione non pulito. –

+0

Non ho familiarità con FMX, specialmente con i compilatori mobili. Ma RTTI per questo è davvero sbagliato. Si sente che dovrebbe esserci un modo migliore ....... –