Jump to content

balabuev

Members
  • Content Count

    242
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by balabuev

  1. DisableWindow with boolean parameter is a bad name, by the same reason why dontUseWidget is a bad name. As already described in this topic.
  2. My viewpoint to the topic's initial question: Whole WinAPI is written this way. I mean, almost every function provides flags parameter, which alters the function behavior. WinAPI also have examples of Enable/Disable like cases: ShowWindow(wnd, SW_HIDE); EnableWindow(wnd, FALSE); I thingk, it's ok, and it's a kind of well known pattern.
  3. balabuev

    Main Form appearing issue..

    This can be achieved by setting form's PopupMode to pmAuto (can't say, why it's not default): if FCreatingMainForm then WndParent := 0 else WndParent := Application.ActiveFormHandle; // <------ ...
  4. balabuev

    Project always opens with .dpr file..

    I have related (opposite) question: how to prevent Delphi from showing main form of the project on project opening? I would prefer not to show anything.
  5. balabuev

    Main Form appearing issue..

    Can you also provide the code, which shows the dialog?
  6. balabuev

    Main Form appearing issue..

    You do something special in your application's code. It's obvious, because the issue cannot be reproduced with simple test project.
  7. Just as an idea: FFreeList can be implemented as a linked list, without any additional allocations.
  8. Ahh, sorry , missed that link. Then my previous message can be deleted.
  9. @dummzeuch Your problem is not in sorting algorithm at all. Trying to optimize sorting algorithm you just solving the wrong task. Even faster way will be to copy the data into some array, sort the array and then copy data back: type TDataItem = record S: string; O: TObject; Checked: Boolean; end; TData = array of TDataItem; var FData: TData; procedure TForm1.Button1Click(Sender: TObject); var c: Cardinal; i: Integer; c2: Cardinal; begin c := GetTickCount; CheckListBox1.Items.BeginUpdate; try SetLength(FData, CheckListBox1.Items.Count); // Copy data from UI for i := 0 to High(FData) do // control. begin // FData[i].S := CheckListBox1.Items[i]; // FData[i].O := CheckListBox1.Items.Objects[i]; // FData[i].Checked := CheckListBox1.Checked[i]; // end; // c2 := GetTickCount; SortList(0, High(FData), SortCompare); // Sort data in array. c2 := GetTickCount - c2; for i := 0 to High(FData) do begin CheckListBox1.Items[i] := FData[i].S; // Copy sorted data CheckListBox1.Items.Objects[i] := FData[i].O; // back. CheckListBox1.Checked[i] := FData[i].Checked; // end; finally CheckListBox1.Items.EndUpdate; c := GetTickCount - c; end; Edit1.Text := IntToStr(c); // Whole time, including UI updates. Edit2.Text := IntToStr(c2); // Sort only time. end; With 10000 items (!) this code run in: Whole time, including UI updates - 1.5 secs (the control is slow, nothing to do with that). Sort only time - 15 msecs. 15 msecs for sorting of 10000 items!
  10. I've uses the following test with 100 items in list (item count as in your initial post): procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin for i := 0 to 99 do // Just init the list with some data. begin CheckListBox1.Items.Add('Long long long string ' + IntToStr(Random(1000))); CheckListBox1.Items.Objects[i] := TObject(i); CheckListBox1.Checked[i] := (Random > 0.5); end; end; function TForm1.SortCompare(Item1, Item2: Integer): Integer; begin Result := CompareStr(CheckListBox1.Items[Item1], CheckListBox1.Items[Item2]); end; procedure TForm1.SortList(L, R: Integer; SCompare: TJCHListSortCompare); var I, J, P: Integer; tmpObj: TObject; tmpStr: string; tmpChecked: Boolean; begin repeat I := L; J := R; P := (L + R) shr 1; repeat while SCompare(I, P) < 0 do Inc(I); while SCompare(J, P) > 0 do Dec(J); if I <= J then begin // exchange I and J tmpStr := CheckListBox1.Items[I]; tmpObj := CheckListBox1.Items.Objects[I]; tmpChecked := CheckListBox1.Checked[I]; CheckListBox1.Items[I] := CheckListBox1.Items[J]; CheckListBox1.Items.Objects[I] := CheckListBox1.Items.Objects[J]; CheckListBox1.Checked[I] := CheckListBox1.Checked[J]; CheckListBox1.Items[J] := tmpStr; CheckListBox1.Items.Objects[J] := tmpObj; CheckListBox1.Checked[J] := tmpChecked; if P = I then P := J else if P = J then P := I; Inc(I); Dec(J); end; until I > J; if L < J then SortList(L, J, SCompare); L := I; until I >= R; end; procedure TForm1.Button1Click(Sender: TObject); var c: Cardinal; begin c := GetTickCount; CheckListBox1.Items.BeginUpdate; try SortList(0, CheckListBox1.Items.Count - 1, SortCompare); finally CheckListBox1.Items.EndUpdate; end; Edit1.Text := IntToStr(GetTickCount - c); end; With BeginUpdate/EndUpdate run time is 32 msecs. Without BeginUpdate/EndUpdate - 422 msecs. As for me, even 32 msecs is a way too big for sorting 100 items, but it not 2 seconds!
  11. Quite strange. Because in my tests they did a drammatic difference (I've used TCheckListBox for test).
  12. The price is - you cannot have DOMs, smaller than the OS memory page (4KB).
  13. balabuev

    Customizing source editor

    Customized colors in black theme + Inconsolata font. Quality image link: https://i.ibb.co/3dDkPNQ/image.png
  14. Sorting time like 2 seconds is not about sorting at all. It's absolutely crazy . The solution is simple: wrap your sorting with Items.BeginUpdate/Items.EndUpdate. And it's not so important which sort algorithm you will use. QuickSort is good enough.
  15. balabuev

    The Case of Delphi Const String Parameters

    var G: string; CriticalSection: ...; procedure TForm11.Button1Click(Sender: TObject); begin G := 7.ToString; // Init with non contant string data. for i := 0 to 1 do begin TTask.Run(procedure var localStr: string; begin CriticalSection.Asquire; // Fetch G into local variable under critical section protection. localStr := G; // CriticalSection.Release; // A(localStr); end); end; end; I claim, that even if we rewrite the code with critical section, it will still not work with your new implementation.
  16. balabuev

    The Case of Delphi Const String Parameters

    So, then please argue, why this code is not correct. In which exact place.
  17. balabuev

    The Case of Delphi Const String Parameters

    "is correct" means that even in current implementation it will (and should) work fine. And so, your new implementation should also not raise any exceptions.
  18. balabuev

    The Case of Delphi Const String Parameters

    Wrong. At least in the context I speaking about. Lets take the code: procedure A(st: string); var TmpLocal: boolean; begin TmpLocal := _AddRefConst(str); try UnLockString(Str); // MakeTheRefCountPositive(str) unlock before B B(st); LockString(str); // MakeTheRefCountNegative(str) lock before C C(st); UnLockString(Str); B(st); LockString(str); C(st); UnLockString(Str); B(st); LockString(str); C(st); UnLockString(Str); B(st); LockString(str); C(st); finally _ReleaseConst(str, TmpLocal); end; end; The initial user's code itself (without our additions) is correct and should work without any bugs or exceptions. During the invokation of this code reference counter will be switched from positive to negative and back several times. Because this is what your LockString/UnlockString function do. So, lets execute this (fully correct) code in two threads concurrently passing the value of the same global variable G into both: var G: string; procedure TForm11.Button1Click(Sender: TObject); begin G := 7.ToString; // Init with non contant string data. TTask.Run(procedure begin A(G); end); TTask.Run(procedure begin A(G); end); end; So, both running A procedures will share same string data and same reference count. And they both will switch this single shared reference count from negative to positive and back in unpredictable order. This single observation lead me to conclusion, that your way is wrong.
  19. balabuev

    The Case of Delphi Const String Parameters

    It was global variable.
  20. balabuev

    The Case of Delphi Const String Parameters

    Thats not true. I've showed it in previous posts.
  21. balabuev

    The Case of Delphi Const String Parameters

    This is impossible because of unpredictable conditions, loops, etc: procedure A(st: string); begin UnLockString(Str); B(st); if SomeCondition then begin LockString(Str); C(st); end; UnLockString(Str); B(st); end; Also, if you add LockString before call of C from A, then you also should add it when calling C from B: procedure B(const st: string); begin LockString(Str); C(st); end; And, actually before any call. And, finally, returning to threads (even without interlocking aspect): You have two states of a string - it can be either locked or unlocked during execution. But, you really lock shared string data. So, having several threads we may run into situation, in which this shared string data should be locked in one thread and unlocked in another thread at the same time.
  22. balabuev

    The Case of Delphi Const String Parameters

    Ok. Then let's call many different procedures procedure A(st: string); begin _AddRef(str); try B(st); C(st); B(st); C(st); B(st); C(st); B(st); C(st); finally _Release(str); end; end; The power of RefCount (as it currently implemented), that AddRef/Release and try/finally is introduced in the A procedure only ones. Moreover, this try/finally is shared among all managed variables in this procedure. And what is more, some cases do not need all this stuff at all: var st: string; // Variable, external to procedure. procedure A; begin B(st); C(st); B(st); C(st); B(st); C(st); B(st); C(st); end;
×