On 5/16/2014 9:13 AM, Dmitry Boyarintsev wrote: > Just a suggestion. Try to rewrite the code not to use anonymous functions. > The need for their support in FPC will go away.
The code in question doesn't use anonymous methods yet, but I've already tried the alternatives and they are not an improvement. I don't really want to re-open the debate about their merits and syntax, but I can explain why I need them: 1) I want to use the OmniThreadLibrary. Setting up objects and thread descendents is fine in moderation, but it's too much of a hassle when you just want a quick parallel for loop. 2) Our application has multiple independent top-level windows, like a web browser. There is no "MainForm". Each window can show modal dialogs that only disable that specific window. In a traditional Delphi/Lazarus app, showing a modal dialog looks something like this: procedure TMyForm.ShowMyDialog; begin Dlg := TMyDialog.Create(...) try if Dlg.ShowModal = mrOk then Do something finally Dlg.Free end; end; To make that work without blocking the rest of the application that needs to be split into two functions: procedure TMyForm.ShowMyDialog; begin Dlg := TMyDialog.Create(...); Dlg.ShowModalNonBlocking(ShowMyDialogDone); end; procedure TMyForm.ShowMyDialogDone(ADialog: TForm); begin if ADialog.ModalResult = mrOk then Do something ADialog.Free end; It's unwieldy with the simplest of dialogs, and gets much worse if you need to share state between the "Show" and "Done" functions, or if the dialog is only shown selectively. To solve that, years ago we started using cooperative threads (coroutines/fibers) in our GUI thread. I re-implemented ShowModal so it handles the details internally. When you call it it displays the dialog, just like the ShowModalNonBlocking() call would, but then switches to another "thread" that processes messages. When the dialog is finally closed the running thread switches back to the ShowModal call, which then exits like normal. As a result, even though we can have several independent modal dialogs up at once, the code is all identical to the first example. Everything is nicely encapsulated and sharing state before and after the dialog is trivial. Unfortunately, fibers introduce incompatibilities on both Windows and OS X, and are deprecated on OS X, so we need to stop using them. They are by far the cleanest approach, and I'd keep using them if I had any choice whatsoever. The second best alternative is to use closures and anonymous methods. The syntax isn't as clean, but at least everything is kept within a single "ShowMyDialog" call. In that case it would become something like: procedure TMyForm.ShowMyDialog; begin Dlg := TMyDialog.Create(...); Dlg.ShowModal( procedure begin if Dlg.ModalResult = mrOk then Do something Dlg.Free; end; end; Again, these examples are extremely simplified. The benefits are much greater when you need to use variables in the outer scope. In our application we have over 90 dialogs and almost 400 calls to ShowModal, so the easier I can make that the better. -- Craig Peterson Scooter Software _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal