RemObjects release a new Oxygene version + C# sister product

I’ve just noticed RemObjects have released a new Oxygene version together with ‘RemObjects C#’, a C# sister product that was codenamed Hydrogene – check out the announcement here. The improved cross platform support sounds interesting (traditionally, the Oxygene language would differ somewhat depending on the target platform), and in the case of RemObjects C#… well, it seems a competitor is a bit rattled!

Miguel

Dearie me – read that and you would never guess that when it comes to targeting Android, Delphi and Xamarin are on one side of the fence and Oxygene and RemObjects C# the other, for better or for worse…

Update

And now we get this…

Hoffman

At least Delphi has done generics on OS X since 2011 😉

StackOverflown

So… I was finally broken: I created a StackOverflow account. Annoyingly, a certain individual in particular is waaaayy too fast in answering most Delphi questions (genuine expertise + quick on the button = cheating, surely?)… so I started picking off Access ones instead (easy points there – write three lines of trivial SQL, and bingo). Alas, but even for a subject area in which one would expect to find a fair few novices asking novice questions, there remains a certain… priggishness about the fact.

Cartman

(Actual picture of self-appointed SO prefect moderator.)

 

[PS: to the literal-minded, no I don’t actually think David is a ‘cheat’ any more than I think Eric Cartman actually patrols StackOverflow 😉 ]

The little things…

Honestly, for how many versions now has the following got through?

unit FMX.Types;

//...

type
  TGradientPoint = class(TCollectionItem)
  private
    FColor: TAlphaColor;
    FOffset: Single;
    function GetColor: TAlphaColor;
    procedure SetColor(const Value: TAlphaColor);
  public
    procedure Assign(Source: TPersistent); override;
    property IntColor: TAlphaColor read FColor write FColor;
  published
    property Color: TAlphaColor read GetColor write SetColor;
    property Offset: Single read FOffset write FOffset nodefault;
  end;

//...

procedure TGradientPoint.Assign(Source: TPersistent);
begin
  if Source is TGradientPoint then
  begin
    FColor := TGradientPoint(Source).FColor;
    FOffset := TGradientPoint(Source).FOffset;
  end
  else
    inherited;
end;

function TGradientPoint.GetColor: TAlphaColor;
begin
  Result := FColor;
end;

procedure TGradientPoint.SetColor(const Value: TAlphaColor);
begin
  FColor := Value;
end;

What am I whinging about you say? This:

  1. What’s with the weird IntColor/Color duplication? Probably an historical thing… but why wasn’t the IntColor version taken out when the Color version was refactored?
  2. Why does Color have a getter that just directly returns the value of the backing field?
  3. Why doesn’t its setter (and Assign) call the Changed method?
  4. Where’s the Add method for TGradientPoints to cast the TCollection implementation’s result to TGradientPoint?
  5. Where’s the Update override for TGradientPoints? We want a property change to make a visible difference, right?

Oh, and don’t get me started on how the TGradient property editor is both horrible to use and set up to replace (not complement) what would have been perfectly reasonable default Object Inspector behaviour…

I’m speechless

Back last July, I blogged about terrible example code posted by Stephen Ball, an Embarcadero ‘Product Evangelist’. Ultimately, the critique of Ball’s code was really just a lead-off for pointing out how the same anti-pattern used had appeared prominently in the FMX source too. Happily, XE3 RTM saw most of that removed (though not all of it). However, for reasons I don’t understand, Ball has now proudly turned his blog post into a YouTube video:

Honestly, view it and weep. I expect his defence will be ‘but I’m only illustrating class helpers’, but if so, that would be dubious given he’s already been warned the example makes him look foolish [on his original post, the automated pingback from my blog was accepted, but my actual comment – ‘I’ve just posted a critical (but friendly) commentary here’ – never got past the moderation queue. His reply implied he still read it though]. Moreover, it’s perfectly possible to demonstrate class helpers without writing rubbish – check out the relevant page on Lachlan Gemmell’s TIndex for examples. (*)

That said, the class helper anti-example wasn’t the first time Ball had put out poor code – if you want something just as bad, check out his ‘white paper’ on packaging a FMX form into a DLL or dylib, which was also something he originally put out in the XE2 timeframe and has now recently re-promoted. The example used in it is an image file picker, which is fair enough, but here’s how he writes his exports:

  function SelectPicture(AFolder : PChar): PChar; cdecl;
  var
    ResultStr : string;
    Temp: PWideChar;
  begin
    ResultStr := '';
    try
      ResultStr := TfrmImages.SelectPicture(AFolder);
    finally
      Result := StrAlloc(Length(ResultStr));
      Temp := Addr(ResultStr[1]);
      StrCopy(Result,Temp);
    end;
  end;

  procedure DisposePicture(SelectPictureResult : PChar); cdecl;
  begin
    StrDispose(SelectPictureResult);
  end;

If that doesn’t embody the mentality of ‘It compiles, so ship it!’, I don’t know what does.

(*) PS – the David Glassborow articles linked to on the TIndex are now found here and here – I’ve posted the corrections to the TIndex blog, so hopefully the links might even be fixed by the time you read this post.

PPS – eh?