I want to list all available raw sensor data in a Memo for Android.
Following code worked over the past years, but it doesn't work with XE8. There is probably an internal compiler bug. Is there anything I can do to make it work again, or is there an alternative solution?
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;
Update
Some experiments:
(1) When I comment out the first "for", it will compile:
// 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) When I comment out the assigning of "n" and "v", it will compile too:
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;
Since neither "for", nor "n" and "v" is the bad region, where is the error then?
(3) When I comment out the second for-loop, it will compile again. If I comment out the first for-loop, it will compile too. Each for-loop works, but in combination they will not work.
It looks like the error is only happening if 5 factors are combined:
Update 2
Here is the smallest reproducible code I could find. If any line is commented out, it compiles:
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.
Yes, this looks like an XE8 compiler bug. I think you've done a fine job isolating it, for which I commend you. You'll need to submit bug report to Quality Portal.
To workaround the fault I think you will be able to put the loops in separate functions. My hypothesis is that the key is the presence of two for in loops with differently typed loop variables that is the key. Avoid that and you should be able to avoid the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With