Jump to content

balabuev

Members
  • Content Count

    241
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by balabuev


  1. 1 minute ago, Mike Torrettinni said:

    Did you try switching between Release/Debug config? It helps my projects and I don't need to do the close and re-open.

    Thank for this hint. Did not checked yet, but it's definitely better than reopening the project.


  2. So, I should conclude that Delphi language LSP in Delphi 11 is very very unsatisfying! It stops working unpredictably, and not even as a result of code changing, but in many cases simply after library units opening in the IDE. And I cannot see a list of properties/methods of an object expression, I cannot use Ctrl+Click, etc. I often see "erroneous type". I often see that the drop-down list does not include all available properties, as shown below:

     

    image.thumb.png.f9906afd70373a2cb97e909aa0be68cd.png

     

    Reopening the project each time is not an acceptable workaround. Effectively this makes Delphi 11.2 useless!

     

    So, whether anyone know, how to return to "old" way in 11.2? May be there is a way to setup a shortcut to "re-run" LSP?


  3. 10 minutes ago, Veikko Nurmonen said:

    Code insight is working very erratically - usually not at all (ctrl-space does nothing, even when waiting for a long time), but sometimes it works for a while after IDE restart.

    I can confirm this 👿.

    It stops working unpredictably. IDE restart helps. Sometimes it stops working when I ctrl+click a method or property to look to its source, and so, some other (library) unit opens as a result of this click.

    From time to time I see many red-line errors in strange places, for example it can mark TComponent or TForm identifiers as errors, while the code itself is compilable.

     

     


  4. 12 hours ago, Mike Torrettinni said:

    11.2 seems to have less delay than 11.1, almost no delay.

    Checked against 10.4 - same delays. The delay, however depends of scope. In global scope, like trying to type "Color" the delay approximate half-second:

    procedure TMainForm.Button6Click(Sender: TObject);
    begin
      Co|
    end;

    In members scope there almost no delay (same as in 10.4):

    procedure TMainForm.Button6Click(Sender: TObject);
    begin
      Margins.|
    end;

     


  5. Overall nice release 👍. Cool welcome page. Cool code tooltips. Cool ASM and messages coloring. Cool colored clXxx constants (btw, what is the problem with system colors, like clBtnFace - they all shown black). IDE feels lighter and faster. IDE Options dialog opens almost immediately.

    Many small things were really fixed! However, some of them were introduced in recent versions 😉, like double-click issue in the Project Manager view - so, here is a parity.

    Some annoing things continue to annoy me, like non-working Copy/Paste shortcuts in Component Palette search field (in case of active VCL designer). Another example is Undo in code editor.

    Compatibility of code analisis/manipulation tools (like Code Insight, Class Completion, Refactoring, etc.) with the "new" language features, like inline variables, generics and even for-in loop - remains far from being perfect.


  6. Given the simple code:

    type
      TMyClass = class
      end;
    
    procedure P;
    begin
      var obj := TMyClass.Create;
      obj.Free;
    end;

    Try to count, how many function calls (and especially virtual calls) are performed here. And after that, it's become clear that additional "inherited" call in destructor changes almost nothing.

     

     

    • Like 1

  7. This manual DPI handling issue will exist forever, and no good solution will be found. Even if the IDE itself will handle some portion of the problem, there will be always bugfull components. And so on, and so on...

     

    Only switching the whole UI library to logical points will really help.


  8. 4 hours ago, Stefan Glienke said:

    Your assessment on the C# dictionary is incorrect

    Why? I claimed that it uses same amount of fields like conventional hash table with heap allocated entries - and that's true. There is an array of indices - called "buckets", and yes, this is the main table array, which is analogous to array of pointers to entries (nothing "pretty compact"). There is the "next" field in each entry. So, the waste of space is roundly the same. The levels of indirections - are the same and even worse. You also ignored the fact that all entries are preallocated - thus even more waste of space.

     

    All entries are stored continuously in a single array - better cache locality - yes, but I've not talked about this. Overall, this topic is a big question.  In real app we have a higly unpredictable sequence of memory accesses, because an app is really a big mess (graph) of heap allocated objects, and hash map access code is mixed with accesses of data from the other objects. And moreover, since hashmap has O(1) average access performance, you do not typically access more than a single entry at a time.

     

    So, speaking more generally, cache locality in OOP language is more a task for memory manager. And overall it importance for real code is imho exaggerated.

     

     


  9. The question is in overall size. If the size is not too big, which is again - typical, then the table with "unnecessary memory indirections" will work faster, because the logic here is simpler.

     

    A table, which inlines everything, must also pay its own price to prevent "wasting space by storing pointers" by introducing additional fields, doing bit manipulation and more array element accesses. But, such a table also wastes space because of lower "load factor", and for yet empty slots when SizeOf(Value) > SizeOf(Pointer).

     

    Some well known examples:

    - Java HashMap and Hashtable - heap allocated entries. Well, they have almost no choice, because Java has no structs. The only way to inline is to keep several parallel arrays.

    - C# Dictionary<K, V> - kind of tricky code, which preallocates all entries in a separate array, and then uses a kind of tiny embedded memory manager to provide entries from this array. As a result it stores two separate arrays (same waste of space) and indexes instead of direct pointers (waste of space; slower). Since all entries are preallocated, then it becomes even more waste of space when SizeOf(Value) > SizeOf(Pointer).

     

     

    • Like 1

  10. On 5/26/2021 at 12:59 AM, Stefan Glienke said:

    with hash table items be scattered all over the heap it most certainly will be memory bound

    All this is true when working with tiny things, like, for example, mapping int to int. But, in more usual case, like string keys, the effect is shadowed by string handling overhead and the fact that strings themselves are heap allocated.


  11. 2 hours ago, angusj said:

    Anyhow, there may be a marginal improvement by reinserting TMapItem items instead of recreating them

    I tried to keep the code reasonably simple. Yes, sure, some improvements are possible. Instead of objects we can at least use records for map items with New/Dispose (or even better, with GetMem/FreeMem), as @Stefan Glienke mentioned before (if I've understood right). We can also go futher and try to minimize heap allocations, or use some sort of map item pool, etc. We also can use some initial capacity as you propose.

     

    But, this will complicate the demo code, thus, hiding the main idea, which it tries to show. Moreover, map filling is not critical for this particular test. We measure only search speed.

     

     


  12. All this is very funny, but the question remains open. We are searching for appropriate source code documentation tool (except Documentation Insight, which we already know about), which is not outdated, and preferably allows to keep documentation separately from the code.


  13. 9 hours ago, Vincent Parrett said:

    SetBounds: Left: -32000 Top: -32000 Width: 1302 Height: 675

    This is the key line. Now let's think, where this strange "-32000" numbers may araise at all. I'm sure 99.9% that the numbers are received from a Windows API function call, such as GetWindowRect (or similar) in minimized window state (IsIconic(Handle) = True).

     

    Simple experiment proves it:

    procedure TForm1.Timer1Timer(Sender: TObject);
    var
      wr: TRect;
    begin
      if WindowState = TWindowState.wsMinimized then
      begin
        GetWindowRect(Handle, wr);
        OutputDebugString(PChar(wr.Left.ToString + ', ' + wr.Top.ToString));
      end;
    end;

    image.png.11425ef07c92213cd50943ccf45c64f3.png

     

     

    So:

    9 hours ago, Vincent Parrett said:

    As you can see it is called at least once with co-ordinates that are on the other monitor (monitor 1)

    With "-32000" left and top values the window is not, of course, within the area of your monitor 1, but this monitor becomes the closest one to the window.

     

     

    • Like 1

  14. Handling of maximized form state is bugfull even without multi-monitor setup, and even without VCL Styles. Use the following code with a simple memo on a form:

     

    procedure TForm1.FormResize(Sender: TObject);
    begin
      Memo1.Lines.Add(Width.ToString + ', ' + Height.ToString + ', ' +
                      IsIconic(Handle).ToString);
    end;
    • Run the project and maximize the form.
    • Minimize the form using taskbar app button.
    • Maximize it back using taskbar app button.

    You will see that during minimize/maximize steps two OnResize events are fired with different Width/Height values. This was not the case in early Delphi versions, like Delphi 7; this was introduced later along with the Application.MainFormOnTaskbar feature.

     

    I'm sure that all such issues are related, and the problem is that they forget to check for IsIconic() whenever appropriate.

     

     


  15. I can confirm the issue with the configuration similar to yours:

    • Monitor 1 - 100% (primary)
    • Monitor 2 - 125%
    • App's main form is shown on the primary monitor (1).

     

    The bug happens if monitors are related like this (monitor 2 has negative X coordinates in its area) 

     

    image.thumb.png.fdb848ae62b8713e56816c8780bbfc44.png

     

    The bug does not happen if monitors are related like this:

     

    image.thumb.png.ddcd30c14b7e1c93cabbfe3fe96679c8.png

     

     


  16. The official APIs in Windows to deal with Unicode stuff - is Uniscribe. It allows to decode Unicode related information from a Utf16 string.

     

    Including the sequence of glyphs for rendering. But, what you will do with them? Because, every glyph is denoted as a number, without any meaningfull value; and you can only pass this sequence to ExtTextOut.

     

    Also, Uniscribe provides supporting attributes to Unicode codepoints, such as: 

    • whether it's a wrod start (for Ctrl+Left/Right navigation)
    • whether it's a word end
    • a valid caret positions (some codepoints are not valid caret positions)
    • should the codepoint be deleted as a group with neightboord codepoints
    • etc.

    All rules are complex and different from each other. There no simple way to move editor caret and select the text in Unicode enabled text editor.

     

    I suggest the following old and great tutorial (an attempt to create the editor with Unicode support)

    http://www.catch22.net/tuts/neatpad/introduction-uniscribe#

     

     


  17. On 2/16/2021 at 9:20 AM, Remy Lebeau said:

    Yes, it is perfectly safe. Using Action=caFree in the Form's OnClose event will call the Form's Release() method, which is a *delayed* destruction.  A CM_RELEASE message is posted to the Form's window. The Form is not actually destroyed until that message is processed at a later time.

     

    As recently has been mentioned in another thread, it's only safe if the code inside try/finally do not occasionally (or indirectly) call Application.ProcessMessages after ShowModal:

    MyForm := TMyForm.Create(...);
    try
      MyForm.ShowModal;
      Application.ProcessMessages; // Or SomeAnotherForm.ShowModal, etc.
    finally
      MyForm.Free;
    end;

    In this case the form may be freed via CM_RELEASE, and then - freed the second time via the code in finally block.

     

     

     

    • Like 2

  18. Also, I've noticed that the strings are different in code editor drop-down and in local variables view:

     

    image.thumb.png.e1a5744bebdb68f3da67b121f3d35d06.png

     

    String in code editor drop-down seems to be more complete (like it should be returned from GetReplacementValue). While the string in local variables view seems to be already processed by IDE.

     

     

×