Jump to content

Der schöne Günther

Members
  • Content Count

    645
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by Der schöne Günther

  1. Der schöne Günther

    Nested TParallel.For: Immediate deadlock

    Thank you, that's also the temporary workaround I have come up with. I discovered it when running code from a library in a TParallel.For-loop that also made use of TParallel.For. They all implicitly used the default thread pool. Still, I'd like this caveat to be properly documented, and not to discover it in a running factory like I just did. And it still leaves me wondering why the C# runtime does not have these problems.
  2. Der schöne Günther

    Nested TParallel.For: Immediate deadlock

    Ooops, sorry - No. I updated my profile to Delphi 11. I noticed that it does run and produce the expected output when I lower the range to something like 0..6. As soon as it is 8² or more, it will block. Maybe it's depending on the number of cores. On my system, TThreadPool.Default.MinWorkerThreads will report 2 and MaxWorkerThreads is 4. It's just a guess, but I changes the example slightly: program Project2; uses System.SyncObjs, System.Threading; begin var counter := 0; const COUNT = TThreadPool.Default.MaxWorkerThreads * 2; TParallel.For( 0, Pred(count), procedure(i: Int64) begin TParallel.For( 0, Pred(count), procedure(i: Int64) begin TInterlocked.Increment(counter); end ); end ); Assert(counter = (COUNT * COUNT)); end.
  3. Der schöne Günther

    Need a "Delphi programming guideline"

  4. Der schöne Günther

    Puzzled by StrToDate

    Can confirm, works for me (Delphi 11.1).
  5. Der schöne Günther

    Detect if WebView2 Runtime is installed

    From my experience, this is sufficient: TWebBrowserHelper = class helper for TWebBrowser function getIsUsingEdge(): Boolean; end; function TWebBrowserHelper.getIsUsingEdge(): Boolean; begin Result := Assigned(GetEdgeInterface()); end;
  6. I think Embarcaderos wrapper does not throw any exceptions or displays error messages if it doesn't find the runtime, but I recall seeing an event that lets you check if loading was successful or not. Whether Edge is installed or not does not matter. You have to ship the WebView2 runtime. It is available as a standalone installer. It took me a few minutes to understand how to use TEdgeBrowser (or TWebBrowser), that the runtime must be installed and your Delphi app will need a "WebView2Loader.dll", but after that, I never had to tweak it again. We started shipping it even when TEdgeBrowser/WebView2 was still in preview.
  7. We are using the built-in TEdgeBrowser which is sufficient for our needs. I am guilty of taking the quick & dirty way out of Edge blocking local files by default. In one of our projects where we needed it, I simply have: Win32Check( SetEnvironmentVariable( 'WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS', '--allow-file-access-from-files' ) ); right in the DPR file. Above it is some kind of //TODO: Patch Vcl.Edge.pas so this is no longer necessary. Overall, I'm rather happy with the Edge Browser. We are using it to play videos, display and annotate PDFs, display web content and using rich HTML content editors like SunEditor.
  8. Der schöne Günther

    Need a "Delphi programming guideline"

    There is a "style guide" which focuses on Delphi-relative conventions like that weird "F" prefix for field names and such: Delphi’s Object Pascal Style Guide - RAD Studio (embarcadero.com) Embarcadero does not provide official guidelines on how to write good and re-usable code in general. At some point, probably most of us have dealt with with ancient Pascal spaghetti code that is almost impossible to understand. I feel your pain. If your colleagues are stuck one or two decades ago and refuse to study further, I doubt an "official" guide from the vendor of your IDE is going to change much.
  9. Under Project > Options > Building > Delphi Compiler > Compiling we have the project-widde option Code inlining control. It can also be set in code with something like {$INLINE ON|OFF|AUTO}. How inlining works and when the compiler cannot inline methods is explained in Delphi's Docwiki under Calling Procedures and Functions. It states that the default project setting is that inlining is set to ON which I found to be correct. However, the Help page Compiling states that OFF is the default setting. I am not sure what is the right choice for debug and for release builds. Wouldn't it be Set Inlining to OFF for all debug builds Set Inlining to AUTO for all release builds Or is there no universal recommendation and it depends on the project and its requirements? Many thanks in advance.
  10. Der schöne Günther

    StacTrace

    The StackTrace property is just a placeholder, it is always empty. There is no built-in way to get the stacktrace. Hard to believe, but here is what the official documentation says: System.SysUtils.Exception.StackTrace - RAD Studio API Documentation (embarcadero.com) A few years ago, I used the Jedi Code library. After that, I completely removed the JCL from our products and since then, I am just using the "FastMM_FullDebugMode.dll" which exports a few handy methods that will give you the stack trace as a string list.
  11. Der schöne Günther

    Vonoroi / Fortunes algorithm

    If you already have code that outputs a bitmap, wouldn't the easiest solution be swapping out the canvas with an "svg canvas" and keeping the drawing code? Quickly Create SVG (Scalable Vector Graphics) files with SVG Canvas Library for VCL in Delphi And C++Builder (embarcadero.com) Haven't tried anything like this, but maybe this is a feasible option.
  12. Der schöne Günther

    Default(TMyRec) usage

    Yes, I do. I expect the compiler to optimise out unnecessary assignments. If it's supposed to be immutable, the record will have private fields and a public constructor you will have to use. Adding a new field to a record later will cause it to be uninitialised, unless you hunt down every instance in your code and add an assignment for the new field manually. Unfortunately, the Delphi compiler isn't even able to emit a warning when an uninitialised record field is used or returned. program Project1; type TRecord = record b: Byte; end; function getRecord(): TRecord; begin // end; var r: TRecord; begin r := getRecord(); WriteLn(r.b); readln; end.
  13. Der schöne Günther

    VM and Legacy apps

    I am using both mechanisms (depending on whether I am using a Mac or the Windows PC they run on directly) and found it to be of little difference. I am running Delphi 10.0 in a VM with 3 gigabytes of RAM and 2 virtual cores, and Delphi 11.1 in a VM with 4 gigabytes and 3 virtual cores. For me, it's more than sufficient. The VM only does the RAD Studio IDE and Visual Studio Code as the frontend for git. Nothing more.
  14. It's the LSP. I sometimes do Delphi inside of Visual Studio Code (which is a fantastic editor), and there Delphi's LSP often crashes as well.
  15. Der schöne Günther

    tgridpanel resize

    The algorithm is not faulty, the problem is that they always try to get to 100%. At runtime, you can easily set them all at once. Do this by calling BeginUpdate() and EndUpdate() on the column collection. 2022-12-14-12-32-02.mp4 Also, by setting all columns to zero, they will take up their space equally. Here is the checkbox from the video above: procedure TForm2.CheckBox1Click(Sender: TObject); begin const cols = GridPanel1.ColumnCollection; if(Sender as TCheckBox).Checked then begin cols.BeginUpdate(); try for var index := 0 to Pred(cols.Count) do cols[index].Value := 0.0; finally cols.EndUpdate(); end; end else cols[0].Value := 0.0; end;
  16. Der schöne Günther

    TestInsight 1.2 released

    @Stefan Glienkewhere is the most recent download? The page still links to https://files.spring4d.com/TestInsight/1.2.0.0/TestInsightSetup.zip Your comment here states that there is at least a 1.2.0.4. The most recent version I have been able to find was listed at https://bitbucket.org/sglienke/testinsight/wiki/Home and links to https://files.spring4d.com/TestInsight/1.2.0.1/TestInsightSetup.zip
  17. Der schöne Günther

    function returning interface

    Shouldn't var Foo: IFoo := FunctionReturningInterface() suffice? 🤔
  18. Der schöne Günther

    Attempt to release mutex not owned by caller

    Hi there. TMutex.Release() is just calling ReleaseMutex(..) of the regular Win32 API. Here is its documentation: ReleaseMutex function (synchapi.h) - Win32 apps | Microsoft Learn You acquired the mutex directly in the constructor of TLockGuard. You will have to release it from the same thread that acquired it. By the way: In your destructor you are calling _mtx.Release() even if _mtx is nil By the way: Can you post a complete example of how you are using your TLockGuard? For simple cases I have not been able to reproduce your issue. If you are constructing it locally, reference it as an IInterface and do not pass it somewhere else, it should be fine ... I guess.
  19. Der schöne Günther

    Can I develop with Smart App Control activated?

    Source: What is Smart App Control? - Microsoft Support
  20. Der schöne Günther

    TestInsight usage

    Do the tests still show up after you have cleared the list? ❌ I think TestInsight will still keep tests in its lists, even if they don't exist anymore.
  21. Can you post a complete, working example? Your TMythread::Execute() is being called.
  22. Der schöne Günther

    floating point error, [solved].

    You really need to understand how floating point numbers work on computers. This is not a "bug" Feel free to try this out with other C++ compilers, they won't report zero either. https://onlinegdb.com/c2zTpiuZ_c Since you did redo your post completely: You need to be aware that you are mutating the variable several times comes with a loss of precision every time. It depends on the target platform, compiler optimizations and more. You will have to accept that regular floating point arithmetics are not 100 % precise.
  23. Der schöne Günther

    Need help with exception messages

    I'm no expert on that, but 0x073302E8 is your instruction address. Can't you just start your application in the debugger (press F8) and then use "Go to address" and see where that ends up?
  24. Der schöne Günther

    My app dies in Server 2019

    See Writing Dynamically Loaded Libraries - RAD Studio (embarcadero.com) Quote (emphasis by me):
  25. Der schöne Günther

    Array size 64bits

    Are you using range checking in your debug build? Maybe the compiler does different range checking for static and dynamic arrays.
×