-
Content Count
2268 -
Joined
-
Last visited
-
Days Won
46
Everything posted by Fr0sT.Brutal
-
Good practices with nested methods
Fr0sT.Brutal replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
Nested methods are fine. Just place as many variables as possible after them to avoid side effects. -
AFAIK there's no way except breakpoint on catch block
-
Recommended Cryptographic Library
Fr0sT.Brutal replied to Ivana's topic in Project Planning and -Management
Check Awesome-Pascal list from my signature as well -
And the next version should be Delphi 10 Wacken \m/
-
Rules for changing cursor to HourGlass and back
Fr0sT.Brutal replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
IMO nowadays it's better to show modal progress window (or even make the process async) -
On The Design Of Uses Clauses
Fr0sT.Brutal replied to Uwe Raabe's topic in Tips / Blogs / Tutorials / Videos
AFAIU, the only truly reliable way of detecting excess uses is removing each used unit one by one and try compiling. But even then there are possible false positives when something useful happens in unit's init section. Anyway I doubt this task is required frequently so slow process or some part of false positives is quite acceptable -
Conceptual - callbacks that are called from background thread
Fr0sT.Brutal posted a topic in Algorithms, Data Structures and Class Design
Hi all, I'm asking for advice. How do you deal with callbacks / events that are called in the context of bg thread? For example, there's a class that, say, performs archiving of data async-ly. It has input buffer and an event with a chunk of data it processed (suppose it doesn't store it but throws away to a caller immediately). And it starts a bg thread to process data. In result, OnProcessedData is called from that bg thread. type TOnDataProcessed = procedure (const Data: TBytes) of object; TСompressor = class constructor Create(const InputData: TBytes; OnDataProcessed: TOnDataProcessed); end; { TСompressor } constructor TСompressor.Create(const InputData: TBytes; OnDataProcessed: TOnDataProcessed); begin TThread.CreateAnonymousThread( procedure var ComprData: TBytes; begin repeat ComprData := Compress(InputData); OnDataProcessed(ComprData); // <-- callback from bg thread until Processed; end).Start; end; And if we create it with handler like usual... Compr := TСompressor.Create(Input, СompressorDataProcessed); procedure TForm1.СompressorDataProcessed(const Data: TBytes); begin Inc(Processed, Length(Data)); // <-- BANG! Access collision possible lblProcessed.Caption := IntToStr(Processed); end; So what's the best way to avoid such situations? I underline - it is a library class. We can't be sure it will be always used in GUI env - so PostMessage is not a reliable option. 0) Comments/documentation - not an option, if some info could be missed, it will be missed 1) Naming convention like OnDataProcessedBgThread: TOnDataProcessedBgThread - simple but just a hint/reminder for a class user. 2) Synchronize is not much more useful because it could lead to deadlocks and lowers performance. 3) PostThreadMessage? Will require message processing loop which is not trivial for main application thread 4) Store records for each callback call in class' thread-safe queue and consume from it by a timer? 5) Ideas? -
Is classic Open package > Build > Install way already obsolete? Just curious - what so specific in install process that it requires special installer? Btw, there's an effort to make a package manager for Delphi called Delphinus. I haven't tried it yet but it looks promising.
-
1. Have IDE open that unit 2. Check its path 3. Profit )))
-
Conceptual - callbacks that are called from background thread
Fr0sT.Brutal replied to Fr0sT.Brutal's topic in Algorithms, Data Structures and Class Design
Thanks to all who answered, sorry for late response. Docs are good but hardly ever being read from A to Z. Interface should be intuitive IMHO or at least give some hints. Very interesting regarding work queues. Have you got any shareable code to look at? What about Synchronize/Queue? I always tried to avoid it but see Emba have done pretty much in this area. Is it safe? -
Refer to Form Control without using the Form unit?
Fr0sT.Brutal replied to Mike Torrettinni's topic in VCL
Well, I don't know your needs but I'd move special translation to the form itself so that translator wouldn't know anything specific about controls. Like Form.OnShow TranslateCommon(Self); TranslateSpecial1([Spec1Button, Spec1Label, ...]); TranslateSpecial2([Spec2Button, Spec2Combo, ...]); -
Suggestion/discussion. Process incoming data when Server has closed connection
Fr0sT.Brutal posted a topic in ICS - Internet Component Suite
Faced the issue in my project. I have OnDataAvailable reading and processing data and OnSessionClosed logging the event and doing some other things. And in some cases server sends a response and then immediately closes connection. So I get: OnDataAvailable OnDataAvailable FD_CLOSE that calls OnDataAvailable and then OnSessionClosed The problem is that in OnDataAvailable I can't tell whether the socket has been closed or not because FCloseInvoked flag is set to True only after DataAvailable loop. I suggest (if that won't harm or change behavior) to set FCloseInvoked flag before DataAvailable loop and publish it as read-only property so that a user could distinguish whether he can expect some more data or not. For now I had to call processing method from OnSessionClosed as well. -
Suggestion/discussion. Process incoming data when Server has closed connection
Fr0sT.Brutal replied to Fr0sT.Brutal's topic in ICS - Internet Component Suite
Angus, I have wsoReceiveLoop option set and before calling OnSessionClosed OnDataAvailable is being called anyway. In current state processing code should be extracted to separate method and called from both OnSessionClosed and OnDataAvailable, moreover it is likely to require SocketClosed parameter to decide whether there will be no data anymore or it could expect some. -
Passing back a string from an external program
Fr0sT.Brutal replied to dummzeuch's topic in Windows API
Why inventing bicycles with triangular wheels when writing to STDOUT is a very simple method proven by decades? All *nix ecosystem is built on this mechanism. Executed app won't need anything more than WriteLn and executor app will have to intercept pipe handles. -
Refer to Form Control without using the Form unit?
Fr0sT.Brutal replied to Mike Torrettinni's topic in VCL
Am I right that you in your TranslateProject method you have mentions of all translatable components from all forms in a project? -
How to reliably know if there is data selected in TVirtualStringTree
Fr0sT.Brutal replied to Mike Torrettinni's topic in VCL
Some of these checks are senseless. Sender could not be nil. And you unlikely need GetFirst check unless you really use the first node not a focused one. In most cases, you only need one check for FocusedNode. -
Things that every desktop program should do
Fr0sT.Brutal replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Addition: if you have splitters or grid-style listviews with columns, save and restore their settings too -
The same for me. 1) Form event handlers 2) Utilities (public/private methods) 2) Child controls' event handlers 3) Message handlers If there's pretty much code, I also put these groups into REGIONs It's a shame IDE autogeneration doesn't have an option to generate method name according to where it is declared
-
Using Continue in repeat statement
Fr0sT.Brutal replied to Kryvich's topic in RTL and Delphi Object Pascal
repeat-until is slightly hard to realize construction because of its negative condition check. I use the following mnemonic: repeat stuff until condition is true. -
On The Design Of Uses Clauses
Fr0sT.Brutal replied to Uwe Raabe's topic in Tips / Blogs / Tutorials / Videos
That's exactly the scheme I came to. I also avoid using units in impl. section except for app's forms. -
(Not a) Design flaw in OverbyteIcsHttpSrv.THttpConnection.ConnectionDataAvailable
Fr0sT.Brutal posted a topic in ICS - Internet Component Suite
Method `OverbyteIcsHttpSrv.THttpConnection.ConnectionDataAvailable` contains following line: { We use line mode. We will receive complete lines } FRcvdLine := ReceiveStr; And below it is supposed that server have received HTTP-complete (ending with CRLF) line. But { Receive as much data as possible into a string } { You should avoid this function and use Receive. Using string will be } { much slower because data will be copied several times. } { ReceiveStr will *NOT* wait for a line to be received. It just read } { already received characters and return them as a string. } function TCustomWSocket.ReceiveStr : String; so a situation is possible when a chunk of header could be processed incorrectly or ignored. I suppose some kind of buffered line reader should be used. -
(Not a) Design flaw in OverbyteIcsHttpSrv.THttpConnection.ConnectionDataAvailable
Fr0sT.Brutal replied to Fr0sT.Brutal's topic in ICS - Internet Component Suite
I'll try to not make false alarms -
(Not a) Design flaw in OverbyteIcsHttpSrv.THttpConnection.ConnectionDataAvailable
Fr0sT.Brutal replied to Fr0sT.Brutal's topic in ICS - Internet Component Suite
Sherlock, feel free to delete the topic completely 😉 -
(Not a) Design flaw in OverbyteIcsHttpSrv.THttpConnection.ConnectionDataAvailable
Fr0sT.Brutal replied to Fr0sT.Brutal's topic in ICS - Internet Component Suite
Yep, false alert, sorry. I was misleaded by that comment above TCustomWSocket.ReceiveStr and didn't notice that TCustomLineWSocket does all the necessary stuff incl. size check. -
Bug: HTTPTunnel and Socks servers can't have non-IP address
Fr0sT.Brutal replied to Fr0sT.Brutal's topic in ICS - Internet Component Suite
I've never dealt with IPv6 but for me the purpose of this piece а code is to 1) assign v6 family from v6 IP address so that a user doesn't have to specify the family manually and 2) if IP is v6 check that OS supports it. And I'm not sure whether 2) is necessary, maybe it would fail later anyway on address resolution.