TPoint - Delphi vs Oxygene (Android)

With the latest Elements compiler, full version, I started to convert some drawing code which works with Delphi to draw inside an Android App. I am using a special “TCanvas” class which handles the current state, such as Brush, Pen and X,Y position and acts as an interface to android.graphics.Canvas.

During the work I stumbled about:

  1. Sets: Delphi vs Oxygene

In Delphi I can write:
TFontStyle = (fsBold, fsItalic, fsUnderline, fsStrikeOut);
TFontStyles = set of TFontStyle ;

In Oxygene the “set of” does not work. In this case the solution is a “flags of (…)” but this will not help me in many cases because code which uses i.e.**array[TFontStyle] of … ** has to be completely rewritten. Is there a WIKI which shows me how to adapt the code to make it work on Delphi and Oxygene?

  1. Records
    In Delphi there is a TPoint - that’s essentially a record. For Android I use the declaration TPoint = public not nullable PointF; and my code compiles without warning. However when started the app shuts down without message!

The reason is code like this:
var p : TPoint;
p.x := 1; //<— SHUTDOWN!

Well - with Java/Android p is an object and what I am doing in the line above is accessing the element x of a non existing object.

But:
a) Why does the Oxygene compiler accept this and does not even show a warning?
b) Can I see the exception in the IDE somehow? I cannot get “Log()” to work.

Is there a possibility to make the compiler initialize variables as the one above automatically.
Yes, I can write
var p : TPoint := new TPoint;
but for arrays I need this:
var pt : array[0…3] of TPoint;
for j := Low(pt) to High(pt) do pt[i] := new TPoint;
which bloats the code a lot.

BTW - I thought this could be coded as
for each j in pt do j := new TPoint;
But that code does not change the array - the elements stay nil!

  1. Exceptions
    If I need to capture (and see) exception like in Delphi how is this does best?
    I cannot makes this code work:
    try
    except
    on e:Exception do // android.util.Log
    Log.e(‘ERR’, e.Message)
    end;

Is it possible to make the Oxygene compiler wrap each method inside try/except so I can see an exception and the app does not shut down?

  1. Sugar / wrapped types
    I understand wrapped classes to work like inline code which translates the API. That’s a good concept, however quite often such translation tasks need state variables. (i.e. a wrapper for Canvas or a wrapper which also adds functionality)
    Is it possible to create a class wrapper which also adds its own set of variables? I can do it with standard code, but then I have to pass through each call. The wrapper should extend the original type, not embed it.

Sorry for this many beginner questions,

Julian

I’m planning on making sets like this work on Java too, though I can’t promise that will make it into the next release. I don’t see a good direct translation that works exactly like delphi and still is backward compatible with Delphi.

Re: Exceptions: See (3) below. The compiler should have warned about assigning values to a not initialized not nullable var. Logged as bugs://71272: Compiler does not fail on not nullable type when used as an alias.

we do support automatic initialization but only for record types defined in Oxygene itself, not for platform defined types. The loop is indeed the easiest way to do this. The reason foreach doesn’t work is because for each uses the loops iterator, which is readonly.

you could with aspects, but it would be easier to just make the debugger stop on exceptions? Debug/Exceptions. Check Java runtime exceptions, expand it and Uncheck “java.lang.ClassNotFoundExceptions”. Note that this will stop on all exceptions, and Java is known for throwing “expected” exceptions, so you might have to ignore those.

You could create a class/record with your variables with inline methods on it. This would essentially make it work like mapped types but with the possibility to hold state.

bugs://71272 got closed with status fixed.

Thank you - this is most important for me. Would it be possible to have the debugger only stop for exceptions which happen in source code which is available? When I trace through the code I also run into the “source not found” problem. Delphi would not try to open source files which it does not have debugging symbols - I find that very useful and time saving.

According to the initialisation of arrays (see above): It would be great if there would be a system function, i.e. _initArray( var myarray : array of object, myType : TClassType) which does the initialisation for me. I know how to code this in Delphi, but not in Oxygene. Having such a function would save me a lot of IFDEFS in my platform independent code.

Big problem there is that the JVM offers no indication of what library the class that got triggered was defined in. Just a source file (often without path) that I hand back to Visual Studio which deals with the displaying of it. You can hoewver disable the exceptions like classNotFound which will hide most of them.

That’s a rather specialized function though? One that fills an array based on the class’ empty constructor. I think this would fit better in the codebase itself?

Yes, I guess I can write a function InitPoints() which does whats necessary. If I get the warning for the non-nullable objects this should not be an issue.

Is there a magic switch to disable the debugger ask me for unknown source files from the runtime when I trace through the code. That would help a lot.

Thanks for your help!

There IS 1 thing I can do. Make it not show source requests when the namespace is java. or android. Will that help you?

Yes, that would be great.
Maybe it would be even better to let the developer edit the list of namespaces which are shown and all others are ignored? Of course the debugger should show all source files which are listed in the project anyway.

Thanks, logged as bugs://71335