Jump to content


Popular Content

Showing content with the highest reputation on 09/21/20 in all areas

  1. David Schwartz

    GLAD loader for Delphi

    Like so many projects people post on github these days, the README seems to cover everything EXCEPT: "What IS glad?" People are just supposed to know this stuff, or search around the internet to find out. Or, you don't care if anybody who doesn't already know what it is learns about it from your post -- IOW, you're basically just "preaching to a choir" and everybody else can just mosey along. Sorry, I'm just exhausted dealing with lack of comments and descriptions of stuff the previous people who maintained the code apparently just kept in their heads. When I ask for help or explanations, I'm told, "Just fire up the debugger and step through the code..."
  2. Vandrovnik

    More performance Stringgrid sorting algorithm help

    Test is not changed, just at the beginning instead of i:=0 I would use i:=1; When I start with i:=1 with Data 3, 2, 1, it is as in your example, just first iteration is already done: iteration elements 0 3 2 1 swap and dec ^ 1 2 3 1 i=0: inc ^ ... If Data is 1, 2, 3, it is: iteration elements 0 1 2 3 inc, because List[1] >= List[0] ^ 1 1 2 3 inc, because List[2] >= List[1] ^
  3. David Schwartz

    GLAD loader for Delphi

    There's an underlying assumption in most communications that requires you know your audience. People who do not fall into that assumed group won't follow what you're saying. It's like listening to a bunch of "inside jokes". How fun is that when you're not privy to what's happening "inside"? If this were a PRIVATE library and this were a PRIVATE discussion between two people, that's fine. In that case, 100% of the participants know the background context. The "open source" part is irrelevant. The fact is, it's taking place in a PUBLIC LIBRARY. There can be hundreds of people looking at it from all around the world, at different times and with completely different backgrounds and perspectives. Adding a simple line at the top that answers the question "What is this about?" and maybe a link (as was offered above, independently of the content in the library) so people at least know what to look for would really be sufficient. As a participant, if you think it's a private discussion, you're going to think it's implied, so why bother stating the obvious? But everything in github is PUBLIC! In general, that's not a valid assumption for over 99% of the people who might view it other than the one or two others you're communicating with. Making a practice of adding a one-line description that answers the most obvious question everybody new to the page will have, "What is this about?", with maybe a link for more info, hardly requires a doctoral thesis. What it DOES ENABLE is MORE INCLUSION AND PARTICIPATION BY OTHERS, which is supposedly the whole goal of the Open Source movement. You don't need to write a damn book! It's a simple one-line description that answers the question, "What is this about?" and a link to learn more. Otherwise, you're simply having a private conversation in a public forum that very few other people are able to follow. And just to be clear, I'm not saying there's anything wrong with that! But the OP posted a message here ANNOUNCING this open-source project and when I went to look, the first question I had -- "What is this about?" -- was not addressed anywhere! All I saw was bits of a private conversation between two people who knew exactly what each other was talking about, and everybody else was relegated to evesdropping. The popular retort is, "Well Google is your friend!" Hey, this is YOUR announcement! Why do you then say to ask Google if I want more information? Why did you bother to make the announcement in the first place? It's like getting in front of a group of several hundred people and announcing, "Hey, we're having a party!" and someone asks "When?" and you say, "ask Google!" and you walk away. I don't know about you, but I'm not wasting another second thinking about it. And I'm not asking Google because adding the Who, Where, and When part is too much trouble for you to mention after the What. I'm guessing the OP posted that here because he wants people to look at the work, maybe see some value in it, perhaps get involved. But if it cannot answer the basic question, "What is this about?" then what's the point of making the announcement? Ask Google? Really? Why bother making the announcement? No, if you CHOOSE to make a public announcement about something, you owe it to your visitors to have at least one line at the beginning that answers the most obvious question every single one of them is going to have: WHAT IS THIS ABOUT? How much time do you expect others to spend trying to answer that most fundamental question before they just turn and walk away? This is a basic building block of how you include others in conversations or not. It happens at parties and social gatherings all the time -- you wander around, listening in on conversations here and there, to see if there's something interesting to follow or jump in on. If you're like most people, you wander around sampling lots of different conversations, and don't spend much time if you cannot get your bearings on what they're discussing. It's no different in public forums online.
  4. Anders Melander

    More performance Stringgrid sorting algorithm help

    Well now that I've had my fun here's a serious suggestion: type TGridCracker = class(TCustomGrid); procedure SortGrid(Grid: TCustomGrid; ACol: integer; Ascending: boolean); begin var Rows := TList<integer>.Create; Rows.Capacity := Grid.RowCount - Grid.FixedRows; // Populate list with row indices for var i := Grid.FixedRows to Grid.RowCount-1 do Rows.Add(i); // Sort the row indices Rows.Sort(TComparer<integer>.Construct( function(const A, B: integer): integer begin Result := AnsiCompareText(Grid.Cells[ACol, A], Grid.Cells[ACol, B]); if (not Ascending) then Result := -Result; end)); // Move the rows in-place to their new position Grid.BeginUpdate; try var ToIndex := Grid.FixedRows; for var FromIndex in Rows do if (FromIndex <> ToIndex) then TGridCracker(Grid).MoveRow(FromIndex, ToIndex); finally Grid.EndUpdate; end; end; I've not used TStringGrid in decades but I think it might be fast enough if you can get it to compile (I haven't tried). I'm assuming that the protected MoveRow method does what we need (i.e. move a whole row in the grid). It might not though. A minor optimization would be to use a TArray<integer> instead of a TList<integer> but the improvement would be minimal.
  5. Angus Robertson

    how to Properly check if Twsocket Tcp client is still connected ?

    The only reliable way to know if a TCP socket is still connected is to send something to the other end and receive a response. If there is no regular traffic, you really don't know the route still exists, so many technical things can cause a connection to fail without any socket close down being received. If you send something and there is no TCP ACK within several seconds, the data should be resent automatically until finally the socket is closed with an error. If you are designing a protocol that leave sockets open for long periods, best to send something regularly. Angus
  6. That is because Win32 structures do not use 1-byte alignment, they use 8-byte alignment. See What structure packing do the Windows SDK header files expect?
  7. Uwe Raabe

    proper way to check server up or down in rest application

    TRestRequest has also a method ExecuteAsync with handlers for successful completion and error handling (in addition to the event handlers OnAfterExecute and OnHTTPProtocolError). Depending on your specific needs it may boil down to just a simple call like this: RequestLogin.ExecuteAsync( procedure begin ShowMessage('server up'); end, True, True, procedure begin ShowMessage('server down'); end);
  8. That one only applies to the map file. Of course, the same code should probably also work for the search path. It's just not called.
  9. Remy Lebeau

    Streaming binary data via TIdHTTPServer

    TIdHTTPServer is not really designed for streaming media. If you don't provide the AResponseInfo with a ContentText or ContentStream value, a default HTML page is sent instead. And if you don't provide a ContentLength value, one is calculated automatically from the ContentText/ContentStream by default. And if you don't send a response before the OnCommand... event handler exits, one is sent automatically. So basically, the only way I see to do what you want is to either: - NOT using HTTP's "chunked" encoding - have your OnCommand... event handler set the AResponseInfo.HeaderHasBeenWritten property to True to disable the server's default response handling, send your own HTTP response headers manually, and then run a loop that sends the raw media samples as needed until finished, and then exit the event handler. - USING HTTP's "chunked" encoding - have your OnCommand... event handler set the AResponseInfo.TransferEncoding property to 'chunked' to disable the server's default ContentLength handling, then call AResponseInfo.WriteHeader() to send the server's default HTTP response headers normally, and then run a loop that sends the media samples (in HTTP chunked format) as needed until finished, and then exit the event handler. There are probably other solutions, like writing a custom TStream class for use with the ContentStream, but that can get a little ugly.
  10. Yes, this should be a read only property. In an ideal world we'd have proper language support for references, as I think is especially we done in D foreach (ref elem; arr) { elem = 0; }
  11. It is not very difficult to make a generic list for records that allows manipulating the record content directly: type TChangeableRecordList<T: record> = class(TList<T>) type PT = ^T; private function GetItem(Index: Integer): PT; procedure SetItem(Index: Integer; const Value: PT); public property Items[Index: Integer]: PT read GetItem write SetItem; default; end; implementation function TChangeableRecordList<T>.GetItem(Index: Integer): PT; begin Result := Addr(PList^[Index]); end; procedure TChangeableRecordList<T>.SetItem(Index: Integer; const Value: PT); begin inherited Items[Index] := Value^; end; A suitable test case could look like this: type TMyRec = record IntValue: Integer; end; var list: TChangeableRecordList<TMyRec>; myRec: TMyRec; begin list := TChangeableRecordList<TMyRec>.Create; try myRec.IntValue := 1; list.Add(myRec); Assert(list[0].IntValue = 1); list[0].IntValue := 3; Assert(list[0].IntValue = 3); finally list.Free; end; end;
  12. TList<T> FWIW my codebase doesn't use the RTL generic collections. It uses a collections library that I wrote, that amongst other things has collection classes that allow access to items via references to the underlying records for exactly this situation. I think that you are making valid points, but you aren't pinning the blame in quite the right place. I don't think the issue is with value types per se. To my mind the issues are more about limitations of the standard RTL collection classes.
  13. Not if you use a collection that provides you access to items via references to the underlying records
  14. Arnaud Bouchez

    Best Practices for FireDAC FetchMode/RecordCount Settings

    I don't agree. This is highly depending on the DB itself. A count(*) could take a lot of time for a huge database, or with a complex query with no proper indexes. You could have a count(*) of a few rows (e.g. one or two rows) which takes a lot of time on big tables with a SQL request bypassing the indexes. In this case, it is better to retrieve the few result rows instead of making a select count(*) following by a select *
  15. Arnaud Bouchez

    Best Practices for FireDAC FetchMode/RecordCount Settings

    You may either: Refine your SQL query, e.g. by adding some proper indexes to the DB, to make it faster on the server; Actually retrieve all data at once (maybe into an in-memory list/array), but use Application.ProcessMessages within the loop to avoid UI freezing; Don't care about exact record count: just fetch the first 1000 for instance, and write '>1000' on the UI if there are more rows.
  16. That would very much depend on the criteria by whom they are looked up, if that criteria changes and how often elements are added/removed don't you think?
  17. Really? How are the records allocated? And if you could do that, why couldn't you do exactly the same with a dictionary. Which is my original point. If you can't use a dictionary with records, then I don't see that you can use any collection with records.
  18. How is it any different from holding them in TList<T>?
  19. Anders Melander

    10.4.1 Released today

    There's no need to post the issues that weren't fixed when we have a list of those that (allegedly) was.
  20. The *correct* way to block the screen saver on XP and later is to use SetThreadExecutionState() with the ES_DISPLAY_REQUIRED flag: PBT_APMQUERYSUSPEND is just a *request for permission* to suspend the system. The system is not actually suspended yet. So you should not be setting your SystemSuspended flag to True in reply to PBT_APMQUERYSUSPEND, only for PBT_APMSUSPEND. And then clearing the Flag in reply to PBT_APMRESUMESUSPEND and PBT_APMRESUMECRITICAL, not just for PBT_APMRESUMEAUTOMATIC. SC_SCREENSAVE and SC_MONITORPOWER are not window messages, they are flags of WM_SYSCOMMAND, so your 1st "If" block will never evaluate as True. Same with the last "If" block here, too. Also, per the WM_SYSCOMMAND documentation:
  21. Yes, that is what I used but it doesn't take care of the screen saver. Thanks to this blog post I updated to use PowerCfg when (OS>=Win7).
  22. I use this function for this: https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-setthreadexecutionstate
  23. Our laptops are under company governance, so we can't prevent the session from locking as it is dictated by the policies. In addition, the idle time is really short. So - we wrote LockBlock which basically simulates toggling the numlock every 60 seconds. That prevented the auto locking, but it also prevented the screensaver from kicking in when the dektkop was locked, so I added handling of lock/unlock to disable the fake keystrokes when it was locked. Super simple UI: 60 second interval, starting at 8 in the morning, lasting for 8 hours - with an add an extra hour button for off work hours lock blocking. Project source attached. LockBlock.zip
  24. FPiette

    git workflow question

    Maybe a direct question would be better in front of your message. Maybe everybody have no time to read such a long text 😉
  25. Sounds like an 'Awesome' feature while entering financial data into a spreadsheet