Xojo Blog Post: Writing Drawing Code for Android, Desktop, iOS and Web

The recent Xojo blog post on cross-platform drawing describes a technique using Variant and conditional compilation to write drawing code that works across platforms (Graphics for Desktop/Mobile and WebGraphics for Web).

To me that has been one of the worst Blog Posts… it shows the bad design of having all the DesktopXXX and WebXXX classes in the Xojo Framework. While this approach works, it introduces unnecessary complexity and hinders code maintainability. It doesn’t feel “x-platform” at all, having to use Conditional Compilation for simple shared Graphics classes/logic.

While we all don’t understand the decision why there is no common base class (remember all the discussions before API 2 has been introduced…?), why isn’t there even a simple Interface for these usages?

That’s what I would like to use for a custom “cross platform” (drawing) class that can be used in any Xojo Project/Target:


I’d like to encourage Xojo once more to provide a Consistent API Design for their cross-platform goal. In this particular case of Graphics the Blog Post has shown: If there was an IGraphics, this would unifiy drawing behavior across platforms with a clean abstraction layer. That would align with object-oriented best practices and be a major step forward for cross-platform/target development in Xojo.

Issue #79006 also contains the example projects with the IGraphics approach (well, obviously just another workaround, since we can’t apply an own Interface to Xojo’s Graphics and WebGraphics - that would need to be provided by the Xojo Framework).

12 Likes

At the very least I hope Xojo will rewrite these example projects in a better way…

Currently one could pass in an Integer or whatever to the drawing methods - and they’d obviously fail with a runtime error. The compiler can’t catch this because of using Variant.

Why not use Constructors (with compatibilty flags)? And the parameter-less Constructor private (so that one needs to use a Constructor with parameter)? Then it’s good enough to use the Variant only internally (private), as it’s all handled within the Class Checkerboard.

And to make conditional compilation more future proof, one should check the else case(s), too - e.g. like this:

#If TargetDesktop Or TargetMobile Then
  Var g As Graphics = context
#ElseIf TargetWeb Then
  Var g As WebGraphics = context
#Else
  #Pragma Error "Unsupported Target"
#EndIf

For those interested: see the attached example projects in Issue #79006

Note:
That Constructor approach still has redundant code in the drawing methods to check the Variants - hence the original suggestion/idea with an Interface. But for the sake of a simple example project, it seems good enough to me - with what’s currently possible and available in the Xojo Framework.


@Geoff_Perlman I know, the Blog and Marketing are targeting “Citizen Developers”. But please, don’t provide such examples that do the contrary of “best practices”. If you feel it’s too complicated otherwise - look at it as a challenge to improve the framework to make it easy in the future :wink:

8 Likes

Ultimately yes an interface is a better solution though I don’t see an issue with using a Variant either. It’s not a matter of complexity. In fact, I like showing users of all levels how when they run into a problem in Xojo, chances are there’s a solution even if it’s one they hadn’t considered.

While creating this example in fact it became clear that a built-in interface was ultimately the best solution.

As for the blog and marketing, we do not exclusively target citizen developers though they certainly are an important target.

Yikes.

More than anything, that example neatly exposes an example of poor system design. If you have two unrelated classes of object who contain a lot of overlapping calls, you’re probably looking at a situation where an Interface would be the best way forward (as noted), or possibly a base class/subclass arrangement.

Perhaps there are lessons here for the other classes that are similar between the various targets.

It might be a good subject for a future blog post to revisit the problem presented in this one and demonstrate how it could more cleanly be solved using an Interface. I can imagine that many developers look to various sources to form an idea of what best practices to follow in the language, even as they create their own classes and APIs - I would hate to see this example get embedded in too many fresh minds. :wink:

In today’s world, medium-sized and large companies focus heavily on best practices.

In my experience with audit procedures, I can see that the weight the results carry among directors is very noticeable. Each audit focuses on controls, processes, and best practices.

I think this is something XOJO should emphasize in everything, regardless of how basic or complex the example is.

Many people, including myself, will appreciate that XOJO supports best practices when programming in this tool.

2 Likes

I agree that a variant is too loosely coupled, infact it makes your autocomplete useless. You have to convert and that gives more work, more to remember, more to act upon. We want less to remember, less to act upon and create more cool stuff.

An interface would be great, heck i’d love to see some updates towards interfaces like:

  • More examples
  • Ability to add properties on interfaces (somehow shadowing properties must be solved).
  • Better, more intuitive way to add, view and remove interfaces from classes.
1 Like

Maybe not in the short term, but it might bite back later :wink:

From the responses it seems that most agree that what the example shows is far from best practice - so it better should not have been published that way.

And we’d like to encourage you to continue creating these kind of examples.

However, if you’re stumbling upon these lacking framework features (which lead to “workarounds” or code that clearly is not the way one would like it to be) - then please take it as a chance to enhance the framework first. We’ll all get a benefit out of that - and the original idea/example (which lead to detect the missing framework features and pieces) can be published in a polished way, which makes a much better impression to the public.

2 Likes

The problem with variants is that you’ve thrown out Xojo’s strongly typed variable declarations where the compiler will warn you during compilation to runtime checking where the user might not be handling errors properly. Or even if they are handling them are unable to do anything other than quit the application. As a developer I want the compiler to be fully engaged and helping me not do stupid things before runtime. Using variants like this allows me to do stupid things that won’t be caught until runtime.

Variants, in my opinion, are very good storage objects but should not be used for any logic. As I’ve written about in the past, “Variants are evil”. Not like full-on lawful evil (to use a Dungeons & Dragons analogy) but more like chaotic neutral with a dash of evil thrown in for some random (non) fun. Variants have their place but I don’t think this is one of them.

7 Likes

I tend to give the advice that if you are using Variants or the Introspection classes, you should take some time to reexamine your design because it’s likely that you’re trying to circumvent Xojo’s many strengths as an object oriented language. It’s softer than “they’re eeeeevil!!” and tends to point users in a more productive direction. :smiling_face_with_horns:

Well, sure. I’m being hyperbolic in my evil comment because variants are incredibly useful - in certain circumstances.

I wrote my blog post (I’m sure the wayback machine could find it if you really cared since the website’s been dark for 5 years now) during my consulting days where I had to fix someone’s project where EVERY variable was global variant. So many things wrong with that project. So it’s easier for me to say they’re bad so people will reconsider their use.

If one person reading this reconsiders their use of a variant in code (other than a convenient storage variable) because they once read ‘they’re evil’ I’m okay with the hyperbole. Peace!

2 Likes

Sorry, didn’t mean to have that come off as so serious. It’s amusing to give language features a moral valence. :smiling_face_with_horns:

No worries. I was having a little fun with a very old high horse topic of mine. :slight_smile: