FileSuite, Delphi Core and the Cross-Platform Quest

Well, we have a new release of FileSuite featuring a fine-grained multi-threaded file engine which can execute any (oh, well…) custom action, exe file or script on a file or host event (yes, you can have a centralized backup control for any host from the network immediately when it will be online – no need to install any software client) enough bug fixes, mirroring enhancements aso. You can see some from the enhancements in the screenshots page. Also we found a new payment processing company which has much more features thing which allowed us to reduce the price. So, we must be happy… And yes we are. Almost.

This because working on FileSuite we found some things which I think that needs fixing. And the very first thing which needs fixing is something related to Delphi’s core: The naturalism of Delphi environment. And here I have in mind firstly the Delphi language and the library (ie. VCL + RTL).

Let us not forget that this is one of the main advantages of Delphi: The natural way in which the things are flowing, thing which started to show its lack of recapitulation. Because I think that together with the continue innovation cycles, a product must have quality (recapitulation) cycles to enhance its usability. And by quality cycle I don’t mean necessarily bugfixing.

Let’s take two examples:

Because TThread.FreeOnTerminate doesn’t give you the possibility to see if the thread is actually finished – in other words it doesn’t set the thread’s variable to nil because it uses Thread.Free and not FreeAndNil(Thread) (@Embarcadero: Guys, how many times we discussed about FreeAndNil vs Free?), forces you to have an entire lifetime management of your thread (which can be a very ‘nice’ task if we are in a parallel environment and ever nicer if the thread in discussion should be created only in certain circumstances) instead of a simple check if Thread=nil then begin..., which at least for me, it would be the natural way to use it. For the hackers, the guilty code is located in Classes.pas in the ThreadProc function:

    FreeThread := Thread.FFreeOnTerminate;
    Result := Thread.FReturnValue;
    Thread.FFinished := True;
    if FreeThread then Thread.Free; //<--- Here!

So in short, watch out if you want to use FreeOnTerminate because you cannot test for its state (nil or not) and you’ll get some very nice ‘random’ Access Violations from ‘nowhere’, if you aren’t careful.

The second example about naturalism is tied about a GUI experiment which we did related to…

Cross-platform quest

First, a small preamble: There were enough speculations about what the cross-platform will bring to us as programmers. But one thing is for sure:

Embarcadero is now in a much worse position than it was in Kylix and .NET campaigns. In the Kylix campaign there were no other commercial vendor to fight with. They were alone in the market. Entirely alone. In the case of .NET there were Delphi 7 against Visual Basic 6 – and we all know that D7 was much more superior than VB6 even than .NET 1.0, even than .NET 1.1, but…

But now the things are changed: Apple is king on his own platform. Mac OSX framework (Cocoa) has a good design and Apple provide free tools which we can regard at least as ‘entirely usable’. At least, if not more. Much more. Their tools support (of course) the entire Mac OSX functionality, including the 64-bit ‘problem’. Delphi will be a newcomer on that platform with (still) a dubious past (not to blame Embarcadero here), capable to compile (most probably) only 32-bit executables (which even if on Mac this doesn’t matter so much, except the memory barrier, it still remains at least an important psychological argument against Delphi). Also, let us not forget the documentation problem and, of course, the quality. Oh, quality. How many bugs will be? …and how many bugs will be compared with Apple’s toolchain?

So what could Delphi offer in order to justify its tag price?

I think that their only chance to succeed there is productivity, power and flexibility. And for this the naturalism is a core component.

So, we tried to see how productive we are with the present Delphi (Delphi 2010 – for conformity). Because besides the standard GUI artifacts there are other widgets which one must build more or less from scratch.

So, the second example about decay of Delphi’s naturalism is a UI ‘component’ which we used in the custom actions engine (see in the left-top area of the screenshot):

You can add many custom actions to any file event. Powerful multi-threaded engine to help you out.

That tab set ‘control’ from the left-top corner was built in approx. 10-15 minutes of coding. Yes, we know that there are better tab controls (also we have a certain library which has a similar component) but I wanted to see how quick we can build from scratch a new one and what hurdles one can found.

The good: Canvas’s properties were good enough to allow us shaping the component in few lines of code (code available upon request, btw).

The bad: The underlying control which we used as ‘layout’ engine (it is a simple TListBox πŸ™‚ ) even if we say ‘OwnerDraw’ our ListBox says ‘No, you won’t have the entire control of the Canvas. I will draw the selected item like I want with the color which I want and you will not change that’ Pretty rude, eh? In fact, once again you must look at the underlying code to see what’s happening because the ‘OwnerDraw‘ has lost a little the meaning of Canvas full control (Owner + Draw).

In fact, I do think that burning in such important things related to program look and feel can be regarded (at least) as a ‘curious’ design decision…

In my humble opinion, the rule of thumb is: If a feature is closer to the user’s human nature (artistic feelings etc.) then that feature is more volatile than a feature which is closer to the technical part of the problem (eg. something which deals with data storage, for example). Hence the said feature must be provided with the according customization engine.

Ok, in this concrete case we could take a grid and do our job. But then another problems arise. Or a simple TPaintBox, TImage etc. Or even to build a ‘real’ component derived from TCustomControl. But we wanted to see how much the framework helps us. It is ok for our needs here but it could be better. Much better.

What are your opinions on this?

PS: As always, we expect feedback on FileSuite also especially now when we added enough interesting things there. Download and see.

14 thoughts on “FileSuite, Delphi Core and the Cross-Platform Quest

  1. It would be nice if Embarcadero looked at introducing a new VCL based on interfaces. That way, as a component builder you are not forced to build components based on a specific base class but rather conform to a specific interfaces. Components would be able to cater for multiple interfaces. eg. IEnabled for supporting the Enabled property or IDataAware for properties such as Datasource and DataField.

    Delphi would need to support both the existing VCL and the interfaced-base VCL at the same time just as they did when they had CLX. This is so you can still support existing “legacy” apps but also build new apps against the new interfaced-base VCL.

    Just an idea.


    • …and also it would be very nice to make VCL classes and components support generics and rtti attributes. I have no hope this will be done in next 2 years, so it is just a dream πŸ™‚

      • Hmmm… Depends. See, Alex Ciobanu’s DeHL it seems a very nice start. So, it is possible. But this is a pet project of a Doc man. It all depends on what direction Embarcadero will take. But they must understand that they will win if we will have a better framework.

    • Oh, yes. The Interface-based VCL is an idea which (re)appears from time to time. But with a little caution from their side and also with some language enhancements, supporting other forms of object creation, the problem of supporting two VCLs will fade away because the new one will be an evolution of the older one (and not a breaking change).

  2. Using FreeAndNIL() in ThreadProc would be completely pointless. “Thread” is local in scope to that procedure, all it would do is NIL that local variable (which is actually a parameter to the proc and isn’t referenced after it is free’d.

    I don’t know what you thought using FreeAndNIL() would achieve there.

    • Also, there could be more than one reference to thread (eg. T1 and T2 are pointing to the same TThread instance) so “nil-ing” all of them from thread itself is pretty big problem.

      You can try writing your own IsThreadDead() function, that will check the given reference. If it is nil or it raises AV when accessing it’s properties – then thread is pretty much dead. But yes, this is ugly solution πŸ™‚

      • “Also, there could be more than one reference to thread (eg. T1 and T2 are pointing to the same TThread instance) so β€œnil-ing” all of them from thread itself is pretty big problem.”

        Sure. But we speak about the case in which one sets FreeOnTerminate explicitly. And also, the pointer is already pointing to ‘nowhere’. Nil-ing it doesn’t make the things worse.

    • 😦 – Saw it. In fact from yesterday I’m thinking to answer you here or to make a new blog post on this. Because this is yet another proof showing how Delphi’s naturalism is fading away. And this isn’t good at all.

  3. It seems hard to locate you. Support@wings-of-wind does not seem to be active.

    I own the software and changed my battery
    The hardware is is FF4F-0F02
    Please send new serial #

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s