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:
- TypInfo
- Accessors
- for loop
- Usage of TypInfo (GetEnumName)
- Both for-loops are used.
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.
p_orientation
is anTCustomOrientationSensor
and the other side too. When I remove irrelevant things like "TypInfo", it works again. – Belgrade// Error (only in XE8): Incompatible types 'TCustomLocationSensor.TProperty' and 'TCustomOrientationSensor.TProperty'
Never assume anything, especially when it comes to blaming someone/something else. – Ahab