List raw sensor data in Memo
Asked Answered
B

1

7

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.
Belgrade answered 21/4, 2015 at 12:34 Comment(9)
Can you please explain a bit more detailled? I am trying to figure it out since many hours. p_orientation is an TCustomOrientationSensor and the other side too. When I remove irrelevant things like "TypInfo", it works again.Belgrade
That statement contradicts what you report in the question.Distributee
My statement is, that it doesn't compile anymore. You can test it yourself. I commented out some things, but I can't find out where the problem is, so I assume a compiler bug.Belgrade
Looks like you found the problem already to me // Error (only in XE8): Incompatible types 'TCustomLocationSensor.TProperty' and 'TCustomOrientationSensor.TProperty' Never assume anything, especially when it comes to blaming someone/something else.Ahab
@JerryDodge What do you mean? I didn't find any problem solution.Belgrade
Can you please tell me WHAT I need to change? I have checked everything. As far as I saw, both sides are compatible.Belgrade
Isn't this looking like a compiler bug to you? Compiler will not compile for-loop 'X' (the first one) if for-loop 'Y' (the second one) is present. When I comment out for-loop 'Y', for-loop 'X' will compile. Both for-loops are a different piece of sequential code. If I comment out for-loop 2, for-loop 1 will work. If I comment out for-loop 1, for-loop 2 will work.Belgrade
After adding your update, yes, it does look very peculiar.Ahab
The update makes things much clearer. Thank you.Distributee
D
5

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.

Distributee answered 21/4, 2015 at 17:8 Comment(2)
Thank you very much for this idea! Now the code compiles in the new version of Delphi again. :-) I also reported the bug: quality.embarcadero.com/browse/RSP-10575 . Btw, do you think using accessors and typeinfo is the only possibility to read out all available sensor data? In my opinion, it appears to be an unclean programming style.Belgrade
I'm not familiar with FMX, especially not the mobile compilers. But RTTI for this does indeed feel pretty wrong. One feels that there ought to be a better way .......Distributee

© 2022 - 2024 — McMap. All rights reserved.